USBメモリーの切り離し – プログラミング – Home

通知
すべてクリア

USBメモリーの切り離し


よっしぃ
 よっしぃ
(@よっしぃ)
ゲスト
結合: 16年前
投稿: 10
Topic starter  

USBメモリに書込後、「抜いてもいいよ。」のところまで、アプリケーションで制御した
いです。

「ハードウエアの安全な切り離し」→「ハードウエアデバイスの停止」
のように、
「USBメモリの停止」をアプリケーションで行うにはどのようにすればよいでしょう。
API等で可能でしょうか?

使用環境はWindows XP/Vistaで、VC++ で開発しております。

よろしくお願いします。


引用解決済
トピックタグ
ITO
 ITO
(@ITO)
ゲスト
結合: 22年前
投稿: 1235
 

>「USBメモリの停止」をアプリケーションで行うにはどのようにすればよいでしょう。
> API等で可能でしょうか?
原則的に不可能です。
 APIで「DeviceIoControl」という関数があるのでデバイスが特定できれば
可能だと思います。
 すべての「USBメモリ」となると不可能だと思います。


返信引用
よっしぃ
 よっしぃ
(@よっしぃ)
ゲスト
結合: 16年前
投稿: 10
Topic starter  

返答ありがとうございます。参考になります。

「DeviceIoControl」で、たとえば、E~Zドライブを順になめていって、
「イジェクト」処理をすればいいのかな。などふと考えました。


返信引用
...
 ...
(@...)
ゲスト
結合: 22年前
投稿: 113
 

>たとえば、E~Zドライブを順になめていって…
FDDもZ:とかに変更出来なかったっけ?


返信引用
瀬戸っぷ
 瀬戸っぷ
(@瀬戸っぷ)
ゲスト
結合: 18年前
投稿: 178
 

>FDDもZ:とかに変更出来なかったっけ?

逆ですが、リムーバブルドライブをB:に割り当て可能ですね。
SDリーダメライタをB:にしています。(XP Pro SP3にて)
# 仮想メモリの変更しようとするとエラーが出ますが。メディア入っていないから。

んで、USBデバイスの停止自体は可能です。
面倒ですけど。

http://winofsql.jp/VA003334/usb080803163310.htm
http://d.hatena.ne.jp/deraw/20060818/1155852407

API名など出てくるのでググって下さい。


返信引用
瀬戸っぷ
 瀬戸っぷ
(@瀬戸っぷ)
ゲスト
結合: 18年前
投稿: 178
 

あんましきれいなコードではありませんが…
# インデント深かったりその他…

