Chapter 13
338
&GVCKNU
The buffer passed to ReadFile should be at least the size reported in the
InputReportByteLength property of the HIDP_CAPS structure returned by
HidP_GetCaps.
The CreateEvent function returns a pointer to an event object that will be set to
the signaled state when the read operation succeeds or the function times out or
returns another error. The call to ReadFile passes the returned pointer in the
HidOverlapped structure. Marshaling allocates memory for the overlapped
structure and the report buffer to ensure that their contents remain accessible
for the life of the overlapped operation.
CreateFile obtains a handle for overlapped I/O by setting the
dwFlagsAndAttributes parameter to FILE_FLAG_OVERLAPPED.
The call to ReadFile passes the handle returned by CreateFile, an array to store
the returned report, the report’s length, a pointer to a variable to hold the num-
ber of bytes read, and a pointer to a NativeOverlapped structure. The struc-
ture’s EventHandle member is the handle returned by CreateEvent.
ReadFile returns immediately. A return value of true indicates that the function
has retrieved one or more reports. False means that a report wasn’t available. To
detect when a report arrives, the application calls WaitForSingleObject, passing
a pointer to the event object and a timeout value in milliseconds.
If WaitForSingleObject returns success (WAIT_OBJECT_0), GetOverlappe-
dResult returns the number of bytes read. The Marshal.Copy method copies
the report data to the managed inputReportBuffer array. The application can
then use the report data as desired and free the memory previously allocated
and no longer needed.
The first byte in inputReportBuffer is the Report ID, and the following bytes
are the report data. If the interface supports only the default Report ID of zero,
the Report ID doesn’t transmit on the bus but is still present in the buffer
returned by ReadFile.
A call to ReadFile doesn’t initiate traffic on the bus. The host begins requesting
reports when the HID driver loads during enumeration, and the driver stores
received reports in a ring buffer. When the buffer is full and a new report
arrives, the buffer drops the oldest report. A call to ReadFile reads the oldest
report in the buffer. If the driver’s buffer is empty, ReadFile waits for a report to
arrive.