USBメモリに書込後、「抜いてもいいよ。」のところまで、アプリケーションで制御した
いです。
「ハードウエアの安全な切り離し」→「ハードウエアデバイスの停止」
のように、
「USBメモリの停止」をアプリケーションで行うにはどのようにすればよいでしょう。
API等で可能でしょうか?
使用環境はWindows XP/Vistaで、VC++ で開発しております。
よろしくお願いします。
>「USBメモリの停止」をアプリケーションで行うにはどのようにすればよいでしょう。
> API等で可能でしょうか?
原則的に不可能です。
 APIで「DeviceIoControl」という関数があるのでデバイスが特定できれば
可能だと思います。
 すべての「USBメモリ」となると不可能だと思います。
返答ありがとうございます。参考になります。
「DeviceIoControl」で、たとえば、E~Zドライブを順になめていって、
「イジェクト」処理をすればいいのかな。などふと考えました。
>たとえば、E~Zドライブを順になめていって…
FDDもZ:とかに変更出来なかったっけ?
>FDDもZ:とかに変更出来なかったっけ?
逆ですが、リムーバブルドライブをB:に割り当て可能ですね。
SDリーダメライタをB:にしています。(XP Pro SP3にて)
# 仮想メモリの変更しようとするとエラーが出ますが。メディア入っていないから。
んで、USBデバイスの停止自体は可能です。
面倒ですけど。
 http://winofsql.jp/VA003334/usb080803163310.htm 
 http://d.hatena.ne.jp/deraw/20060818/1155852407 
API名など出てくるのでググって下さい。
あんましきれいなコードではありませんが…
# インデント深かったりその他…
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);
↓次に続く
↓上から続き
			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で動作確認しました。

 
  
  
  
  