After teaching driver programming seminars to hundreds of students over the past several years, I've come to understand that people learn things in fundamentally different ways. Some people like to learn a great deal of theory about something and then learn how to apply that theory to practical problems. Other people like to learn practical things first and then learn the general theory. I'd call the former approach deductive and the latter approach inductive. I personally prefer an inductive approach, and I've organized this book to suit that style of learning.
My aim is to explain how to write device drivers. Broadly speaking, I wanted to provide the minimum background you'll need to write an actual driver and then move on to more specialized topics. That "minimum background" is pretty extensive, however; it consumes six chapters. Once past Chapter 7, you'll be reading about topics that are important but not necessarily on the fall line that leads straight downhill to a working driver.
Chapter 2, "Basic Structure of a WDM Driver," explains the basic data structures that Windows 2000 uses to manage I/O devices and the basic way your driver relates to those data structures. I'll discuss the driver object and the device object. I'll also discuss how you write two of the subroutines—the DriverEntry and AddDevice routines—that every WDM driver package contains.
Chapter 3, "Basic Programming Techniques," describes the most important service functions you can call on to perform mundane programming tasks. In that chapter, I'll discuss error handling, memory management, and a few other miscellaneous tasks.
Chapter 4, "Synchronization," discusses how your driver can synchronize access to shared data in the multitasking, multiprocessor world of Windows 2000. You'll learn the details about IRQL and about various synchronization primitives that the operating system offers for your use.
Chapter 5, "The I/O Request Packet," introduces the subject of input/output programming, which of course is the real reason for this book. I'll explain where I/O request packets come from, and I'll give an overview of what drivers do with them when they follow what I call the "standard model" for IRP processing. I'll also discuss the knotty subject of IRP cancellation, wherein accurate reasoning about synchronization problems becomes crucial.
Chapter 6, "Plug and Play," concerns just one type of I/O request packet, namely IRP_MJ_PNP. The Plug and Play Manager component of the operating system sends you this IRP to give you details about your device's configuration and to notify you of important events in the life of your device. Being a good PnP citizen implies that many drivers can't use the "standard model" for IRP processing. I'll therefore describe an object I named a DEVQUEUE that you can use to queue and dequeue IRPs appropriately when PnP events are occurring all around you.
Chapter 7, "Reading and Writing Data," is where we finally get to write driver code that performs I/O operations. I'll discuss how you obtain configuration information from the PnP Manager and how you use that information to prepare your driver for "substantive" IRPs that read and write data. I'll present two simple driver sample programs as well: one for dealing with a PIO device and one for dealing with a bus-mastering DMA device.
Chapter 8, "Power Management," describes how your driver participates in power management. I think you'll find, as I did, that power management is pretty complicated. Unfortunately, you have to participate in the system's power management protocols or else the system as a whole won't work right. Worse yet, the system will sometimes present a dialog box that identifies you as the culprit if you don't do the right things. Luckily, the community of driver writers already has a grand tradition of cutting and pasting, and that will save you.
Chapter 9, "Specialized Topics," contains a discussion of filter drivers, error logging, I/O control operations, and system threads.
Chapter 10, "Windows Management Instrumentation," concerns a scheme for enterprisewide computer management in which your driver can and should participate. I'll explain how you can provide statistical and performance data for use by monitoring applications, how you can respond to standard WBEM controls, and how you can alert controlling applications of important events when they occur.
Chapter 11, "The Universal Serial Bus," describes how to write drivers for USB devices.
Chapter 12, "Installing Device Drivers," tells you how to arrange for your driver to get installed onto end user systems. You'll learn the basics of writing an INF file to control installation, and you'll also learn some interesting and useful things to do with the system registry.
Appendix A, "Coping with Windows 98 Incompatibilities," explains a VxD-based scheme that will allow you to deploy the same driver binary on both Windows 2000 and Windows 98 platforms. The basic problem you now have to solve—and the basic reason a distinction exists between PnP drivers and WDM drivers—is that Windows 2000 was finished after Windows 98 and predictably exports some service routine that Windows 98 either doesn't export or doesn't implement in quite the same way. You can solve this problem with a short VxD that I'll show you.
Appendix B, "Using GENERIC.SYS," describes the public interface to my GENERIC.SYS library. Most of my sample drivers use GENERIC.SYS, and you might need to consult this documentation to fully understand how the samples work.
Appendix C, "Using WDMWIZ.AWX," describes how to use my Visual C++ application wizard to build a driver. I repeat that WDMWIZ.AWX is not intended to take the place of a commercial toolkit. Among other things, that means that it's not easy enough to use that you can dispense with documentation.
This book is as accurate as I could make it. Let's face it, though: when writing about a complex technology with many new elements, it's impossible to be 100 percent right. In addition, WDM will inevitably change over the next few months as the Windows 2000 beta period winds down to a retail release. My publisher and I have a plan to deal with this. To deal with errors, I'll publish an errata page at my Web site (http://www.oneysoft.com). I hope friendly readers will email me comments that I can post there.