Programming the Microsoft Windows Driver Model ... - Parent Directory

were programmed in assembly language and relied to a greater or lesser extent on ..... fundamental differences between how Windows services 32-bit and 16-bit ...... two slightly different methods, depending on whether the hardware is Plug ...... Instructs bus driver to arm wake-up feature; provides way for function driver to.
5MB taille 21 téléchargements 366 vues
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. 1 2 3 4 5 6 7 8 9

QWT 8 7 6 5 4 3

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 [email protected]. 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

I

Table of Contents Acknowledgments Introduction 1 Beginning a Driver Project 1.1 1.2

1.3

2

-1-3-3-4-6-7-8-9-

Basic Structure of a WDM Driver

- 11 -

2.1

- 11 - 11 - 12 - 14 - 14 - 15 - 17 - 18 - 19 - 20 - 23 - 23 - 25 - 27 - 28 - 29 - 29 - 30 - 31 - 39 - 42 - 43 - 43 - 43 - 43 - 43 -

2.2

2.3

2.4

2.5

2.6

3

A Brief History of Device Drivers An Overview of the Operating Systems 1.2.1 Windows XP Overview 1.2.2 Windows 98/Windows Me Overview What Kind of Driver Do I Need? 1.3.1 WDM Drivers 1.3.2 Other Types of Drivers 1.3.3 Management Overview and Checklist

IX X -1-

How Drivers Work 2.1.1 How Applications Work 2.1.2 Device Drivers How the System Finds and Loads Drivers 2.2.1 Device and Driver Layering 2.2.2 Plug and Play Devices 2.2.3 Legacy Devices 2.2.4 Recursive Enumeration 2.2.5 Order of Driver Loading 2.2.6 IRP Routing The Two Basic Data Structures 2.3.1 Driver Objects 2.3.2 Device Objects The DriverEntry Routine 2.4.1 Overview of DriverEntry 2.4.2 DriverUnload The AddDevice Routine 2.5.1 Creating a Device Object 2.5.2 Naming Devices 2.5.3 Other Global Device Initialization 2.5.4 Putting the Pieces Together Windows 98/Me Compatibility Notes 2.6.1 Differences in DriverEntry Call 2.6.2 DriverUnload 2.6.3 The \GLOBAL?? Directory 2.6.4 Unimplemented Device Types

Basic Programming Techniques

- 45 -

3.1

- 45 - 46 - 46 -

The Kernel-Mode Programming Environment 3.1.1 Using Standard Run-Time Library Functions 3.1.2 A Caution About Side Effects

II

3.2

3.3

3.4 3.5

3.6

4

Synchronization 4.1 4.2

4.3

4.4

4.5

5

Error Handling 3.2.1 Status Codes 3.2.2 Structured Exception Handling 3.2.3 Bug Checks Memory Management 3.3.1 User-Mode and Kernel-Mode Address Spaces 3.3.2 Heap Allocator 3.3.3 Linked Lists 3.3.4 Lookaside Lists String Handling Miscellaneous Programming Techniques 3.5.1 Accessing the Registry 3.5.2 Accessing Files 3.5.3 Floating-Point Calculations 3.5.4 Making Debugging Easier Windows 98/Me Compatibility Notes 3.6.1 File I/O 3.6.2 Floating Point An Archetypal Synchronization Problem Interrupt Request Level 4.2.1 IRQL in Operation 4.2.2 IRQL Compared with Thread Priorities 4.2.3 IRQL and Paging 4.2.4 Implicitly Controlling IRQL 4.2.5 Explicitly Controlling IRQL Spin Locks 4.3.1 Some Facts About Spin Locks 4.3.2 Working with Spin Locks 4.3.3 Queued Spin Locks Kernel Dispatcher Objects 4.4.1 How and When You Can Block 4.4.2 Waiting on a Single Dispatcher Object 4.4.3 Waiting on Multiple Dispatcher Objects 4.4.4 Kernel Events 4.4.5 Kernel Semaphores 4.4.6 Kernel Mutexes 4.4.7 Kernel Timers 4.4.8 Using Threads for Synchronization 4.4.9 Thread Alerts and APCs Other Kernel-Mode Synchronization Primitives 4.5.1 Fast Mutex Objects 4.5.2 Interlocked Arithmetic 4.5.3 Interlocked List Access 4.5.4 Windows 98/Me Compatibility Notes

