Obtaining HID Reports

This section describes how user-mode applications and kernel-mode drivers obtain HID reports from a HID collection.

Obtaining HID Reports by user-mode applications

This topic discusses the obtaining of HID input reports or HID feature reports, by user-mode applications using ReadFile or the HidD_GetXxx routines.

However, an application should only use the HidD_GetXxx routines to obtain the current state of a device. If an application attempts to use HidD_GetInputReport to continuously obtain input reports, the reports can be lost. In addition, some devices might not support HidD_GetInputReport, and will become unresponsive if this routine is used.

Using ReadFile

An application uses the open file handle it obtained by using CreateFile to open a file on the collection. When the application calls ReadFile, it does not have to specify overlapped I/O because the HID Client Drivers buffers reports in a ring buffer. However, an application can use overlapped I/O to have more than one outstanding read request.

Using HidD_GetXxx Routines

An application can use the following HIDClass support routines to obtain the most current input reports and feature reports from a HID collection:

An application can request the return of a specific report. To retrieve a specific report using these routines, the application allocates the report output buffer, zero-initializes the buffer, and sets the first byte in the buffer to the specific report ID. For more information, see Initializing HID Reports.

Obtaining HID Reports by kernel-mode drivers

This topic discusses how a kernel-mode driver should use IRP_MJ_READ requests as its main approach for continuously obtaining HID input reports.

Consecutive read requests return input reports in the order in which they were received from the collection. The driver can also use IOCTL_HID_GET_Xxx requests to obtain input and feature reports. However, a driver should only use these I/O requests to obtain the current state of a device. If the driver attempts to use IOCTL_HID_GET_INPUT_REPORT to continuously obtain input reports, reports can be lost. In addition, some devices might not support IOCTL_HID_GET_INPUT_REPORT, and will become unresponsive if this request is used.

Using IRP_MJ_READ Requests

Non-WDM Windows 2000 drivers, and drivers for Windows XP and later versions, can use a single IRP for all read requests to a device. However, Windows 2000 WDM drivers must allocate a new IRP for each read request. For general information about how to use and reuse IRPs, see Handling IRPs and Reusing IRPs.

If a driver reuses an IRP, the IRP's IoCompletion routine should complete the request with a status of STATUS_MORE_PROCESSING_REQUIRED (and not free the IRP). When the driver no longer requires the IRP, it should complete and free the IRP by calling IoCompleteRequest and IoFreeIrp. For example, a driver might typically complete and free the IRP in its Unload routine, or after a device is removed.

If a driver uses an IRP for only one read request, the IRP's IoCompletion routine should complete and free the IRP, and return STATUS_SUCCESS.

Before a driver can request an input report, it must first allocate a zero-initialized input report buffer from nonpaged memory pool. The size, in bytes, of the buffer is specified by the InputReportByteLength member of a HID collection's HIDP_CAPS structure. A driver must then use an MDL to map the input report buffer for a read request. The driver calls IoAllocateMdl to allocate the MDL for an input report buffer, and sets the read IRP's Irp->MdlAddress member to the MDL address of the input report buffer. The driver should free the report buffer and the MDL when they are no longer required.

In addition to setting the read IRP's MDL address, the driver must also set the I/O stack location of the next lower-level driver. A driver obtains access to the I/O stack location of the next lower-level driver by calling IoGetNextIrpStackLocation. The driver sets the following members of the I/O stack location:

Parameters.Read.Length
Set to the size, in bytes, of the read buffer. This must be greater than or equal to the value specified by the InputReportByteLength member of a HID collection's HIDP_CAPS structure.

Parameters.Read.Key
Set to zero.

Parameters.Read.ByteOffset.QuadPart
Set to zero.

MajorFunction
Set to IRP_MJ_READ.

FileObject
Set to the file object pointer that represents the open file on the HID collection.

After the driver has obtained an input report, it can access control data, as described in Interpreting HID Reports.

Using IOCTL_HID_GET_Xxx Requests

A driver can use the following I/O requests to obtain the most current input and feature reports from a HID collection:

A driver can request the return of a specific report. To retrieve a specific report using these I/O requests, the driver first allocates the output report buffer, then zero-initializes the buffer, and sets the first byte in the buffer to the specific report ID.

For more information, see Interpreting HID Reports.