用win32 API监听U盘插拔并取得其盘符/取得当前插入U盘的盘符

用win32 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\n", driverLabel);
			} else {
				printf("remove %c\r\n", driverLabel);
			}
        }
    }
    return 0;
}

用win32 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;
}


你可能感兴趣的:(用win32 API监听U盘插拔并取得其盘符/取得当前插入U盘的盘符)