diff options
author | Pete Batard <pbatard@gmail.com> | 2010-04-08 11:46:55 +0100 |
---|---|---|
committer | Pete Batard <pbatard@gmail.com> | 2010-04-08 11:46:55 +0100 |
commit | bb3280741d3675dee6274be60ce352e3a2f5370a (patch) | |
tree | 7067af0e6fb4e494d9cc8139d90d3a0c927538f6 /libusb/os/windows_usb.c | |
parent | d102dd23992cadc056cf28a3aefb8cfbcf532e31 (diff) | |
download | libusb-bb3280741d3675dee6274be60ce352e3a2f5370a.tar.gz |
workaround for MS's HidD_GetFeature bug with report IDs
When report IDs are in use, the payload starts at buffer+0 not buffer+1
as indicated at http://msdn.microsoft.com/en-us/library/ff538910.aspx
Bug reported by Axel Rohde
Diffstat (limited to 'libusb/os/windows_usb.c')
-rw-r--r-- | libusb/os/windows_usb.c | 25 |
1 files changed, 21 insertions, 4 deletions
diff --git a/libusb/os/windows_usb.c b/libusb/os/windows_usb.c index 42b7133..2d1526d 100644 --- a/libusb/os/windows_usb.c +++ b/libusb/os/windows_usb.c @@ -3220,11 +3220,28 @@ static int _hid_get_feature(struct hid_device_priv* dev, HANDLE hid_handle, int usbi_dbg("report ID: 0x%02X", buf[0]); if (HidD_GetFeature(hid_handle, buf, read_size)) { - if (buf[0] != id) { - usbi_dbg("program assertion failed - mismatched report ID (got %02X instead of %02X)", - buf[0], id); + // There is a major bug with HidD_GetFeature where the actual data payload starts + // at buf+0 when report IDs are in use by the device, but buf+1 otherwise. + // To try to work around this bug, we assume that if the id provided is + // nonzero, then report IDs are in use by the device + if (id != 0) { + // Try to compensate for a wrong assumption + if ((buf[read_size-1] != 0) && (buf[0] == 0)) { + usbi_warn(NULL, "program assertion failed - report ID provided but device does not"); + usbi_warn(NULL, "seem to use report IDs. Compensating by shifting payload data"); + memcpy(data, buf+1, read_size); + } else { + memcpy(data, buf, read_size); + } + } else { + if (buf[0] != 0) { + usbi_warn(NULL, "program assertion failed - report ID received (0x%02X) was", buf[0]); + usbi_warn(NULL, "supposed to be zero. Compensating by shifting payload data"); + memcpy(data, buf, read_size); + } else { + memcpy(data, buf+1, read_size); + } } - memcpy(data, buf+1, read_size); r = LIBUSB_COMPLETED; } else { err = GetLastError(); |