Skip to content

Multiple WinUSB devices in single composite device #1177

@Novakov

Description

@Novakov

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:
image

Registry, interface 0 with GUID:
image

Registry, interface 1 with GUID:
image

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:

image

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.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions