|
From: Jef D. <jef...@ho...> - 2017-08-15 06:28:52
|
Hi,
I'm having trouble communication with a HID device on Windows. If the WinUSB
driver is installed, everything works fine. But with the default Microsoft HID
driver installed, the libusb_interrupt_transfer() function returns
LIBUSB_ERROR_IO. The underlying WriteFile call fails with
ERROR_INVALID_PARAMETER. I've attached the debug log file.
When I switch to the hidapi library instead of libusb, then the problem
disappears. So I checked what hidapi is doing different, and I think I found the
problem. It seems the Windows HID api always expects to receive a fixed size
buffer (corresponding to the largest report supported by the device). Therefore
the hidapi library internally pads the buffer with zeros to the expected size
when doing a smaller write:
/* Make sure the right number of bytes are passed to WriteFile. Windows
expects the number of bytes which are in the _longest_ report (plus
one for the report number) bytes even if the data is a report
which is shorter than that. Windows gives us this value in
caps.OutputReportByteLength. If a user passes in fewer bytes than this,
create a temporary buffer which is the proper size. */
if (length >= dev->output_report_length) {
/* The user passed the right number of bytes. Use the buffer as-is. */
buf = (unsigned char *) data;
} else {
/* Create a temporary buffer and copy the user's data
into it, padding the rest with zeros. */
buf = (unsigned char *) malloc(dev->output_report_length);
memcpy(buf, data, length);
memset(buf + length, 0, dev->output_report_length - length);
length = dev->output_report_length;
}
So I suspect libusb need the same type of fix. The expected size is already
available in the hid->output_report_size field.
Jef
|