summaryrefslogtreecommitdiff
path: root/libusb/os/windows_common.h
diff options
context:
space:
mode:
authorRyan Metcalfe <ryan.metcalfe@novanta.com>2021-07-26 16:16:54 -0400
committerTormod Volden <debian.tormod@gmail.com>2023-01-19 15:02:11 +0100
commit5ec2821fdc491b470306d3cbb7175e53388d46fd (patch)
treede5bd9b242d17f420d318bda13d856f8f89a6ff9 /libusb/os/windows_common.h
parent809a6df614b87be780df9b0c97ba6c0bb6172aab (diff)
downloadlibusb-5ec2821fdc491b470306d3cbb7175e53388d46fd.tar.gz
windows: Allow claiming all interfaces for a WINUSBX composite function
On Windows 10, when a USB composite device is using usbccgp to manage the parent device, there can be problems when an application tries to claim multiple interfaces for a WINSBX-enabled subfunction. For example, a common scenario is that an application is able to claim the first interface of a given child function, but not the others. This commit attempts to resolve this issue by making use of (potentially) available interface association descriptors (IADs). Within set_composite_interface(), which is normally called for the first interface of a composite child function (Some MI_XX device, where XX is the first interface), the set of IADs for the current configuration is retrieved and, if the current interface matches the 'bFirstInterface' for one of the returned IADs then the API backend, sub_api is also set up for the other 'associated' interfaces. Subsequent calls to libusb_claim_interface for any of these 'associated' interfaces will get properly routed to winusbx_claim_interface. Two fields have been added to winusb_device_priv.usb_interface: num_associated_interfaces first_associated_interface These are made use of by winusbx_claim_interface() to decide whether Initialize() or GetAssociatedInterface() function calls are needed, as well as within winusbx_close() to perform proper cleanup for groups of associated functions. About composite functions in Windows (by Maciej T. Nowak): (1) Non-composite device: Single device is created with all interfaces grouped (associated) together. WinUSB_Initialize gives access to first interface and WinUSB_GetAssociatedInteface can be used to get access to remaining interfaces. (2) Composite device without IAD is presented by set of devices each containing single interface. As they are separate devices, separate WinUSB_Initialize calls are required to gain access to each interface. As there are no more interfaces in each device, WinUSB_GetAssociatedInterface has no use in this case. In other words: Each interface is grouped (associated) with itself. (3) When we add IAD to a composite device, interfaces specified in each IAD are grouped (associated) into single devices where WinUSB_Initialize is required to open the first interface in each association and WinUSB_GetAssociatedInterface for the remaining interfaces in each group. Effectively this case is a mix of (1) and (2). Closes #965 Signed-off-by: Ryan Metcalfe <ryan.metcalfe@novanta.com> [Tormod: Removed redundant is_associated_interface member] Signed-off-by: Tormod Volden <debian.tormod@gmail.com>
Diffstat (limited to 'libusb/os/windows_common.h')
-rw-r--r--libusb/os/windows_common.h7
1 files changed, 7 insertions, 0 deletions
diff --git a/libusb/os/windows_common.h b/libusb/os/windows_common.h
index 4582ce4..ff0a5b7 100644
--- a/libusb/os/windows_common.h
+++ b/libusb/os/windows_common.h
@@ -257,6 +257,13 @@ struct winusb_device_priv {
int current_altsetting;
bool restricted_functionality; // indicates if the interface functionality is restricted
// by Windows (eg. HID keyboards or mice cannot do R/W)
+ uint8_t num_associated_interfaces; // If non-zero, the interface is part of a grouped
+ // set of associated interfaces (defined by an IAD)
+ // and this is the number of interfaces within the
+ // associated group (bInterfaceCount in IAD).
+ uint8_t first_associated_interface; // For associated interfaces, this is the index of
+ // the first interface (bFirstInterface in IAD) for
+ // the grouped set of associated interfaces.
} usb_interface[USB_MAXINTERFACES];
struct hid_device_priv *hid;
PUSB_CONFIGURATION_DESCRIPTOR *config_descriptor; // list of pointers to the cached config descriptors