Back to Kernel Mode Systems home page
Summary: DRAFT Description and primer on Windows NT kernel-mode drivers
Last-modified: Aug. 27, 1996 Posting-Frequency: monthly
Version: 0.1
Editor and principal author: Jamie Hanrahan, Kernel Mode Systems (jeh@cmkrnl.com)
0 Welcome
WELCOME to the VERY FIRST *DRAFT* EDITION of the Windows NT Kernel-Mode Device Driver FAQ.
If the dates on the directories in my news spool can be trusted, the newsgroup comp.os.ms-windows.programmer.nt.kernel-mode has been in existence for nearly a year now, and still no FAQ has appeared. I have therefore fearlessly and foolishly volunteered to write and maintain it.
Like all FAQs, this one is very much a work in progress, and volunteers are strongly encouraged. If you want to suggest questions to be included, please feel free to e-mail me: jeh@cmkrnl.com . If you want to provide *answers* to be included, or additions or (heaven forbid) corrections to what's already here, that's even better! I will of course maintain full author credit in the text on all submissions. On the other hand, I reserve the right to not include certain items. For example, information on writing Windows 95 VxDs, NT display and printer drivers, or NT Virtual Device Drivers probably doesn't belong here.
0.1 Where To Find This FAQ
This FAQ will be posted to the newsgroups comp.os.ms-windows.programmer.nt.kernel-mode, microsoft.public.win32.programmer.kernel, and (once approved by the moderators) news.answers. I will also upload it to the CompuServe Win32 forum, section 13 (NT DDK), and make it available on my web site, http://www.cmkrnl.com/ .
0.2 Just Who Told You You Could Do This?
No one. I have simply stepped into the void, in an attempt to fill it. That's how most FAQs happen here on Usenet. Isn't anarchy wonderful? (Strange, there seems to be no air here. Choke...)
I do have some credentials in the field (you'll find them if you read the following closely enough). If someone else wants the job of NT Kernel Driver FAQ maintainer badly enough, let me know and we'll talk about it. For now, I am clearly making far too many nickels by writing, editing, and distributing this thing for free to ever give it up.
Yes, I do do business in this field... but I think I've kept the blatant commercialism to a minimum, and I've even included pointers to my competitors, on a pretty equal footing. All of which you'll find if you read this closely enough. If you have complaints in this area, just as if you have any other comments on this FAQ, please let me know. (The alternative -- having someone write it who *doesn't* work in the field -- does not seem to me to be preferable.)
0.3 What's Coming in the Next Version?
Sections on specific programming techniques, such as providing for "IRP extensions", and some conceptual background on IRQLs, spinlocks, and DPCs. For now, I have to stop writing and post this thing.
1 Basic questions
1.1 Help, I need a driver for...
Sorry, wrong FAQ, wrong newsgroup, and/or wrong web page. This is about *writing* drivers.
1.2 What is a "device driver"?
In terms of computer software, a "driver" is a routine or set of routines that implements the device-specific aspects of generic I/O operations. For example, an application calls a system function that says "write this buffer to that device". The driver for the device handles the device-specific parts of the job. By substituting other drivers, other devices can be substituted without changing the rest of the operating system or the application.
In primitive PC operating environments such as MS-DOS, drivers were specific to individual applications. For example, Word Perfect got pretty successful by including drivers that supported a wide variety of printers. But none of those drivers would work with any other applications, so when you installed Autocad, you had to install Autocad's printer drivers as well. Under the Windows environment, the display and printer drivers became the province of the "operating system", such as it was. Under Windows NT, operating system drivers handle *all* I/O devices.
1.3 What types of device drivers does WNT use?
Three types:
"Virtual device drivers" (VDDs) allow 16-bit applications (DOS and Win16 applications) to access certain I/O ports when running under Windows NT.
"GDI drivers" are called by Win32's GDI services and implement the video controller-specific card printer-specific aspects of GDI functions.
"Kernel mode drivers" implement the device-specfic aspects of CreateFile, CloseHandle (for file objects), ReadFile, WriteFile, and DeviceIoControl functions (speaking in Win32 terms). Kernel mode drivers are the only drivers that can service interrupts or initiate DMA transfers.
SCSI miniport and netcard (NDIS) drivers are special cases of kernel mode drivers. So are SCSI class drivers, file system drivers, redirectors, and transport-layer network components, although these do not touch I/O hardware directly.
Note that as of NT 4.0, GDI drivers also run in kernel mode, but they have a substantially different architecture from the drivers we call "kernel mode drivers."
This FAQ is mostly about kernel mode drivers. Other types of WNT drivers may eventually be covered in other FAQs, though I know of none at the moment.
1.4 So, how do I know if I need a kernel mode driver?
If you have an I/O device controller for which NT doesn't have a driver, or for which the NT-supplied driver doesn't implement the functions you need, you'll need to find or write a kernel mode driver for your device.
1.4.1 But do I *really* need a kernel mode driver?
This question usually appears something like this: "Look, my application just wants to reference a few IO ports a few times. Are you telling me that I absolutely cannot do this directly from my application, that I have to provide a driver and issue DeviceIoControl calls?"
To be rigorous about it, yes. Under Windows NT, applications run in user mode (ring 3 on Intel). Under WNT, code executing in user mode is not allowed to issue IN or OUT instructions, nor can it access adapter RAM space. To preserve system security, WNT requires that these functions be performed from kernel mode.
1.4.2 I thought heard about an article in Dr. Dobbs' Journal that showed a way around this.
There was indeed an article in DDJ, April 1996, about allowing Win32 applications under NT to directly access I/O ports. The technique works by changing the privilege context of the desired process to allow it to issue IN and OUT instructions. This works only on Intel platforms. This is not really a counterexample to the statement that "you need a kernel mode driver", since it takes code running in kernel mode -- supplied by a kernel mode driver -- to change the privilege context. It does not allow you to service interrupts, initiate DMA, or do anything else with the device other than reference I/O ports. You can actually get that functionality with the GENPORT.C example from the DDK, and it is platform-independent.
1.4.3 What about VDDs?
The Virtual Device Drivers do not actually do any I/O. They simply provide routines which the NTVDM calls when it traps a 16-bit app's attempts to reference IO ports. The routines in the vDD then issue ordinary Win32 ReadFile, WriteFile, or DeviceIoControl calls, which in turn are implemented by a corresponding kernel-mode driver. That kernel-mode driver might be one that was specially written to accompany the VDD, or it might be one that already exists within NT. In any case the VDD does not actually do any I/O.
1.5 Okay, so I need a driver. But can I get away without *writing* a driver?
Depending on your requirements, there are two commercial products that may allow you to avoid writing a driver for your device:
o "WinRT", from BlueWater Systems, 206-771-3610, http://www.bluewatersystems.com/
o "DeviceX", from WinStar Technologies, 415-647-2815, http://www.wintech.com/
Each of these products provides a kernel mode driver that implements a variety of DeviceIoControl functions for accessing random I/O devices, which are configured through convenient GUI tools. The DeviceIoControl functions are "wrapped" by convenient APIs in a supplied DLL. There are also GUI tools for experimenting with the device.
If you have more time than money, there are two example drivers supplied with the DDK that allow you to access I/O port and physical memory space:
o \ddk\src\general\portio - implements DeviceIoControl calls that issue simple IN or OUT instructions to selected I/O ports. You select the I/O ports through registry changes.
o \ddk\src\general\mapmem - implements DeviceIoControl calls that map any range of physical memory (including adapter RAM space) into a process's user-mode address space.
Both of these drivers require some knowledge of NT kernel drivers to compile, install, and use, and are probably not something you want to put in the field as part of a production system. But they're fine for experimenting, and they serve as good simple illustrations of many essential techniques for all drivers.
1.6 What about "driver wizards"?
Yes, some of these have appeared in various magazines, in Microsoft Developer Network (MSDN) articles, etc.
It is my opinion that, first, most of the drivers that can be written by "wizards" have already been written, and second, that overreliance on such tools fosters an ignorance of underlying principles -- principles which MUST be thoroughly understood when it's time to fill in the parts of the code that the wizard doesn't supply. (Of course, I can defend this opinion against all objections simply by supplying appropriate definitions of "most" and "overreliance". :-)
1.7 What is this new "Windows Driver Model" that Microsoft has been talking about?
It is the NT driver model, plus hooks for plug-n-play and power management. The NT driver model is not changing, it is merely being adopted by a future version of Windows 95.
2 Driver Development
2.1 What hardware do I need to develop WNT KMDs?
Two systems running WNT are needed, one to exercise the driver and one to run the kernel debugger UI. They are referred to as the target and host, respectively. These need not be the same processor architecture (Intel, Alpha, etc.).
The driver must be compiled and linked on a system of the same processor architecture as that on which it will be tested, as there are no cross-compilers available. This may be the target system or any other system of the same processor architecture, including the debug host.
2.1.1 I thought I heard somewhere that you could use a Windows 95 system as the host for the debugger.
Not today. Microsoft has unofficially stated that Windows 95 might be usable in the near future, but as of this writing the kernel debugger seems to be dependent not just on Windows NT but on the specific version of Windows NT.
2.1.2 I thought I heard somewhere that you could use a serial terminal for the debugger UI.
Nope.
2.2 What software tools do I need to develop WNT KMDs?
Windows NT (free and checked build), Device Driver Kit (DDK), Software Development Kit (SDK, for WinDbg only), and Visual C++ (VC++).
2.2.1 Where do I get all this stuff?
o NT free build: Retail, or MSDN >= "Professional" level
o NT checked build, SDK, DDK: MSDN >= "Professional" level
o VC++: Retail, or MSDN "Universal" level
2.2.2 Can't I use someone else's 32-bit C compiler?
Maybe. The technical answer is: As long as it generates essentially the same code, supports all of the MS extensions to C, and takes all of the same command line options, it should work fine. Same for the linker.
Opinion: VC++ is part of the driver build environment supported by MS, and using anything else feels too much to me like swimming upstream with a brick in each hand, a practice I try to avoid.
2.2.3 What about other languages like Pascal?
In theory, as long as you adhere to C calling conventions, don't use too much stack space, etc., you should be fine. In practice, there are several tens of thousands of lines of header files in \DDK\INC which you will have to translate to your language of choice.
2.3 What's this about C++ and drivers?
Although we use the VC++ compiler to compile drivers, MS has stated many times that C++ language extensions should not be used in writing NT drivers. It is true that a few people have written about their successes in using C++. However, C++ language features tend to use large amounts of stack space, and large amounts of stack space are not available under WNT in kernel mode.
2.4 What about building drivers? Do we use the VC++ IDE to build drivers? What "project type" in the VC++ IDE do I select?
None of the above. You build drivers using the "build" utility that comes with the DDK.
Some people have successfully configured the VC++ IDE to build drivers, through careful editing of the project options. If you want to do this to gain access to the Browser and other tools availalble in the IDE, fine, but for building the production driver, I stick with "build".
2.5 Why are you so (cautious, cowardly, unimaginative) about using MS-recommended tools and techniques?
Considering how important it is to get drivers exactly, precisely, positively right, I am reluctant to experiment with other compilers, other languages or language dialects, or anything else that MS does not recommend... especially when I'm shipping a driver to a client. MS's tools may be buggy and their recommendations may be wrong, but at least if I adhere to them I can point back to MS as the culprit. If I ignore their recommendations, problems are solely on my head.
2.6 What other information sources are available for kernel driver writers?
2.6.1 What MSDN articles exist?
The MSDN Library has a number of articles with relevant information, although I would ignore their advice about writing drivers using C++ features. A good place to start is "The Windows NT Device Driver Resource Book". It contains links to many other relevant articles along with references to magazine articles.
One useful article that he missed is Q113996, Mapping NT Status Error Codes to Win32 Error Codes". This relates NT kernel STATUS_xxxxx error codes to their corresponding Win32 ERROR_xxxxx codes.
2.6.2 What newsgroups exist?
The main discussion point for NT kernel driver writers is comp.os.ms-windows.programmer.nt.kernel-mode . Please note, this is *not* a place to ask about the availability of off-the-shelf drivers. Nor is it the place to ask about any Win32 programming issues, unless they are directly related to a driver you're working on.
There is no newsgroup in the microsoft hierarchy (accessed officially through the nntp server at nntp.microsoft.com) specifically for NT kernel driver writers. Many have been using microsoft.public.win32.programmer.kernel, although this was originally intended for discussion of the Win32 APIs exported by Kernel32.DLL.
2.6.3 What mailing lists exist?
There are three mailing lists that are relevant, though none focus exclusively on NT kernel-mode drivers:
SEND (in message body) TO -------------------------------------------------------------------- subscribe ntdev majordomo@atria.com Peer support for sw development on NT, including device drivers
subscribe ntfsd majordomo@atria.com Peer support for those doing file system driver development (low activity)
subscribe ddk-l-request@albany.net Peer support for driver writers on all MS operating systems (not NT only). $15/year fee. --------------------------------------------------------------------
2.6.4 What courses exist?
To my knowledge, the following companies offer courses in the field:
o David Solomon Expert Seminars, http://www.solsem.com/ , 800-492-4898. Yes, this is the company through which I offer my seminars. This is my FAQ, so I get to list my offerings first! Actually, I'll rotate the list each time I update the FAQ.
o Open Systems Resources, http://www.osr.com/ , 603-595-6500.
o Art Baker offers an NT driver course through Cydonix (no contact information available).
2.6.5 What World Wide Web sites exist?
My web site, http://www.cmkrnl.com/ , maintains a copy of this FAQ and, soon, additional free information and source examples.
Open Systems Resources, http://www.osr.com/ , has copies of articles and related source code from past issues of their "NT Insider" newsletter.
To my knowledge there are no other web sites that focus exclusively on Windows NT device drivers. Several others focus on various aspects of Windows programming, sometimes including Win 3.1 and Windows 95 drivers. If you are interested in these areas, you might start with the Windows driver FAQ, available at http://www.smartpages.com/faqs/windows/programming/device-drivers/faq.html
2.6.6 What other FAQs exist?
From ms-windows/programmer.how-to-find-faqs (posted weekly to comp.os.ms-windows.programmer.misc):
There is one general Windows NT FAQ; you can find it at: http://www.iea.com/~daler/nt/faq/toc.html
There are also three specialized Windows NT FAQs:
Windows NT Admin FAQ: http://www.iftech.com/classes/admin/admin.htm Windows NT Fax FAQ: http://www.mcs.com/~sculptor/NTFAX-FAQ.HTML Windows NT Internet FAQ: http://www.mcs.com/~thomas/www/ntfaq/
2.6.7 What books exist?
There are no books currently on the market on this topic. I'm in the process of writing one with co-authors Ruth Goldenberg and Jim Fraser; it will be published by O'Reilly and Associates and is not due to be turned into to the publisher until near the end of 1996. Please do not write me to ask about when the book will be published, nor to be notified of publication, nor to volunteer to review it (we have far more volunteers than we can use already). If you want to be notified of its publication, your best bet is to contact O'Reilly and Associates and ask to be put on their mailing list.
Another book has reportedly been in progress by Art Baker. The publisher will be Prentice-Hall.
2.6.8 What conference materials are available?
From the Windows Driver FAQ, maintained by Stephen T. Lewin-Berlin, Berlin@vireo.com:
The video and audio tapes and handouts from Microsoft's October '92 NT Driver Developer's Conference are still available. Contact:
MobilTape Co. Inc. address: 25061 W. Stanford, Suite 70; Valencia, CA 91355, USA phone (orders): 800.369.5718 phone (info): 805.295.0504 fax: 805.295.8474
ask for the order form for the event:
Microsoft Windows NT Device Driver Developer's Conference October 26-28, 1992 Anaheim, CA
2.6.9 What other related products exist?
Open Systems Resources, http://www.osr.com/ , 603-595-6500, has a File System Filter Driver kit and a forthcoming File System Driver Kit available.
For applications needing simple access to I/O ports, investigate these products:
o "WinRT", from BlueWater Systems, 206-771-3610, http://www.bluewatersystems.com/
o "DeviceX", from WinStar Technologies, 415-647-2815, http://www.wintech.com/
For driver debugging, "SoftICE for NT" by NuMega Technologies, 800-4-NU-MEGA, http://www.numega.com/ provides single-machine debugging capability, for Intel platforms only.
3 Building and Debugging Drivers
3.1 What is the role of the NT checked build in driver development and debugging?
All drivers should be exercised under the checked build, to the extent of traversing all code paths at least once. The checked build has a large amount of internal consistency and constraint checking code, which the free build omits. In addition, the checked build goes through the motions of spinlock acquisition and release, even on a single-processor system, which the free build avoids.
Final long-duration stress testing should be done with the target system running under the free build.
Routine driver debugging may be done with the target system running under either the free or the checked build. I prefer the free build most of the time, simply because it is so much faster.
There is no reason as far as driver development is concerned to run the host system under anything except the free build.
3.2 What is the role of the "Checked Build Environment" program item in driver development and debugging?
You use the two "Build Environment" program items to create console windows in which to run the BUILD utility to build drivers.
You use the "Free Build Environment" to build the "retail" version of the driver, with compiler optimizations enabled and without full symbolic debugging information in the driver.SYS file.
You use the "Checked Build Environment" to build the "debug" version of the driver, with compiler optimizations DISabled and WITH full symbolic debugging information in the driver.SYS file.
A driver built under either "environment" will run on either build of Windows NT.
3.3 I'm having problems getting the kernel debugger extensions to WinDbg to work. What's wrong?
TBD
(I posted a checklist on this to comp.os.ms-windows.programmer.nt.kernel-mode. Did anyone save it? I apparently didn't.)
4 Basic Kernel Driver Development
4.1 Okay, I need to write a kernel mode driver. Tell me how.
The answer to this question would fill a fair-sized book (and will).
4.2 What is the basic structure of a kernel mode driver?
Every kernel mode driver must have a DriverEntry routine, and for all practical purposes, at least one Dispatch routine is required also. The DriverEntry routine must be called "DriverEntry", other routines can have any name you like. Drivers should also have an Unload routine, which permits the driver to be (guess what) unloaded, or removed from the system.
4.3 The NT driver doc talks about all these different types of drivers. How do they all relate to one another?
4.3.1 Basic driver structure
Let's define a "canonical" driver first. This will be a monolithic (non-layered) driver for a single-device controller that can handle only one I/O request at a time. In such a driver, I/O requests, which are described by data structures known as I/O Request Packets (IRPs), are handled by Dispatch, StartIo, InterruptService, and DpcForIsr routines, in that order. Unless the device is very well-behaved and can never interrupt unexpectedly, a SynchCritSection routine is also needed.
If the device controller can be programmed for more than one I/O request at a time, the StartIo routine is usually replaced by one or more IrpQueueing routines.
Any driver that holds I/O requests (ie that does not complete them right away or pass them on to other drivers) should have a Cancel routine. This includes any driver with a StartIo routine or an IrpQueueing routine.
Drivers that use controller objects and/or adapter objects will usually have ControllerControl and/or AdapterControl routines, respectively.
4.3.2 What about layered drivers?
NT allows drivers to be layered on top of one another. You can start with a monolithic (self-contained) driver and put an upper-layer driver above it. I/O requests to the device(s) controlled by the lower-layer driver now come to the upper-layer driver first. You can layer on top of any existing driver, but you cannot install a layer under a lowest-layer driver. The lowest-layer driver is the one that actually talks to the I/O hardware, and NT offers no mechanism for "hooking" or intercepting those operations and doing something else instead.
Other driver layers are generically called "highest-layer" (the first driver that handles a particular IRP), "upper-layer" (any layer except the lowest), and "lower-layer" (any layer except the highest).
In terms of routines, an upper-layer driver puts its own Dispatch routine(s) "ahead of" another driver's Dispatch routine(s). Hence, of all the routines in a driver that handle I/O, upper-layer drivers generally have only Dispatch routines. (They still have DriverEntry and Unload routines.) They may also have IoCompletion routines, which are invoked when the lower-layer driver completes an IRP that has come through the upper-layer driver.
If an upper-layer driver does its own IRP queueing, it adds either StartIo or IrpQueueing routines, plus one or more Cancel routines. In that case, the flow of an I/O request is: Upper-layer driver, Dispatch and (StartIo or IrpQueueing), then lower-layer driver's Dispatch and subsequent routines.
Upper-layer drivers do not handle interrupts, so they do not generally need an InterruptService routine, nor a DpcForIsr routine. They may have TimerDpc routines.
A good "starter" example for an upper-layer driver is the DISKPERF driver. This driver collects disk I/O performance statistics and makes them available to Performance Monitor and related tools.
NT driver layering is not at all like the Unix Streams environment.
The NT driver layering mechanism is not completely generalized, and probably works best in environments where drivers at all layers are written by the same team, or at least by people who can speak with each other easily. It is not really possible or advisable to layer a driver on top of an existing driver unless you know quite a bit about how the driver you're on top of does things. For example, drivers that use buffered I/O are usually incompatible with the associated IRP mechanism. How do you know if your soon-to-be-lower-layer driver uses buffered I/O? You just have to attach to its device object and look. For that matter, the associated IRP mechanism is incompatible with itself; only one driver in a stack of layered drivers can safely IoMakeAssociatedIrp.
4.3.3 What about file system drivers?
A file system driver is generally a highest-layer driver sitting atop the driver for random-access mass storage devices. It implements the semantics of file-system-oriented I/O requests, such as requests to create, open, extend, and delete files and directories. Different file system drivers exist for different on-disk structures, such as FAT, NTFS, and the CD-ROM file system. File system drivers are presently difficult to write, conceptually because they have complex jobs to do and have intricate interactions with the cache and the memory manager, and practically because Microsoft has not put much information about them in the DDK documentation, and some necessary header files and libraries are missing from the DDK.
Open Systems Resources ( http://www.osr.com/ ) has a forthcoming File System Developers Kit which should address these issues.
4.3.4 What are class and port drivers?
Class and port drivers exist for I/O hardware in which a number of substantially different types, or classes, of I/O devices are accessed through a common I/O device controller. The class drivers implement the semantics of the different types of devices, such as disks vs. tapes, while the port driver deals with programming the controller's I/O ports (hence "port driver") or register.
4.3.5 What about NIC miniport drivers?
A NIC miniport driver is a lowest-layer driver which is "wrapped" by support routines provided by the NDIS port driver. It provides support for a specific network interface card (NIC).
4.3.6 What about SCSI miniport drivers?
An SCSI miniport driver is a lowest-layer driver which is "wrapped" by support routines provided by the SCSI port driver. It provides support for a specific SCSI controller.
4.3.7 What is this port/miniport thing?
Microsoft realized that all SCSI port drivers would have a great deal of common code, because they would all have to interface with the existing SCSI class drivers.
Similarly, all NIC drivers would have a great deal of common code, because they would all have to interface with the existing transport-layer drivers.
The SCSI port driver and NDIS port driver, respectively, attempt to pull all of this common code into common modules within NT.
The port drivers also abstract the NT I/O support routines. For example, a NIC miniport driver does not call IoMapTransfer, but rather NdisMSetupDmaTransfer. They do this to such an extent that other operating systems, such as Windows 95, can supply a NDIS port driver and SCSI port driver and hence allow the miniport drivers to be compatible with those other systems.
5 Data Structures and Objects
TBD
6 Specific Programming Techniques
TBD
7 Principles: Synchronization, IRQLs, Spinlocks, and DPCs
TBD
8 Legal Stuff, For What It's Worth
8.1 DISCLAIMER
This article is provided as is without any express or implied warranties. While every effort has been taken to ensure the accuracy of the information contained in this article, the author and contributors assume no responsibility for errors or omissions, or for damages resulting from the use of the information contained herein.
8.2 COPYRIGHT NOTICE
Copyright (c) 1996 by Jamie Hanrahan. All rights reserved.
This article may be posted to any USENET newsgroup, on-line service, or BBS as long as it is posted in its entirety and includes this copyright statement.
This FAQ may not be distributed for financial gain. This FAQ may not be included in commercial collections or compilations without express permission from the primary author and editor.
8.3 VESTED INTEREST DISCLAIMER
Yes, I teach seminars and offer consulting services in this field.
--- Jamie Hanrahan, Kernel Mode Systems, San Diego CA Internet: jeh@cmkrnl.com (JH645) CompuServe: 74140,2055 drivers, internals, networks, applications, and training for VMS and Windows NT NT driver seminars: email seminars@solsem.com , or see http://www.solsem.com/ NT driver information: http://www.cmkrnl.com/ ------------------------------------------------------------------------------- We are dreamers, shapers, singers and makers. We study the mysteries of laser and circuit, crystal and scanner, holographic demons, and invocations of equations. These are the tools we employ. And we know... many things. --- J. Michael Straczynski, "Babylon 5"
(end)