Code Example: A Loopback Device

< BACK  NEXT >
[oR]

An interesting (albeit simplistic) example to consider is a loopback device. The driver processes write requests by reserving a paged pool buffer and copying user data into this temporary buffer. The buffer is retained until such time as a read request is issued. The data returned by the read request is the contents of the temporary buffer, which is then released. The example demonstrates the implementation of read and write Dispatch routines as well as user buffer access.

 NTSTATUS DispatchWrite(  INPDEVICE_OBJECT pDO                          IN PIRP pIrp) {     NTSTATUS status = STATUS_SUCCESS;     PDEVICE_EXTENSION pDE;     PVOID userBuffer;     ULONG xferSize;     // The stack location contains the user buffer info     PIO_STACK_LOCATION pIrpStack;     pIrpStack = IoGetCurrentIrpStackLocation( pIrp );     // The example assumes the device is using BUFFERED_IO     userBuffer = pIrp->AssociatedIrp.SystemBuffer;     xferSize = pIrpStack->Parameters.Write.Length;     // The temporary buffer pointer is kept     // in the DEVICE_EXTENSION (obtained from Device obj)     pDE = (PDEVICE_EXTENSION) pDO  > DeviceExtension;     // If there is already a buffer, free it...     if (pDE->deviceBuffer != NULL) {          ExFreePool( pDE->deviceBuffer );          PDE->deviceBuffer = NULL;          xferSize = 0;     }     pDE->deviceBuffer =             ExAllocatePool(PagedPool, xferSize);     if (pDE->deviceBuffer == NULL) {          // buffer didn't allocate???          status = STATUS_INSUFFICIENT_RESOURCES;          xferSize = 0;     } else {          // copy the buffer          pDE->deviceBufferSize = xferSize;          RtlCopyMemory( pDE->deviceBuffer, userBuffer,                              xferSize );     }     // Now complete the IRP no device operation needed     pIrp->IoStatus.Status = status;     pIrp->IoStatus.Information = xferSize;     IoCompleteRequest( pIrp, IO_NO_INCREMENT );     return status;     } NTSTATUS DispatchRead(  IN PDEVICE_OBJECT pDO,                         IN PIRP pIrp ) {     NTSTATUS status = STATUS_SUCCESS;     PDEVICE_EXTENSION pDE;     PVOID userBuffer;     ULONG xferSize;     // The stack location contains the user buffer info     PIO_STACK_LOCATION pIrpStack;     pIrpStck = IoGetCurrentIrpStackLocation( pIrp );     userBuffer = pIrp->AssociatedIrp.SystemBuffer;     xferSize = pIrpStack->Parameters.Read.Length;     // The temporary buffer pointer is kept     // in the DEVICE_EXTENSION (obtained from Device obj)     pDE = (PDEVICE_EXTENSION) pDO  > DeviceExtension;     // Don't transfer more than the user's request     xferSize = (xferSize < pDE->deviceBufferSize) ?               xferSize : pDE->deviceBufferSize;     // Now copy the temporary buffer into user space     RtlCopyMemory(userBuffer, pDE->deviceBuffer,                                      xferSize);     // Free the temporary paged pool buffer     ExFreePool( pDE->deviceBuffer );     pDE->deviceBuffer = NULL;     pDE->deviceBufferSize = 0;     // and complete the I/O request...     pIrp->IoStatus.Status = status;     pIrp->IoStatus.Information = xferSize;     IoCompleteRequest( pIrp, IO_NO_INCREMENT );     return status; } 

This code example shows only the Dispatch routines for read and write. While they do very little, create and close Dispatch routines must be provided to make this a usable driver. A complete working version of this loopback driver, including a Win32 console test program, is included on the accompanying disk for chapter 7. The driver requires manual installation, as was demonstrated in the last chapter.

< BACK  NEXT >


The Windows 2000 Device Driver Book(c) A Guide for Programmers
The Windows 2000 Device Driver Book: A Guide for Programmers (2nd Edition)
ISBN: 0130204315
EAN: 2147483647
Year: 2000
Pages: 156

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net