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 |