自定义HID应用程序开发(Windows)
+ -

Windows下枚举系统中所有HID设备

2020-10-29 4324 3

Windows下对任何设备,文件的打开都是通过CreateFile来实现的,不过要打开一个设备得首先知道设备或文件名。
由上节可知道,对于HID设备,都会注册一个接口类型为{2ACCFE60-C130-11D2-B082-00A0C91EFB8B}的GUID。我们可以通过Setup系列函数枚举出系统中所有的HID设备,然后再根据其属信息判断(如PID,VID,报告描述符长度等)来进行过滤。

枚举系统中所有HID设备信息代码示例

  1. #include<windows.h>
  2. #include <winioctl.h>
  3. #include <setupapi.h>
  4. #include <initguid.h>
  5. #include <stdio.h>
  6. #include<hidsdi.h>
  7. #include<tchar.h>
  8. #pragma comment(lib,"Setupapi.lib ")
  9. #pragma comment(lib,"hid.lib ")
  10. BOOL USBEnumDevice(OUT PTCHAR pDeviceName, IN LPGUID pGuid,IN int instance)
  11. {
  12. HDEVINFO info = SetupDiGetClassDevs((GUID*)pGuid, NULL, NULL, DIGCF_PRESENT | DIGCF_INTERFACEDEVICE);
  13. if (info == INVALID_HANDLE_VALUE)
  14. {
  15. printf("No HDEVINFO available for this GUID\n");
  16. return FALSE;
  17. }
  18. // Get interface data for the requested instance
  19. SP_INTERFACE_DEVICE_DATA ifdata;
  20. ifdata.cbSize = sizeof(ifdata);
  21. if (!SetupDiEnumDeviceInterfaces(info, NULL, (GUID*)pGuid, instance, &ifdata))
  22. {
  23. _tprintf(TEXT("No SP_INTERFACE_DEVICE_DATA available for this GUID instance\n"));
  24. SetupDiDestroyDeviceInfoList(info);
  25. return FALSE;
  26. }
  27. // Get size of symbolic link name
  28. DWORD ReqLen;
  29. SetupDiGetDeviceInterfaceDetail(info, &ifdata, NULL, 0, &ReqLen, NULL);
  30. PSP_INTERFACE_DEVICE_DETAIL_DATA ifDetail = (PSP_INTERFACE_DEVICE_DETAIL_DATA)(new TCHAR[ReqLen]);
  31. if (ifDetail == NULL)
  32. {
  33. SetupDiDestroyDeviceInfoList(info);
  34. return FALSE;
  35. }
  36. // Get symbolic link name
  37. ifDetail->cbSize = sizeof(SP_INTERFACE_DEVICE_DETAIL_DATA);
  38. if (!SetupDiGetDeviceInterfaceDetail(info, &ifdata, ifDetail, ReqLen, NULL, NULL))
  39. {
  40. SetupDiDestroyDeviceInfoList(info);
  41. delete ifDetail;
  42. return FALSE;
  43. }
  44. //printf("Symbolic link is %s\n", ifDetail->DevicePath);
  45. memcpy(pDeviceName, ifDetail->DevicePath, _tcslen(ifDetail->DevicePath) * sizeof(TCHAR));
  46. pDeviceName[_tcslen(ifDetail->DevicePath)] = TEXT('\0');
  47. delete [] ifDetail;
  48. SetupDiDestroyDeviceInfoList(info);
  49. return TRUE;
  50. }
  51. int main()
  52. {
  53. GUID hidGuid;
  54. ::HidD_GetHidGuid((LPGUID)&hidGuid); // 取HID设备GUID
  55. for (int i = 0;; i++)
  56. {
  57. TCHAR strDevicePath[512] = { 0 };
  58. if (!USBEnumDevice(strDevicePath, &hidGuid, i))
  59. {
  60. break;
  61. }
  62. HANDLE tmp_DeviceHandle = CreateFile(strDevicePath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE,
  63. NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL);
  64. if (tmp_DeviceHandle == INVALID_HANDLE_VALUE)
  65. {
  66. CloseHandle(tmp_DeviceHandle);
  67. continue;
  68. }
  69. //=============== Get Attribute ===============
  70. HIDD_ATTRIBUTES Attributes;
  71. ZeroMemory(&Attributes, sizeof(Attributes));
  72. Attributes.Size = sizeof(HIDD_ATTRIBUTES);
  73. if (!HidD_GetAttributes(tmp_DeviceHandle, &Attributes))
  74. {
  75. CloseHandle(tmp_DeviceHandle);
  76. continue;
  77. }
  78. _tprintf(TEXT("%d %s\n"), i, strDevicePath);
  79. _tprintf(TEXT("Vendor ID: %04x, Product ID:%04x\n"), Attributes.VendorID, Attributes.ProductID);
  80. /////////////////////////////////
  81. ULONG bufferLength = 126;
  82. TCHAR ProductString[126] = { 0 };;
  83. if (!HidD_GetProductString(tmp_DeviceHandle, ProductString, bufferLength))
  84. {
  85. CloseHandle(tmp_DeviceHandle);
  86. continue;
  87. }
  88. //=============== Get Capabilities ===============
  89. PHIDP_PREPARSED_DATA PreparsedData;
  90. if (!HidD_GetPreparsedData(tmp_DeviceHandle, &PreparsedData))
  91. {
  92. CloseHandle(tmp_DeviceHandle);
  93. printf("Cannot get the Preparsed Data...\n");
  94. continue;
  95. }
  96. HIDP_CAPS ReturnCapabilities;
  97. if (!HidP_GetCaps(PreparsedData, &ReturnCapabilities))
  98. {
  99. CloseHandle(tmp_DeviceHandle);
  100. printf("Cannot get the Cap Data...\n");
  101. continue;
  102. }
  103. // Normal USB Device
  104. if ((ReturnCapabilities.OutputReportByteLength == 0x40) &&
  105. (ReturnCapabilities.InputReportByteLength == 0x40) &&
  106. (ReturnCapabilities.Usage == 0x0001) &&
  107. (ReturnCapabilities.UsagePage == 0xFF00))
  108. {
  109. }
  110. }
  111. }
