diff options
-rw-r--r-- | libusb/os/windows_usb.c | 81 | ||||
-rw-r--r-- | libusb/os/windows_usb.h | 1 |
2 files changed, 54 insertions, 28 deletions
diff --git a/libusb/os/windows_usb.c b/libusb/os/windows_usb.c index fed17b2..dae05ef 100644 --- a/libusb/os/windows_usb.c +++ b/libusb/os/windows_usb.c @@ -3,6 +3,7 @@ * Copyright (c) 2009-2010 Pete Batard <pbatard@gmail.com> * With contributions from Michael Plante, Orin Eman et al. * Parts of this code adapted from libusb-win32-v1 by Stephan Meyer + * Major code testing contribution by Xiaofan Chen * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -3150,51 +3151,75 @@ static int _hid_set_report(struct hid_device_priv* dev, HANDLE hid_handle, int i static int _hid_get_feature(struct hid_device_priv* dev, HANDLE hid_handle, int id, void *data, size_t *size) { - uint8_t buf[HID_MAX_REPORT_SIZE + 1]; - uint32_t r; + uint8_t *buf; + ULONG read_size = (ULONG)(*size + 1); + int r = LIBUSB_ERROR_OTHER; + uint32_t err; - if (*size >MAX_HID_REPORT_SIZE) + if (*size > MAX_HID_REPORT_SIZE) return LIBUSB_ERROR_INVALID_PARAM; + buf = (uint8_t*)calloc(1, read_size); + if (buf == NULL) { + return LIBUSB_ERROR_NO_MEM; + } buf[0] = (uint8_t)id; + usbi_dbg("report ID: 0x%02X", buf[0]); - *size += 1; - if (HidD_GetFeature(hid_handle, buf, (ULONG)*size)) { - return LIBUSB_COMPLETED; - } - r = GetLastError(); - switch (r) { - case ERROR_INVALID_FUNCTION: - return LIBUSB_ERROR_NOT_FOUND; - default: - usbi_dbg("error %s", windows_error_str(r)); - return LIBUSB_ERROR_OTHER; + 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); + } + memcpy(data, buf+1, read_size); + r = LIBUSB_COMPLETED; + } else { + err = GetLastError(); + switch (err) { + case ERROR_INVALID_FUNCTION: + r = LIBUSB_ERROR_NOT_FOUND; + default: + usbi_dbg("error %s", windows_error_str(r)); + r = LIBUSB_ERROR_OTHER; + } } + safe_free(buf); + return r; } static int _hid_set_feature(struct hid_device_priv* dev, HANDLE hid_handle, int id, void *data, size_t *size) { - uint8_t buf[HID_MAX_REPORT_SIZE + 1]; - uint32_t r; + uint8_t *buf; + uint32_t err; + int r = LIBUSB_ERROR_OTHER; + ULONG write_size = (ULONG)(*size + 1); if (*size >MAX_HID_REPORT_SIZE) return LIBUSB_ERROR_INVALID_PARAM; + buf = (uint8_t*)malloc(write_size); + if (buf == NULL) { + return LIBUSB_ERROR_NO_MEM; + } buf[0] = (uint8_t)id; - memcpy(buf + 1, data, *size); + usbi_dbg("report ID: 0x%02X", buf[0]); - *size += 1; - if (HidD_SetFeature(hid_handle, buf, (ULONG)*size)) { - return LIBUSB_COMPLETED; - } - r = GetLastError(); - switch (r) { - case ERROR_INVALID_FUNCTION: - return LIBUSB_ERROR_NOT_FOUND; - default: - usbi_dbg("error %s", windows_error_str(r)); - return LIBUSB_ERROR_OTHER; + memcpy(buf+1, data, *size); + + if (HidD_SetFeature(hid_handle, buf, write_size)) { + r = LIBUSB_COMPLETED; + } else { + err = GetLastError(); + switch (err) { + case ERROR_INVALID_FUNCTION: + r = LIBUSB_ERROR_NOT_FOUND; + default: + usbi_dbg("error %s", windows_error_str(r)); + r = LIBUSB_ERROR_OTHER; + } } + safe_free(buf); + return r; } static int _hid_class_request(struct hid_device_priv* dev, HANDLE hid_handle, int request_type, diff --git a/libusb/os/windows_usb.h b/libusb/os/windows_usb.h index 1d729e8..11b51a9 100644 --- a/libusb/os/windows_usb.h +++ b/libusb/os/windows_usb.h @@ -3,6 +3,7 @@ * Copyright (C) 2009-2010 Pete Batard <pbatard@gmail.com> * With contributions from Michael Plante, Orin Eman et al. * Parts of this code adapted from libusb-win32-v1 by Stephan Meyer + * Major code testing contribution by Xiaofan Chen * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public |