- 46 - 47 - 48 - 54 - 55 - 55 - 60 - 64 - 67 - 69 - 71 - 71 - 76 - 78 - 79 - 82 - 82 - 82 -

- 83 - 83 - 85 - 86 - 86 - 87 - 87 - 88 - 88 - 89 - 89 - 90 - 91 - 91 - 92 - 93 - 94 - 96 - 97 - 98 - 101 - 102 - 104 - 104 - 106 - 108 - 110 -

The I/O Request Packet

- 111 -

5.1

- 111 - 111 -

Data Structures 5.1.1 Structure of an IRP

III

5.2

5.3 5.4

5.5

5.6

6

5.1.2 The I/O Stack The “Standard Model” for IRP Processing 5.2.1 Creating an IRP 5.2.2 Forwarding to a Dispatch Routine 5.2.3 Duties of a Dispatch Routine 5.2.4 The StartIo Routine 5.2.5 The Interrupt Service Routine 5.2.6 Deferred Procedure Call Routine Completion Routines Queuing I/O Requests 5.4.1 Using the DEVQUEUE Object 5.4.2 Using Cancel-Safe Queues Cancelling I/O Requests 5.5.1 If It Weren’t for Multitasking… 5.5.2 Synchronizing Cancellation 5.5.3 Some Details of IRP Cancellation 5.5.4 How the DEVQUEUE Handles Cancellation 5.5.5 Cancelling IRPs You Create or Handle 5.5.6 Handling IRP_MJ_CLEANUP 5.5.7 Cleanup with a DEVQUEUE 5.5.8 Cleanup with a Cancel-Safe Queue Summary—Eight IRP-Handling Scenarios 5.6.1 Scenario 1—Pass Down with Completion Routine 5.6.2 Scenario 2—Pass Down Without Completion Routine 5.6.3 Scenario 3—Complete in the Dispatch Routine 5.6.4 Scenario 4—Queue for Later Processing 5.6.5 Scenario 5—Your Own Asynchronous IRP 5.6.6 Scenario 6—Your Own Synchronous IRP 5.6.7 Scenario 7—Synchronous Pass Down 5.6.8 Scenario 8—Asynchronous IRP Handled Synchronously

- 113 - 114 - 114 - 116 - 119 - 123 - 124 - 124 - 125 - 132 - 134 - 136 - 140 - 140 - 140 - 141 - 142 - 146 - 151 - 152 - 153 - 153 - 154 - 154 - 155 - 156 - 157 - 158 - 159 - 160 -

Plug and Play for Function Drivers

- 163 -

6.1 6.2

- 164 - 165 - 166 - 167 - 168 - 169 - 169 - 171 - 171 - 172 - 173 - 174 - 176 - 178 - 181 - 181 - 182 -

6.3

6.4

IRP_MJ_PNP Dispatch Function Starting and Stopping Your Device 6.2.1 IRP_MN_START_DEVICE 6.2.2 IRP_MN_STOP_DEVICE 6.2.3 IRP_MN_REMOVE_DEVICE 6.2.4 IRP_MN_SURPRISE_REMOVAL Managing PnP State Transitions 6.3.1 Starting the Device 6.3.2 Is It OK to Stop the Device? 6.3.3 While the Device Is Stopped 6.3.4 Is It OK to Remove the Device? 6.3.5 Synchronizing Removal 6.3.6 Why Do I Need This @#$! Remove Lock, Anyway? 6.3.7 How the DEVQUEUE Works with PnP Other Configuration Functionality 6.4.1 Filtering Resource Requirements 6.4.2 Device Usage Notifications

