用win32 API监听U盘插拔并取得其盘符/取得当前插入U盘的盘符
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了用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();
- 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盘的盘符的主要内容,如果未能解决你的问题,请参考以下文章
x86下 linux qt检测U盘插拔------- HAL 与UDISKS
装daemon tools 或者 Virtual CloneDrive 无法加载光盘映像,也看不到虚拟的盘符,我的系统是win7 32位