Working with USB Devices

This topic describes the operations that a Kernel-Mode Driver Framework (KMDF) or User-Mode Driver Framework (UMDF) driver starting in version 2 can perform using the USB device object methods provided by Windows Driver Frameworks (WDF).

It contains the following sections:

For step-by-step directions on writing a simple KMDF-based USB client driver, see How to write your first USB client driver (KMDF).

Creating a USB device object

To use the framework's USB I/O target objects (WDFUSBDEVICE, WDFUSBINTERFACE, and WDFUSBPIPE), your client driver must first call WdfUsbTargetDeviceCreateWithParameters to create a USB device object. Typically, a driver calls WdfUsbTargetDeviceCreateWithParameters from its EvtDevicePrepareHardware callback function.

When the driver calls WdfUsbTargetDeviceCreateWithParameters, the framework creates a WDFUSBDEVICE object and associates it with the FDO that represents the USB device. The method returns a handle to the new framework USB device object that the USB client driver can then use to communicate with the physical device.

After calling WdfUsbTargetDeviceCreateWithParameters, the driver can call WdfUsbTargetDeviceGetDeviceDescriptor and WdfUsbTargetDeviceRetrieveConfigDescriptor to obtain USB descriptors from the device. Those descriptors contain information about the device's first configuration, its interface settings, and their defined endpoints. (The USB descriptors are defined in the official USB specification.)

Configuring a USB Device

The WdfUsbTargetDeviceCreateWithParameters method also creates a framework USB interface object for each USB interface that the device's first configuration contains.

After calling WdfUsbTargetDeviceCreateWithParameters, the client driver must call WdfUsbTargetDeviceSelectConfig to select a configuration. This method creates framework interface objects for each alternate setting of the interface in the selected configuration.

The method also creates pipe objects that represent endpoints defined in each alternate setting of each interface of the selected configuration.

After you have selected a configuration, you can change alternate settings for the configuration's interfaces, if necessary.

You can also call WdfUsbTargetDeviceSelectConfig to deconfigure a device.

For related information, see:

Obtaining Device Information

After configuring a device, your client driver can call the following methods to obtain information about a USB device:

WdfUsbTargetDeviceQueryUsbCapability
Determines whether the host controller and USB driver stack support a specific capability. Before calling WdfUsbTargetDeviceQueryUsbCapability, a driver must call WdfUsbTargetDeviceCreateWithParameters.

WdfUsbTargetDeviceGetIoTarget
Returns a handle to the I/O target object that is associated with a USB device. The driver can pass this handle to WdfRequestSend or WdfIoTargetStop.

WdfUsbTargetDeviceRetrieveInformation
Retrieves version and capability information that is associated with a USB device.

WdfUsbTargetDeviceIsConnectedSynchronous (KMDF only)
Determines if the device is connected.

WdfUsbTargetDeviceRetrieveCurrentFrameNumber (KMDF only)
Retrieves the current USB frame number.

Getting USB Descriptors

To obtain the Unicode strings that are contained in a USB device's descriptors, the driver can call any of the following methods:

WdfUsbTargetDeviceGetDeviceDescriptor
Obtains a device's USB device descriptor.

WdfUsbTargetDeviceRetrieveConfigDescriptor
Obtains a device's USB configuration descriptor, interface descriptors, and endpoint descriptors.

WdfUsbTargetDeviceQueryString
Copies a Unicode string to a driver-supplied buffer.

WdfUsbTargetDeviceAllocAndQueryString
Copies a Unicode string to a framework-supplied buffer.

WdfUsbTargetDeviceFormatRequestForString
Formats a request for a Unicode string. The driver can call WdfRequestSend to send the request synchronously or asynchronously.

Sending a Control Transfer

Your driver can call the following methods to send an I/O request that describes a standard, device class-specific, or vendor-specific USB control transfer.

WdfUsbTargetDeviceSendControlTransferSynchronously
Synchronously sends a USB control transfer request.

WdfUsbTargetDeviceFormatRequestForControlTransfer
Formats a request for a USB control transfer. The driver can call WdfRequestSend to send the request synchronously or asynchronously.

For related information, see How to send a USB control transfer.

Resetting and Power-Cycling a Device's Port

Your driver can call the following methods to reset or power-cycle the USB port that a device is connected to:

WdfUsbTargetDeviceResetPortSynchronously
Synchronously sends a request to reset a device's USB port.

WdfUsbTargetDeviceCyclePortSynchronously (KMDF only)
Synchronously sends a request to power-cycle a device's USB port.

WdfUsbTargetDeviceFormatRequestForCyclePort (KMDF only)
Formats a request to power-cycle a device's USB port. The driver must call WdfRequestSend to send the request synchronously or asynchronously.

For related information, see How to recover from USB pipe errors.

Sending an URB to a Device

If your KMDF driver communicates with its USB device by sending I/O requests that contain URBs, the driver can call the following methods:

WdfUsbTargetDeviceCreateUrb (KMDF only)
Allocates a USB request block (URB). Before calling WdfUsbTargetDeviceCreateUrb, a driver must call WdfUsbTargetDeviceCreateWithParameters.

WdfUsbTargetDeviceCreateIsochUrb (KMDF only)
Allocates an isochronous USB request block (URB). Before calling WdfUsbTargetDeviceCreateIsochUrb, a driver must call WdfUsbTargetDeviceCreateWithParameters.

WdfUsbTargetDeviceSendUrbSynchronously (KMDF only)
Synchronously sends an I/O request that contains an URB.

WdfUsbTargetDeviceFormatRequestForUrb (KMDF only)
Formats an I/O request that contains a URB. The driver must call WdfRequestSend to send the request synchronously or asynchronously.

WdfUsbTargetDeviceWdmGetConfigurationHandle (KMDF only)
Returns a device's USBD configuration handle. Some URBs require this handle.

For general conceptual background on URBs, see Allocating and Building URBs.