お世話になります。
Windows7、VC++6.0にて作成したアプリから
ハードウェアの取り外しを行いたいのですが手段がわかりません。
ハードウェアの取り外しを行うAPI等を御存知方がおりました
お教えください。
ハードウェアって何を指し示しているのでしょうか?
USB関係?PCIボード?
探せば、結構あるんですがネ〜
以上。
取り外しを行いたいハードウェアはUSBメモリです。
API、DeviceIoControlは既に試しましたが、完全に外しきれないように
しかできませんでした。
「コンピューター」から見た場合、ツリー表示からは消えますが
アイコンは残るので、DVDドライブからディスクだけイジェクトした
ような状態といいますか・・・。
色々と探したつもりなのですが、他の手段等ありましたらお教えください。
やはりUSBメモリでしたか・・・
簡単そうで結構厄介
例えばC$で書かれたもの
http://www.codeproject.com/KB/system/usbeject.aspx
Win7なので、実際には管理者権限が必要ですが・・・
ガジェットでできるものが・・・
http://gallery.live.com/results.aspx?bt=1&pl=1&ds=1&la=%7B%7D&tier=0&st=4&p=1&tag=usb&c=8
ここの「Q's Drive Info」に含まれているもので
RD.exeがその動作を行います。
これでは管理者権限が無いのでイジェクトしています。
私も調べていないので、管理者権限を必要とせず完全にイジェクト
する方法は知りません。
以上。参考まで
あれ?誤記・・・
C#の間違いネ!
以上。
いろいろ調べているうちに、C++で書かれたソースコード
見つけました。VC6 でしたが、VS2008でリコンパイルも
問題なくできました
http://www.techtalkz.com/microsoft-device-drivers/250734-remove-usb-device-c-3.html
で、APIですが・・・
USBメモリが、単体で1ドライブとして割り付けられたもの
では、管理者権限は必要なく、CM_Request_Device_EjectW
で、リムーブできます。
逆にセキュアなUSBメモリでは、CD-ROMとリムーバブルに
見える(複数ドライブに割り付けられたもの)では、
CM_Query_And_Remove_SubTreeW で、先頭ドライブを設定
することでリムーブできました。
※ 上記URLのスースコードを変更してます。
参考コード(修正点)
bool IsRemovable = ((DriveType & DRIVE_REMOVABLE) != 0);
for ( long tries=1; tries<=3; tries++ ) { // sometimes we need some tries...
VetoNameW[0] = 0;
// CM_Query_And_Remove_SubTree doesn't work for restricted users
//res = CM_Query_And_Remove_SubTreeW(DevInstParent, &VetoType, VetoNameW, MAX_PATH, CM_REMOVE_NO_RESTART); // CM_Query_And_Remove_SubTreeA is not implemented under W2K!
//res = CM_Query_And_Remove_SubTreeW(DevInstParent, NULL, NULL, 0, CM_REMOVE_NO_RESTART); // with messagebox (W2K, Vista) or balloon (XP)
// res = CM_Request_Device_EjectW(DevInstParent, &VetoType, VetoNameW, MAX_PATH, 0);
//res = CM_Request_Device_EjectW(DevInstParent, NULL, NULL, 0, 0); // with messagebox (W2K, Vista) or balloon (XP)
if ( IsRemovable ) {
res = CM_Request_Device_EjectW(DevInstParent, &VetoType, VetoNameW, MAX_PATH, 0);
} else {
res = CM_Query_And_Remove_SubTreeW(DevInstParent, &VetoType, VetoNameW, MAX_PATH, CM_REMOVE_NO_RESTART);
}
bSuccess = (res==CR_SUCCESS && VetoType==PNP_VetoTypeUnknown);
if ( bSuccess ) {
break;
}
Sleep(500); // required to give the next tries a chance!
}
以上。
ご回答ありがとうございました。
現在、この件からは離れてしまっているのですが、
再開の際にぜひ参考にさせていただきたいと思います。
解決チェックを忘れていました。
編集 削除