SourceQuest, Inc. Microsoft OS Descriptors
Copyright (c) 2004, SourceQuest, Inc.
Last update:  2004-10-18
Introduction
Microsoft OS Descriptors or MODs provide a way for USB devices to supply additional configuration information to the latest Microsoft operating systems. This information is requested from USB devices using a proprietary technique which has not been fully documented.

Some information is available from Microsoft through these links:

Microsoft OS Descriptor (WHDC)
Microsoft-Defined USB Descriptors (MSDN)
The last article states that full documentation will be forthcoming in a future Longhorn Driver Kit (LDK). Some of the important structures are already defined in the Windows 2003 Server DDK. So, with a little effort we can surmise how this new feature is going to work.

Hardware Examples
First, it helps to have a piece of hardware that supports MODs. So far, we have not seen any so we had to create our own. MODHID is EZ-USB firmware for a minimal HID that supports MODs. It has been used with the Devasys USB I2C/IO board for the following experiments. Our testing has been primarily with Windows XP SP1.

How does the OS know a device supports MODs?
Currently, Windows XP (SP1,SP2) and Windows 2003 Server, check if a device supports MODs the first time it is enumerated. The check consists of a GET_DESCRIPTOR request for a string descriptor with index 0xEE. The string returned should be Unicode "MSFT100" and the last two bytes of the buffer contain a one byte "bVendorCode" and a one byte pad. This structure is defined in the DDK as OS_STRING.

After completing the first steps of enumeration, Windows XP SP1 and newer, creates a unique UsbFlags entry for a newly encountered USB device. For example, with the MODHID device, it concatenates the vendor ID ("14f5"), product ID ("0002"), and device revision ("0100"), to create the key: "14f500020100" under "..\CurrentControlSet\Control\UsbFlags".


A two byte osvc binary value is stored under this key. The first byte is 1 if the GET_DESCRIPTOR request returned a valid OS_STRING structure indicating the device supports MODs. In this case, the second byte contains the value of bVendorCode. For devices not supporting MODs, both bytes are 0. In the screen shot above, note that MODHID is using a bVendorCode of 0x0C.

The next time MODHID is plugged into this system, the OS will look for a "14f500020100" key under UsbFlags. Since it will find this key, the GET_DESCRIPTOR request for the OS_STRING will be bypassed and the "osvc" value in the registry will be used. To force the OS to re-issue the check, you will need to delete your device's key under UsbFlags. Note that uninstalling a device does not remove this key.

How is bVendorCode used?
bVendorCode becomes the bRequest value in setup packets subsequently sent to your device. You won't want it to coincide with other vendor commands your device or chipset uses, so you'll want to select a value accordingly. In tests with MODHID, only setup packets with bmRequest values of 0xC0 and 0xC1 have been observed. These are vendor-device-input and vendor-interface-input respectively. These two types of setup packets correspond to the two kinds of OS Descriptors which are returned. One which extends the standard configuration descriptor by defining new device classes and one which returns registry type properties that describe the device.

Retrieval of Extended Configuration Descriptors
The first MOD-specific request a device will see, is for an extended configuration descriptor. If your device doesn't need this capability, you can either fail the request or return a minimal descriptor. The request comes in the form of the following vendor-device-input setup packet:

Field Type Value
bmRequest BYTE 0xC0
bRequest BYTE bVendorCode
wValueL BYTE 0x00 (PageIndex)
wValueH BYTE 0x00 (Interface Number)
wIndex WORD 0x0004
wLength WORD length of descriptor

A device supporting MODs will see two such requests, the first has a wLength of 16 bytes, which is large enough to hold just the header portion of the extended configuration descriptor. The subsequent request has wLength set to the full length of the descriptor. This descriptor can associate two strings to an interface for a device. Not all interfaces need to have an association defined, only those you select. The strings are up to 8 characters in length. See the firmware listing, Descriptors.a51, of MODHID for details on the descriptor definition.

