Programming the Microsoft Windows Driver Model

What Kind of Driver Do I Need?

Many kinds of drivers form a complete Windows XP system. Figure 1-4 diagrams several of them.

Figure 1-4. Types of device drivers in Windows XP.

Not all the distinctions implied by this classification scheme are important all of the time. As I remarked in my previous book Systems Programming for Windows 95 (Microsoft Press, 1996), you haven t stumbled into a nest of pedants by buying my book. In particular, I m not always going to carefully distinguish between WDM and PnP drivers in the rigorous way implied by the preceding taxonomy. The distinction is a phenomenological one based on whether a given driver runs both in Windows 2000/XP and Windows 98/Me. Without necessarily using the technically exact term, I ll be very careful to discuss system dependencies when they come up hereafter.

Faced with all these categories of driver, a new driver writer or manager would understandably be confused about what sort of driver he or she needs for a given piece of hardware. For some devices, you don t need to write any driver at all because Microsoft already ships a generic driver that will work with your device. Here are some examples:

WDM Drivers

For most devices that Microsoft doesn t directly support, you need to write a WDM driver. You will decide first whether to write a monolithic function driver, a filter driver, or just a minidriver. You ll probably never need to write a class driver because Microsoft would like to reserve that specialty to itself in order to serve the broadest range of hardware makers.

WDM Minidrivers

The basic rule of thumb is that if Microsoft has written a class driver for the type of device you re trying to support, you should write a minidriver to work with that class driver. Your minidriver is nominally in charge of the device, but you ll call subroutines in the class driver that basically take over the management of the hardware and call back to you to do various device-dependent things. The amount of work you need to do in a minidriver varies tremendously from one class of device to another.

Here are some examples of device classes for which you should plan to write a minidriver:

WDM Filter Drivers

You may have a device that operates so closely to a recognized standard that a generic Microsoft driver is almost adequate. In some situations, you may be able to write a filter driver that modifies the behavior of the generic driver just enough to make your hardware work. This doesn t happen very frequently, by the way, because it s often not easy to change the way a generic driver accesses the hardware. I ll discuss filter drivers in great detail in Chapter 16.

Monolithic WDM Function Drivers

With some exceptions to be noted in the next section, most other types of device require what I ve called here a monolithic WDM function driver. Such a driver essentially stands alone and handles all the details of controlling your hardware.

When this style of driver is appropriate, I recommend the following approach so that you can end up with a single binary that will work on Intel x86 platforms in all operating systems. First, build with the most recent DDK I used a beta version of the .NET DDK for the samples in the companion content. You can use IoIsWdmVersionAvailable to decide which operating system you happen to be using. If you happen to be running in Windows 2000 or Windows XP, you can call MmGetSystemRoutineAddress to get a pointer to a Windows XP-only function. I also suggest shipping WDMSTUB.SYS, which is discussed in Appendix A, to define MmGetSystemRoutineAddress and other critical kernel functions in Windows 98/Me; otherwise, your driver simply won t load in Windows 98/Me because of undefined imports.

Here are some examples of devices for which you might write a monolithic WDM function driver:

More About Binary Compatibility

Originally, WDM was to have been binary portable across all versions of Windows. Because of release schedules and second (and higher-order) thoughts, every release since Windows 98 has included support for more and more kernel functions that are useful, and sometimes even essential, for robust and convenient programming. An example is the IoXxxWork Item family of functions, discussed in Chapter 14, which was added to Windows 2000 and which must be used instead of the similar but less robust ExXxxWorkItem family. Unless you do something extra, a driver that calls IoXxxWorkItem functions simply won t load in Windows 98/Me because the operating system doesn t export the functions. MmGetSystemRoutineAddress is another function that didn t make it into Windows 98/Me, unfortunately, so you can t even make a run-time decision regarding which work item functions to call. As if this weren t enough, the WHQL tests for all drivers flag calls to the ExXxxWorkItem functions.

In Windows 98/Me, a VxD named NTKERN implements the WDM subset of kernel support functions. As discussed in more detail in Appendix A, NTKERN relies on defining new export symbols for use by the run-time loader. You can also define your own export symbols, which is how WDMSTUB manages to define missing symbols for use by the kind of binary-portable driver I m advocating you build.

The companion content for this book includes the WDMCHECK utility, which you can run on a Windows 98/Me system to check a driver for missing imports. If you ve developed a driver that works perfectly in Windows XP, I suggest copying the driver to a Windows 98/Me system and running WDMCHECK first thing. If WDMCHECK shows that your driver calls some unsupported functions, the next thing to check is whether WDMSTUB supports those functions. If so, just add WDMSTUB to your driver package as shown in Appendix A. If not, either modify your driver or send me an e-mail asking me to modify WDMSTUB. Either way, you ll eventually end up with a binary-compatible driver.

Other Types of Drivers

A few situations exist in which a monolithic WDM function driver won t suffice because of architectural differences between Windows 98/Me and Windows 2000/XP. In the following cases, you would need to write two drivers: a WDM driver for Windows 2000/XP and a VxD driver for Windows 98/Me:

For two classes of device, Microsoft defined a portable driver architecture long before WDM:

Категории