MS OS 2.0 (USB) Descriptor trouble

  • Thread starter Thread starter Benjamin Riggs
  • Start date Start date
B

Benjamin Riggs

Guest
I have a composite device with two USB CDC interfaces ('wrapped' in an IAD) and a custom interface, which I want to access via WinUSB. I can create the appropriate OS 2.0 descriptor to enable this and load the correct drivers. However, I can only do this if I put the CDC Interfaces before the custom interface. Unfortunately, because of convoluted reasons, I need the custom interface to be ahead of the CDC interfaces. When I simply swap the order of the OS descriptors (along with USB descriptors & interface IDs to match), Windows no longer recognizes the custom interface and fails to load WinUSB.sys for it. The CDC interface loads correctly both times.

Works:


// device.h

typedef struct
{
MS_OS_20_Descriptor_Set_Header_t Header;
MS_OS_20_Configuration_Subset_Header Configuration1;
MS_OS_20_Function_Subset_Header CDC_Function;
MS_OS_20_CompatibleID_Descriptor CDC_CompatibleID; // USBSER.SYS driver for COM port
MS_OS_20_Function_Subset_Header WebUSB_Function;
MS_OS_20_CompatibleID_Descriptor WebUSB_CompatibleID; // WINUSB.SYS driver

} MS_OS_20_Descriptor_t;


Doesn't work:


// device.h

typedef struct
{
MS_OS_20_Descriptor_Set_Header_t Header;
MS_OS_20_Configuration_Subset_Header Configuration1;
MS_OS_20_Function_Subset_Header WebUSB_Function;
MS_OS_20_CompatibleID_Descriptor WebUSB_CompatibleID; // WINUSB.SYS driver
MS_OS_20_Function_Subset_Header CDC_Function;
MS_OS_20_CompatibleID_Descriptor CDC_CompatibleID; // USBSER.SYS driver for COM port
} MS_OS_20_Descriptor_t;


For reference:

// device.c
const MS_OS_20_Descriptor_t PROGMEM MS_OS_20_Descriptor =
{
.Header =
{
.Length = CPU_TO_LE16(10),
.DescriptorType = CPU_TO_LE16(MS_OS_20_SET_HEADER_DESCRIPTOR),
.WindowsVersion = MS_OS_20_WINDOWS_VERSION_8_1,
.TotalLength = CPU_TO_LE16(MS_OS_20_DESCRIPTOR_SET_TOTAL_LENGTH)
},

.Configuration1 =
{
.Length = CPU_TO_LE16(8),
.DescriptorType = CPU_TO_LE16(MS_OS_20_SUBSET_HEADER_CONFIGURATION),
.ConfigurationValue = 1,
.Reserved = 0,
.TotalLength = CPU_TO_LE16(8 + 8 + 20)
},

.CDC_Function =
{
.Length = CPU_TO_LE16(8),
.DescriptorType = CPU_TO_LE16(MS_OS_20_SUBSET_HEADER_FUNCTION),
.FirstInterface = INTERFACE_ID_CDC_CCI,
.Reserved = 0,
.SubsetLength = CPU_TO_LE16(8 + 20)
},

.CDC_CompatibleID =
{
.Length = CPU_TO_LE16(20),
.DescriptorType = CPU_TO_LE16(MS_OS_20_FEATURE_COMPATBLE_ID),
.CompatibleID = u8"USBSER\x00", // Automatically null-terminated to 8 bytes
.SubCompatibleID = {0, 0, 0, 0, 0, 0, 0, 0}
},

.WebUSB_Function =
{
.Length = CPU_TO_LE16(8),
.DescriptorType = CPU_TO_LE16(MS_OS_20_SUBSET_HEADER_FUNCTION),
.FirstInterface = INTERFACE_ID_WEBUSB,
.Reserved = 0,
.SubsetLength = CPU_TO_LE16(8 + 20)
},

.WebUSB_CompatibleID =
{
.Length = CPU_TO_LE16(20),
.DescriptorType = CPU_TO_LE16(MS_OS_20_FEATURE_COMPATBLE_ID),
.CompatibleID = u8"WINUSB\x00", // Automatically null-terminated to 8 bytes
.SubCompatibleID = {0, 0, 0, 0, 0, 0, 0, 0}
},
};

Continue reading...
 
Back
Top