Sending HID reports
This article describes how user-mode applications and kernel-mode drivers send HID reports to a HID collection.
Send HID reports by user-mode applications
User-mode applications use WriteFile to continuously send output reports to a HID collection. You can also use HidD_SetXxx routines to send output reports and feature reports to a collection. However, only use HidD_SetXxx routines to set the current state of a collection. Some devices might not support HidD_SetOutputReport and become unresponsive if this routine is used.
WriteFile routine
Use write requests to send output reports to a HID collection. After a user-mode application creates an output report, it can send an output report to a collection using WriteFile.
HidD_SetXxx routines
Use these HIDClass support routines to send HID reports to a HID collection:
- HidD_SetOutputReport: Sends an output report to a HID collection (Windows XP and later versions).
- HidD_SetFeature: Sends a feature report to a HID collection.
Send HID reports by kernel-mode drivers
Kernel mode drivers use IRP_MJ_WRITE requests to continuously send output report to a HID collection. You can also use IOCTL_HID_SET_Xxx requests to send output reports and feature reports to a collection. However, only use IOCTL_HID_SET_Xxx requests to set the current state of a collection. Some devices might not support IOCTL_HID_SET_OUTPUT_REPORT and become unresponsive if this request is used.
IRP_MJ_WRITE requests
Non-WDM Windows 2000 drivers, and drivers for Windows XP and later versions, can use a single IRP for all write requests sent to a collection. However, Windows 2000 WDM drivers must allocate a new IRP for each write request. For more information about how to use and reuse IRPs, see Handling IRPs and Reusing IRPs.
If the driver reuses a write 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 write request, the IRP's IoCompletion routine should complete and free the IRP, and return STATUS_SUCCESS.
When a driver sends an output report, it must first initialize and set an output report buffer, as described in Initializing HID Reports. The driver must then use an MDL to map the output report buffer for a write request. A driver calls IoAllocateMdl to allocate the MDL for an output report, and sets a write IRP's Irp->MdlAddress member to the MDL address of the output report buffer. The driver must free the report buffer and the MDL when they're no longer required.
In addition to setting the write 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.Write.Length: Set to the length, in bytes, of an output report. Set this member to the length of a HID collection's output reports, as specified by the OutputReportByteLength member of a collection's HIDP_CAPS structure.
- Parameters.Write.Key: Set to zero.
- Parameters.Write.ByteOffset.QuadPart: Set to zero.
- MajorFunction: Set to
IRP_MJ_WRITE
. - FileObject: Set to the file object pointer that represents the open file on the HID collection.
IOCTL_HID_SET_Xxx requests
You can also use the following I/O requests to send output and feature reports to a HID collection:
- IOCTL_HID_SET_OUTPUT_REPORT: Sends an output report to a collection (Windows XP and later versions).
- IOCTL_HID_SET_FEATURE: Sends a feature report to a collection.