Wissen Sie, welche API oder welche Sequenz von API-Aufrufen Windows verwendet, um die Funktion "Eject" auszuführen, die im Shell-Kontextmenü für austauschbare Volumes verfügbar ist?Wie wird ein USB-Wechseldatenträger/Volume ausgeworfen, ähnlich der "Auswerfen" -Funktion im Windows Explorer?
Bisher habe ich versucht, zwei Dinge:
CM_Request_Device_Eject verwenden, aufzuzählen ich die Festplatten (mit dem SetupDiXXX APIs), finden die, die ich interessiert bin, gehen die Geräte-Manager-Hierarchie (Verwenden CM_XXX APIs) und schließlich Anruf
CM_Request_Device_Eject
auf derdevInst
des Geräts, das ich interessiere. Dieses funktioniert in dem Sinne, dass es die Volumes von Arbeitsplatz entfernt und macht das Gerät "sicher zu entfernen" (bereit, entfernt werden) aber es ist nicht dasselbe wie das Shell-Kontextmenü "Auswerfen" -Funktion. Die Art, wie ich das weiß ist, weil das Gerät, das ich ausstoßen will etwas tun soll, wenn es ausgeworfen wird und dass etwas nicht passiert, wenn ich den Auswurf mitCM_Request_Device_Eject
.mit DeviceIoControl mit dem IOCTL_STORAGE_EJECT_MEDIA Steuercode. Die Abfolge der Ereignisse ist:
- einen Griff auf das Volumen in CreateFile wie in der Dokumentation
- vorgeschlagen mit Interesse Ich bin erhalten versuchen, die Lautstärke mit FSCTL_LOCK_VOLUME
- Versuch zu verriegeln mit abzusteigen FSCTL_DISMOUNT_VOLUME
- deaktivieren Sie das Entfernen des Speichermediums mit IOCTL_STORAGE_MEDIA_REMOVAL
- und führen Sie schließlich die IOCTL_STORAGE_EJECT_MEDIA Funktion aus.
Dies funktioniert überhaupt nicht. Jeder der
DeviceIoControl
Aufrufe schlägt mitERROR_IVALID_FUNCTION
(0x00000001) fehl. Ich weiß nicht, warum die Anrufe fehlschlagen. Ich habe festgestellt, dass weitere Anrufe funktionieren für die gleiche Datei-Handle (wie IOCTL_STORAGE_GET_DEVICE_NUMBER)
Schließlich meine Entwicklung Maschine läuft Windows 7 x64, und um DeviceIOControl die zweite Methode zu arbeiten, ich zu bekommen habe versucht, meine Anwendung mit Administratorrechten auszuführen, und das hat nichts geändert.
EDIT
Schließlich fand ich heraus, wo ich einen Fehler mit Ansatz # 2 zu machen war. Es stellt sich heraus, dass ich aus irgendeinem Grund den gewünschten Zugriff nicht richtig eingestellt habe, wenn ich den Griff zum Volume mit CreateFile
geöffnet habe. Der korrekte Zugriffsmodus ist GENERIC_READ | GENERIC_WRITE
und ich passierte 0. Nach der Korrektur meines Fehlers konnte ich das Gerät mit DeviceIoControl - IOCTL_STORAGE_EJECT_MEDIA
, sowie mit Methode # 1, CM_Request_Device_Eject
erfolgreich auswerfen.
Und es stellt sich heraus, dass Methode # 2 tatsächlich die Methode ist, die von der "Auswerfen" -Funktion des Shell-Kontextmenüs verwendet wird. Mit dieser Methode reagiert das Gerät korrekt.
Ihr Ansatz # 2 sollte funktionieren. Auf http://stackoverflow.com/questions/58670/windows-cdrom-eject hat mir die Antwort von Andreas Magnusson geholfen, einen USB-Stick auszuwerfen. Die einzige Änderung war, seine Schreibweise von "DeviceIoControl" zu korrigieren. – Nate
Außerdem gibt 'DeviceIoControl' bei Erfolg '1' zurück. Wenn Sie den Fehler 'ERROR_INVALID_FUNCTION' erhalten, ist das der Rückgabewert von 'DeviceIoControl' oder gibt es '0' zurück und Sie rufen' GetLastError' auf? – Nate
@Nate: DeviceIoControl gibt 0 zurück, wenn ich es mit einem der Steuercodes, die ich erwähnte, aufrufe. Wenn ich dann GetLastError() aufrufen, gibt es 1 zurück, was ERROR_INVALID_FUNCTION ist. –