win 32 APIでUディスクの挿抜を傍受し、そのディスクを取得する/現在挿入されているUディスクのディスクを取得する

3742 ワード

win 32 APIでUディスクの挿抜を傍受し、そのディスク文字を取得する
1.RegisterDeviceNotification()関数を使用して登録
static const GUID GUID_DEVINTERFACE_USB_DEVICE = 
	{0xA5DCBF10, 0x6530, 0x11D2, {0x90, 0x1F, 0x00, 0xC0, 0x4F, 0xB9, 0x51, 0xED}};

void RegisterDeviceNotify()
{
    HDEVNOTIFY hDevNotify;
    DEV_BROADCAST_DEVICEINTERFACE NotificationFilter;
    ZeroMemory( &NotificationFilter, sizeof(NotificationFilter) );
    NotificationFilter.dbcc_size = sizeof(DEV_BROADCAST_DEVICEINTERFACE);
    NotificationFilter.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
    NotificationFilter.dbcc_classguid = GUID_DEVINTERFACE_USB_DEVICE;
    hDevNotify = RegisterDeviceNotification(hWnd, &NotificationFilter, DEVICE_NOTIFY_WINDOW_HANDLE);
}

2.
WndProc()関数でWM_を受信DEVICECHANGEメッセージ
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch(message)
    {
    case WM_DEVICECHANGE:
        return DeviceChange(message, wParam, lParam);
    }

    return DefWindowProc(hWnd, message, wParam, lParam);
}

3.受信したWM_の処理DEVICECHANGEメッセージ
char FirstDriveFromMask(ULONG unitmask)
{
   char i;

   for (i = 0; i < 26; ++i)
   {
      if (unitmask & 0x1)
         break;
      unitmask >>= 1;
   }

   return (i + 'A');
}

LRESULT DeviceChange(UINT message, WPARAM wParam, LPARAM lParam)
{
    if ( DBT_DEVICEARRIVAL == wParam || DBT_DEVICEREMOVECOMPLETE == wParam ) 
    {
        PDEV_BROADCAST_HDR pHdr = (PDEV_BROADCAST_HDR)lParam;
        if (pHdr->dbch_devicetype == DBT_DEVTYP_VOLUME) 
        {
            PDEV_BROADCAST_VOLUME pDevVolume = (PDEV_BROADCAST_VOLUME)lParam;
			char driverLabel = FirstDriveFromMask(pDevVolume->dbcv_unitmask);
			if (wParam == DBT_DEVICEARRIVAL) {
				printf("add %c\r
", driverLabel); } else { printf("remove %c\r
", driverLabel); } } } return 0; }

win 32 APIで現在挿入されているUディスクのディスクを取得する
1.GetLogicalDrives()を使用して各パーティションを表すマスクを取得する
DWORD mask = GetLogicalDrives();
2.マスクの各ビットを巡回し、対応するパーティションがUディスクであるか否かを判断する
bool IsUsbDevice(wchar_t letter)
{
    wchar_t volumeAccessPath[] = L"\\\\.\\X:";
    volumeAccessPath[4] = letter;

    HANDLE deviceHandle = CreateFile(
	    volumeAccessPath,
	    0,                // no access to the drive
	    FILE_SHARE_READ | // share mode
	    FILE_SHARE_WRITE, 
	    NULL,             // default security attributes
	    OPEN_EXISTING,    // disposition
	    0,                // file attributes
	    NULL);            // do not copy file attributes

    // setup query
    STORAGE_PROPERTY_QUERY query;
    memset(&query, 0, sizeof(query));
    query.PropertyId = StorageDeviceProperty;
    query.QueryType = PropertyStandardQuery;

    // issue query
    DWORD bytes;
    STORAGE_DEVICE_DESCRIPTOR devd;
    STORAGE_BUS_TYPE busType = BusTypeUnknown;

    if (DeviceIoControl(deviceHandle,
		IOCTL_STORAGE_QUERY_PROPERTY,
		&query, sizeof(query),
		&devd, sizeof(devd),
		&bytes, NULL))
    {
	busType = devd.BusType;
    }

    CloseHandle(deviceHandle);

    return BusTypeUsb == busType;
}

//   U 
//   :  _letter   U   
//    :true    U 
//       false    U 
bool findUSBStorage(char* _letter)
{
    DWORD mask = GetLogicalDrives();
    int count = 0;
    while (mask != 0)
    {
	    if ((mask & 0x01) == 1)
	    {
	        wchar_t letter = L'A' + count;

                //           U 
	        if (IsUsbDevice(letter))
	        {
                    wcstombs(_letter, &letter, 1);
                    return true;
	        }
	    }
	    count++;
	    mask = mask >> 1;
    }
    return false;
}