summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libusb/os/windows_usb.c63
1 files changed, 28 insertions, 35 deletions
diff --git a/libusb/os/windows_usb.c b/libusb/os/windows_usb.c
index a4d7f97..d26f01f 100644
--- a/libusb/os/windows_usb.c
+++ b/libusb/os/windows_usb.c
@@ -2465,21 +2465,42 @@ static int winusb_claim_interface(struct libusb_device_handle *dev_handle, int i
struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev);
struct windows_device_handle_priv *handle_priv = __device_handle_priv(dev_handle);
struct windows_device_priv *priv = __device_priv(dev_handle->dev);
- bool is_composite = (priv->apib->id == USB_API_COMPOSITE);
+ bool is_using_usbccgp = (priv->apib->id == USB_API_COMPOSITE);
HANDLE file_handle, winusb_handle;
- USB_INTERFACE_DESCRIPTOR if_desc;
UCHAR policy;
uint8_t endpoint_address;
int i;
CHECK_WINUSB_AVAILABLE;
- // interfaces for composite devices are always independent, therefore
- // "alt" interfaces are only found on non-composite
- if ((!is_composite) && (iface != 0)) {
+ // If the device is composite, but using the default Windows composite parent driver (usbccgp)
+ // or if it's the first WinUSB interface, we get a handle through WinUsb_Initialize().
+ if ((is_using_usbccgp) || (iface == 0)) {
+ // composite device (independent interfaces) or interface 0
+ winusb_handle = handle_priv->interface_handle[iface].api_handle;
+ file_handle = handle_priv->interface_handle[iface].dev_handle;
+ if ((file_handle == 0) || (file_handle == INVALID_HANDLE_VALUE)) {
+ return LIBUSB_ERROR_NOT_FOUND;
+ }
+
+ if (!WinUsb_Initialize(file_handle, &winusb_handle)) {
+ usbi_err(ctx, "could not access interface %d: %s", iface, windows_error_str(0));
+ handle_priv->interface_handle[iface].api_handle = INVALID_HANDLE_VALUE;
+
+ switch(GetLastError()) {
+ case ERROR_BAD_COMMAND: // The device was disconnected
+ return LIBUSB_ERROR_NO_DEVICE;
+ default:
+ usbi_err(ctx, "could not claim interface %d: %s", iface, windows_error_str(0));
+ return LIBUSB_ERROR_ACCESS;
+ }
+ }
+ handle_priv->interface_handle[iface].api_handle = winusb_handle;
+ } else {
+ // For all other interfaces, use WinUsb_GetAssociatedInterface()
winusb_handle = handle_priv->interface_handle[0].api_handle;
- // It is a requirement on Windows that to claim an interface >= 1
- // on a non-composite WinUSB device, you must first have claimed interface 0
+ // It is a requirement for multiple interface devices on Windows that, to you
+ // must first claim the first interface before you claim the others
if ((winusb_handle == 0) || (winusb_handle == INVALID_HANDLE_VALUE)) {
#if defined(AUTO_CLAIM)
file_handle = handle_priv->interface_handle[0].dev_handle;
@@ -2510,35 +2531,7 @@ static int winusb_claim_interface(struct libusb_device_handle *dev_handle, int i
return LIBUSB_ERROR_ACCESS;
}
}
- } else {
- // composite device (independent interfaces) or interface 0
- winusb_handle = handle_priv->interface_handle[iface].api_handle;
- file_handle = handle_priv->interface_handle[iface].dev_handle;
- if ((file_handle == 0) || (file_handle == INVALID_HANDLE_VALUE)) {
- return LIBUSB_ERROR_NOT_FOUND;
- }
-
- if (!WinUsb_Initialize(file_handle, &winusb_handle)) {
- usbi_err(ctx, "could not access interface %d: %s", iface, windows_error_str(0));
- handle_priv->interface_handle[iface].api_handle = INVALID_HANDLE_VALUE;
-
- switch(GetLastError()) {
- case ERROR_BAD_COMMAND: // The device was disconnected
- return LIBUSB_ERROR_NO_DEVICE;
- default:
- usbi_err(ctx, "could not claim interface %d: %s", iface, windows_error_str(0));
- return LIBUSB_ERROR_ACCESS;
- }
- }
- handle_priv->interface_handle[iface].api_handle = winusb_handle;
}
- if (!WinUsb_QueryInterfaceSettings(winusb_handle, 0, &if_desc)) {
- usbi_err(ctx, "could not query interface settings for interface %d: %s", iface, windows_error_str(0));
- } else if (if_desc.bInterfaceNumber != iface) {
- usbi_warn(ctx, "program assertion failed - WinUSB interface %d found at position %d",
- if_desc.bInterfaceNumber, iface);
- }
-
usbi_dbg("claimed interface %d", iface);
handle_priv->active_interface = iface;