On USB Driver #4

Hi,

As you’ve seen, there are a series of Configuration to accomplish in order to have a fully transactional USB Driver, now is the time on I/O Configuration which sounds also as IO Implementation. Essentially we have to implement a Device IO Control Handler, in other words a mechanism that for each IO Request provides a different procedure.

This is the procedure to send an IO Request (directly taken from Microsoft USB_WDF Documentation):

  • Create the request or use a request that the framework delivered.
  • Set up the memory objects and buffers for the request.
  • Format the request.
  • Set an I/O completion callback for the request, if appropriate.
  • Send the request.

Let’s consider an InGoing requests are processed troughout In/Out Endpoints, so everything you put into In-Endpoint are pulled out the Out-Endpoint, we have the called Double Buffered Mechanism.

VOID
EvtDeviceIoWrite(
IN WDFQUEUE  Queue,
IN WDFREQUEST  Request,
IN size_t  Length
)
{
NTSTATUS status = STATUS_SUCCESS;
PDEVICE_CONTEXT devCtx = NULL;
WDFMEMORY requestMem;

devCtx = GetDeviceContext(WdfIoQueueGetDevice(Queue));

status = WdfRequestRetrieveInputMemory(Request, &requestMem);

status = WdfUsbTargetPipeFormatRequestForWrite(
devCtx->UsbBulkOutPipe,
Request,
requestMem,
NULL);

WdfRequestSetCompletionRoutine(Request,
EvtIoWriteComplete,
devCtx->UsbBulkOutPipe);

status = WdfRequestGetStatus(Request);
WdfRequestComplete(Request, status);

The EvtIoWriteComplete associated with our EvtDeviceIoWrite to fix unreferenced parameters as Context and Target.

Let’s se now an Asynchronous Read Request:

VOID EvtIoReadRequest(IN WDFQUEUE         Queue,
IN WDFREQUEST       Request,
IN size_t           Length
)
{
WDFUSBPIPE          pipe;
NTSTATUS            status;
WDFMEMORY           reqMemory;
PDEVICE_CONTEXT     pDeviceContext;

pDeviceContext = GetDeviceContext(WdfIoQueueGetDevice(Queue));
pipe = pDeviceContext->BulkReadPipe;
status = WdfRequestRetrieveOutputMemory(Request, &reqMemory);
status = WdfUsbTargetPipeFormatRequestForRead(pipe,
Request,
reqMemory,
NULL // Offsets
);
WdfRequestSetCompletionRoutine( Request,
EvtRequestReadCompletionRoutine,
pipe
);
if (WdfRequestSend(Request,
WdfUsbTargetPipeGetIoTarget(pipe),
WDF_NO_SEND_OPTIONS) == FALSE) {
status = WdfRequestGetStatus(Request);
goto Exit;
}
Exit:
if (!NT_SUCCESS(status)) {
WdfRequestCompleteWithInformation(Request, status, 0);
}
return;
}

[Code is taken from USB_WDF.doc]

As you’ve seen from the code, the involved Functions are WdfRequestRetrieveOutputMemory, WdfUsbTargetPipeFormatRequestForRead and WdfUsbTargetPipeGetIoTarget, for the Reading Process.

For write request we have WdfUsbTargetPipeFormatRequestForWrite and WdfUsbTargetPipeWriteSynchronously.

Here some coding reference:

http://www.microsoft.com/whdc/driver/wdf/default.mspx
http://www.microsoft.com/whdc/driver/wdf/kmdf-arch.mspx
http://go.microsoft.com/fwlink/?LinkId=80613

http://go.microsoft.com/fwlink/?LinkId=80619

With this post, ends the pure theoretical part, next post will contains 1 or 2 downloadable source code drivers, and observations about USB Security.

See you to the next post..🙂

http://go.microsoft.com/fwlink/?LinkId=83355

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: