Using windows devices usb

How to connect to a USB device (UWP app)

Summary

  • How to use the DeviceWatcher object to detect devices
  • How to open the device for communication
  • How to close the device when you are finished using it

Important APIs

When you write a UWP app that interacts with a USB device, the app can send control commands, get device information, and read and write data to/from bulk and interrupt endpoints. Before you can do all that, you must find the device and establish connection.

Before you start.

  • This is the first topic in a series. Before you start this tutorial, you must have created a basic Visual Studio project that you can extend in this tutorial. Read Getting started with UWP apps for more info.
  • Code examples are based on the CustomUsbDeviceAccess sample. You can download the complete sample from this code gallery page.
  • The USB device used in tutorial is the SuperMUTT device.
  • In order to use the Windows.Devices.Usb namespace to write a Windows app that interacts with a USB device, the device must have the Winusb.sys driver loaded as its function driver. Winusb.sys is provided by Microsoft and is included with Windows in the \Windows\System32\drivers folder.

Flowchart: Finding the device

To connect to a USB device, you must first find the device based on various discovery patterns and then connect to it:

  • Connect to any USB device with a specific device interface GUID.
  • Connect to a USB device with a particular Vendor ID and Product ID and that has a specific device interface GUID.
  • Connect to a USB device with a particular Vendor ID and Product ID without knowing the device interface GUID.
  • Connect to a USB device which has known device class.

Key concepts

What is a device interface GUID?

A kernel-model driver, during its initialization, register and exposes a GUID called the device interface GUID. Typically, the app uses the exposed GUID to find the associated driver and its device, and then open a handle to the device. The retrieved handle is used for subsequent read and write operations.

However, in the case of Winusb.sys, instead of the driver exposing the device interface GUID, it can be provided in one of two ways:

  • In the device’s MS OS descriptors. The device manufacturer sets DeviceInterfaceGUID as a custom property in the extended properties descriptor in the device. For more details, see the «Extended Properties Descriptors» document in Microsoft OS Descriptors.
  • If you installed Winusb.sys manually through a custom INF, the INF registered a GUID in the INF. See WinUSB (Winusb.sys) Installation.

If a device interface GUID is found for the device, your UWP app can find all devices that match that device interface GUID.

How is USB device identification shown in Windows?

Every USB device must have two pieces of information: vendor ID and product ID.

USB-IF assigns those identifiers and the device manufacturer must expose them in the device. So how can you obtain that information?

Even when the device doesn’t have a device driver loaded, that is, Windows detects it as an «Unknown Device», you can still view the identifiers in the Device Manager in the Hardware Id property value. That value is a combination of those two identifiers. For example, for the SuperMUTT device, the Hardware Id is «USB\VID_045E&PID_F001»; vendor id is «0x045E» and product id is «0xF001».

If there is an INF for the device, obtain that string from the Models section.

You can inspect various registry settings. The easiest way is to see the

HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Enum\USB\

Hardware ID is used by the app manifest to identify the device.

Your UWP app can find all devices that match a specific vendor and product ids. You can narrow the search results by specifying the device interface GUID.

What are USB device classes?

Most USB devices conform to device class specifications approved by USB-IF. By using those specifications, devices of similar nature can exhibit their functionality in a standard way. The biggest advantage of this approach is that the device can use a Microsoft provided in-box class driver or the generic Winusb.sys driver.

Some devices might not follow a USB-IF specification. Instead they expose vendor-defined functionality. For such devices, either the vendor must provide the device driver or Winusb.sys can be used.

Whether a device is vendor-defined or conforms to a device class, it must describe this device class related information:

  • Class code: Indicates the device class to which the device belongs.
  • Subclass code: Within the device class, indicates the subclass of device.
  • Protocol code: The protocol that the device uses.

For example, the SuperMUTT device is a vendor-defined device and that information is indicated by class code is FF. If your device shows class code as FEh, subclass code as 02h, and protocol code 00h, you can conclude that the device is a class-compliant IrDA bridge device. Your UWP app can communicate with devices that belong to these device classes:

  • ActiveSync
  • CdcControl
  • DeviceFirmwareUpdate
  • IrDA
  • Measurement
  • PalmSync
  • PersonalHealthcare
  • Physical
  • VendorSpecific
