Search code examples
windowsusbrndis

Composite RNDIS HID with MS OS 2.0 Descriptors


I'm developing a USB RNDIS and HID composite device. For the RNDIS device, I'm using MS OS 2.0 Descriptors described in the Microsoft document "Microsoft OS 2.0 Descriptors Specification" dated April, 2017 (linked at the bottom of https://learn.microsoft.com/en-us/windows-hardware/drivers/usbcon/microsoft-defined-usb-descriptors). I'm working with a Windows 10 host.

Both devices are recognized but only the HID device is recognized correctly; windows assigns the RNDIS device to be a serial port.

Here's some of the pertinents. Device descriptor:

.bLength = 18
.bDescriptorType = 1
.bcdUSB = 0x0201
.bDeviceClass = 0xef
.bDeviceSubClass = 2
.bDeviceProtocol = 1
.bMaxPacketSize0 = 64
.idVendor = USB_DEVICE_VENDOR_ID,
.idProduct = USB_DEVICE_PRODUCT_ID,
.bcdDevice = (USB_DEVICE_MAJOR_VERSION << 8) | USB_DEVICE_MINOR_VERSION,
.iManufacturer = 1
.iProduct = 2
.iSerialNumber = 3
.bNumConfigurations = 1

Configuration descriptor

Configuration Header:

    .bLength = 9
    .bDescriptorType = 2
    .wTotalLength = 100
    .bNumInterfaces = 3
    .bConfigurationValue = 1
    .iConfiguration = 0,
    .bmAttributes = 0xc0
    .bMaxPower = 0xfa

Interface Association Descritpor

    .bLength = 8
    .bDescriptorType = 11
    .bFirstInterface = 0
    .bInterfaceCount = 2
    .bFunctionClass = 2
    .bFunctionSubClass = 2
    .bFunctionProtocol = 0xff,
    .iFunction = 0

RNDIS Descriptor

    CDC IF Descriptor

        .bLength = 9
        .bDescriptorType = 4
        .bInterfaceNumber = 0
        .bAlternateSetting = 0,
        .bNumEndpoints =  1
        .bInterfaceClass = 2
        .bInterfaceSubClass = 2
        .bInterfaceProtocol = 0xff,
        .iInterface = 0

    [Remainder of RNDIS Control & Data interface]

HID Descriptor
[HID Descriptor details]

BOS Descriptor

Header

    .bLength = 5
    .bDescriptorType = 15
    .wTotalLength = 33
    .bNumDeviceCaps = 1

Platform Capabilities Descriptor

    .bLength = 28
    .bDescriptorType = 16
    .bDevCapability = 5
    .bReserved = 0,
    .capabilityId = {0xdf, 0x60, 0xdd, 0xd8, 0x89, 0x45, 0xc7, 0x4c, 0x9c, 0xd2, 0x65, 0x9d, 0x9e, 0x64, 0x8a, 0x9f}

Windows Descriptor Set

    .dwWindowsVersion = 0x06030000
    .wLength = 46
    .bMsVendorCode = 1
    .bAltEnumCode = 0

MS Compatibility Descriptor:

Header

    .wLength = 10
    .wDescriptorType = 0
    .dwWindowsVersion = 0x06030000
    .wTotalLength = 46

Configuration Subset Header

    .wLength = 8
    .wDescriptorType = 1
    .bConfigurationValue = 1
    .bReserved = 0,
    .wTotalLength = 36

Function Subset Header

    .wLength = 8
    .wDescriptorType = 2
    .bFirstInterface = 0
    .bReserved = 0,
    .wSubsetLength = 28

Compatibility ID

    .wLength = 20
    .wDescriptorType =  3
    .compatibleId = {'R', 'N', 'D', 'I', 'S', 0, 0, 0},
    .subCompatibleId = {'5', '1', '6', '2', '0', '0', '1', 0}

If I build my device to be a strictly RNDIS device then all works as expected - the device is recognized by Windows as an RNDIS device; I do not install any drivers. Here's a summary of the modifications I make for an RNDIS-only device (needed size changes were also made):

  • Change the Device Descriptor device class fields
  • Remove the IAD & HID sections of the Configuration Descriptor
  • Reduce the Configuration Descriptor bNumInterfaces count to 2
  • Remove the Configuration Subset Header & Function Subset Header from the MS Compatibility Descriptor

Note that if I leave the Configuration Subset Header & Function Subset Header in the MS Compatibility Descriptor, Windows responds as above - assigns the RNDIS device to be a serial port.

I've tried various permutations but can't seem to get beyond this point. I have not yet tried creating an INF for a custom device, but that is something I want to avoid.

Any help or suggestions?

Thanks.


Solution

  • Try changing the bConfigurationValue in your Microsoft OS 2.0 Descriptors (specifically the Configuration Subset Header) from 1 to 0. It is actually an index in the array of configurations; it is not the same as the thing that is named bConfigurationValue in the USB 2.0 specification.

    I had the same problem, as described here:

    https://social.msdn.microsoft.com/Forums/windowsdesktop/en-US/ae64282c-3bc3-49af-8391-4d174479d9e7/microsoft-os-20-descriptors-not-working-on-an-interface-of-a-composite-usb-device?forum=wdk

    I did not check the rest of your descriptors so there very well might be other issues.