HID人机交互QQ群:564808376    UAC音频QQ群:218581009    UVC相机QQ群:331552032    BOT&UASP大容量存储QQ群:258159197    STC-USB单片机QQ群:315457461    USB技术交流QQ群2:580684376    USB技术交流QQ群:952873936   

0 篇笔记 写笔记

Windows下枚举系统中所有HID设备
Windows下对任何设备,文件的打开都是通过CreateFile来实现的,不过要打开一个设备得首先知道设备或文件名。由上节可知道,对于HID设备,都会注册一个接口类型为{2ACCFE60-C130-11D2-B082-00A0C91EFB8B}的GUID。我们可以通过Setup系列函数枚举出系统中......
USB复合HID设备报告描述符的区分
在USB规范中,设备的功能是通过接口来承载的,在USB规格书中就是接口描述符。对于一般的设备,一般一个接口就是一个功能,这个功能可以是鼠标,键盘或其它设备类型。当然这个只是对USB简易设备而言的,对于一些USB复杂设备如UVC摄像头,UAC音频等是多接口相互配合来实现其功能的,为了整合这么多接口使......
USB通用父驱动usbccgp.sys的过滤UVC摄像头、UAC麦克风和HID设备硬件ID
激动的心情,无溢言表。。虽然只是一个很简单的东西。。但相于折腾了这么久,还是很开心的了。最近有个需求,功能是这样的:有一个USB复合设备,连接到windows系统中它在windows下的设备树如下:USB Composite Device(usbccgp.sys)UVC CameraUAC ......
HID设备固件升级失败
USB设备现在比较多,像UVC摄像头,UAC音频或TOUCH设备,这些设备在设备管理器中无不都会带一个自定义的HID设备。这个自定义的HID主要的功能一般是通过应用层与固件进行数据通讯,比如对固件参数的配置,甚至固件的升级。在Windows下,两2套与HID设备的通讯的接口,一组是WriteFil......
USB复合设备-UVC摄像头HID设备共存的设计实现
通常做USB设备的开发,我们做的都是单一的功能设备。这种单一的功能设备只实现某种特定的功能,如只实现一个HID鼠标或键盘,只实现一个USB存储功能,或再复杂一点只实现一个UVC音频麦克风和扬声器功能或一个UVC摄像头功能。但我们在一般的市场上看到的设备通常不只实现一种功能,如UVC摄像头功能还提供......
HID设备的实现原理-HID描述符
USB设备的信息存储在USB设备的固件中,当USB设备接入PC机启动后,主机会通过USB的标准请求对存储在USB设备的固件信息进行读取分析。这些存储的信息主要包括各种USB描述符信息,如设备描述符,配置描述符,接口描述符、端点描述符和字符串描述符等。USB设备的功能按接口来进行分类的,一个接口就代......
HID设备描述符的级级关系
和大多数的USB设备一样,HID设备也有USB设备的一些标准描述符,如设备描述符、配置描述符、接口描述符、端点找述符。但HID设备也有一些特的描述述,如HID描述符和报告描述符(也叫描表描述符)。HID设备的设备类型不是在设备类型中定义,而是在接口描述符中定义。设备描述符中的bDeviceCla......
HID设备的bInterfaceClass、bInterfaceSubClass和bInterfaceProtocol
HID设备是USB规范定义的设备类型之一,其分类号为0x03.关于USB设备类型定义,可参见本站:http://www.usbzh.com/article/detail-221.htmlHID设备除了用于专门的输入输出设备外,有时也与其它的设备类型组合成一个复杂的设备。如对于UVC摄像头设备,可以......
Windows下自定义HID设备通讯调试工具HidTool
功能枚举系统中可用的自定义HID设备,并进行数据通讯.在软件界面中显示该HID设备的,VID,PID,产品名称,输入报告长度,输出报告长度,特性报告长度和该输入报告所使用的USAGE_PAGE和USAGE。另外,对于一些用户,也可以指定Windows系统关于HID读取输入报告的缓冲区大小,系统默......
HID设备虚拟触摸屏上报的多点数据系统不响应
前一般时间在Windows10下使用USB驱动虚拟了一个触摸屏设备,上层软件按照HID报告述符的格式下发触摸屏数据给驱动,再由驱动将数据上交给系统,实现虚拟触摸屏的功能。今天,突发奇想,上次的报告描述符仅支持的是一个点触摸效果,今天保不实现了一下多点触摸效果,所以我通过在一个支持多点触摸屏的设备......
Windows下虚拟USB设备数据的读写请求调试笔记
到现在为止,本人已经在Windows下确切来说是Windows10 x64下开发了以下USB虚拟USB设备:USB虚拟UVC摄像头设备USB虚拟UAC麦克风设备USB虚拟HID键盘设备USB虚拟HID鼠标设备USB虚拟HID键盘鼠标复合设备USB虚拟HID单点触摸屏设备USB虚拟HID多点触摸屏......
Windows自定义HID设备通讯开发概述
HID设备是USB规范中最早提出并支持的一类通讯设备,常见的键盘、鼠标、游戏手柄都属于HID设备HID设备一般用于数据量小但实时性要求较高的环境,所以HID设备采用的是USB四种通讯类弄的中中断传传输类型。除了上述描述符的标准的HID设备,HID也提供一种自定义通讯,并由Windows提供驱动,而......
HID设备SET_IDLE时遇到c0000004
下午,USB中文网技术交流群里的一个同学,说他的HID设备时好时不好的,有时会花很长的时间才能枚举成功。没有抓包,没的截图…我是一顿乱扯,从硬件电路到各种抓包方法….晚上11点,这位同学发来了BUSHOUND抓的包,打开一看:Device Length Phase Data ......
UAC复合设备(麦克风,扬声器,HID设备)的示例
UAC符合设备(麦克风,扬声器,HID设备)在设备管理器中如下图所示:在BUSHOUND下如下图所示:UAC音频设备UAC音频设备包括扬声器和麦克风。其中USB Pnp Audio Device使用了接口0,1,2,分别用于控制接口,扬声器和麦克风。HID音量控制设备USB输入设备用于音频的......
USB鼠标HID设备示例
本示例的鼠标是一个最简单的USB鼠标,不包括任何其它附加设备。该设备在设备管理器中如下图所示:该USB鼠标的枚举过程如示:Device Length Phase Data Descriptio......
关注公众号
  • HID人机交互
  • Linux&USB
  • UAC音频
  • TYPE-C
  • USB规范
  • USB大容量存储
  • USB百科
  • USB周边
  • UVC摄像头
  • Windows系统USB
  • 音视频博客
  • 取消
    感谢您的支持,我会继续努力的!
    扫码支持
    扫码打赏,你说多少就多少

    打开支付宝扫一扫,即可进行扫码打赏哦

    您的支持,是我们前进的动力!