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

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了用win32 API监听U盘插拔并取得其盘符/取得当前插入U盘的盘符相关的知识,希望对你有一定的参考价值。

版权声明:本文为博主原创文章,未经博主允许不得转载。

用win32 API监听U盘插拔并取得其盘符

1.使用RegisterDeviceNotification()函数注册

 

[cpp] view plain copy
 
  1. static const GUID GUID_DEVINTERFACE_USB_DEVICE =   
  2.     {0xA5DCBF10, 0x6530, 0x11D2, {0x90, 0x1F, 0x00, 0xC0, 0x4F, 0xB9, 0x51, 0xED}};  
  3.   
  4. void RegisterDeviceNotify()  
  5. {  
  6.     HDEVNOTIFY hDevNotify;  
  7.     DEV_BROADCAST_DEVICEINTERFACE NotificationFilter;  
  8.     ZeroMemory( &NotificationFilter, sizeof(NotificationFilter) );  
  9.     NotificationFilter.dbcc_size = sizeof(DEV_BROADCAST_DEVICEINTERFACE);  
  10.     NotificationFilter.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;  
  11.     NotificationFilter.dbcc_classguid = GUID_DEVINTERFACE_USB_DEVICE;  
  12.     hDevNotify = RegisterDeviceNotification(hWnd, &NotificationFilter, DEVICE_NOTIFY_WINDOW_HANDLE);  
  13. }  

2.在WndProc()函数中接收WM_DEVICECHANGE消息

 

 

[cpp] view plain copy
 
  1. LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)  
  2. {  
  3.     switch(message)  
  4.     {  
  5.     case WM_DEVICECHANGE:  
  6.         return DeviceChange(message, wParam, lParam);  
  7.     }  
  8.   
  9.     return DefWindowProc(hWnd, message, wParam, lParam);  
  10. }  

3.处理接收到的WM_DEVICECHANGE消息

 

 

[cpp] view plain copy
 
  1. char FirstDriveFromMask(ULONG unitmask)  
  2. {  
  3.    char i;  
  4.   
  5.    for (i = 0; i < 26; ++i)  
  6.    {  
  7.       if (unitmask & 0x1)  
  8.          break;  
  9.       unitmask >>= 1;  
  10.    }  
  11.   
  12.    return (i + ‘A‘);  
  13. }  
  14.   
  15. LRESULT DeviceChange(UINT message, WPARAM wParam, LPARAM lParam)  
  16. {  
  17.     if ( DBT_DEVICEARRIVAL == wParam || DBT_DEVICEREMOVECOMPLETE == wParam )   
  18.     {  
  19.         PDEV_BROADCAST_HDR pHdr = (PDEV_BROADCAST_HDR)lParam;  
  20.         if (pHdr->dbch_devicetype == DBT_DEVTYP_VOLUME)   
  21.         {  
  22.             PDEV_BROADCAST_VOLUME pDevVolume = (PDEV_BROADCAST_VOLUME)lParam;  
  23.             char driverLabel = FirstDriveFromMask(pDevVolume->dbcv_unitmask);  
  24.             if (wParam == DBT_DEVICEARRIVAL) {  
  25.                 printf("add %c\r\n", driverLabel);  
  26.             } else {  
  27.                 printf("remove %c\r\n", driverLabel);  
  28.             }  
  29.         }  
  30.     }  
  31.     return 0;  
  32. }  

用win32 API取得当前插入U盘的盘符

1.使用GetLogicalDrives()取得代表各分区的掩码

 

[cpp] view plain copy
 
  1. DWORD mask = GetLogicalDrives();  
2.遍历掩码的每一位,判断对应的分区是否是U盘

 

 

[cpp] view plain copy
 
  1. bool IsUsbDevice(wchar_t letter)  
  2. {  
  3.     wchar_t volumeAccessPath[] = L"\\\\.\\X:";  
  4.     volumeAccessPath[4] = letter;  
  5.   
  6.     HANDLE deviceHandle = CreateFile(  
  7.         volumeAccessPath,  
  8.         0,                // no access to the drive  
  9.         FILE_SHARE_READ | // share mode  
  10.         FILE_SHARE_WRITE,   
  11.         NULL,             // default security attributes  
  12.         OPEN_EXISTING,    // disposition  
  13.         0,                // file attributes  
  14.         NULL);            // do not copy file attributes  
  15.   
  16.     // setup query  
  17.     STORAGE_PROPERTY_QUERY query;  
  18.     memset(&query, 0, sizeof(query));  
  19.     query.PropertyId = StorageDeviceProperty;  
  20.     query.QueryType = PropertyStandardQuery;  
  21.   
  22.     // issue query  
  23.     DWORD bytes;  
  24.     STORAGE_DEVICE_DESCRIPTOR devd;  
  25.     STORAGE_BUS_TYPE busType = BusTypeUnknown;  
  26.   
  27.     if (DeviceIoControl(deviceHandle,  
  28.         IOCTL_STORAGE_QUERY_PROPERTY,  
  29.         &query, sizeof(query),  
  30.         &devd, sizeof(devd),  
  31.         &bytes, NULL))  
  32.     {  
  33.     busType = devd.BusType;  
  34.     }  
  35.   
  36.     CloseHandle(deviceHandle);  
  37.   
  38.     return BusTypeUsb == busType;  
  39. }  
  40.   
  41. // 查找U盘  
  42. // 参数:  _letter 存储U盘盘符  
  43. // 返回值:true 当前有U盘  
  44. //       false 当前无U盘  
  45. bool findUSBStorage(char* _letter)  
  46. {  
  47.     DWORD mask = GetLogicalDrives();  
  48.     int count = 0;  
  49.     while (mask != 0)  
  50.     {  
  51.         if ((mask & 0x01) == 1)  
  52.         {  
  53.             wchar_t letter = L‘A‘ + count;  
  54.   
  55.                 // 判断取得的盘符是否是U盘  
  56.             if (IsUsbDevice(letter))  
  57.             {  
  58.                     wcstombs(_letter, &letter, 1);  
  59.                     return true;  
  60.             }  
  61.         }  
  62.         count++;  
  63.         mask = mask >> 1;  
  64.     }  
  65.     return false;  
  66. }  





以上是关于用win32 API监听U盘插拔并取得其盘符/取得当前插入U盘的盘符的主要内容,如果未能解决你的问题,请参考以下文章

electron 监听U盘插拔事件,并获得U盘路径

U盘序列号怎么获取?怎么清楚U盘插拔痕迹?

x86下 linux qt检测U盘插拔------- HAL 与UDISKS

为啥我的U盘插在电脑上没反应?

装daemon tools 或者 Virtual CloneDrive 无法加载光盘映像,也看不到虚拟的盘符,我的系统是win7 32位

如何取得某进程的句柄 = =?谢谢了