Sample Files
You can find sample files for this book at the Microsoft Press Web site at http://www.microsoft.com/mspress/books/6262.asp. Clicking the Companion Content link takes you to a page from which you can download the samples. You can also find the files on the book's companion CD.
This book s companion content contains a great many sample drivers and test programs. I crafted each sample with a view toward illustrating a particular issue or technique that the text discusses. Each of the samples is, therefore, a toy that you can t just ship after changing a few lines of code. I wrote the samples this way on purpose. Over the years, I've observed that programmer-authors tend to build samples that illustrate their prowess at overcoming complexity rather than samples that teach beginners how to solve basic problems, so I won t do that to you. Chapter 7 and Chapter 12 have some drivers that work with real hardware, namely development boards from the makers of a PCI chip set and a USB chip set. Apart from that, however, all the drivers are for nonexistent hardware.
In nearly every case, I built a simple user-mode test program that you can use to explore the operation of the sample driver. These test programs are truly tiny: they contain just a few lines of code and are concerned with only whatever point the driver sample attempts to illustrate. Once again, I think it s better to give you a simple way to exercise the driver code that I assume you re really interested in instead of trying to show off every MFC programming trick I ve ever learned.
You re free to use all the sample code in this book in your own projects without paying me or anyone else a royalty. (Of course, you must consult the detailed license agreement at the end of this book this paraphrase is not intended to override that agreement in any way.) Please don t ship GENERIC.SYS to your customers, and please don't ship a driver that calls functions from GENERIC.SYS. The GENERIC.CHM help file in the companion content contains instructions on how to rename GENERIC to something less, well, generic. I intend readers to ship WDMSTUB.SYS and the AutoLaunch.exe modules, but I ll ask you to execute a royalty-free license agreement before doing so. Simply e-mail me at waltoney@oneysoft.com, and I ll tell you what to do. The license agreement basically obligates you to ship only the latest version of these components with an installation program that will prevent end users from ending up with stale copies.
About the Companion CD
The CD that comes with this book contains the complete source code and an executable copy of each sample. To access those files, insert the companion CD in your computer s CD-ROM drive, and make a selection from the menu that appears. If the AutoRun feature isn t enabled on your system (if a menu doesn t appear when you insert the disc in your computer s CD-ROM drive), run StartCD.exe in the root folder of the companion CD. Installing the sample files on your hard disk requires approximately 50 MB of disk space.
The companion CD also contains a few utility programs that you might find useful in your own work. Open the file WDMBOOK.HTM in your Web browser for an index to the samples and an explanation of how to use these tools.
The setup program on the CD gives you the option to install all the samples on your own disk or to leave them on the CD. However, setup will not actually install any kernel-mode components on your system. Setup will ask your permission to add some environment variables to your system. The build procedure for the samples relies on these environment variables. They will be correctly set immediately on Windows XP and the next time you reboot Windows 98/Windows Me.
If your computer runs both Windows XP and Windows 98/Windows Me, I recommend performing a full install under both operating systems so that the registry and the environment are correctly set up in both places. Run the setup program from the installed sample directory the second time too, to avoid useless file copying. It isn t necessary or desirable to specify different target directories for the two installations.
Each sample includes an HTML file that explains (very briefly) what the sample does, how to build it, and how to test it. I recommend that you read the file before trying to install the sample because some of the samples have unusual installation requirements. Once you ve installed a sample driver, you ll find that the Device Manager has an extra property page from which you can view the same HTML file, as shown here:
How the Samples Were Created
There s a good reason why my sample drivers look as though they all came out of a cookie cutter: they did. Faced with so many samples to write, I decided to write a custom application wizard. The wizard functionality in Microsoft Visual C++ version 6.0 is almost up to snuff for building a WDM driver project, so I elected to depend on it. The wizard is named WDMWIZ.AWX, and you ll find it in the companion content. I ve documented how to use it in Appendix B. Use it, if you want, to construct the skeletons for your own drivers. But be aware that this wizard is not of product grade it s intended to help you learn about writing drivers rather than to replace or compete with a commercial toolkit. Be aware too that you need to change a few project settings by hand because the wizard support is only almost what s needed. Refer to the WDMBOOK.HTM in the root directory of the companion CD for more information.
Building the Samples
I vastly prefer using the Microsoft Visual Studio 6.0 integrated development environment for driver projects. If you share this preference, you can follow suit when you work with my samples. The WDMBOOK.HTM file in the companion content contains detailed instructions about how to set up the development environment. I m deliberately not repeating those instructions here because they may change in the future. Each sample also includes a standard SOURCES file for use with the Driver Development Kit (DDK) build environments, in case your preference lies in that direction.
Updates to the Samples
At my Web site, http://www.oneysoft.com, you ll find a page concerning service packs for the sample drivers. In the three years since the first edition was printed, I issued about a dozen service packs. Service packs fix bugs and offer new samples. If you install my sample drivers, I recommend that you also install each new service pack as it comes out.
If you want to find out when a new service pack is available, you can fill out a simple online form to be added to my mailing list. First edition subscribers needn t reregister, by the way: you re all grandfathered in.
GENERIC.SYS
A WDM driver contains a great deal of code that you could call boilerplate for handling Plug and Play and power management. This code is long. It s boring. It s easy to get wrong. My samples all rely on what amounts to a kernel-mode DLL named GENERIC.SYS. WDMWIZ.AWX will build a project that uses GENERIC.SYS or that doesn t, as you specify. GENERIC.CHM in the companion content details the support functions that GENERIC.SYS exports, in case you want to use them yourself.
The downside to my using GENERIC all over the place is that I managed to obscure how some crucial things occur in the driver. The drivers that use GENERIC delegate all of the IRP_MJ_PNP (see Chapter 6) and IRP_MJ_POWER (see Chapter 8) handling to GENERIC, which then calls back to driver-specific routines to handle details. The following table describes the important callback functions.
IRP Type | Callback Function | Purpose |
IRP_MJ_PNP | StartDevice | Start the device (map memory registers, connect interrupt, and so on). |
| StopDevice | Halt device and release I/O resources (unmap memory registers, disconnect interrupt, and so on). |
| RemoveDevice | Undo steps performed in AddDevice (disconnect from lower device object, delete device object, and so on). |
| OkayToStop | (Optional) Is it OK to stop this device now (used while processing IRP_MN_QUERY_STOP_DEVICE)? |
| OkayToRemove | (Optional) Is it OK to remove this device now (used while processing IRP_MN_QUERY_REMOVE_DEVICE)? |
| FlushPendingIo | (Optional) Take any required action to force pending operations to finish in the near future. |
IRP_MJ_POWER | QueryPower | (Optional) Is a proposed change in device power OK (used while processing IRP_MN_QUERY_POWER)? |
| SaveDeviceContext | (Optional) Save any device context that will be lost during a period of low power. |
| RestoreDeviceContext | (Optional) Restore device context after a period of low power. |
| GetDevicePowerState | (Optional) Get device power state corresponding to a given system power state. |