Writing Windows WDMDevice Drivers
Covers NT 4, Win 98, and Win 2000
Chris Cant
Preface
First, I suggest that you check the book's web site at www.phdcc.com/wdmbook/. These pages will list any errata, etc., and include a feedback page. This book was written mainly using Windows 98 and the Beta 2 version of Windows 2000, with some updates for the Beta 3 version. I will try to ensure that I post any necessary updates on the book's web site.
Although this book and the Microsoft documentation can give you a good start when writing device drivers, it is only when you write one yourself that you really learn about device drivers. Often it is only when you make mistakes that you find out how to write code correctly. I have tried to include some anecdotes of when I have erred and the techniques I have used to track down the problem and sort it out. Trying to explain the example code in detail in this book has helped iron out some wrinkles, so I recommend that you describe your code line by line to someone else.
Read this book if you want to learn how to write device drivers for Windows 98 and Windows 2000. It covers the core Windows Driver Model (WDM) fully and looks at two types of system class driver in detail, for the Universal Serial Bus (USB) and Human Input Devices (HID).
The book also covers Window NT 4 and NT 3.51 drivers. These 'NT style' drivers will also run in Windows 2000 and sometimes in Windows 98.
I suggest that you run all the examples and study their source code to get the full benefit. The book software includes some software called DebugPrint that lets you view the trace debug statements produced by the example drivers.
If you use a proprietary device driver toolkit, you should still find this book useful. First, the core WDM chapters give a background to the whole subject and might help explain how your toolkit works. Some features of WDM may not be covered by your toolkit and so will need to be implemented 'by hand'. More importantly, the class driver chapters give you the information you need to write drivers for various device categories.
Firmware or hardware engineers will also find it useful to read some sections of this book. When you design your external device, a software engineer will need to write a device driver to talk to it. Reading the first chapters of this book should let you speak 'their language'. Help them by providing clear specifications of your hardware at the appropriate level.
If you are currently a VxD driver writer, then many of the general concepts presented in this book will be familiar. However, you will find that the implementation techniques are quite different.
If you have written drivers for NT 4 and NT 3.51, some of the core WDM chapters will be familiar territory. However, Plug and Play and Power Management are crucial new areas of functionality. Supporting Windows Management Instrumentation (WMI) is desirable. The system class drivers will be new to you as well.
NT drivers should run unchanged in Windows 2000, and can sometimes run in Windows 98. However, you should seriously consider migrating to the Plug and Play if it's appropriate. Supporting Power Management will help to reduce power on and shutdown delays, making PCs more pleasant to use. The Direct Memory Access (DMA) system is used in a slightly different way by WDM device drivers.
Whenever a new and important piece of terminology is introduced, it is highlighted in
Acronyms are spelled out when they are first used. Please refer to the Glossary for a full list.
Globally Unique Identifiers (GUIDs) are long obscure strings used to identify Component Object Model (COM) objects and device interfaces. A full GUID such as
{C0CF0640– 5F5E-11d2-b677-00c0dfe4c1f3} is often abbreviated as {COCF0640…}.
When I refer to 'Windows', you can take it that I mean both Windows 98 and Windows 2000. 'Windows' does not refer to NT 3.51 and NT 4 unless the text specifically says so. In case it is not obvious, W98 refers to Windows 98 and W2000 refers to Windows 2000. Windows 2000 was originally called NT5.
You will have to endure the coding style that I have used for the book and its example source code. You will find that actual driver code on disk often contains more comments than the main text listings.
Most of the code examples are written using C++ although I do not make great use of C++ features. For example, there are no C++ classes used.
Boolean true and false values arc represented by two different types. Kernel calls must use the BOOLEAN type, which is really an unsigned char, where zero means FALSE and non-zero means TRUE. For any other Boolean values, I use the intrinsic C++ bool type that has false and true values.
The main text often refers to Win32 applications. I have not yet come to grips with the implications of Win64, the 64-bit version of Windows 2000. However, you can assume that whatever calls a Win32 application can make, a Win64 application will also be able to make.
Of more importance, I have not yet found out what happens to device drivers in Win64 systems.
Revised source code for the following files are on the
• DebugPrintsysDebugPrint.INF
• Wdm3sysWdm3free.inf
• NTinstall.cpp
Several people have helped directly and indirectly in making this book. First, thanks to Alec Erskine for drawing the cartoons and Ian Cuthbert for scanning them. Caz, Jenny, and Viv have stoically endured months of me ''putering too much'. Berney Williams at R&D provided the initial impetus for the project and gave crucial support as the book was written. My brother John and my friend Robin Sillem have helped considerably with ideas and proofreading. Thanks to Vireo Software, Inc., for the review copies of Driver::Works and Driver::Agent, and for a useful web site.
Chapter 1
Introduction
In this book, I will tell you how to write some types of device driver for Windows. I will primarily describe the Windows Driver Model for Windows 98 and Windows 2000. Additionally, I will cover device drivers that also run in Windows NT 3.51 and NT 4, which I call 'NT style' drivers.
A device driver provides a software interface to hardware connected to a computer. It is a trusted part of the operating system. User application programs can access hardware in a well- defined manner, without having to worry about how the hardware must be controlled. For example, a disk driver might hide the fact that data must be written in 512-byte chunks. A
In Windows, a driver always makes a device look like a file. A handle to the device can be opened. An application program can then issue read and write requests to the driver, before the device handle is finally closed.
Clearly, there are many pieces of hardware that are essentially alike, because they share a bus or do similar tasks. Microsoft provides several generic drivers that perform these common tasks. Device drivers can use the facilities of these standard drivers. This approach makes it easier to share a common bus, and makes it simpler to write new drivers.
The task of writing a new driver, therefore, often starts by identifying which generic drivers can be used. A
In Windows 98 and Windows 2000, device drivers must be designed according to the Windows Driver Model (WDM), which I describe in the following section. WDM is based on the device driver model used in Windows NT 4 and NT 3.51.
The Windows Driver Model
The Windows Driver Model has two separate but equally important aspects. First, the core model describes the standard structure for device drivers. Second, Microsoft provides a series of bus and class drivers for common types of devices.
The core WDM model describes how device drivers are installed and started, and how they should service user requests and interact with hardware. A WDM device driver must fit into the Plug and Play (PnP) system that lets users plug in devices that can be configured in software.
Microsoft provides a series of system drivers that have all the basic functionality needed to service many standard types of device. The first type of system driver supports different types of bus, such as the Universal Serial Bus (USB), IEEE 1394 (FireWire) and Audio port devices. Other class drivers implement standard Windows facilities such as Human Input Devices (HID) and kernel streaming. Finally, the Still Image Architecture (STI) provides a framework for handling still images, scanners, etc.
These system class drivers can make it significantly easier to write some types of device driver. For example, the USB system drivers handle all the low-level communications across this bus. A well defined interface is made available to other drivers. This makes it fairly straightforward to issue requests to the USB bus.
Originally Microsoft stated that WDM drivers would be binary compatible between Windows 98 and Windows 2000 x86, and source code compatible to Windows 2000 Alpha platforms. However, it now seems as though binary compatibility is not assured, even though the DDKs are unclear on the subject.
I have erred on the safe side, only installing drivers that have been built for the right operating system. That is, the Windows 98 Driver Development Kit (DDK) is used when building drivers for Windows 98, and the W2000 DDK for W2000.