On USB Driver #3

Hi,

As you can see from the previous posts, Usb Architecture is more complex that other Serial Interfaces, due to layerization and complex packet architecture, so is necessary to have a well organized Coding Framework, to avoid and mitiagate the coding difficulties.
To implement a basical USB Device Driver, you need The latest version of the WDF DDK, Version 1.1 of the KMDF, and for professionally intersted subject in USB Coding OSR USB-FX2 learning kit.

Common WDM functions are great for USB Coding, but is any case coder needs to implements complex mechanisms, that can lead to heavy performances/working problems of the driver you coded, so Microsoft provided with KMDF an Encapsulation mechanism, that make more easy the code implementation.

The Device Descriptor

As previously said, the first operation to access an USB Device is to fill the Device Descriptor, that contains between the other settings the Number of Configurations, this field in our case is 1, because WDF supports only one onfiguration. Each Configuration has a Descriptor, that mantains trace of all Active Interfaces, these interfaces can have alternate settings, in other words various Endpoints, but at least you need for each interface Endpoint0. Pay attention to the USB Device Specifications, because many devices does not supports Multiple Alternate Settings, and your driver will deadly BSOD.

Now let’s see how to Configure our USB Device:

NTSTATUS ConfigOurUsb(WDFDEVICE Device, PDEVICE_CONTEXT DeviceContext)
{
NTSTATUS status = STATUS_SUCCESS;
PDEVICE_CONTEXT pDeviceContext;
WDF_USB_DEVICE_SELECT_CONFIG_PARAMS usbConfig;

status = WdfUsbTargetDeviceCreate(Device,
WDF_NO_OBJECT_ATTRIBUTES,
&DeviceContext->UsbDevice);

WdfUsbTargetDeviceCreate, takes as input parameters a handle to the device object and a pointer to a WDF_OBJECT_ATTRIBUTES structure and returns a handle to a WDFUSBDEVICE object, if Configuration goes ok, we can Select the Choised Configuration, we will use:

WDF_USB_DEVICE_SELECT_CONFIG_PARAMS_INIT_SINGLE_INTERFACE

WdfUsbTargetDeviceSelectConfig, creates WDF USB interface and pipe objects, and returns information about the specified configuration. Is importanto to say that the configuration process is done by filling WDF_USB_DEVICE_SELECT_CONFIG_PARAMS structs (which have In and Out params). As you have seen we uses INIT_SINGLE_INTERFACE, but KMDF have various INIT_XXX pre setted configs, so you’ve only to choise the one you need. There are also other functions to get informations about Configuration:

WdfUsbTargetDeviceRetrieveConfigDescriptor
WdfUsbTargetDeviceGetDeviceDescriptor
WdfUsbTargetDeviceGetInterface

After Usb Configuration, we can proceed with Pipe Configuration:

The framework creates a pipe object for each pipe in the setting, and gets access for each pipe with WdfUsbInterfaceGetConfiguredPipe.

As said for each alternate setting there are one or more associated Endpoints, so our driver needs an Enumeration Procedure to identify and use these pipes:

NTSTATUS ConfigUsbPipe(PDEVICE_CONTEXT DeviceContext)
{

NTSTATUS status = STATUS_SUCCESS;
WDF_USB_PIPE_INFORMATION pipeInfo;
WDFUSBPIPE pipe = NULL;
UCHAR index;

for(index=0; index < numberConfiguredPipes; index++) {
WDF_USB_PIPE_INFORMATION_INIT(&pipeInfo);
pipe = WdfUsbInterfaceGetConfiguredPipe( pDeviceContext->UsbInterface,
index, //PipeIndex,
&pipeInfo
);

if(WdfUsbPipeTypeInterrupt == pipeInfo.PipeType) {
pDeviceContext->InterruptPipe = pipe;
}
if(WdfUsbPipeTypeBulk == pipeInfo.PipeType
&& WdfUsbTargetPipeIsInEndpoint(pipe)) {
pDeviceContext->BulkReadPipe = pipe;
}
if(WdfUsbPipeTypeBulk == pipeInfo.PipeType
&& WdfUsbTargetPipeIsOutEndpoint(pipe)) {
pDeviceContext->BulkWritePipe = pipe;
}
}

Obviously, the most important function in our case is, WdfUsbInterfaceGetConfiguredPipe(), the out Struct WDF_USB_PIPE_INFORMATION mantains trace of each Pipe Configuration.

Here finishes the third part of Usb Coding, in the next days I’ll complete the coding part (probably with a full working USB Driver, and finally a we will talk about Usb Forensics.

See you to the next post..🙂

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: