16

Windows がリムーバブル ボリュームのシェル コンテキスト メニューで使用できる「取り出し」機能を実行するために使用する API、または一連の API 呼び出しを知っていますか?

これまでのところ、次の 2 つのことを試しました。

  1. CM_Request_Device_Ejectを使用して、( SetupDiXXX APIを使用して) リムーバブル ディスクを列挙し、関心のあるディスクを見つけ、( CM_XXX APIを使用して) デバイス マネージャー階層をたどり、最後に、関心のあるデバイスの を呼び出しCM_Request_Device_EjectますdevInst。これは、マイ コンピュータからボリュームを削除し、デバイスを「安全に削除できる」(削除できる状態にする) という意味で機能しますが、シェル コンテキスト メニューの「取り出し」機能とは異なりますこれを知る方法は、イジェクトしようとしているデバイスが、イジェクト時に何かを実行するはずであり、 を使用してイジェクトを実行しても何も起こらないためCM_Request_Device_Ejectです。

  2. IOCTL_STORAGE_EJECT_MEDIA制御コードでDeviceIoControlを使用します。イベントのシーケンスは次のとおりです。

    これはまったく機能しません。各呼び出しは(0x00000001)DeviceIoControlで失敗します。ERROR_IVALID_FUNCTION通話が失敗する理由がわかりません。DeviceIoControl への他の呼び出しが同じファイル ハンドル ( IOCTL_STORAGE_GET_DEVICE_NUMBERなど)に対して正常に機能することを確認しました。

最後に、私の開発マシンは Windows 7 x64 を実行しており、2 番目の方法を機能させるために、管理者権限でアプリケーションを実行しようとしましたが、何も変わりませんでした。

編集

最終的に、アプローチ 2 のどこで間違いを犯していたのかがわかりました。を使用してボリュームへのハンドルを開くときに、何らかの理由で目的のアクセスを正しく設定していなかったことが判明しましたCreateFile。正しいアクセス モードはGENERIC_READ | GENERIC_WRITEで、0 を渡していました。エラーを修正した後、 を使用してデバイスを正常に取り出すことができました。DeviceIoControl - IOCTL_STORAGE_EJECT_MEDIAまた、方法 #1 を使用してCM_Request_Device_Eject.

そして、メソッド #2 は、実際にシェル コンテキスト メニューの "Eject" 機能で使用されるメソッドであることがわかります。この方法を使用すると、デバイスは正しく反応します。

4

2 に答える 2

2

最終的に、アプローチ 2 のどこで間違いを犯していたのかがわかりました。

CreateFile を使用してボリュームへのハンドルを開くときに、何らかの理由で目的のアクセスを正しく設定していなかったことが判明しました。

正しいアクセス モードはGENERIC_READ | GENERIC_WRITEで、私は を渡して0いました。エラーを修正した後、DeviceIoControl - IOCTL_STORAGE_EJECT_MEDIA を使用してデバイスを正常に取り出すことができました。また、CM_Request_Device_Eject を使用して方法 1 を使用しました。

最後に、メソッド #2 はシェル コンテキスト メニューの「イジェクト」機能で使用されるメソッドであることがわかります。この方法を使用すると、デバイスは正しく反応します。

于 2015-03-20T02:56:22.390 に答える
0

「CM_Request_Device_Eject」で検索しているときに偶然ここに来て、最近私が同様のソリューションをまとめて行ったソリューションに似ていることがわかりました。遅い答えを許してください。

私のプロジェクトでこれまでに行った手順を、この SO answerにまとめました。

于 2015-03-19T01:27:06.013 に答える