summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorkuro68k <mojo@world3.net>2018-02-26 15:46:11 +0000
committerNathan Hjelm <hjelmn@me.com>2019-04-04 22:29:24 -0600
commit070efbb1dd3d5fe03fccaf2ca154ae92c1710e78 (patch)
treea83b96a6e6d2c0d721a9e80f402870345158bdd1
parent028e75355e2a97b7a3e7ab67f0356a06d1fa303e (diff)
downloadlibusb-070efbb1dd3d5fe03fccaf2ca154ae92c1710e78.tar.gz
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 <hjelmn@me.com>
-rw-r--r--libusb/os/windows_winusb.c36
-rw-r--r--libusb/version_nano.h2
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,16 +2343,38 @@ 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
*/
static int interface_by_endpoint(struct winusb_device_priv *priv,
@@ -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, &current_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