Windows动态库hid.dll
+ -

HID设备读取输入报告机制概述

2022-05-30 568 0

在Windows系统中,一般是通过ReadFile中来获取输入报告的。我们在Windows系统HID设备获取报告描述符ReadFile和HidD_GetInputReport区别一文中介绍过它的大概原理。这里我们更加深理细节的说明一下ReadFile读取输入报告的细节原理。

在应用层,使用ReadFile函数读取输入报告,在内核层则进行了HIDCLASS.SYS中,其对应的IRP为IRP_MJ_READ。
在ReactOS中对应的函数为HidClass_Read,而Windows 10中为HidpIrpMajorRead。

在ReactOS中,可以通过源代码直接看到,是通过创建一个IRP,下发给HIDUSB.SYS中,然后设置完成例程,该IRP完成之后,将数据复制给IRP_MJ_READ。

    Status = HidClass_BuildIrp(DeviceObject,
                               Irp,
                               Context,
                               IOCTL_HID_READ_REPORT,
                               IoStack->Parameters.Read.Length,
                               &NewIrp,
                               &NewIrpContext);
...
IoSetCompletionRoutine(NewIrp, HidClass_ReadCompleteIrp, NewIrpContext, TRUE, TRUE, TRUE);

这个不是Windows系统真正的实现机制,这是按需进行输入报告的读取,即需要上层调用ReadFile。

而在Windows中并不是这样实现的。

  • HID设备PDO在启动设备(IRP_MN_START_DEVICE)开始,执行HidpStartCollectionPDO开启读输入报告。
  • HidpStartCollectionPDO函数的具体流程是从父驱动FDO中找到其对应的子输入报告COLLECTION。
  • HidpStartAllPingPongs函数使用2个PINGPANG的IPR来从HIDUSB.SYS中读取输入报告。
  • 对于每个PINGPANG的IRP,读取输入报告的函数为HidpSubmitInterruptRead,其就是和ReactOS类似,下发IOCTL_HID_READ_REPORT来读取输入报告的内容。然后将收到的数据分发给上层打开该设备的所有HIDCLASS_FILE_EXTENSION(IRP_MJ_CREATE).这样当一个HID被上层多个应用打开时,只要有数据,会将数据分发给所有的已打开的设备。如我们通过SimpleHIDWrite工具打开同一个HID设备,当HID的输入报告时,会同时收到输入报告。如下图:
    HID输入报告
  • HID输入报告的分发是通过HidpDistributeInterruptReport函数实现的。
  • 在分发输入报告时,会有2种情况。
    • 第一种情况是有待读的IRP_MJ_READ,那么从队列中取出PEDNING的IRP,完成并返顺。
    • 第二种情况是虽然打开了HID设备(CreateFile,IRP_MJ_CREATE),但是没有读ReadFile,则将数据缓存。缓存的最大数据个数默认为32,可以由HidD_SetNumInputBuffers(IOCTL_SET_NUM_DEVICE_INPUT_BUFFERS)来设置。

由于存在数据缓存,故也可以对缓存的输入报告进行清除。清除已经缓存的输入报API函数为HidD_FlushQueue,这其实也解释了CSDN上关于HID函数HidD_FlushQueue的问题,原网址为:https://bbs.csdn.net/topics/330044399

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 篇笔记 写笔记

HID.DLL导出函数HidD_GetInputReport探究
HidD_GetInputReport的功能HidD_GetInputReport用于获取输入报告(input report)。说明:不过微软关于此函数有一个特别的说明,就是只能获取当前的输入报告,不能连续的获取,因为可能会丢数据。所以如果要连续的获取输入报告,需要使用ReadFile函数。同时,......
Windows系统HID设备获取输入报告ReadFile和HidD_GetInputReport区别
在Windows系统提供的HID接口中获取输入报告内容一般通过两个接口,分别为ReadFile和HidD_GetInputReport。不过大家有没有发现,在实际的使用过程中,大家还是使用ReadFile多一些,在某些的时候也会用HidD_GetInputReport,不过它们之间的区别,好像有时很......
HID设备读取输入报告机制概述
在Windows系统中,一般是通过ReadFile中来获取输入报告的。我们在Windows系统HID设备获取报告描述符ReadFile和HidD_GetInputReport区别一文中介绍过它的大概原理。这里我们更加深理细节的说明一下ReadFile读取输入报告的细节原理。在应用层,使用ReadF......
hidclass.sys多输入报告的长度研究
有没有思考过一个问题,一般我们的HID设备只一个输入输出报告,那么在hidclass.sys中在循环读取输入报告时,按指定的长度来进行读取即可。但是,我们知道,一个HID设备是可以支持多个输入报告的,多个输入报告使用ReportId来区分的。如我们提供如下的一个自定义通讯HID设备:0x06,0x......
HID设备输入报告的安全方式
HIDCLASS.SYS驱动中定义了一个HID设备的安全读模式,安全模式的开启与关闭是通过IOCTL_HID_ENABLE_SECURE_READ和IOCTL_HID_DISABLE_SECURE_READ实现的。当然可发送此IOCTL的前提是需要打开设备。打开设备时,系统会对打开的请求模式进行判断......
Windows系统对HIDUSAGE_PAGE和USAGE的支持
Windows 支持以下顶级集合:Usage PageUsageWindows 7Windows 8Windows 10NotesAccess Mode0x00010x0001 - 0x0002YesYesYesMouse class driver and m......
Windows系统HID读输入报告的两种方式HidD_GetInputReport和ReadFile的补充
Windows系统提供了两种方式读取HID的输入报告,分别为HidD_GetInputReport和ReadFile,两都本质都是读取HID的输入报告,但从操作系统层来讲,两都又不同。在 Windows系统HID设备获取输入报告ReadFile和HidD_GetInputReport区别:https......
关注公众号
取消
感谢您的支持,我会继续努力的!
扫码支持
扫码打赏,你说多少就多少

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

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