用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. void RegisterDeviceNotify()
  4. {
  5. HDEVNOTIFY hDevNotify;
  6. DEV_BROADCAST_DEVICEINTERFACE NotificationFilter;
  7. ZeroMemory( &NotificationFilter, sizeof(NotificationFilter) );
  8. NotificationFilter.dbcc_size = sizeof(DEV_BROADCAST_DEVICEINTERFACE);
  9. NotificationFilter.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
  10. NotificationFilter.dbcc_classguid = GUID_DEVINTERFACE_USB_DEVICE;
  11. hDevNotify = RegisterDeviceNotification(hWnd, &NotificationFilter, DEVICE_NOTIFY_WINDOW_HANDLE);
  12. }

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. return DefWindowProc(hWnd, message, wParam, lParam);
  9. }

3.处理接收到的WM_DEVICECHANGE消息

[cpp] view plain copy

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

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

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

C#.NET U盘插拔监控

[1]涉及的知识点 1) windows消息处理函数 ? 1 protected override void WndProc(ref Message m) 捕获Message的系统硬件改变发出的系统消息 2) 硬件信息类 ? 1 DriveInfo [2]核心函数 消息常量: ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 /// <summary> /// windows消息常量 /// </summary> class CWn

Android_ UEventObserver_监听USB插拔

本博文为子墨原创,转载请注明出处! http://blog.csdn.net/zimo2013/article/details/38950363 1.简介 最近做一个项目,主要通过usb完成pc与Android端的数据传输.但是根据api提供的无法监听usb的插拔,有解释为不同版本会存在BUG.本打算放弃跳过监听usb,改为在连上usb后pc点击按钮发出一个广播来主动打开Android端的应用程序,然后通过socket完成数据交互.这里主要通过UEventObserver,而该类位于/frame

ionic3 监听软键盘的高度

ionic1 和普通cordova的大家都知道 就是看ionic3 和4 https://blog.csdn.net/sean_css/article/details/70243893 ionic cordova plugin add ionic-plugin-keyboard $ npm install --save @ionic-native/keyboard 经过本人测试 这个方法 ionic1 ionic3 都可以用 ionic3 把方法写到 构造器 或者 生命周期事件里面就行 ioni

Android USB大容量存储时SD卡状态监听(转)

对SD卡状态监听,到现在为止我知道的有两种方式: 1.注册StorageEventListener来监听sd卡状态 StorageEventListener中有onStorageStateChanged()方法,当sd卡状态改变时,此方法会调用,对各状态的判断一般会用到Environment类,此类中包含的有关sd卡状态的常量有: MEDIA_BAD_REMOVAL:表明SDCard 被卸载前己被移除 MEDIA_CHECKING:表明对象正在磁盘检查 MEDIA_MOUNTED:表明sd对象是

利用select/poll监听多个设备详解

如果一个应用程序去处理多个设备,例如应用程序读取网路数据,按键,串口,一般能想到的有三种方法: 方法1: 串行+阻塞的方式读取: while(1) { read(标准输入); read(网络); } 缺点:每当阻塞读取标准输入时,如果用户不进行标准输入的操作,而此时客户端给服务器发送数据,导致服务器无法读取客户端发送来的数据! 方法2: 采用多线程或者多进程机制来实现读取: 开辟多个线程,每一个线程处理一个设备,不会导致的数据的无法读取,但是系统的开销相比方法1要大! 方案3:采用linux系统

JQuery 节点监听

DOMSubtreeModified: 在DOM结构发生任何变化的时候.这个事件在其他事件触发后都会触发: 1 $(".attr_box").bind("DOMSubtreeModified",function(e){ 2 //监听事件操作 3 }); DOMNodeInserted: 当一个节点作为子节点被插入到另一个节点中时触发: DOMNodeRemoved: 在节点从其父节点中移除时触发: DOMNodeInsertedIntoDocument: 在一个节点

vue监听浏览器返回

代码 监听返回 mounted () { if (window.history && window.history.pushState) { // 向历史记录中插入了当前页 history.pushState(null, null, document.URL); window.addEventListener('popstate', this.goBack, false); } }, destroyed () { window.removeEventListener('popstate',

Windows API 教程(七) hook 钩子监听

Windows API 教程(七) hook 钩子监听 Posted on 2013-08-15 茵蒂克丝 如何创建一个窗口 手动创建窗口的流程 实际代码 安装钩子 (Install hook) 钩子简介 SetWindowsHookEx 函数 设置监听[键盘]消息 设置监听[鼠标]消息 如何创建一个窗口 另外一个再录的 Windows SDK教程 里面有讲到快捷创建窗口的方式,不过这样的话要分好几个文件,感觉有点混所以这里就用原始的方式创建一个窗口. 那么,为什么讲到 hook(钩子)的时候要

ArcGIS API for JavaScript 4.2学习笔记[7] 鹰眼(缩略图的实现及异步处理、Promise、回调函数、监听的笔记)

文前说明:关于style就是页面的css暂时不做评论,因为官方给的例子的样式实在太简单了,照抄阅读即可. 这篇文章有着大量AJS 4.x版本添加的内容,如监听watch.Promise对象.回调函数.异步处理等内容,原理性的东西我会在文末解释,各位看官不用担心看不懂,我尽量用通俗的语言解释这些. 惯例,如果不习惯从头看到尾,可以直接跳到后面看总结. 大家应该看过商业地图的缩略图功能吧?以度娘地图为例,在使用街景地图的时候,左下角会出现一个地点一样的2D小地图: 这个就是鹰眼功能的应用,在很多桌面