获取 HID 报告

本文介绍了用户模式应用程序和内核模式驱动程序如何从 HID 集合中获取 HID 报告。

通过用户模式应用程序获取 HID 报告

本部分讨论用户模式应用程序使用 ReadFileHidD_GetXxx 例程获取 HID 输入报告或 HID 功能报告。

但是,应用程序只能使用 HidD_GetXxx 例程来获取设备的当前状态。 如果应用程序尝试使用 HidD_GetInputReport 来连续获取输入报告,则报告可能会丢失。 此外,某些设备不支持 HidD_GetInputReport,如果使用此例程,设备就会无响应。

使用 ReadFile

应用程序使用通过 CreateFile 获得的打开文件句柄,在集合上打开文件。 当应用程序调用 ReadFile 时,不必指定重叠的 I/O,因为 HID 客户端驱动程序会在环形缓冲区中缓冲报告。 但是,应用程序可以使用重叠的 I/O,使未完成的读取请求超过一个。

使用 HidD_GetXxx 例程

应用程序可以使用以下 HIDClass 支持例程,从 HID 集合中获取最新的输入报告和功能报告:

应用程序可以要求返还特定报告。 要使用 HidD_GetXxx 例程检索特定报告,应用程序需要分配报告输出缓冲区,对缓冲区进行零初始化,并将缓冲区中的第一个字节设置为特定报告 ID。 有关详细信息,请参阅初始化 HID 报告

通过内核模式驱动程序获取 HID 报告

本部分将讨论内核模式驱动程序应如何使用 IRP_MJ_READ 请求作为持续获取 HID 输入报告的主要方法。

连续读取请求会按照从数据集中接收的顺序返回输入报告。 驱动程序还可以使用 IOCTL_HID_GET_Xxx 请求来获取输入和功能报告。 但是,驱动程序只能使用 IOCTL_HID_GET_Xxx 请求来获取设备的当前状态。 如果驱动程序尝试使用 IOCTL_HID_GET_INPUT_REPORT 来持续获取输入报告,则可能会丢失报告。 此外,某些设备不支持 IOCTL_HID_GET_INPUT_REPORT,因此在使用该请求时会出现无响应的情况。

使用 IRP_MJ_READ 请求

有关如何使用和重复使用 I/O 请求数据包 (IRP) 的一般信息,请参阅处理 IRP重复使用 IRP

如果驱动程序重复使用 IRP,则 IRP 的 IoCompletion 例程应在状态为 STATUS_MORE_PROCESSING_REQUIRED 时完成请求(而不是释放 IRP)。 当驱动程序不再需要 IRP 时,应通过调用 IoCompleteRequestIoFreeIrp 来完成和释放 IRP。 例如,驱动程序通常会在其 Unload 例程中完成并释放 IRP,或者在设备被移除后完成并释放 IRP。

如果驱动程序仅为一个读取请求使用 IRP,则 IRP 的 IoCompletion 例程应完成并释放 IRP,并返回 STATUS_SUCCESS

在驱动程序请求输入报告之前,必须先从非分页内存池中分配一个零初始化的输入报告缓冲区。 缓冲区的大小(字节)由 HID 集合 HIDP_CAPS 结构的 InputReportByteLength 成员指定。 然后,驱动程序必须使用 MDL 映射读取请求的输入报告缓冲区。 驱动程序会调用 IoAllocateMdl 来为输入报告缓冲区分配 MDL,并将读取 IRP 的 Irp->MdlAddress 成员设置为输入报告缓冲区的 MDL 地址。 当不再需要报告缓冲区和 MDL 时,驱动程序应释放它们。

除了设置读取 IRP 的 MDL 地址外,驱动程序还必须设置下一级驱动程序的 I/O 堆栈位置。 驱动程序通过调用 IoGetNextIrpStackLocation 来访问下一级驱动程序的 I/O 堆栈位置。 驱动程序会设置 I/O 堆栈位置的以下成员:

  • Parameters.Read.Length:设置为读取缓冲区的大小(以字节为单位)。 大小必须大于或等于 HID 集合 HIDP_CAPS 结构的 InputReportByteLength 成员指定的值。
  • Parameters.Read.Key:设置为零。
  • Parameters.Read.ByteOffset.QuadPart:设置为零。
  • MajorFunction:设置为 IRP_MJ_READ。
  • FileObject:设置为表示 HID 集合上打开文件的文件对象指针。

驱动程序获取输入报告后,就可以访问控制数据,如解释 HID 报告所述。

使用 IOCTL_HID_GET_Xxx 请求

驱动程序可使用以下 I/O 请求,从 HID 数据集中获取最新的输入和功能报告:

驱动程序可要求退回特定报告。 要使用这些 I/O 请求检索特定报告,驱动程序首先分配输出报告缓冲区,然后对缓冲区进行零初始化,并将缓冲区中的第一个字节设置为特定报告 ID。

有关详细信息,请参阅解释 HID 报告