MODHID's extended configuration descriptor returns the strings "WIDGET" and "0100" for its interface 0. These names can be thought of as defining a new class and subclass of device. Just as a standard interface descriptor's class, subclass, and protocol are used to create a series of compatible IDs, "WIDGET" and "0100" are used to create Microsoft-specific compatible IDs. These take the form:

"USB\MS_COMP_class&MS_SUBCOMP_subclass"
as shown in the screen shot below. For MODHID, the CompatibleIDs MULTI_SZ value is stored under the key, "..\CurrentControlSet\Enum\USB\Vid_14f5&Pid_0002\5&4e338fd&0&":

Compatible IDs are used to load generic system supplied drivers for certain classes of devices, e.g. hidusb.sys for USB HIDs or usbstor.sys for USB mass storage. These associations are defined by INF files such as input.inf and usbstor.inf. A casual search for the "MS_COMP" string in Windows XP's INF directory did not turn up any matches. However, this is where you can expect to see MS_COMP IDs being used to associate new Microsoft device classes with supporting device class drivers.

Retrieval of Extended Properties Descriptors
The next MOD-specific request a device will see, is for an extended properties descriptor. If your device doesn't need this capability, you can either fail the request or return a minimal descriptor. The request comes in the form of the following vendor-interface-input setup packet:

Field Type Value
bmRequest BYTE 0xC1
bRequest BYTE bVendorCode
wValueL BYTE 0x00 (PageIndex)
wValueH BYTE 0x00
wIndex WORD 0x0005
wLength WORD length of descriptor

A device supporting MODs will see two such requests, the first has a wLength of 10 bytes, which is large enough to hold just the header portion of the extended properties descriptor. The subsequent request has wLength set to the full length of the descriptor. This descriptor can define property-value pairs for a device. These pairs are installed under the "Device Parameters" hardware registry key. So the properties you define are destined to become device specific registry entries. See the firmware listing, Descriptors.a51, of MODHID for an example definition of an extended properties descriptor.

MODHID returns a property named "WidgetName" which has a REG_SZ value of "Tiger". The screenshot below shows the registry entry created for this MODHID property:

Unlike extended configuration descriptors, extended properties descriptors are installed just once, the first time the device is enumerated. This is enforced by creating the REG_DWORD value ExtPropDescSemaphore under the "Device Parameters" key. Once this value is defined, extended properties descriptors will not be installed again for this device.

There are several user-mode and kernel-mode APIs that can be used to access these registry values. In kernel-mode, IoOpenDeviceRegistryKey is used with the PLUGPLAY_REGKEY_DEVICE flag to open the "Device Parameters" key and then ZwQueryKeyValue retrieves specific values. In user-mode, SetupDiOpenDevRegKey is used with the DIREG_DEV flag to open the "Device Parameters" key and then RegQueryValueEx retrieves specific values. Extended properties descriptors will be useful for devices to pass capability and configuration information to installation programs and device drivers.

It seems that Microsoft intends to make considerable use of this feature in future operating system releases. In the MSDN article they state, "With the help of Microsoft OS Descriptors, you can use the firmware to deliver help files, special icons, Uniform Resource Locators (URLs), registry settings, and other data that is required to ease installation and enhance customer satisfaction. In some cases, you can forgo storage media such as floppy disks and CDs—which simplifies the delivery and support of upgrades."

A new URB
During enumeration, SourceUSB logs URB_FUNCTION_VENDOR_DEVICE and URB_FUNCTION_VENDOR_INTERFACE for the extended descriptor requests. However, the DDK has introduced a new function: URB_FUNCTION_GET_MS_FEATURE_DESCRIPTOR. It appears that this URB can be used by drivers to request both types of extended descriptors. It is used in conjunction with the URB structure, _URB_OS_FEATURE_DESCRIPTOR_REQUEST. There is also a macro for initializing this URB, UsbBuildOsFeatureDescriptorRequest. However, it is safer to directly initialize the _URB_OS_FEATURE_DESCRIPTOR_REQUEST structure, since the current macro fails to set a value for bRecipient (device or interface).

Patents
Microsoft has filed for several patents related to MODs. The two most relevant are:

These patent applications can be viewed online at http://www.espacenet.com.