Читайте также:  Samsung rv520 не устанавливается windows 10

Your UWP app can find all devices that match a specific set of class, subclass, and protocol codes.

Get the Advanced Query Syntax (AQS) string for the device

Generate an advanced query string (AQS) that contains identification information about the device that you want to detect. You can generate the string either by specifying the vendor/product IDs, device interface GUID, or by the device class.

If you want to provide the vendor ID/product ID or the device interface GUID, call any overload of GetDeviceSelector.

In the example of the SuperMUTT device, GetDeviceSelector retrieves an AQS string similar to this string:

«System.Devices.InterfaceClassGuid:=»» AND System.Devices.InterfaceEnabled:=System.StructuredQueryType.Boolean#True AND System.DeviceInterface.WinUsb.UsbVendorId:=1118 AND System.DeviceInterface.WinUsb.UsbProductId:=61441″

NoteВ В Notice that the device interface GUID that appears in the string is not the one you specified. That GUID is the actual device interface GUID registered by Winusb.sys for UWP apps.

If you know the device class of the device or its class, subclass, and protocol codes, call GetDeviceClassSelector to generate the AQS string.

Create a UsbDeviceClass object by specifying ClassCode, SubclassCode, and ProtocolCode property values. Alternatively, if you know the device class of the device, you can call the constructor by specifying a particular UsbDeviceClasses property.

Finding the device—The basic way

This is the simplest way to find a USB device. For details, see Quickstart: enumerating commonly used devices.

  1. Pass the retrieved AQS string to FindAllAsync. The call retrieves a DeviceInformationCollection object.
  2. Loop through the collection. Each iteration gets a DeviceInformation object.
  3. Get the DeviceInformation.Id property value. The string value is the device instance path. For example, «\\\\?\\USB#VID_045E&PID_078F#6&1b8ff026&0&5#«.
  4. Call FromIdAsync by passing the device instance string and get the UsbDevice object. You can then use the UsbDevice object to perform other operations, such as sending a control transfer. When the app has finished using the UsbDevice object, the app must release it by calling Close. NoteВ В When UWP app suspends, the device is closed automatically. To avoid using a stale handle for future operations, the app must released the UsbDevice reference.

Find the device—using DeviceWatcher

Alternatively, you can enumerate devices dynamically. Then, your app can receive notification if devices are added or removed, or if device properties change. For more information, see How to get notifications if devices are added, removed, or changed.

A DeviceWatcher object enables an app to dynamically detect devices as they get added and removed from the system.

Create a DeviceWatcher object to detect when the device is added to or removed from the system. You must create the object by calling CreateWatcher and specifying the AQS string.

Implement and register handlers for Added and Removed events on the DeviceWatcher object. Those event handlers are invoked when devices (with the same identification information) are added or removed from the system.

The app must start the DeviceWatcher object by calling Start so that it can start detecting devices as they are added or removed from the system. Conversely, the app must stop the DeviceWatcher by calling Stop, when it’s no longer necessary to detect devices. The sample has two buttons that allows the user to start and stop DeviceWatcher.

This code example shows how to create and start a device watcher to look for instances of the SuperMUTT device.

Open the device

To open the device, the app must start an asynchronous operation by calling the static method FromIdAsync and passing the device instance path (obtained from DeviceInformation.Id). That result of that operation obtain is a UsbDevice object, which is used for future communication with the device, such as performing data transfers.

After you are finished using the UsbDevice object, you must release it. By releasing the object, all pending data transfers are canceled. The completion callback routines for those operations are still invoked with canceled error or the operation completed.

C++ apps must release the reference by using the delete keyword. C#/VB apps must call the UsbDevice.Dispose method. JavaScript apps must call UsbDevice.Close.

The FromIdAsync fails if the device is in use or cannot be found.

WinUSB Device

In this topic, you will learn about how a WinUSB device is recognized in WindowsВ 8.