IV

6.5

7

- 193 -

7.1 7.2

- 193 - 195 - 195 - 198 - 200 - 201 - 201 - 202 - 203 - 204 - 207 - 211 - 212 - 213 - 222 - 224 - 225 -

7.4

7.5

7.6

Configuring Your Device Addressing a Data Buffer 7.2.1 Specifying a Buffering Method Ports and Registers 7.3.1 Port Resources 7.3.2 Memory Resources Servicing an Interrupt 7.4.1 Configuring an Interrupt 7.4.2 Handling Interrupts 7.4.3 Deferred Procedure Calls 7.4.4 A Simple Interrupt-Driven Device Direct Memory Access 7.5.1 Transfer Strategies 7.5.2 Performing DMA Transfers 7.5.3 Using a Common Buffer 7.5.4 A Simple Bus-Master Device Windows 98/Me Compatibility Notes

Power Management

- 227 -

8.1

- 227 - 227 - 227 - 228 - 229 - 231 - 232 - 233 - 233 - 238 - 238 - 244 - 245 - 245 - 250 - 252 - 253 - 253 - 253 - 253 - 253 - 253 -

8.2

8.3

8.4

9

- 184 - 191 - 191 - 191 - 191 -

Reading and Writing Data

7.3

8

6.4.3 PnP Notifications Windows 98/Me Compatibility Notes 6.5.1 Surprise Removal 6.5.2 PnP Notifications 6.5.3 The Remove Lock

The WDM Power Model 8.1.1 The Roles of WDM Drivers 8.1.2 Device Power and System Power States 8.1.3 Power State Transitions 8.1.4 Handling IRP_MJ_POWER Requests Managing Power Transitions 8.2.1 Required Infrastructure 8.2.2 Initial Triage 8.2.3 System Power IRPs That Increase Power 8.2.4 System Power IRPs That Decrease Power 8.2.5 Device Power IRPs 8.2.6 Flags to Set in AddDevice Additional Power-Management Details 8.3.1 Device Wake-Up Features 8.3.2 Powering Off When Idle 8.3.3 Using Sequence Numbers to Optimize State Changes Windows 98/Me Compatibility Notes 8.4.1 The Importance of DO_POWER_PAGABLE 8.4.2 Completing Power IRPs 8.4.3 Requesting Device Power IRPs 8.4.4 PoCallDriver 8.4.5 Other Differences

I/O Control Operations

- 255 -

V

9.1

9.2 9.3

9.4 9.5

9.6

The DeviceIoControl API 9.1.1 Synchronous and Asynchronous Calls to DeviceIoControl 9.1.2 Defining I/O Control Codes Handling IRP_MJ_DEVICE_CONTROL METHOD_BUFFERED 9.3.1 The DIRECT Buffering Methods 9.3.2 METHOD_NEITHER 9.3.3 Designing a Safe and Secure IOCTL Interface Internal I/O Control Operations Notifying Applications of Interesting Events 9.5.1 Using a Shared Event for Notification 9.5.2 Using a Pending IOCTL for Notification Windows 98/Me Compatibility Notes

10 Windows Management Instrumentation 10.1 WMI Concepts 10.1.1 A Sample Schema 10.1.2 Mapping WMI Classes to C Structures 10.2 WDM Drivers and WMI 10.2.1 Delegating IRPs to WMILIB 10.2.2 Advanced Features 10.3 Windows 98/Me Compatibility Notes

