52964.fb2 Writing Windows WDM Device Drivers - читать онлайн бесплатно полную версию книги . Страница 20

Writing Windows WDM Device Drivers - читать онлайн бесплатно полную версию книги . Страница 20

Chapter 19WDM System Drivers

This chapter serves as a brief introduction to the system drivers that are provided as a part of the Windows Driver Model (WDM). These bus and class drivers are a very important part of the model. You can and should use the relevant system driver to access standard types of bus. These bus drivers are sometimes called class drivers, as they let you talk to a whole class of devices.

Figure 19.1 shows the main system drivers. Chapter 2 gave a brief overview of each of these. The remaining chapters of this book look in detail at the Universal Serial Bus (USB) and Human Input Device (HID) class drivers.

Figure 19.1 WDM system drivers

Writing Client Drivers

Each type of system driver has its own documentation that you must consult. In many cases, there will be a specification provided by a major standards body and a further specification provided by Microsoft for its system driver. For example, the core USB specification is produced jointly by Compaq, Intel, Microsoft, and NEC. However, the Windows USB Driver Interface (USBDI) is solely Microsoft's responsibility.

There are two main ways to work with system drivers. The first, a client, is when you use the system drivers to access your device. The second driver category interfaces the system to your hardware, by writing a minidriver, a miniclass driver, or a miniport driver. This book does not cover this last type of driver.

If you are writing a client driver, you need to understand and use the core WDM driver technologies as well as all the system driver's capabilities. This usually means that you must write a Plug and Play device driver with Power Management and Windows Management Instrumentation capabilities. Although this seems like an onerous task, the provision of standard system drivers definitely makes your task easier. To help you further, for the USB and HID cases, you can base your driver on the examples given in the rest of this book.

There are two main types of client driver that you can write[46]. The first is when you use a standard Plug and Play (PnP) INF file to make yourself part of the driver stack for a particular device, as all the WDM drivers in this book have done so far. The second type of client is an NT style driver that uses PnP Notification. Such a driver is notified when a device of the right type arrives. Your client can then make its own device object to represent the underlying device. The USB and HID drivers in the rest of this book illustrate how to write both types of client.

Common Devices

Occasionally you may want to control the behavior of all your devices. Rather than find each device and send IOCTLs to each one, a useful technique is to provide an additional "common device" that can be used to control the features that are common to all the other devices.

This common device object is typically an NT style device object created in your DriverEntry routine with a fixed symbolic link name. Your control application would open a handle to this common device, and, for example, use some IOCTLs to change the general behavior of your driver.

The complication to this approach is that your IRP dispatch routines will receive requests both for your ordinary devices and for your common device. Control requests for the ordinary devices should be rejected, and vice versa. The simplest way to achieve this functionality is to have a flag in the device extension that indicates the device type. You could have two separate device extensions, with the device type flag in a common portion of each structure.

Filter Drivers

Filter drivers let you modify the behavior of standard system drivers. A WDM filter driver is inserted into the device stack when the device stack is built. Figure 19.2 shows the different types of filter driver. This book does not cover filter drivers.

Figure 19.2 WDM filter drivers

Filter drivers can also be written to work in Windows NT 4 and NT 3.51. However, WDM device stacks are not available in these older operating systems. Instead, the IoGetDeviceObjectPointer or IoAttachDevice routines can be used to layer your device transparently above existing device objects. This book does not cover these types of filter driver, either.

NT Layering

Windows NT 4, NT 3.51, and 2000 use layers of NT style drivers. This is not the layering of Plug and Play devices seen in most of this book. Instead, each driver must be loaded in the correct order and use any existing drivers.

Parallel Port Drivers

As an example, Figure 19.3 shows the layering of the parallel port drivers. The parport driver is loaded first. parport arbitrates access to the parallel port hardware. The parallel and parvdm drivers are then loaded. When these drivers want to access the parallel port hardware, they must ask parport for access rights. Once access rights have been obtained, they can talk to the parallel port electronics directly.

New parallel port drivers should use the same technique to get access to the hardware[47]. The DDK recommends that you grab access to the port on a per-IRP basis. For most applications, I recommend taking control of the port for the duration of a larger transaction (e.g., while a handle is open to your device).

Figure 19.3 Parallel port layering

The parport driver creates a named kernel device object for each parallel port it finds. These device objects have kernel names starting with \Device\ParallelPort0. Use IoGetDeviceObjectPointer to obtain a pointer to the relevant device object[48]. Store this in your device extension for later use.

The parport driver supports several Internal IOCTLs. IOCTL_INTERNAL_GET_PARALLEL_PORT_INFO returns information about the parallel port (the base register address and port allocation routines). When the information is safely stored away, a similar (but undocumented) IOCTL_INTERNAL_RELEASE_PARALLEL_PORT_INFO call is made to release the information.

Two port allocation routines are available. TryAllocatePort tries to allocate the port and returns straightaway. If this succeeds, FreePort is used (later) to return the port. Call TryAllocatePort when you want to start accessing a parallel port and FreePort when you are finished with it.

When you install a driver that uses the parport driver, you must make sure that your driver loads after parport has started. Do this by including a DependOnService string value in your driver's registry entry that is set to parport.

Microsoft may be introducing a new WDM architecture for these parallel port drivers. A parallel port bus driver would replace parport. It would enumerate the ports available on the "bus". This is particularly important, as several IEEE 1284.3 printers may be daisy-chained on a single parallel port connection. The header file parallel.h in the W2000 DDK src\kernel\inc directory gives a hint of how the new interface will work.

Conclusion

Writing a client driver to access standard buses has been made much easier with the provision of several important system drivers. In addition, you can write minidrivers to interface these standard drivers to your own specialized hardware.

Let's now start looking at the standard system drivers by considering the Universal System Bus.


  1. You can also access the HID class driver in a user-mode client application.

  2. The only alternative is to remove the parport, parallel, and parvdm drivers, which would stop any existing parallel port access. 

  3. See Chapter 23 for details of IoGetDeviceObjectPointer.