Authored by Eliyas Yakub [MSFT] and Qiang Qiu [MSFT]

WinUSB is a Microsoft-provided kernel-mode client driver for USB devices. If you are developing a USB device for which Windows doesn’t include an in-box class driver, you can use Winusb.sys as the device driver instead of writing your own driver. In this blog, we’ll explain how you can build your device so that the Winusb.sys gets installed automatically on Windows 8 and earlier versions of the operating system.

Prior to Windows 8 if you choose Winusb.sys as the function driver for your device, you have to write a custom INF (see Writing an .Inf File for WinUSB Installation, and then install the driver on the target machine. The custom INF must specify your device specific hardware ID and also include sections from the inbox Winusb.inf. Those sections are required for instantiating the service, copying inbox binaries, and registering DeviceInterfaceGUID that is required by applications to find the device and talk to it.

In Windows 8, the in-box Winusb.inf file has been updated. The INF includes an install section that references a compatible ID called USB\MS_COMP_WINUSB. It also includes a newly defined setup class called “USBDevice”.

The compatible ID and USBDevice definitions are shown here:

[Version]
Class=USBDevice
ClassGuid={88BAE032-5A81-49f0-BC3D-A4FF138216D6}

[Generic.Section.NTamd64]
%USB\MS_COMP_WINUSB.DeviceDesc%=WINUSB,USB\MS_COMP_WINUSB
 

In order to match the compatible ID, the device must provide the ID by using Microsoft OS Descriptors. By building a device that reports the MS_COMP_WINUSB compatible ID, you can avoid writing a custom INF. The ability to provide compatible IDs through Microsoft OS descriptors has existed for several OS releases and has been widely used by other classes of devices, such as MTP, RNDIS, and Bluetooth.

The new USBDevice class is used for USB devices that do not conform to a USB-specific class specification. We will talk about need for defining this new USBDevice class later in this document.

Here are the steps for installing your device automatically using WinUSB.INF:

  1. The device must provide a compatible-ID using the extended MS OS feature descriptor as described in WinUSB Device. This is sufficient to match the in-box Winusb.inf and load the WinUSB driver module.
  2. However, to find the device from your application, configure the device, and perform I/O operations, you need to register its DeviceInterfaceGUID. In previous versions of Windows, that registration was done through the custom INF. Starting in Windows 8, your device should report the interface GUID by using extended properties OS feature descriptor as described in the WinUSB Device.
  3. There are several device registry settings, that control the behavior of WinUSB, such as selective suspend, power policy ownership, idle timeout, wake settings. Those properties can also be provided by including one or more extended properties feature descriptors on the device.

WinUSB compatible ID support on earlier versions of Windows

As stated earlier, the ability to provide compatible and sub-compatible IDs through Microsoft OS Descriptors has existed since Windows XP SP3, and has been widely used by other classes of devices such as MTP, RNDIS, and Bluetooth. To enable the use of compatible ID for WinUSB devices, a new certified INF is now available on Windows update for down-level operating systems. If your computer is configured to get driver update automatically, the WinUSB driver will get installed without any user intervention by using the new INF package.

For some reason, if you have to provide an INF then there is no point in building your device with compatible-ID because you cannot certify the INF with a compatible-ID match. You must use device specific hardware-ID in your INF.

USBDevice Class

For years, development community has misused the “USB” setup class by using it for their unclassified devices instead of defining a custom class. The USB controller class is strictly used for installing controllers, hubs, and composite devices. For instance, if you use “USB” class for a class filter driver for a device, the filter gets applied to other USB stack drivers which are also part of that class. Misusing the “USB” class has led to reliability and performance issues.

To prevent that scenario, we have defined a new class, “USBDevice” for devices that do not belong to any other class.

Class=USBDevice
ClassGuid={88BAE032-5A81-49f0-BC3D-A4FF138216D6}

When a device is installed by using WinUSB.INF on Windows 8, it automatically installs the device under the “USBDevice” class. This class is system-defined on Windows 8. On down-level OS versions, this class is defined by the new INF available through Windows Update. Note that this class is not limited to WinUSB. If you have a custom driver for your device, you can use the “USBDevice” setup class in the INF.

For some reason, if you have to install the device under a custom class then you do need to write your own INF. If you do write your INF then there is no point in building the device to report compatible-ID because you cannot certify your INF with a compatible-ID match. You have to use most device specific hardware-ID in your INF.

Showing a meaningful device description in Device Manager

Typically the description of the device that is shown in Device Manager is derived from the INF file. One drawback of using a generic in-box INF to install the driver is that all devices installed through that INF get the same device description, which is "WinUsb Device". This is not ideal.

To uniquely identify and differentiate the device in Device Manager, Windows 8 provides a new property on a device class that instructs the system to give precedence to the device description reported by the device (iProduct string descriptor) over the description that comes from the INF. The USBDevice class defined in Windows 8 has this property. In other words, when a device is installed under USBDevice class, system queries the device for a device description and sets the Device Manager string to whatever is retrieved in the query. The device description provided in the INF is ignored.

The new class property is not supported on earlier versions of Windows. So if you really care about having a customized description for your device on earlier version of Windows, you have to write your own custom INF.

In the Device Manager images shown in this blog post, notice the device description strings: “MUTT”, “FX3”, and “SuperMUTT”. Those strings are provided by the USB device in its product string descriptor.

Examples

We built couple of test devices using MUTT to demonstrate how this feature works. We have below snapshots of device manager and registry settings to show what the compat-id and device description looks.

Example 1: Single Interface Device

This picture is for a single interface MUTT device that provides “WINUSB” as the compatibleID and as a result Winusb.sys gets loaded as the function driver for the device.

clip_image002

Example 2: Composite Device

This image shows how a composite device appears that provides WINUSB compatible-ID for each of the functions in Device Manager.

clip_image004

clip_image002[6]

 

Example 3: Providing selective suspend and system wake settings

Until now, in order to configure power management features of WinUSB, you had to write registry entry values in the HW.AddReg section of your custom INF. The details can be found in WinUSB Power Management.

Now you can configure the behavior of Winusb.sys through the device itself. You can report registry values through the extended properties OS feature descriptor that enable or disable features in WinUSB for that device. In this example, we updated the single interface MUTT device to configure selective suspend and system wake capabilities of the device..

Selective suspend allows the device to enter low-power state when it is idle. System wake refers to the ability to a device to wake up a system when the system is in low-power state.

For selective suspend and system wake, these registry entries are required.

Registry Key

Description

DeviceIdleEnabled

This value is set to 1 to indicate that the device can power down when idle (selective suspend).

DefaultIdleState

This value is set to 1 to indicate that the device can be suspended when idle by default.

DefaultIdleTimeout

This value is set to 5000 in milliseconds to indicate the amount of time in milliseconds to wait before determining that a device is idle.

UserSetDeviceIdleEnabled

This value is set to 1 to allow the user to control the ability of the device to enable or disable USB selective suspend. A check box Allow the computer to turn off this device to save power on the device Power Management property page and the user can check or uncheck the box to enable or disable USB selective suspend.

SystemWakeEnabled

This value is set to 1 to allow the user to control the ability of the device to wake the system from a low-power state. A check box Allow this device to wake the computer shows up in the device power management property page and the user can check or uncheck the box to enable or disable USB system wake.

After the device is enumerated and initialized, these registry entries get written under the Device Parameters section of the hardware key. The picture below shows the registry entries for the customer properties that are reported by the device using extended properties OS feature descriptor.

clip_image006

This image shows device’s Power Management Properties page:

clip_image008

Summary

We explored in this article how you can build a device by using Microsoft OS descriptors to provide compatible ID and configuration information so that Winusb.sys is installed automatically as a function driver. This feature is available on Windows 8 and earlier versions up to Windows XP SP3. We hope that by reading this post you will understand best practices for using the new USBDevice class.

-Eliyas Yakub and Qiang Qiu