11 Controller and Multifunction Devices 11.1 Overall Architecture 11.1.1 Child Device Objects 11.2 Handling PnP Requests 11.2.1 Telling the PnP Manager About Our Children 11.2.2 PDO Handling of PnP Requests 11.2.3 Handling Device Removal 11.2.4 Handling IRP_MN_QUERY_ID 11.2.5 Handling IRP_MN_QUERY_DEVICE_RELATIONS 11.2.6 Handling IRP_MN_QUERY_INTERFACE 11.2.7 Handling IRP_MN_QUERY_PNP_DEVICE_STATE 11.3 Handling Power Requests 11.4 Handling Child Device Resources

12 The Universal Serial Bus 12.1 Programming Architecture 12.1.1 Device Hierarchy 12.1.2 What’s in a Device? 12.1.3 Information Flow 12.1.4 Descriptors 12.2 Working with the Bus Driver 12.2.1 Initiating Requests 12.2.2 Configuration 12.2.3 Managing Bulk Transfer Pipes 12.2.4 Managing Interrupt Pipes 12.2.5 Control Requests 12.2.6 Managing Isochronous Pipes

- 255 - 256 - 257 - 258 - 259 - 260 - 261 - 262 - 263 - 264 - 265 - 266 - 269 -

- 271 - 271 - 272 - 273 - 274 - 275 - 280 - 285 -

- 287 - 287 - 287 - 289 - 290 - 290 - 293 - 293 - 294 - 294 - 297 - 297 - 299 -

- 301 - 301 - 302 - 303 - 304 - 310 - 315 - 315 - 317 - 323 - 329 - 329 - 331 -

VI

12.2.7 Idle Power Management for USB Devices

13 Human Interface Devices 13.1 Drivers for HID Devices 13.2 Reports and Report Descriptors 13.2.1 Sample Keyboard Descriptor 13.2.2 HIDFAKE Descriptor 13.3 HIDCLASS Minidrivers 13.3.1 DriverEntry 13.3.2 Driver Callback Routines 13.3.3 Internal IOCTL Interface 13.3.4 IOCTL_HID_GET_DEVICE_DESCRIPTOR 13.4 Windows 98/Me Compatibility Notes 13.4.1 Handling IRP_MN_QUERY_ID 13.4.2 Joysticks

14 Specialized Topics 14.1 Logging Errors 14.1.1 Creating an Error Log Packet 14.1.2 Creating a Message File 14.2 System Threads 14.2.1 Creating and Terminating System Threads 14.2.2 Using a System Thread for Device Polling 14.3 Work Items 14.3.1 Watchdog Timers 14.4 Windows 98/Me Compatibility Notes 14.4.1 Error Logging 14.4.2 Waiting for System Threads to Finish 14.4.3 Work Items

15 Distributing Device Drivers 15.1 The Role of the Registry 15.1.1 The Hardware (Instance) Key 15.1.2 The Class Key 15.1.3 The Driver Key 15.1.4 The Service (Software) Key 15.1.5 Accessing the Registry from a Program 15.1.6 Device Object Properties 15.2 The INF File 15.2.1 Install Sections 15.2.2 Populating the Registry 15.2.3 Security Settings 15.2.4 Strings and Localization 15.2.5 Device Identifiers 15.2.6 Driver Ranking 15.2.7 Tools for INF Files 15.3 Defining a Device Class 15.3.1 A Property Page Provider 15.4 Customizing Setup 15.4.1 Installers and Co-installers

- 340 -

- 343 - 343 - 343 - 343 - 345 - 346 - 346 - 347 - 351 - 353 - 360 - 360 - 361 -

- 363 - 363 - 364 - 365 - 367 - 368 - 369 - 371 - 372 - 375 - 375 - 375 - 375 -

- 377 - 377 - 378 - 379 - 380 - 380 - 381 - 382 - 383 - 386 - 388 - 391 - 392 - 392 - 396 - 397 - 399 - 400 - 402 - 403 -

VII

