Copyright © 2003 by Walter Oney PUBLISHED BY Microsoft Press A Division of Microsoft Corporation One Microsoft Way Redmond, Washington 98052-6399 Copyright © 2003 by Walter Oney All rights reserved No part of the contents of this book may be reproduced or transmitted in any form or by any means without the written permission of the publisher Library of Congress Cataloging-in-Publication Data Oney, Walter Programming the Microsoft Windows Driver Model / Walter Oney 2nd ed p cm Includes index ISBN 0-7356-1803-8 1 Microsoft Windows NT device drivers (Computer programs) 2 Computer programming I Title QA76.76.D49 O54 2002 005.7'126 dc21 2002038650 Printed and bound in the United States of America QWT Distributed in Canada by H.B Fenn and Company Ltd A CIP catalogue record for this book is available from the British Library Microsoft Press books are available through booksellers and distributors worldwide For further information about international editions, contact your local Microsoft Corporation office or contact Microsoft Press International directly at fax (425) 936-7329 Visit our Web site at www.microsoft.com/mspress Send comments to mspinput@microsoft.com Klingon font Copyright 2002, Klingon Language Institute Active Directory, DirectX, Microsoft, MSDN, MS-DOS, Visual C++, Visual Studio, Win32, Windows, and Windows NT are either registered trademarks or trademarks of Microsoft Corporation in the United States and/or other countries Other product and company names mentioned herein may be the trademarks of their respective owners The example companies, organizations, products, domain names, e-mail addresses, logos, people, places, and events depicted herein are fictitious No association with any real company, organization, product, domain name, e-mail address, logo, person, place, or event is intended or should be inferred Acquisitions Editor: Juliana Aldous Project Editor: Dick Brown Technical Editor: Jim Fuchs Acknowledgments Many people helped me write this book At the beginning of the project, Anne Hamilton, Senior Acquisitions Editor at Microsoft Press, had the vision to realize that a revision of this book was needed Juliana Aldous, the Acquisitions Editor, shepherded the project through to the complete product you're holding in your hands Her team included Dick Brown, Jim Fuchs, Shawn Peck, Rob Nance, Sally Stickney, Paula Gorelick, Elizabeth Hansford, and Julie Kawabata That the grammar and diction in the book are correct, that the figures are correctly referenced and intelligible, and that the index accurately correlates with the text are due to all of them Marc Reinig and Dr Lawrence M Schoen provided valuable assistance with a linguistic and typographical issue Mike Tricker of Microsoft deserves special thanks for championing my request for a source code license, as does Brad Carpenter for his overall support of the revision project Eliyas Yakub acted as the point man to obtain technical reviews of the content of the book and to facilitate access to all sorts of resources within Microsoft Among the developers and managers who took time from busy schedules to make sure that this book would be as accurate as possible are—in no particular order—Adrian Oney (no relation, but I'm fond of pointing out his vested interest in a book that has his name on the spine), Allen Marshall, Scott Johnson, Martin Borve, Jean Valentine, Doron Holan, Randy Aull, Jake Oshins, Neill Clift, Narayanan Ganapathy, Fred Bhesania, Gordan Lacey, Alan Warwick, Bob Fruth, and Scott Herrboldt Lastly, my wife, Marty, provided encouragement and support throughout the project Introduction This book explains how to write device drivers for the newest members of the MicrosoftWindows family of operating systems using the Windows Driver Model (WDM) In this Introduction, I'll explain who should be reading this book, the organization of the book, and how to use the book most effectively You'll also find a note on errors and a section on other resources you can use to learn about driver programming Looking ahead, Chapter 1 explains how the two main branches of the Windows family operate internally, what a WDM device driver is, and how it relates to the rest of Windows Who Should Read This Book I've aimed this book at experienced programmers who don't necessarily know anything about writing device drivers for Windows operating systems This book is for you if you want to learn how to do that To succeed at driver writing, you will need to understand the C programming language very well because WDM drivers are written in C You'll also need to be exceptionally able to tolerate ambiguity and to reverse-engineer portions of the operating system because a good deal of trial and error in the face of incomplete or inaccurate information is required Writing a WDM driver is much like writing a kernel-mode driver for Windows NT 4.0 It's a bit easier because you don't have to detect and configure your own hardware Ironically, it's simultaneously harder because correctly handling Plug and Play and power management is fiendishly difficult If you've written kernelmode drivers for Windows NT, you'll have no trouble at all reading this book You'll also be glad to have some code samples that you can cut and paste to deal with the aforementioned fiendishly difficult areas Writing a WDM driver is completely unlike writing a virtual device driver (VxD) for Windows 3.0 and its successors, a UNIX driver, or a real-mode driver for MS-DOS If your experience lies in those areas, expect to work hard learning this new technology Nonetheless, I think programming WDM drivers is easier than programming those other drivers because you have more rules to follow, leading to fewer choices between confusing alternatives Of course, you have to learn the rules before you can benefit from that fact If you already own a copy of the first edition of this book and are wondering whether you should buy this revised edition, here's a bit of information to help you decide Windows XP and Windows Me made few changes in the way you develop drivers for Windows 2000 and Windows 98, respectively The main reason we decided to revise this book is that so many changes had accumulated on my update/errata Web page This edition does, of course, explain some of the new bells and whistles that Windows XP brings with it It contains more explicit advice about writing robust, secure drivers It also, frankly, explains some things much better than the first edition does Chapter 1 has some information that will be useful to development managers and others who need to plan hardware projects It's very embarrassing to be brought up short near the end of a hardware development project by the realization that you need a driver Sometimes you'll be able to find a generic driver that will handle your hardware Often, however, such a driver won't exist and you'll need to write one yourself I hope to convince you managers in the first chapter that writing drivers is pretty hard and deserves your attention earlier rather than later When you're done reading that chapter, by the way, give the book to the person who's going to carry the oar And buy lots more copies (As I told one of my college friends, you can always use the extra copies as dining room chair extenders for a young family.) Organization of This Book After teaching driver programming seminars for many 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 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 want 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 seven 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 1, "Beginning a Driver Project," as I've mentioned, describes WDM device drivers and how they relate to Windows itself Along the way, I'll relate the story of how we got to where we are today in operating system and driver technology The chapter also explains how to choose the kind of driver you need, provides an overview and checklist specifically for development managers, and addresses the issue of binary compatibility 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 XP You'll learn the details about interrupt request level (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 queuing and cancellation, wherein accurate reasoning about synchronization problems becomes crucial Chapter 6, "Plug and Play for Function Drivers," 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 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 Luckily, the community of driver writers already has a grand tradition of cutting and pasting, and that will save you Chapter 9, "I/O Control Operations," contains a discussion of this important way for applications and other drivers to communicate "out of band" with your driver 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 WMI controls, and how you can alert controlling applications of important events when they occur Chapter 11, "Controller and Multifunction Devices," discusses how to write a driver for a device that embodies multiple functions, or multiple instances of the same function, in one physical device Chapter 12, "The Universal Serial Bus," describes how to write drivers for USB devices Chapter 13, "Human Interface Devices," explains how to write a driver for this important class of devices Chapter 14, "Specialized Topics," describes system threads, work items, error logging, and other special programming topics Chapter 15, "Distributing Device Drivers," tells you how to arrange for your driver to get installed on 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 This is where to look for information about WHQL submissions too Chapter 16, "Filter Drivers," discusses when you can use filter drivers to your advantage and how to build and install them Appendix A, "Coping with Cross-Platform Incompatibilities," explains how to determine which version of the operating system is in control and how to craft a binary-compatible driver Appendix B, "Using WDMWIZ.AWX," describes how to use my Visual C++ application wizard to build a driver 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 (RtlAssert) that’s a no-operation in the free build of Microsoft Windows 2000 The checked build of your driver will therefore not stop in the free build of the operating system Set this option to redefine ASSERT so that the checked build of your driver halts even in the free build of the operating system Use GENERIC.SYS Library Set this option to make use of the standardized driver code in GENERIC.SYS Clear this option to put all that standardized code in your own driver Windows 98 Detection Set this option to include a run-time check for whether your driver is running under Windows 98/Me or Windows 2000/XP Clear this option to omit the check You can also specify the base pathname where you’ve installed the Windows NET DDK and the samples for this book The default values—$(DDKPATH) and $(WDMBOOK)—rely on the environment variables that the sample setup program creates Finally you can click the Dispatch Functions button to specify the types of IRP your driver will handle, as Figure B-2 shows The dialog box embodies some design decisions that you can’t override Your driver will include support for IRP_MJ_PNP and IRP_MJ_POWER If you specify handling for IRP_MJ_CREATE, you’ll get support for IRP_MJ_CLOSE If you specify handling for IRP_MJ_READ, IRP_MJ_WRITE, or IRP_MJ_DEVICE_CONTROL, you’ll get support for IRP_MJ_CREATE (and therefore IRP_MJ_CLOSE) WDMWIZ.AWX doesn’t generate skeleton dispatch functions for many types of IRP that are used only by file system drivers Figure B-2 Dialog box for specifying the IRP major function codes for which you want dispatch functions DeviceIoControl Codes If you specified handling for IRP_MJ_DEVICE_CONTROL, the wizard will present a page (depicted in Figure B-3) to allow you to specify information about the control operations you support Figure B-3 Page for specifying supported I/O control operations Figure B-4 is an example of how you specify information about a particular DeviceIoControl operation Most of the fields correspond directly to parameters in the CTL_CODE preprocessor macro and should therefore require no explanation Setting the Asynchronous option generates support for an operation that you complete asynchronously after the dispatch function returns STATUS_PENDING Figure B-4 Dialog box for adding and editing an I/O control operation I/O Resources If your device uses any I/O resources, you can fill in the third page with information about them, as Figure B-5 shows Figure B-5 Page for specifying I/O resources USB Endpoints If you selected USB Function Driver on the first page, the wizard will present a page that allows you to describe the endpoints of your device, as Figure B-6 shows This page lists the names of variables in your device extension that will hold pipe handles The order of names corresponds to the order of endpoint descriptors on your device NOTE This page isn’t sufficiently complex to let you describe a device with multiple interfaces or with alternate settings for interfaces Figure B-6 Page for defining USB endpoints Refer to Figure B-7 for an illustration of the dialog box you can use to describe a single endpoint The Description Of Endpoint group relates to the description of the endpoint in your device firmware and should be self-explanatory Within the Resources In The Driver group, complete the fields as follows: Name Of Pipe Handle In Device Extension Supply the name of a DEVICE_EXTENSION member to hold the pipe handle you’ll use for operations on this endpoint Maximum Transfer Per URB Specify here the maximum number of bytes you’ll transfer in a single URB In general, this value is much larger than the endpoint maximum Figure B-7 Dialog box for adding and editing a USB endpoint WMI Support If you’ve specified that you want to handle IRP_MJ_SYSTEM_CONTROL requests, the wizard will present the page shown in Figure B-8 to allow you to specify the elements of your custom Windows Management Instrumentation (WMI) schema or to specify any Microsoft-standard classes you will support Figure B-8 Page for specifying WMI options The Block Identifiers list names the class globally unique identifiers (GUIDs) in the order they’ll appear in the GUID list for WMILIB Figure B-9 illustrates how you can describe one of the standard Micrsoft classes The topmost (unlabeled) control is the symbolic name of the GUID By typing in a name, you can specify a class in your custom schema You can specify the following attributes of a WMI class: Number Of Instances Indicates how many instances of the class your driver will create Expensive Indicates an expensive class that must be specifically enabled Event Only Indicates that the class is used only to fire an event Traced Corresponds to a WMI option that I don’t currently understand But if I ever do understand it, I’ll be able to use this check box to influence its state You can choose between physical device object (PDO)-based instance naming and instance naming using a base name Microsoft recommends you use PDObased naming Figure B-9 Dialog box for specifying a WMI class Parameters for the INF File The last page in the wizard (shown in Figure B-10) lets you specify information for the INF file that becomes part of your driver project The fields in this page are as follows: Manufacturer Name Name of the hardware manufacturer Device Class The standard device class to which your device belongs Sample is my own class for the driver samples in this book; you shouldn’t use this class for a production device Hardware ID The hardware identifier for this device I made up *WCO0B01 for this example You should specify the identifier that will match one of the identifiers that the relevant bus driver will create Refer to the section titled “Device Identifiers” in Chapter 15 for more information Friendly Name For Device If you want to have a FriendlyName value inserted into the device’s hardware key, specify that name here Auto-Launch Command If you want the AutoLaunch service to automatically start an application when your device starts, specify the command line here For example, when I built the AutoLaunch sample for Chapter 15, I specified %windir%\altest.exe %s %s in this field Device Description Insert the description of your device here Figure B-10 Page for specifying INF file options Now What? After you run through all the pages of the wizard, you'll have a project that you can use to finish crafting your driver Because of limitations on the custom wizard support in Visual C++, you'll need to modify the project settings by hand Please refer to WDMBOOK.HTM in the companion content for a description of these settings The generated code will contain a number of TODO comments that highlight areas where you need to write some code I suggest you use the Find In Files command to locate these items WDMWIZ also generates a standard DDK SOURCES file that you can use with the BUILD utility Many people prefer to use BUILD for driver builds, and this feature will make your life easier if you're one of them About the Author Walter Oney has 35 years of experience in systems-level programming and has been teaching Windows device driver classes for 10 years He was a contributing editor to Microsoft Systems Journal during its heyday and is a Microsoft MVP He has written several books, including Systems Programming for Windows 95 and the first edition of Programming the Microsoft Windows Driver Model In his free time, he’s a committed jogger, a fan of classical dance, and an amateur oboist He and his wife, Marty, live in Boston, Massachusetts About This eBook This eBook has been converted from the print version of this title Every effort has been made to ensure the accuracy of this conversion For readability and accessibility reasons, the eBook version may contain differences in formatting from the original print version The content of the eBook is not updated to reflect any content changes made for reprint releases Figures and Images The figures and screen shots throughout the book are converted to electronic format as 1:1 images The eBook uses Microsoft® Internet Explorer to shrink the images down to fit within the content pane To see the larger 1:1 image, simply click on the image The 1:1 image will open in a separate window If you click on more than one image to view the 1:1 image, each image will open in a separate window, and remain open until that window is closed Search The CHM format allows full-text searching to better locate the information you need To conduct a search, open the eBook and click the Search tab In the Search Topics text box, type the word or topic on which you wish to search Click List Topics to display the search results To view a search result, either a) double-click on the result in the Select Topic list, or b) click on the result in the Select Topic list, and click Display The topic will then display in the content pane Search results are ranked by the number of times the words searched on occur within the topic results The highest-ranked topic will include the most references to the search criteria For advanced search options, open the drop-down list next to the search input box to clarify multiple search terms with the parameters AND, OR, NEAR, or NOT Favorites To save a topic for viewing later, select the topic so that it displays in the content pane Select the Favorites tab The topic title, or heading, will appear in the Current Topic box Click Add and the topic title will appear in the Topics pane To view a topic saved in Favorites, select the title, and click Display To remove a Favorite topic at any time, select it from the topic pane, and click Remove External Links This eBook may contain links to Web sites outside of the Microsoft domain All hyperlinks within the text were valid at the time this eBook was published Due to the nature of the World Wide Web, we cannot guarantee that all links to Web sites are still valid after the release date of the eBook Accessibility This eBook utilizes Internet Explorer to display content Internet Explorer offers many accessibility features, such as keyboard shortcuts and compatibility with Assistive Technology To find out more about accessibility within Internet Explorer, go to www.microsoft.com/enable/products and select the version of Internet Explorer installed on your computer Tell Us What You Think We need to hear from you regarding your experience with our eBooks Tell us what you like, don't like; which features you use, and which features you would like to see in future versions of our eBooks Send your comments to epublish@microsoft.com Please note that technical support is not offered through this alias About Microsoft Press Microsoft Press® is a division of Microsoft Corporation and the leading source of comprehensive self-paced learning, training, evaluation, and support resources to help everyone from developers to IT professionals to end users get the most from Microsoft technology Choose from hundreds of current titles in print, multimedia, and network-ready formats—learning solutions made by Microsoft, with the most timely and accurate information available For more information, visit www.microsoft.com/mspress ... on which to run Windows Drivers for Windows NT used a brand-new kernelmode technology that shared practically nothing with the other two driver technologies then in vogue Windows NT drivers used the C programming. .. Enough was enough Microsoft designed a new technology for device drivers, the Windows Driver Model (WDM), and put it into Windows 98 and Windows Me, the successors to Windows 95 They also put this technology into Windows. .. Lastly, my wife, Marty, provided encouragement and support throughout the project Introduction This book explains how to write device drivers for the newest members of the MicrosoftWindows family of operating systems using the Windows Driver Model (WDM)