The information in this topic applies to you if you are an OEM or independent hardware vendor (IHV) developing a device for which you want to use Winusb.sys as the function driver and want to load the driver automatically without having to provide a custom INF.

What is a WinUSB device

A WinUSB device is a Universal Serial Bus (USB) device whose firmware defines certain Microsoft operating system (OS) feature descriptors that report the compatible ID as «WINUSB».

The purpose of a WinUSB device is to enable Windows to load Winusb.sys as the device’s function driver without a custom INF file. For a WinUSB device, you are not required to distribute INF files for your device, making the driver installation process simple for end users. Conversely, if you need to provide a custom INF, you should not define your device as a WinUSB device and specify the hardware ID of the device in the INF.

Microsoft provides Winusb.inf that contains information required by to install Winusb.sys as the device driver for a USB device.

Before WindowsВ 8, to load Winusb.sys as the function driver, you needed to provide a custom INF. The custom INF specifies the device-specific hardware ID and also includes sections from the in-box Winusb.inf. Those sections are required for instantiating the service, copying inbox binaries, and registering a device interface GUID that applications required to find the device and talk to it. For information about writing a custom INF, see WinUSB (Winusb.sys) Installation.

In WindowsВ 8, the in-box Winusb.inf file has been updated to enable Windows to automatically match the INF with a WinUSB device.

WinUSB device installation by using the in-box Winusb.inf

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».

The updated INF also includes a new setup class called «USBDevice».

The «USBDevice» setup class is available for those devices for which Microsoft does not provide an in-box driver. Typically, such devices do not belong to well-defined USB classes such as Audio, Bluetooth, and so on, and require a custom driver. If your device is a WinUSB device, most likely, the device does not belong to a USB class. Therefore, your device must be installed under «USBDevice» setup class. The updated Winusb.inf facilitates that requirement.

About using the USBDevice class:

Do not use the «USB» setup class for unclassified devices. That class is reserved for installing controllers, hubs, and composite devices. Misusing the «USB» class can lead to significant reliability and performance issues. For unclassified devices, use «USBDevice».

In Windows 8, to use «USBDevice» device class, simply add this to your INF:

In Device Manager you will see a new node USB Universal Serial Bus devices and your device appears under that node.

In Windows 7, in addition to the preceding lines, you need to create these registry settings in the INF:

In Device Manager, you will see your device appear under USB Universal Serial Bus devices. However, the device class description is derived from the registry setting specified in your INF.

Note that the «USBDevice» class is not limited to WinUSB. If you have a custom driver for your device, you can use the «USBDevice» setup class in the custom INF.

During device enumeration, the USB driver stack reads the compatible ID from the device. If the compatible ID is «WINUSB», Windows uses it as the device identifier and finds a match in the updated in-box Winusb.inf, and then loads Winusb.sys as the device’s function driver.

This image is for a single interface MUTT device that is defined as a WinUSB device and as a result Winusb.sys gets loaded as the function driver for the device.

For versions of Windows earlier than WindowsВ 8, the updated Winusb.inf is available through Windows Update. If your computer is configured to get driver update automatically, WinUSB driver will get installed without any user intervention by using the new INF package.

How to change the device description for a WinUSB device

For a WinUSB device, Device Manager shows «WinUsb Device» as the device description. That string is derived from Winusb.inf. If there are multiple WinUSB devices, all devices get the same device description.

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 (in its iProduct string descriptor) over the description in the INF. The «USBDevice» class defined in Windows 8 sets 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. In that case, the device description provided in the INF is ignored. Notice the device description strings: «MUTT» in the preceding image. The string is provided by the USB device in its product string descriptor.

The new class property is not supported on earlier versions of Windows. To have a customized device description on an earlier version of Windows, you have to write your own custom INF.

How to configure a WinUSB device

To identify a USB device as a WinUSB device, the device firmware must have Microsoft OS Descriptors. For information about the descriptors, see the specifications described here: Microsoft OS Descriptors.

Supporting extended feature descriptors