15.4.2 Preinstalling Driver Files 15.4.3 Value-Added Software 15.4.4 Installing a Driver Programmatically 15.4.5 The RunOnce Key 15.4.6 Launching an Application 15.5 The Windows Hardware Quality Lab 15.5.1 Running the Hardware Compatibility Tests 15.5.2 Submitting a Driver Package 15.6 Windows 98/Me Compatibility Notes 15.6.1 Property Page Providers 15.6.2 Installers and Co-installers 15.6.3 Preinstalled Driver Packages 15.6.4 Digital Signatures 15.6.5 Installing Drivers Programmatically 15.6.6 CONFIGMG API 15.6.7 INF Incompatibilities 15.6.8 Registry Usage 15.7 Getting Device Properties

16 Filter Drivers 16.1 The Role of a Filter Driver 16.1.1 Upper Filter Drivers 16.1.2 Lower Filter Drivers 16.2 Mechanics of a Filter Driver 16.2.1 The DriverEntry Routine 16.2.2 The AddDevice Routine 16.2.3 The DispatchAny Function 16.2.4 The DispatchPower Routine 16.2.5 The DispatchPnp Routine 16.3 Installing a Filter Driver 16.3.1 Installing a Class Filter 16.3.2 Installing a Device Filter with the Function Driver 16.3.3 Installing a Device Filter for an Existing Device 16.4 Case Studies 16.4.1 Lower Filter for Traffic Monitoring 16.4.2 Named Filters 16.4.3 Bus Filters 16.4.4 Keyboard and Mouse Filters 16.4.5 Filtering Other HID Devices 16.5 Windows 98/Me Compatibility Notes 16.5.1 WDM Filters for VxD Drivers 16.5.2 INF Shortcut 16.5.3 Class Filter Drivers

A Coping with Cross-Platform Incompatibilities Determining the Operating System Version Run-Time Dynamic Linking Checking Platform Compatibility Defining Win98/Me Stubs for Kernel-Mode Routines Version Compatibility

- 407 - 407 - 408 - 408 - 409 - 409 - 409 - 413 - 417 - 417 - 417 - 417 - 418 - 418 - 418 - 418 - 418 - 419 -

- 421 - 421 - 421 - 423 - 424 - 424 - 424 - 426 - 426 - 427 - 428 - 428 - 430 - 430 - 430 - 430 - 431 - 433 - 433 - 435 - 435 - 435 - 436 - 436 -

- 437 - 437 - 437 - 438 - 439 - 440 -

VIII

Stub Functions Using WDMSTUB Interaction Between WDMSTUB and WDMCHECK Special Licensing Note

B Using WDMWIZ.AWX Basic Driver Information DeviceIoControl Codes I/O Resources USB Endpoints WMI Support Parameters for the INF File Now What?

- 440 - 442 - 442 - 442 -

- 443 - 443 - 444 - 445 - 445 - 446 - 447 - 448 -

IX

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.

X

Introduction This book explains how to write device drivers for the newest members of the Microsoft Windows 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 NT4.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 kernel-mode 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.

Driver Security and Reliability>>>>

XI

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.

Driver Security and Reliability Software security and reliability is everybody's job. Those of us who write drivers have a special responsibility because our code runs in the trusted kernel. When our code crashes, it usually takes the whole system with it. When our code has a trap door, a hacker can squeeze through to take over the whole system and, perhaps, the enterprise it serves. It behooves all of us to take these issues seriously. If we don't, real people can suffer economic and physical injury. Because of the seriousness of security issues in driver programming, this edition uses a special icon to highlight areas that are especially important to driver reliability and security. The Driver Verifier component of the operating system performs a variety of checks on a driver—if we ask it to. The Windows Hardware Quality Laboratory (WHQL) will run your driver with all sorts of Driver Verifier tests enabled, so you might as well beat them to it by enabling Driver Verifier as soon as your driver is minimally functional. We'll use this icon to mark discussions of how the Driver Verifier can help you debug your driver.

Programming The Microsoft Windows Driver Model 2nd Edition

Copyright © 2003 by Walter Oney

XII