BOOL USBDriveRemove(TCHAR Drive)
{
BOOL fResult = FALSE;

Drive = static_cast<TCHAR>(_totupper(static_cast<unsigned int>(Drive)));
if((GetLogicalDrives() & (1 << (Drive - _T('A'))))) {
TCHAR szMountedDevicesName[] = { _T(\\DosDevices\\A:) };
HKEY hRegKey = NULL;
TCHAR szCheckStr[MAX_PATH] = {0}, szTemp[MAX_PATH] = {0}, szTemp2[MAX_PATH],
szDeviceId[MAX_PATH] = {0};
DWORD dwType, dwSize = MAX_PATH;
LPBYTE lpData = NULL;

szMountedDevicesName[_tcslen(szMountedDevicesName) - _tcslen(_T(A:))] = Drive;
RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T(SYSTEM\\MountedDevices), 0,
KEY_ALL_ACCESS, &hRegKey);
dwType = REG_BINARY;
RegQueryValueEx(hRegKey, szMountedDevicesName, NULL, &dwType, NULL, &dwSize);
lpData = reinterpret_cast<LPBYTE>(HeapAlloc(hHeap, HEAP_ZERO_MEMORY, dwSize
+ sizeof(TCHAR))); // '\0'分を付加
RegQueryValueEx(hRegKey, szMountedDevicesName, NULL, &dwType, lpData, &dwSize);
RegCloseKey(hRegKey);
hRegKey = NULL;

// REG_BINARY(WCHAR_T?)から文字列へ(UNICODEの場合は別…か?)
WideCharToMultiByte(CP_ACP, 0, reinterpret_cast<LPCWSTR>(lpData), dwSize,
szTemp, MAX_PATH, NULL, NULL);
HeapFree(hHeap, 0, lpData);
lpData = NULL;
// 取得した文字列から取り除き
if(_tcsstr(szTemp, _T(STORAGE#RemovableMedia#)) != NULL && _tcsstr(szTemp,
_T(&RM#{)) != NULL) {
static_cast<TCHAR>(*(_tcsstr(szTemp, _T(&RM#{)))) = '\0';
_tcscpy(szCheckStr, _tcsstr(szTemp, _T(STORAGE#RemovableMedia#)) +
_tcslen(_T(STORAGE#RemovableMedia#)));
}
// 取得できたら…
if(_tcslen(szCheckStr) != 0) {
TCHAR szEnumNo[16];
DWORD dwLoopCnt, dwCount;

RegOpenKeyEx(HKEY_LOCAL_MACHINE,
_T(SYSTEM\\CurrentControlSet\\Services\\Disk\\Enum), 0, KEY_ALL_ACCESS, &hRegKey);
if(hRegKey) {
dwSize = sizeof(DWORD);
dwType = REG_DWORD;
RegQueryValueEx(hRegKey, _T(Count), NULL, &dwType,
reinterpret_cast<LPBYTE>(&dwCount), &dwSize);
for(dwLoopCnt = 0;dwLoopCnt < dwCount;dwLoopCnt++) {
wsprintf(szEnumNo, %d, dwLoopCnt);
dwSize = MAX_PATH;
dwType = REG_SZ;
RegQueryValueEx(hRegKey, szEnumNo, NULL, &dwType,
reinterpret_cast<LPBYTE>(szTemp2), &dwSize);
if(_tcsstr(szTemp2, _T(USBSTOR\\Disk&)) != NULL) {
HKEY hQueryKey = NULL;

_tcscpy(szTemp, _T(SYSTEM\\CurrentControlSet\\Enum\\));
_tcscat(szTemp, szTemp2);
RegOpenKeyEx(HKEY_LOCAL_MACHINE, szTemp, 0, KEY_READ, &hQueryKey);
dwSize = MAX_PATH;
dwType = REG_SZ;
RegQueryValueEx(hQueryKey, _T(ParentIdPrefix), NULL, &dwType,
reinterpret_cast<LPBYTE>(szTemp2), &dwSize);
RegCloseKey(hQueryKey);
if(_tcscmp(szCheckStr, szTemp2) == 0) {
_tsplitpath(szTemp, NULL, NULL, szCheckStr, NULL);
static_cast<TCHAR>(*(_tcschr (szCheckStr, _T('&')))) = '\0';
break;
}
}
}
if(dwLoopCnt == dwCount) {
ZeroMemory(szCheckStr, sizeof(szCheckStr));
}
}
RegCloseKey(hRegKey);

↓次に続く


返信引用
瀬戸っぷ
 瀬戸っぷ
(@瀬戸っぷ)
ゲスト
結合: 18年前
投稿: 178
 

↓上から続き
if(_tcslen(szCheckStr) != 0) {
HDEVINFO hDevInfo;

hDevInfo = SetupDiGetClassDevs( NULL, 0, 0, DIGCF_PRESENT | DIGCF_ALLCLASSES );
if(hDevInfo != INVALID_HANDLE_VALUE) {
SP_DEVINFO_DATA DeviceInfoData = {sizeof(SP_DEVINFO_DATA)};

for (dwCount=0; SetupDiEnumDeviceInfo(hDevInfo, dwCount, &DeviceInfoData);
dwCount++) {
// デバイスのステータスを取得
ULONG status = 0;
ULONG problem = 0;
CONFIGRET cr = CM_Get_DevNode_Status(&status, &problem,
DeviceInfoData.DevInst, 0);

if (cr == CR_SUCCESS) {
if ((status & DN_DISABLEABLE)) {
BOOL ret = FALSE;
BYTE* value = NULL;
DWORD type;
DWORD size = 0;

while(1)
{
ret = SetupDiGetDeviceRegistryProperty(hDevInfo, &DeviceInfoData,
SPDRP_SERVICE, &type, value, size, &size);

if(ret || (GetLastError() != ERROR_INSUFFICIENT_BUFFER)) {
break;
}

if (value) {
HeapFree(hHeap, 0, value);
value = NULL;
}
value = reinterpret_cast<BYTE *>(HeapAlloc(hHeap, 0, size));
}
if(value && _tcscmp(reinterpret_cast<TCHAR *>(value), _T(USBSTOR)) ==
0 && DeviceInfoData.DevInst > 0) {

CM_Get_Device_ID(DeviceInfoData.DevInst, szTemp, MAX_PATH, 0);
_tsplitpath(szTemp, NULL, NULL, szDeviceId, NULL);
if(_tcscmp(szCheckStr, szDeviceId) == 0 &&
CM_Request_Device_Eject(DeviceInfoData.DevInst, NULL, NULL, 0, 0) == CR_SUCCESS) {
// 取り外し成功
fResult = TRUE;
} else {
// 取り外し失敗
}
}
if (value) {
HeapFree(hHeap, 0, value);
value = NULL;
}
}
}
}
}
}
}
}

return fResult;
}

グローバルとしてヒープハンドルなhHeapが必要です。
setupapi.libのリンク、setupapi.hとcfgmgr32.hのインクルードも必要。
# 使用しているAPIで他にもたぶん必要。
レジストリも参照していたりします。

WinXP Pro SP2にVS2008EEで動作確認しました。


返信引用
ZCH
 ZCH
(@ZCH)
ゲスト
結合: 16年前
投稿: 25
 

WMI を使えば比較的簡単なコードでできます。

http://blog701.seesaa.net/article/104160698.html
とかどうでしょうか。


返信引用

返信する

投稿者名

投稿者メールアドレス

タイトル *

プレビュー 0リビジョン 保存しました
共有:
タイトルとURLをコピーしました