Windows系统HID设备获取输入报告ReadFile和HidD_GetInputReport区别
在Windows系统提供的HID接口中获取输入报告内容一般通过两个接口,分别为ReadFile和HidD_GetInputReport。
不过大家有没有发现,在实际的使用过程中,大家还是使用ReadFile多一些,在某些的时候也会用HidD_GetInputReport,不过它们之间的区别,好像有时很难说清楚。
在《圈圈教你学习USB》一书P170,是这样说明它们之间的区别的:
- ReadFile对于USB HID设备,使用ReadFile只能从中断端点获了报告数据,如果要从控制端点获取报告,则使用函数HidD_GetInputReport.
- HidD_GetInputReport:调用该函数可以通过控制端点0获取报告,调用成功时,返回非0值,失败时,返回0。
所以,从上面来看,ReadFile是通过中断端点来获取输入报告数据时,而HidD_GetInputReport是通过控制端点获取输入报告数据的。这是因为对于HID设备,如果没有中断输入端点,系统可以通过控制端点获取输入报告。
实际上我们在看分析HidD_GetInputReport函数的功能时,最终从hidclass.sys进入hidusb.sys的,就可以看到,其实是通过HumBuildClassRequest宏实现一个USB控制请求。
- HID.DLL导出函数HidD_GetInputReport探究:http://www.usbzh.com/article/detail-933.html
- HID 类特定请求: http://www.usbzh.com/article/detail-686.html
而ReadFile我们之前的文章有说过,其实是IRP_MJ_READ之后,从HIDCLASS的链表中取数据,而在hidclass中会不停地从输入端点中获取数据,如果有就完成该READ请求,如果没有,就等待有数据时再完成。
所以我们可以进行一个整理:
HidD_GetInputReport是从上层下发IOCTL_HID_GET_INPUT_REPOR后,经过HIDCLASS.SYS转发给USBHID之后,通过控制请求下发给设备端。
而IRP_MJ_READ只是到了HIDCLASS之后就停止,然后从HIDCLASS驱动中等待有效数据返回给应用层。而在HIDCLASS中,会不停地从使用中断端点获取输入报告,有就挂入队列,并完成读IRP,否则就挂入队列。至于该队列缓存多少个包的数据,本人测试时,这个值是1,也即如果旧数据没有及时被读取,新数据会把旧的数据冲掉,并且这个读的请求会一直存在,无论上层是否打开设备。
相关文章可见:
- HID多ReportId数据长度返回的问题 http://www.usbzh.com/article/detail-904.html