The companion disc 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. Chapters 7 and 11 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 only with 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 ever learned.
You're free to use all of 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 the book—this paraphrase is not intended to override that agreement in any way.) There are few cases in which I ask that you get my permission before redistributing one of my sample modules as a freestanding piece of software, however; these include GENERIC.SYS (discussed in Appendix B) and WDMSTUB.VXD (discussed in Appendix A). I'll gladly give permission, but I will need to ask your company to agree to some conditions designed to ensure that if a bunch of readers all decide to ship copies of these modules along with their production drivers, end users receive up-to-date and reliable versions. See the companion disc for more information on redistribution.
The CD-ROM that comes with this book contains the complete source code and an executable copy of each sample. It 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 disc gives you the option to install all of the samples on your own disk or to leave them on the CD-ROM. However, setup will not install any kernel-mode components on your system. Setup will ask your permission to add some environment variables to your AUTOEXEC.BAT file. The build procedure for the samples relies on these environment variables. They will be correctly set the next time you reboot your Windows 2000 or Windows 98 computer. Setup will also install the necessary registry entries to define a SAMPLE class of device, to which each of the sample drivers belongs.
If your computer runs both Windows 2000 and Windows 98, I recommend performing a full install under one OS and a compact install under the other. Additionally, I recommend allowing the setup program to modify your AUTOEXEC.BAT under just one OS. If you follow these suggestions, setup will be able to make necessary changes in both registry databases but will copy the sample code only one time. (Note that Windows 2000 interprets your AUTOEXEC.BAT file at startup time to set environment variables. That's why the setup program needs to modify this file.)
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. (See Figure 1-6.)
Figure 1-6. A custom Device Manager property page for sample drivers.
There's a good reason why my sample drivers look like 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 on the companion disc. I've documented how to use it in Appendix C. Use it, if you wish, to construct the skeletons for your own drivers. But be wary 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 disc for more information.
Installing the Windows 2000 Device Driver Kit provides you with Start menu commands for opening a "checked build" environment and a "free build" environment. Each environment is a command prompt with a collection of environment variables set in a particular way to dovetail with a command line-based method of building drivers. This method relies on a utility named BUILD.EXE that comes with the DDK and on the existence of a file named SOURCES that describes a driver project. I've provided a SOURCES file for each project so that you can use this method for building a driver if you want to.
I personally prefer using the Microsoft Visual Studio environment for driver projects. I used to advocate using BUILD.EXE because I was afraid that Microsoft might change some important compile or link option in such a way that any approach based on an integrated development environment (IDE) would break. Something like this happened during the Windows 2000 beta period, in fact. (Somebody decided to change the decade-old structure of library files, and I had to change a slew of project settings.) I guess I think the productivity improvement I gain by using modern IDE-based tools is significant enough that I'll run the risk of having to make similar changes in the future.
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. Appendix B details the support functions that GENERIC.SYS exports in case you want to use them yourself.