windowsusbdriver

Why isn't windows loading the WINUSB Driver?


I'm developing a USB Device containing a couple of USB Functions (CDC-ACM and DFU as of now), using windows provided drivers.

The device descriptor indicates the device uses IAD (Interface Association Descriptor) and the configuration descriptor reflects that, containing all the descriptors for the CDC function as well as the DFU Function. This configuration works right out of the box on non-windows platforms, with both drivers correctly assigned.

Due to WCID (Windows Compatible ID) requirements, I have setup the following descriptor indicating that windows should load WINUSB for the DFU Interface.

USB_MicrosoftCompatibleDescriptor msft_compID = 
{
.dwLength =  sizeof(USB_MicrosoftCompatibleDescriptor) + (2 * sizeof(USB_MicrosoftCompatibleDescriptor_Interface)),

.bcdVersion = 0x0100,
.wIndex = 0x0004,
.bCount = 2,
.interfaces = {
  {
    .bFirstInterfaceNumber = 0, //CDC
    .compatibleID = {0, 0, 0, 0, 0, 0, 0, 0},
    .subCompatibleID = {0, 0, 0, 0, 0, 0, 0, 0}
  },
  {
    .bFirstInterfaceNumber = INTERFACE_DFU,
    .compatibleID = {0x57, 0x49, 0x4E, 0x55, 0x53, 0x42, 0x00, 0x00},
    .subCompatibleID = {0, 0, 0, 0, 0, 0, 0, 0}
  }
}
};

When the device is connected, I observed windows requesting for the 0xEE string descriptor followed by a request for the CompatibleID descriptor. The device manager confirms this as shown in the following screenshot. However, the host side software that uses the WINUSB API calls fails to detect the device. When I checked with Zadig, it's clear windows had loaded the libusb driver, instead of the winusb I requested.

Screenshot of device manager showing WINUSB as the compatible ID Screenshot of Zadig showing libusb driver

Despite this issue, the CDC-ACM function works as intended with a functioning virtual serial port appearing in the device manager.

Have I made any mistake in the ComaptibleID descriptor configuration, or are there any additional steps to take in order to make sure the correct driver is loaded?


Solution

  • I found the solution after reading between the lines of Microsoft Descriptor documentation. In order for windows to load the WINUSB driver, just the MicrosoftComaptibleID descriptor is not sufficient. Windows requires the device to add a DeviceGUID registry entry with the help of another Microsoft specific descriptor. This can be done under the Microsoft Descriptor Specification 1, but I updated the whole device to support the version 2.0 with the help of this excellent guide by google.

    Therefore my current descriptor structure looks like this.

    BOS descriptor 
        Bos header 
        WEBusb capability
        Microsoft capability
            Microsoft descriptor set header
    

    The BOS descriptor is a part of official USB specification released between 2.0 and 3.0. When windows reads the Microsoft descriptor set header, it requests for the Microsoft descriptor set by the means of a vendor request.

    MSFTDesc
    USB_MSFTDescriptorHeader            
        USB_MSFTConfigurationSubsetHeader   
        USB_MSFTFunctionSubsetHeader        
        USB_MSFTCompatibleIDFeatureDescriptor   
        USB_MSFTRegPropertyDescriptor 
    

    The Microsoft descriptor set contains the compatible IDs as well as the registry property descriptor for the GUID.