In order for the USB driver stack to know that the device supports extended feature descriptors, the device must define an OS string descriptor that is stored at string index 0xEE. During enumeration, the driver stack queries for the string descriptor. If the descriptor is present, the driver stack assumes that the device contains one or more OS feature descriptors and the data that is required to retrieve those feature descriptors.

The retrieved string descriptor has a bMS_VendorCode field value. The value indicates the vendor code that the USB driver stack must use to retrieve the extended feature descriptor.

For information about how to define an OS string descriptor, see «The OS String Descriptor» in the specifications described here: Microsoft OS Descriptors.

Setting the compatible ID

An extended compat ID OS feature descriptor that is required to match the in-box Winusb.inf and load the WinUSB driver module.

The extended compat ID OS feature descriptor includes a header section followed by one or more function sections depending on whether the device is a composite or non-composite device. The header section specifies the length of the entire descriptor, number of function sections, and version number. For a non-composite device, the header is followed by one function section associated with the device’s only interface. The compatibleID field of that section must specify «WINUSB» as the field value. For a composite device, there are multiple function sections. The compatibleID field of each function section must specify «WINUSB».

Registering a device interface GUID

An extended properties OS feature descriptor that is required to register its device interface GUID. The GUID is required to find the device from an application or service, configure the device, and perform I/O operations.

In previous versions of Windows, device interface GUID registration is done through the custom INF. Starting in Windows 8, your device should report the interface GUID by using extended properties OS feature descriptor.

The extended properties OS feature descriptor includes a header section that is followed by one or more custom property sections. The header section describes the entire extended properties descriptor, including its total length, the version number, and the number of custom property sections. To register the device interface GUID, add a custom property section that sets the bPropertyName field to «DeviceInterfaceGUID» and wPropertyNameLength to 40 bytes. Generate a unique device interface GUID by using a GUID generator and set the bPropertyData field to that GUID, such as «<8fe6d4d7-49dd-41e7-9486-49afc6bfe475>«. Note that the GUID is specified as a Unicode string and the length of the string is 78 bytes (including the null terminator).

7B 00 38 00 46 00 45 00 36 00 44 00 34 00 44 00 37 00 2D 00 34 00 39 00 00 44 00 2D 00 34 00 31 00 45 00 37 00 2D 00 39 00 34 00 38 00 36 00 2D 00 34 00 39 00 41 00 46 00 43 00 36 00 42 00 46 00 45 00 34 00 37 00 35 00 7D 00 00 00

bPropertyData 78 bytes Property value is <8fe6d4d7-49dd-41e7-9486-49afc6bfe475>.

During device enumeration, The USB driver stack then retrieves the DeviceInterfaceGUID value from the extended properties OS feature descriptor and registers the device in the device’s hardware key. An application can retrieve the value by using SetupDiXxx APIs (See SetupDiOpenDevRegKey). For more information, see How to Access a USB Device by Using WinUSB Functions.

Enabling or disabling WinUSB power management features

Before WindowsВ 8, to configure power management features of WinUSB, you had to write registry entry values in the HW.AddReg section of your custom INF.

In WindowsВ 8, you can specify power settings in device. You can report values through the extended properties OS feature descriptor that enable or disable features in WinUSB for that device. There are two features that we can be configured: selective suspend and system wake. 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 information about power management features of WinUSB, see WinUSB Power Management.

Property name 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. When enabled, the Allow this device to wake the computer check box appears in the device power management property page. The user can check or uncheck the box to enable or disable USB system wake.

For example, to enable selective suspend on the device, add a custom property section that sets the bPropertyName field to a Unicode string, «DeviceIdleEnabled» and wPropertyNameLength to 36 bytes. Set the bPropertyData field to «0x00000001». The property values are stored as little-endian 32-bit integers.

During enumeration, the USB driver stack reads the extended properties feature descriptors and creates registry entries under this key:

HKEY_LOCAL_MACHINE\System\CurrentControlSet\Enum\USB\ \ \Device Parameters

This image shows sample settings for a WinUSB device.

For additional examples, see the specifications on Microsoft OS Descriptors.

Читайте также:  Лучший дистрибутив linux для разработчика
Оцените статью