ドライブレターを指定して、USBメモリを安全に取り外す方法

[戻る]
ブヒブヒ 2010/02/05(金) 15:48:35
いつもお世話になっております。
ブヒブヒでございます。

USBメモリをドライブレターを指定して
安全に取り外す方法を教えていただけないでしょうか。

開発環境
WindowsXP Pro SP3
Visual Studio 2005 SP1
WinDDK
プラットフォームSDK

動作対象
2000SP4, XP, Vista, 7

いろいろなサイトのソースを見て
試行錯誤しているのですが、うまくいきません。

大変申し訳ありませんが、
よろしくお願いいたします。

tetrapod 2010/02/05(金) 16:46:34
> いろいろなサイトのソースを見て
> 試行錯誤しているのですが、うまくいきません。
こんな中途半端なことを書かずに、何を調べて何がダメだったのかを書くべし。

http://www.usefullcode.net/2006/12/post_22.html
この辺は参考にならんかのぉ
すると CM_Request_Device_Eject_Ex とか書いてあるから、これで検索したら
http://www.codeguru.com/forum/showthread.php?t=281916
こんなものまで見つかるわけで、ここまで5分程度・・・

ブヒブヒ 2010/02/05(金) 18:32:05
tetrapod様、
お返事ありがとうございます。


なるほど、
デバイスインスタンスIDで
USBメモリを指定して取り外す方法ですね。
試してみます。



私が試したのは以下になります。

相談天国: VC++
http://blog701.seesaa.net/category/5399058-1.html
上記サイトを元に、
USBViewで取得できるiProductの文字列を
SetupDiGetDeviceRegistryProperty( hDevInfo, &sDevInfo, 
SPDRP_LOCATION_INFORMATION, .....);
で同じ文字列を探して、
CM_Request_Device_Eject(...);
を実行していたのですが、
Vistaや7ではiProductと同じ文字列を取得することが出来ず、
デバイスの取り外しが出来ません。

そこで
ドライブレターを指定してQueryDosDeviceで取得できる、
文字列を
SetupDiGetDeviceRegistryProperty( hDevInfo, &sDevInfo, 
SPDRP_PHYSICAL_DEVICE_OBJECT_NAME, .....);
で同じものを探して、
CM_Request_Device_Eject(...);
を実行すると、
「この汎用ボリュームは取り外せません。」
というエラーが出てだめでした。


ブヒブヒ

ブヒブヒ 2010/02/09(火) 18:08:39
[[解決]]
お返事が遅くなり、大変申し訳ありません。
下記、ソースで取り外しを行うことが出来ました。
ありがとうございました。

※引数にデバイスインスタンスIDを渡す
int DeviceEject( CString strDeviceInstID )
{
    HMACHINE hMachine = NULL;
    DEVINST dnDevInst = NULL;
    PDEVINST pdnDevInst_OUT = &dnDevInst;

    TCHAR szDeviceInstID[ 512 ];
    SecureZeroMemory( szDeviceInstID, sizeof(TCHAR) * 512 );

#if UNICODE
    wcsncpy_s( szDeviceInstID, 512, strDeviceInstID, 
strDeviceInstID.GetLength() );
#else
    strncpy_s( szDeviceInstID, 512, strDeviceInstID, 
strDeviceInstID.GetLength() );
#endif

    {
        int iRet = CM_Locate_DevNode_Ex(pdnDevInst_OUT, 
szDeviceInstID, CM_LOCATE_DEVNODE_NORMAL, hMachine);
        if( iRet != 0 )
        {
            return -1;//デバイスが無かった
        }
    }

    {
        int iRet = CM_Request_Device_Eject_Ex(dnDevInst, NULL, NULL, 
0, 0, hMachine );
        if( iRet == 0 )
        {
            return 1;// 取り外せた
        }
    }

    return 0;// 取り外せなかった
}

古いスレッドには追加発言できません。