Code Example: Driver Initialization

< BACK  NEXT >
[oR]

The following example shows how a basic kernel-mode device driver initializes itself. The code for this example is in chapter 6 directory on the disk that accompanies this book.

This first minimal driver must be manually loaded. It does not touch any hardware, but instead creates an internal device name (MINIMAL0) and a symbolic link name (MIN1). It consists of a single source module, Driver.cpp. A header file, Driver.h, declares driver-specific information about our nonhardware device, such as the DEVICE_EXTENSION.

DRIVERENTRY

In our first non-WDM driver example, the DriverEntry routine is small and straightforward. The responsibilities include

  1. Announcing other DriverEntry points. For the Minimal driver, the only other routine to announce is the driver's Unload function.

  2. Creating the logical devices that will be managed by the Minimal driver. For initial testing purposes, only a single device will be created.

 //++ // Function:  DriverEntry // // Description: //    Initializes the driver, locating and claiming //    hardware resources. Creates the kernel objects //    needed to process I/O requests. // // Arguments: //    pDriverObject - Passed from I/O Manager //    pRegistryPath - UNICODE_STRING pointer to //              registry info (service key) //              for this driver // // Return value: //    NTSTATUS signaling success or failure // NTSTATUS DriverEntry (           IN PDRIVER_OBJECT pDriverObject,           IN PUNICODE_STRING pRegistryPath ) {    ULONG ulDeviceNumber = 0;    NTSTATUS status;        // If this driver controlled real hardware,    // code would be placed here to locate it.    // Using IoReportResourceUsage, the ports,    // IRQs, and DMA channels would be "marked"    // as "in use" and under the control of this driver.    // This minimal driver has no HW, so...        // Announce other driver entry points    pDriverObject->DriverUnload = DriverUnload;    // Over time, the MajorFunction array will be filled        // For each physical or logical device detected    // that will be under this Driver's control,    // a new Device object must be created.    status =         CreateDevice(pDriverObject, ulDeviceNumber);    // This call would be repeated until    // all devices are created. E.g.,    // ulDeviceNumber++;    // status =    // CreateDevice(pDriverObject, ulDeviceNumber);        return status; } 

CREATEDEVICE

The work of actually creating the device object is delegated to a module-private (static) routine called CreateDevice. Although this routine doesn't do much, modularizing this work is appropriate as this driver evolves into a full WDM driver. Its responsibilities include

  1. Choosing and forming an internal device name. This driver hard-codes the name passed into the function.

  2. Creating the internal device object. The size of the DEVICE_EXTENSION is specified in the call to IoCreateDevice.

  3. Initializing the DEVICE_EXTENSION. In the case of this Minimal driver, the DEVICE_EXTENSION holds a back pointer to the device object and names for the device and symbolic link.

  4. Forming a symbolic link name and linking the name created.

The CreateDevice routine relies on the C++ class, CUString, discussed in the last chapter. The use of CUString makes it simple to convert numbers into Unicode strings and append them onto device names.

 //++ // Function: CreateDevice // // Description: //      Adds a new device // // Arguments: //      pDriverObject - Passed from I/O Manager //      ulDeviceNumber - Logical device number (zero-based) // // Return value: //      None // NTSTATUS CreateDevice (        IN PDRIVER_OBJECT  pDriverObject,        IN ULONG           ulDeviceNumber ) {         NTSTATUS status; PDEVICE_OBJECT pDevObj; PDEVICE_EXTENSION pDevExt; // Form the internal Device Name CUString devName("\\Device\\MINIMAL"); // for "minimal" device devName += CUString(ulDeviceNumber); // Now create the device status =        IoCreateDevice( pDriverObject,                            sizeof(DEVICE_EXTENSION),                            &(UNICODE_STRING)devName,                            FILE_DEVICE_UNKNOWN,                            0, TRUE,                            &pDevObj ); if (!NT_SUCCESS(status))        return status;         // Initialize the Device Extension pDevExt = (PDEVICE_EXTENSION)pDevObj->DeviceExtension; pDevExt->pDevice = pDevObj;   // back pointer pDevExt->DeviceNumber = ulDeviceNumber; pDevExt->ustrDeviceName = devName; // Form the symbolic link name CUString symLinkName("\\??\\MIN"); symLinkName += CUString(ulDeviceNumber+1);   // 1 based pDevExt->ustrSymLinkName = symLinkName; // Now create the link name status =        IoCreateSymbolicLink( &(UNICODE_STRING)symLinkName,                                       &(UNICODE_STRING)devName ); if (!NT_SUCCESS(status)) {        // if it fails now, must delete Device object        IoDeleteDevice( pDevObj );        return status; } // Made it return STATUS_SUCCESS; } 
< 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