-
Notifications
You must be signed in to change notification settings - Fork 2k
Description
Let's assume USB device reporting itself as composite device with two interfaces (0 and 1) of class vendor. Using Microsoft OS 1.0 descriptors they are assigned WinUSB driver (using WINUSB CompatibilityId descriptor with two sections) and unique DeviceInterfaceGUID (using two separate Extended Compatibilty descriptor, one for each interface)
Some screenshots:
Device manager:

Registry, interface 0 with GUID:

Registry, interface 1 with GUID:

Now, there is well known limitation of WinUSB: "WinUSB is not an option if: Your device is accessed by multiple applications". However in the context of composite device interface 0 and interface 1 are separate devices.
Given that by using SetupAPI and WinUSB native API I'm able to lookup specific interface (single child device from composite device) that gives me paths:
\\?\usb#vid_4d4e&pid_4455&mi_00#7&57ec2a6&2&0000#{644991b2-1f10-45f7-a445-9a50ee4ce73d}for interface 0\\?\usb#vid_4d4e&pid_4455&mi_01#7&57ec2a6&2&0001#{13b2b252-adbf-45f8-9512-07342e35f305}for interface 1
As intended each path points to specific interface. Opening them (CreateFile) and wraping it in WinUSB (WinUSB_Initialize) in two different applications (one application for interface 0 and one for interface 1) gives me two separate handles for two separate devices. I can use these handles to issue control transfers and they are correctly interpreted by USB device as transfers to two different interfaces.
Observation: From WinUSB point of view it is possible to access different child devices of composite device from multiple application. It is not possible to access the same child device of composite device from multiple application.
Sorry for long introduction and probably stating facts that might be obvious but I wanted to describe context and what is possible before going to libusb specifics.
Libusb allows to use WinUSB devices however it is not aware of DeviceInterfaceGUID and composite device is treated as a whole. In WinUSB backend implementation there is function winusbx_open (https://github.com/libusb/libusb/blob/master/libusb/os/windows_winusb.c#L2428) which opens all child devices:
As you can see priv->usb_interface array contains device paths for both child devices.
As both child devices are opened (even if only single interface is required) no other application can open any child device of composite device.
Function libusb_wrap_sys_device that (in theory) could be used to mix SetupAPI (lookup and open device) with libusb (issue usb transfers) is not implemented on Windows.
It would be great if libusb only opened child device required by specific application, as that would allow other applications to access remaining child devices. However, at this moment I have no idea how that can be implemented nicely in libusb. I'm reporting this issue to keep a record of my experiments and findings as it is not 100% clear from documentation how WinUSB and composite devices play together.
