From 070efbb1dd3d5fe03fccaf2ca154ae92c1710e78 Mon Sep 17 00:00:00 2001 From: kuro68k Date: Mon, 26 Feb 2018 15:46:11 +0000 Subject: Fix control transfer interface selection When bmRequestType indicates the recipient is an interface, get interface number from wIndex. Closes #398 Signed-off-by: Nathan Hjelm --- libusb/os/windows_winusb.c | 36 +++++++++++++++++++++++++++++++----- libusb/version_nano.h | 2 +- 2 files changed, 32 insertions(+), 6 deletions(-) diff --git a/libusb/os/windows_winusb.c b/libusb/os/windows_winusb.c index 2c4a81e..43b9f1a 100644 --- a/libusb/os/windows_winusb.c +++ b/libusb/os/windows_winusb.c @@ -2302,6 +2302,7 @@ static int winusbx_claim_interface(int sub_api, struct libusb_device_handle *dev return LIBUSB_ERROR_ACCESS; } } + handle_priv->interface_handle[iface].dev_handle = handle_priv->interface_handle[0].dev_handle; } usbi_dbg("claimed interface %d", iface); handle_priv->active_interface = iface; @@ -2342,15 +2343,37 @@ static int get_valid_interface(struct libusb_device_handle *dev_handle, int api_ } for (i = 0; i < USB_MAXINTERFACES; i++) { - if (HANDLE_VALID(handle_priv->interface_handle[i].dev_handle) - && HANDLE_VALID(handle_priv->interface_handle[i].api_handle) - && (priv->usb_interface[i].apib->id == api_id)) - return i; + if (HANDLE_VALID(handle_priv->interface_handle[i].dev_handle) + && HANDLE_VALID(handle_priv->interface_handle[i].api_handle) + && (priv->usb_interface[i].apib->id == api_id)) + return i; } return -1; } +/* +* Check a specific interface is valid (of the same API type), for control transfers +*/ +static int check_valid_interface(struct libusb_device_handle *dev_handle, unsigned short interface, int api_id) +{ + struct winusb_device_handle_priv *handle_priv = _device_handle_priv(dev_handle); + struct winusb_device_priv *priv = _device_priv(dev_handle->dev); + + if ((api_id < USB_API_WINUSBX) || (api_id > USB_API_HID)) { + usbi_dbg("unsupported API ID"); + return -1; + } + + // try the requested interface + if (HANDLE_VALID(handle_priv->interface_handle[interface].dev_handle) + && HANDLE_VALID(handle_priv->interface_handle[interface].api_handle) + && (priv->usb_interface[interface].apib->id == api_id)) + return interface; + + return -1; +} + /* * Lookup interface by endpoint address. -1 if not found */ @@ -2395,7 +2418,10 @@ static int winusbx_submit_control_transfer(int sub_api, struct usbi_transfer *it if (size > MAX_CTRL_BUFFER_LENGTH) return LIBUSB_ERROR_INVALID_PARAM; - current_interface = get_valid_interface(transfer->dev_handle, USB_API_WINUSBX); + if ((setup->RequestType & 0x1F) == LIBUSB_RECIPIENT_INTERFACE) + current_interface = check_valid_interface(transfer->dev_handle, setup->Index, USB_API_WINUSBX); + else + current_interface = get_valid_interface(transfer->dev_handle, USB_API_WINUSBX); if (current_interface < 0) { if (auto_claim(transfer, ¤t_interface, USB_API_WINUSBX) != LIBUSB_SUCCESS) return LIBUSB_ERROR_NOT_FOUND; diff --git a/libusb/version_nano.h b/libusb/version_nano.h index ec9aa04..e65f26a 100644 --- a/libusb/version_nano.h +++ b/libusb/version_nano.h @@ -1 +1 @@ -#define LIBUSB_NANO 11355 +#define LIBUSB_NANO 11356 -- cgit v1.2.1