Developing Windows NT Device Drivers Vol. 1 : A Programmer's Handbook

by ;
Edition: 1st
Format: Hardcover
Pub. Date: 1999-03-30
Publisher(s): Addison-Wesley Professional
  • Free Shipping Icon

    This Item Qualifies for Free Shipping!*

    *Excludes marketplace orders.

List Price: $73.49

Rent Book

Select for Price
There was a problem. Please try again later.

New Book

We're Sorry
Sold Out

Used Book

We're Sorry
Sold Out

eBook

We're Sorry
Not Available

How Marketplace Works:

  • This item is offered by an independent seller and not shipped from our warehouse
  • Item details like edition and cover design may differ from our description; see seller's comments before ordering.
  • Sellers much confirm and ship within two business days; otherwise, the order will be cancelled and refunded.
  • Marketplace purchases cannot be returned to eCampus.com. Contact the seller directly for inquiries; if no response within two days, contact customer service.
  • Additional shipping costs apply to Marketplace purchases. Review shipping costs at checkout.

Summary

Developing Windows NT Device Drivers: A Programmer's Handbook offers programmers a comprehensive and in-depth guide to building device drivers for Windows NT. Written by two experienced driver developers, Edward N. Dekker and Joseph M. Newcomer, this book provides detailed coverage of techniques, tools, methods, and pitfalls to help make the often complex and byzantine "black art" of driver development straightforward and accessible.

This book is designed for anyone involved in the development of Windows NT Device Drivers, particularly those working on drivers for nonstandard devices that Microsoft has not specifically supported. Because Windows NT does not permit an application program to directly manipulate hardware, a customized kernel mode device driver must be created for these nonstandard devices. And since experience has clearly shown that superficial knowledge can be hazardous when developing device drivers, the authors have taken care to explore each relevant topic in depth.

This book's coverage focuses on drivers for polled, programmed I/O, interrupt-driven, and DMA devices. The authors discuss the components of a kernel mode device driver for Windows NT, including background on the two primary bus interfaces used in today's computers: the ISA and PCI buses. Developers will learn the mechanics of compilation and linking, how the drivers register themselves with the system, experience-based techniques for debugging, and how to build robust, portable, multithread- and multiprocessor-safe device drivers that work as intended and won't crash the system. The authors also show how to call the Windows NT kernel for the many services required to support a device driver and demonstrate some specialized techniques, such as mapping device memory or kernel memory into user space. Thus developers will not only learn the specific mechanics of high-quality device driver development for Windows NT, but will gain a deeper understanding of the foundations of device driver design.



0201695901B04062001

Author Biography

Edward N. Dekker is a well-known authority on device drivers. He heads Electric Engineering, Inc., a consulting service that specializes in device drivers, systems programming, and real-time systems. For a number of years, his work has focused on device driver development for Windows NT. He has more than 20 years of computer software experience. Joseph M. Newcomer is head of The Joseph M. Newcomer Company, where he specializes in Windows application design, device drivers, and real-time and embedded systems. He has considerable experience in compiler and operating system design and implementation. A frequent contributor to Dr. Dobb's Journal, he has also written several books, including Win 32 Programming (with Brent Rector, Addison-Wesley). In addition to his consulting practice, he serves as adjunct senior scientist at Carnegie Mellon University and has been an active contributor to CompuServe and Internet Windows online forums. In recognition of these contributions, he was named a Most Valuable Professional (MVP) by Microsoft.

Table of Contents

List of Figures
xxv
List of Tables
xxxi
Code Listings
xxxv
Preface xxxix
Overview of Drivers
1(30)
Historical Overview
1(8)
Overview of the NT Architecture
9(1)
The Priority System
10(3)
NT System Architecture
13(7)
Kernel versus User Modes
14(1)
The Hardware Abstraction Layer
14(1)
The BIOS and ARC
15(1)
The Kernel
15(1)
The Executive Services
15(1)
Getting from Here to There
16(1)
The Boot Process
17(3)
Overview of Device Drivers
20(4)
There's Lots More
24(1)
Driver Writing: Getting Started
24(3)
Using C++
27(2)
Planning a Device Driver
29(1)
Further Reading
29(2)
I/O: User-Level Overview
31(14)
User-Level I/O Basics
31(12)
Synchronous versus Asynchronous I/O
31(2)
User-Level APIs
33(9)
Other I/O Operations
42(1)
Further Reading
43(2)
Planning a Device Driver
45(26)
Planning the User-Level Interface
45(3)
Device Scenario 1
46(1)
Device Scenario 2
47(1)
Device Scenario 3
47(1)
Even More Design Decisions
48(1)
Windows NT: Not a Real-Time System
48(1)
Understanding the Application(s)
49(1)
Understanding the Hardware
50(2)
How Does It Work, Really?
52(1)
Designing the Driver
52(6)
Choosing among ReadFile, WriteFile, DeviceIoControl, and CancelIo
53(1)
Address Mapping
53(1)
Paged and Nonpaged Memory
54(2)
Buffered and Direct Access
56(1)
Handling I/O Request Packets
57(1)
Devices and Device Objects
58(1)
Devices and Controllers
58(1)
Adapter Objects
59(1)
Handling Interrupts
59(2)
The Interrupt Service Routine
59(1)
The Deferred Processing Routine
59(1)
Polled Devices and Interrupt Frequency
60(1)
Synchronization and Serialization
61(2)
Driver Threads
62(1)
Full-Duplex Devices
62(1)
Bus Enumeration
63(1)
Power Management
63(1)
Unloading Drivers
64(1)
The Registry
64(1)
Event Logging and Journaling
64(2)
International Drivers
66(1)
Driver Coding
67(1)
Driver Testing
68(1)
Further Reading
69(2)
I/O Hardware: Internal Busses
71(24)
Device Registers
72(2)
Memory-Mapped Device Registers
74(1)
Device Memory
75(1)
Bus Structures
76(16)
ISA Bus
76(3)
The MicroChannel (MCA) Bus
79(1)
The EISA Bus
80(3)
The PCI Bus
83(6)
PCI Bridges
89(3)
Basic Questions About the Device
92(1)
Summary
92(1)
Further Reading
93(2)
Device Driver Basics
95(12)
A Taxonomy of Kernel-Mode Drivers
96(1)
Driver Limitations
96(1)
The Registry
97(1)
Drivers: Always Preemptible, Always Interruptible
98(1)
Multithreading and Multiprocessor Considerations
99(2)
I/O Request Packets
101(4)
Layered Drivers and IRPs
104(1)
Asynchronous I/O
105(1)
Object-Oriented Structures
106(1)
Further Reading
106(1)
Overview of Kernal Memory: Caching, Paging, and Pipelining
107(22)
Device Drivers and Memory Management
107(2)
The Virtual Address Space
109(1)
The Physical Memory System
110(9)
More-Sophisticated Caching
115(1)
Cache Management on Intel Hardware
115(2)
Pipelining: A Form of Caching
117(2)
Caching Page Table Information
119(1)
Cache-Line Alignment
119(1)
Memory Management in NT
120(5)
The Least-Recently-Used Algorithm, Working Set, and Thrashing
122(2)
Nonpaged Memory
124(1)
Memory Management for Device Drivers: Overview
125(1)
The File Cache
126(1)
Further Reading
126(3)
Driver Data Structures
129(22)
Loading and Starting a Driver
129(5)
Driver Objects
134(4)
Driver Loading
134(1)
Driver Load Order
135(1)
Adding a Driver
136(1)
Driver Object Structure
136(2)
Creating Device Objects
138(3)
Device Object Structure
139(2)
Adapter Objects
141(1)
Controller Objects
141(1)
Interrupt Objects
141(1)
Timer Objects
141(1)
DPC Objects
142(1)
File Objects
142(2)
Event, Semaphore, and Mutex Objects
144(1)
I/O Request Packets
144(5)
IRP_MJ_Create
145(1)
IRP_MJ_Read
145(1)
IRP_MJ_Write
146(1)
IRP_MJ_Close
147(1)
IRP_MJ_Device_Control
147(1)
IRP_MJ_Internal_Device_Control
148(1)
IRP_MJ_Shutdown
149(1)
IRP_MJ_Cleanup
149(1)
IRP_MJ_Flush_Buffers
149(1)
Summary
149(2)
Device Driver Structure
151(18)
The ``Hello World'' Driver
151(9)
Doing Debug Printout
151(3)
The hello.h File
154(1)
The hello.c File
154(1)
The ``Hello World'' DriverEntry Routine
155(2)
The HelloOpen Function
157(1)
The HelloClose Function
158(1)
The HelloUnload Function
159(1)
The Test Program
160(2)
Building the Driver
162(3)
The Checked and Free Build Environments
162(1)
The BUILD Command
162(2)
Output from the BUILD Process
164(1)
Registry Entries for ``Hello World''
165(1)
The REGEDIT/REGEDT32 Programs
165(1)
The REGINI Program
165(1)
Running the ``Hello World'' Test Program and Driver
165(1)
Starting the Driver
165(1)
Running the Test Program
166(1)
The I/O Explorer
166(1)
Further Reading
167(2)
Debugging a Device Driver
169(52)
Application Level: The IDE Debugger
169(1)
Application Level: Bounds Checker for Windows
169(1)
Kernal: WinDbg
170(1)
Kernel: SoftICE
170(1)
Kernel: kd
171(1)
Retail and Checked Builds
171(2)
Symbol Tables
171(1)
Stripping Symbol Tables
172(1)
Using the Debugging Tools
173(33)
Physical Configuration
174(2)
Using Autologin
176(2)
Installing Your Driver
178(1)
Modifying the BOOT.INI File
179(5)
Setting Parameters on the Alpha
184(1)
Configuring WinDbg
184(4)
Staring a Debug Session
188(1)
Loading the Driver
189(2)
It Crashed. Now What?
191(13)
Restarting After an Error
204(1)
Reading a Crash Dump
205(1)
Unhandled Exceptions
206(1)
WinDbg Reference
206(4)
If in Doubt, Get Hardware Debug Assistance
210(8)
Extender Cards
210(2)
The PCI Bus Monitor
212(3)
The Logic Analyzer
215(1)
The Oscilloscope
215(2)
If Still in Doubt, Rent an ICE---It's Expensive, but So Are You
217(1)
Summary
218(1)
Product List
218(1)
Further Reading
219(2)
Approaching Reality: Moving Data
221(26)
IRP_MJ_Device_Control and IRP_MJ_Internal_Device_Control
221(17)
Buffers for Device Control
222(9)
Completion of the Request
231(1)
Example: Buffered IOCTL
231(1)
Declarations and Interface
231(3)
Sample Usage: Application Level
234(4)
IRP_MJ_Read and IRP_MJ_Write
238(7)
Buffers for Read and Write
238(2)
Completion of the Request
240(1)
Example: Buffered IRP_MJ_Read and IRP_MJ_Write Completed in Dispatch
241(3)
Example: Direct I/O IRP_MJ_Read and IRP_MJ_Write Completed in Dispatch
244(1)
Summary
245(2)
Approaching Reality: Synchronization
247(18)
Spin Locks
247(3)
KeInitializeSpinLock
249(1)
KeAcquireSpinLock
249(1)
KeReleaseSpinLock
249(1)
KeAcquireSpinLockAtDpcLevel
249(1)
KeReleaseSpinLockFromDpcLevel
250(1)
Mutexes and Fast Mutexes
250(3)
Fast Mutex Operations
251(1)
Mutex Operation
252(1)
Semaphores
253(2)
Semaphore Operations
254(1)
The Executive Resource
255(4)
Executive Resource Operations
256(3)
Wait Routines
259(2)
KeWaitForMultipleObjects
260(1)
KeWaitForSingleObject
260(1)
SynchCritSection Routine
261(1)
Device Consistency: KeSynchronizeExecution
261(1)
The Cancel Spin Lock
262(1)
Summary
262(1)
Further Reading
263(2)
Achieving Reality: Memory Management
265(14)
Memory Allocation/Management Operations
266(5)
Basic Kernel Memory Allocation Operations
266(3)
Lookaside Lists
269(2)
Zone Buffers
271(1)
Mapping Device Memory and I/O Space
271(3)
Functions to Manage Device Memory
272(2)
Managing User Memory
274(3)
Functions to manage User Memory
274(3)
Summary
277(2)
Achieving Reality: Touching the Hardware
279(12)
Accessing Ports
280(3)
Mapping Ports
280(1)
Reading and Writing Ports
281(2)
Accessing Device Memory
283(5)
Reading and Writing Device Memory
284(4)
The Joy of Hardware
288(2)
Summary
290(1)
Achieving Reality: Interrupts and the Driver
291(20)
Role of the Low-Level Driver
291(1)
Interrupt Processing
292(1)
What Is an Interrupt?
292(3)
Interrupt Levels
293(1)
ISR Synchronization: the ISR Spin Lock
293(2)
ISR Levels and Device Priority
295(1)
Overview of an ISR
295(8)
The ISR Prototype
296(1)
Interrupt Service Routine Requirements
296(1)
Registering the ISR
297(1)
Processing the Interrupt
297(2)
Deferred Procedure Call Overview
299(1)
DPC for ISR versus Custom DPC
300(1)
Multiple DPC Routines
300(1)
DpcForIsr
301(1)
Custom DPC Routines
302(1)
Writing an ISR
303(4)
A Prototypical ISR
303(1)
ISRs and Shared Interrupts
304(1)
The Deferred Procedure Call
305(2)
ISRs and the Unload Routine
307(1)
The SynchCritSection Routine
307(3)
Resource Allocation Interlocks
309(1)
Summary
310(1)
Achieving Reality: Timers
311(14)
Hardware Timers
311(1)
Time Delay
311(10)
Performance Measurement
312(1)
Time Delays
313(1)
Timeout Routines
314(1)
IoTimer Routines
314(3)
Custom Timer Routines
317(1)
Waiting on a Custom Timer Object
317(1)
Polling a Custom Timer Object
317(1)
The CustomTimerDpc Routine
317(1)
Notification Timers and Synchronization Timers
318(1)
Functions for Custom Timers
318(2)
Example: Setting an IoTimer Routine
320(1)
Time-of-Day Functions
321(2)
Reading the Time of Day
322(1)
Time-of-Day Conversion Functions
322(1)
Summary
323(2)
Achieving Reality: Driver Initialization
325(12)
Initialization Functions
325(2)
Driver Initialization Prototype
327(9)
Setting Up the ISR
331(1)
Functions Used by Initialization
332(3)
The Unload Routine
335(1)
Summary
336(1)
Achieving Reality: Direct Memory Access
337(16)
How Is DMA Done at the Hardware Level?
337(1)
Direct Memory Access Operations
338(1)
Use of DMA
338(4)
Scatter/Gather
340(2)
Using Adapter Objects to Represent DMA Adapters
342(3)
Adapter Control Routine
343(2)
Overview of DMA Processing
345(5)
DriverEntry Setup
345(1)
Dispatch Routine Processing
345(1)
StartIo Processing
345(2)
ISR Processing
347(1)
DPC Processing
347(1)
Optimizations and Simplifications
347(1)
Maintaining Cache Consistency
348(1)
DMA Channel Allocation
348(2)
Controller Objects
350(2)
Multiple Synchronization Objects and Deadlock
350(1)
Creating and Managing Controller Objects
351(1)
Summary
352(1)
Achieving Reality: The Rest of the Details
353(10)
The Unload Function
353(2)
Parameterizing a Driver: The Registry
355(7)
Reading the Registry
356(2)
Using the Registry Values
358(1)
Initializing the Driver Object
359(2)
The Unload Handler
361(1)
Summary
362(1)
Mapping Kernel and Device Memory to User Space
363(20)
Mapping Nonpaged Pool to User Space
363(1)
An Overview of the MapMem Driver
364(17)
The Registry Entry
365(1)
Reading the Registry
365(1)
Using the Registry Values
366(1)
Initializing the Driver Object
367(2)
The MapMem IRP_MJ_Create Handler
369(1)
The IRP_MJ_Close Handler
369(1)
The MJ_IRP_Device_Control Handler
370(5)
The MapMem Unload Handler
375(1)
The mapSystemLogicalMemory Function
375(6)
Mapping Device Memory
381(1)
Summary
381(2)
I/O Hardware: The ISA Bus
383(12)
Problems with the ISA Bus
383(1)
History of the ISA Bus
384(1)
Overview of the ISA Architecture
385(3)
More about ISA Bus Problems
387(1)
ISA Interrupt Structure
388(4)
ISA Plug-and-Play
390(1)
Claiming Resources
390(2)
ISA DMA
392(1)
Summary
393(1)
Further Reading
393(2)
I/O Hardware: The PCI Bus
395(38)
The PCI Bus Hardware
395(4)
PCI Transactions
396(2)
The North Bridge
398(1)
Windows NT Support of the PCI Bus
399(20)
PCI Device Enumeration
399(1)
PCI Configuration Space
400(6)
HalGetBusData in More Detail
406(1)
Assigning Resources
407(1)
Using HalAssignSlotResources
408(5)
Claiming Resources
413(2)
Using IoAssignResources
415(2)
Overriding Assignments
417(1)
Mapping Memory
417(2)
The PCI Explorer
419(11)
The PCISCAN Driver
421(7)
The PCI Explorer Source
428(2)
Summary
430(1)
Further Reading
430(3)
Serialization within the Driver
433(28)
Introduction to Serialization
433(1)
Basic Serialization: StartIo
434(5)
Driver-Managed Queues
439(7)
Low-Level Primitives
439(4)
The Device Queue
443(3)
A Substitute for StartIo
446(1)
A Multiqueue Device
446(8)
Nonexclusive Devices
454(1)
Canceling and I/O Request
455(4)
Cancel and Layered Drivers
456(1)
The Cancel Routine
456(1)
Cancel Routine and Cancel Spin Lock
457(1)
Cancelling IRPs Managed by StartIo
457(2)
Cancelling Device-Managed IRPs
459(1)
Summary
459(2)
Layered Drivers
461(30)
Layered Driver Architecture
461(1)
Filter Drivers
462(4)
Object Manager
466(9)
Reference Counts
467(1)
Object Manager Name Space
468(3)
Object Manager Functions
471(1)
Creating Object Manager Entries
471(3)
Objects and Waiting
474(1)
Implementation of Layered Drivers
475(1)
DriverEntry
475(1)
Unload Routine
476(1)
Implementation of Filter Drivers
476(1)
DriverEntry
477(1)
Unload Routine
477(1)
Implementation Techniques
477(9)
The IRP Stack
478(1)
IRP Processing
478(3)
Calling Lower-Level Drivers
481(1)
Passing Buffers to Lower-Level Drivers
481(1)
Completion Routines
481(4)
Use of IoMarkIrpPending
485(1)
Direct Calls from Driver to Driver
486(1)
Layered Driver Examples
486(3)
Passing an Allocated IRP to a Lower-Level Driver
486(1)
Passing the IRP to a Lower-Level Driver By Using a Completion Routine
487(2)
Summary
489(2)
Driver Threads
491(34)
The Need for Driver Threads
491(2)
System Worker Thread WorkItems
493(1)
Driver-Dedicated Threads
494(2)
Multiprocessor Systems and Threads
496(1)
Waits
497(2)
Alertable and Nonalertable Waits
497(1)
Asynchronous Procedure Call
497(1)
The Wait Routines
498(1)
Event Objects
499(1)
Semaphore Objects
500(1)
Mutexes
501(1)
Fast Mutexes
501(1)
Resources
502(2)
Synchronizing on Thread Objects
504(1)
A Multiple Queue Example using Threads
505(13)
Finite State Machines and Drivers
518(5)
Cancelling the Active IRP
522(1)
Further Reading
523(2)
Specialized Drivers in NT: An Overview
525(28)
Graphics Drivers
525(2)
Display Drivers
527(15)
The Miniport Driver
529(2)
DDI (Display) Driver
531(9)
OpenGL
540(1)
Direct3D and DirectDraw
541(1)
Printer Drivers
542(2)
The SCSI Bus
544(7)
The SCSI Physical Bus
544(1)
The SCSI Command Set
545(1)
SCSI Drivers
546(2)
The Port Driver
548(3)
Summary
551(1)
Further Reading
551(2)
Useful Driver Techniques
553(52)
Deferred Procedure Calls
553(5)
Threads and DPC Queueing: A Fatal Problem
554(1)
Example: DPC Queueing Failure
554(4)
Deferred and Multiphase Driver Initialization
558(1)
The Registry
559(6)
Registry Access Functions
562(3)
The Windows NT Event Log
565(12)
The Event Viewer Utility
565(1)
The Message Table
566(5)
Creating Driver Events
571(6)
BugCheck!
577(3)
Invoking a Blue Screen of Death
579(1)
Surviving a Blue Screen of Death
579(1)
Reading and Writing Files
580(9)
Functions for Reading and Writing Files
581(8)
Rebooting: Avoid When Possible
589(1)
Pageable Drivers
590(5)
Why a Pageable Driver?
590(1)
Creating a Pageable Driver
591(2)
Validating Pageability
593(1)
Locking Down Data
593(1)
Improving Performance by Locking Down Code
594(1)
Paging Entire Drivers
595(1)
Product Driver Installation
595(7)
The Service Control Manager
596(1)
The Registry
596(1)
Programming the SCM
596(6)
The Alpha Memory Barrier
602(1)
Summary
603(1)
Further Reading
603(2)
A Hardware Simulator
605(30)
Why a Simulator?
605(1)
Basic Design of a Simulator
606(4)
The Hardware Simulator Driver
610(5)
Hardware Simulator Driver Source Code
610(5)
The Hardware Simulator Control Panel
615(4)
Hardware Simulator State Diagram
615(2)
Using the Hardware Simulator Controller
617(2)
The I/O Explorer
619(1)
Sample Device Drivers
620(14)
Testing State: Macros, Bitmaps, and Offsets
621(2)
A Polled Device Driver
623(5)
A Simple Interrupt-Driven Device Driver
628(6)
Summary
634(1)
Windows 2000 Preview
635(48)
Windows 2000 Enhancements
635(1)
New Driver Support Routines
636(3)
Obsolete Driver Support Routines
638(1)
New DMA Programming Techniques
639(2)
Power Management
641(3)
Plug-and-Play
644(1)
The Win32 Driver Model
645(1)
The Hardware Installer Wizard
645(1)
Other Changes
646(1)
The Windows 2000 DriverEntry (and Friends)
646(3)
Handling IRP_MJ_Power
649(6)
The DEVICE_CAPABILITIES Structure
651(1)
The PoCallDriver Function
652(1)
The PoSetPowerSate Function
652(1)
The PoRegisterDeviceForIdleDetection Function
652(1)
The IRP_MJ_WMI Message
653(1)
The IRP_MJ_PNP Message
653(2)
A ``Simple'' Windows 2000 Driver
655(1)
Publishing Books and Software Releases
655(26)
The DriverEntry Handler
656(1)
The AddDevice Handler
657(2)
The IRP_MJ_PNP Handler
659(17)
The IRP_MJ_POWER Handler
676(5)
The Unload Handler
681(1)
Summary
681(2)
I/O Hardware: The Universal Serial Bus
683(56)
Overview of External Busses
683(1)
Need for the Universal Serial Bus
683(2)
USB Implementation
685(1)
USB Architecture
686(2)
The Root Hub
687(1)
Endpoints
687(1)
Pipes
687(1)
Transfer Types
688(6)
Isochronous Transfers
688(2)
Interrupt Transfers
690(1)
Control Transfers
691(1)
Bulk Transfers
692(1)
Packet Bandwidth
693(1)
USB Packet Protocols
694(3)
SOF Packet
695(1)
IN Packet
695(1)
OUT Packet
695(1)
SETUP Packet
695(1)
DATA0 and DATA1 Packets
696(1)
Handshake Packets: ACK, NAK, and STALL
696(1)
PRE Packets
696(1)
Transaction Details
697(6)
IN Transactions
697(1)
OUT Transactions
698(1)
SETUP Transactions
698(1)
IN Transactions
698(2)
OUT Transactions
700(1)
SETUP Transactions and Control Transfers
700(3)
Plug-and-Play Hardware
703(2)
Power Management
705(1)
USB Device States
706(3)
USB Device Requests
709(9)
Standard Device Requests
710(8)
USB Descriptors
718(11)
DEVICE Descriptor
719(3)
Configuration Descriptor
722(2)
INTERFACE Descriptor
724(1)
ENDPOINT Descriptor
725(1)
STRING Descriptor
726(1)
POWER Descriptor
727(2)
Device Communication
729(5)
USB Device Configuration
732(2)
Isochronous Transfers
734(1)
USB Hubs
734(3)
Further Reading
737(2)
The Win32 Driver Model
739(40)
How the WDM Extends the basic Driver Model
739(1)
The Driver Hierarchy
739(2)
The WDM Classes
741(4)
The HID Class
742(1)
The Streams Class
743(2)
The Audio Class
745(1)
The Video Class
745(1)
The Still Image Class
745(1)
Loading the WDM Drivers
745(1)
A Monolithic WDM Driver
746(6)
Important Differences Between Drivers
746(1)
Design of a Monolithic USB Driver
746(2)
Creating a WDM Device Object
748(2)
Calling the USB Driver
750(2)
The USB and the WDM
752(1)
The USB Subsystem
752(3)
The USB Card MiniDriver
753(1)
UHCI/OHCI Drivers
753(1)
The USB Class Driver
753(1)
The USB Hub Class Driver
753(1)
The HID/USB Interface
754(1)
Communicating to the USBDI
754(1)
USB Request Blocks
754(1)
The USB and Power Management
755(1)
A USB Filter Driver
755(18)
The ValueAdd.c File
756(1)
The DriverEntry Routine
757(2)
The Pass-Thru Routine
759(1)
The Create/Close Handler
759(2)
The AddDevice Function
761(1)
The Unload Function
762(1)
The PnP.c File
763(1)
The Power Dispatch Function
763(1)
The Plug-and-Play Handler
764(4)
The Plug-and-Play Completion Routine
768(1)
Starting the Device
769(1)
Stopping the Device
770(1)
Sending Down the USB Request
771(1)
The USB Completion Handler
772(1)
Processing the USB Descriptor
772(1)
The usb.c File
773(3)
The IRP_MJ_Internal_Device_Control Handler
773(2)
The URB Handler Completion Routine
775(1)
The URB Printout Routine
775(1)
USB Support Functions and Structures
776(1)
UsbBuildGetDescriptorRequest
776(1)
Summary
777(2)
Appendix A Reference
779(222)
Support Function Overview
779(2)
Legal Issues
781(1)
Support Function and Data Structure Reference
781(217)
ANSI_String
864(1)
Assert
864(1)
Assertmsg
865(1)
CM-Full_Resource_Descriptor
865(1)
CM-Partial_Resource_Descriptor
866(1)
CM_Partial_Resource_List
867(1)
CM_Resource_List
868(1)
Configuration_Information
868(1)
Containing_Record
869(1)
Controller_Object
869(1)
DbgBreakPoint
870(1)
DbgPrint
870(1)
Device_Description
870(2)
Device_Object
872(3)
DriverEntry
875(1)
Driver_Extension
875(1)
Driver_Object
875(1)
ExAcquireFastMutex
876(1)
ExAcquireFastMutexUnsafe
876(1)
ExAcquireResourceExclusiveLite
877(1)
ExAcquireResourceSharedLite
877(1)
ExAcquireSharedStarveExclusive
877(1)
ExAcquireSharedWaitForExclusive
878(1)
ExAllocateFromNPagedLookasideList
879(1)
ExAllocateFromPagedLookasideList
879(1)
ExAllocatePool
879(1)
ExAllocatePoolWithQuota
880(1)
ExAllocatePoolWithQuotaTag
881(1)
ExAllocatePoolWithTag
882(1)
ExConvertExclusiveToSharedLite
883(1)
ExDeleteNPagedLookasideList
883(1)
ExDeletePagedLookasideList
884(1)
ExDeleteResourceLite
884(1)
ExFreePool
884(1)
ExFreeToNPagedLookasideList
884(1)
ExFreeToPagedLookasideList
884(1)
ExGetCurrentResourceThread
885(1)
ExInitializeFastMutex
885(1)
ExInitializeNPagedLookasideList
885(1)
ExInitializePagedLookasideList
886(1)
ExInitializeResourceLite
886(1)
ExInitializeWorkItem
887(1)
ExInterlockedInsertHeadList
887(1)
ExtInterlockedInsertTailList
887(1)
ExInterlockedRemoveHeadList
887(1)
ExIsResourceAcquiredExclusiveLite
888(1)
ExIsResourceAcquiredSharedLite
888(1)
ExQueueWorkItem
888(1)
ExReleaseFastMutex
888(1)
ExReleaseFastMutexUnsafe
889(1)
ExReleaseResourceForThreadLite
889(1)
ExTryToAcquireFastMutex
889(1)
ExTryToAcquireResourceExclusiveLite
889(1)
HalAllocateCommonBuffer
890(1)
HalAssignSlotResources
891(1)
HalFreeCommonBuffer
891(1)
HalGetAdapter
891(1)
HalGetBusData
892(1)
HalGetBusDataByOffset
892(1)
HalGetInterruptVector
893(1)
HalSetBusData
893(1)
HalSetBusDataByOffset
894(1)
HalTranslateBusAddress
894(1)
Hkey_Local_Machine
895(2)
InitializeListHead
897(1)
InitializeObjectAttributes
898(1)
InsertHeadList
898(1)
InsertTailList
898(1)
Interface_Type
899(1)
InterlockedDecrement
899(1)
InterlockedExchange
899(1)
InterlockedExchangeAdd
899(1)
InterlockedIncrement
900(1)
IoAcquireCancelSpinLock
900(1)
IoAllocateAdapterChannel
900(1)
IoAllocateController
900(1)
IoAllocateErrorLogEntry
901(1)
IoAllocateIrp
901(1)
IoAllocateMdl
902(1)
IoAssignResources
902(1)
IoAttachDevice
902(1)
IoAttachDeviceToDeviceStack
903(1)
IoBuildAsynchronousFsdRequest
904(1)
IoBuildDeviceIoControlRequest
905(1)
IoBuildPartialMdl
906(1)
IoBuildSynchronousFsdRequest
906(1)
IoCallDriver
907(1)
IoCancelIrp
907(1)
IoCompleteRequest
908(1)
IoConnectInterrupt
908(1)
IoCopyCurrentIrpStackLocationToNext
909(1)
IoCreateController
909(1)
IoCreateDevice
909(1)
IoCreateNotificationEvent
910(1)
IoCreateSymbolicLink
911(1)
IoCreateSynchronizationEvent
911(1)
IoDeleteController
912(1)
IoDeleteDevice
912(1)
IoDeleteSymbolicLink
913(1)
IoDetachDevice
913(1)
IoDisconnectInterrupt
913(1)
IO-Error_Log_Packet
913(1)
IoFlushAdapterBuffers
914(2)
IoFreeAdapterChannel
916(1)
IoFreeController
916(1)
IoFreeIrp
916(1)
IoFreeMapRegisters
916(1)
IoFreeMdl
917(1)
IoGetConfiguationInformation
917(1)
IoGetCurrentIrpStackLocation
917(1)
IoGetCurrentProcess
917(1)
IoGetDeviceObjectPointer
918(1)
InGoetNextIrpStackLocation
918(1)
IoInitializeDpcRequest
918(1)
IoInitializeIrp
918(1)
IoInitializeTimer
919(1)
IoMakeAssociatedIrp
919(1)
IoMapTransfer
920(1)
IoMarkIrpPending
920(1)
IoRegisterShutdownNotification
920(1)
IoReleseCancelSpinLock
921(1)
IoRequestDpc
921(1)
Io_Resource_Descriptor
921(2)
Io_Resource_List
923(1)
Io_Resource_Requirements_List
923(1)
IoSetCancelRoutine
924(1)
IoSetCompletionRoutine
924(1)
IoSetNextIrpStackLocation
925(1)
IoSizeOfIrp
925(1)
IoSkipCurrentIrpStackLocation
926(1)
Io_Stack_Location
926(5)
IoStartNextPacket
931(1)
IoStartNextPacketByKey
931(1)
IoStartPacket
931(1)
IoStartTimer
931(1)
IO_Status_Block
931(1)
IoStopTimer
932(1)
IoUnregisterShutdownNotification
932(1)
IoWriteErrorLogEntry
932(1)
IsListEmpty
932(1)
IRP
932(2)
KdPrint
934(1)
KeAcquireSpinLock
934(1)
KeAcquireSpinLockAtDpcLevel
935(1)
KeBugCheck
935(1)
KeBugCheckEx
936(1)
KeCancelTimer
936(1)
KeClearEvent
936(1)
KeDelayExecutionThread
936(1)
KeDeregisterBugCheckCallback
937(1)
KeFlushIoBuffers
937(1)
KeGetCurrentIrql
937(1)
KeGetCurrentProcessorNumber
938(1)
KeGetDcacheFillSize
938(1)
KeInitializeCallbackRecord
938(1)
KeInitializeDeviceQueue
938(1)
KeInitializeDpc
938(1)
KeInitializeEvent
939(1)
KeInitializeMutex
939(1)
KeInitializeSemaphore
940(1)
KeInitializeSpinLock
940(1)
KeInitializeTimer
940(1)
KeInitializeTimerEx
940(1)
KeInsertByKeyDeviceQueue
941(1)
KeInsertDeviceQueue
941(1)
KeInsertQueueDpc
941(1)
KeLowerIrql
942(1)
KeNumberProcessors
942(1)
KeQueryPerformanceCounter
942(1)
KeQuerySystemTime
943(1)
KeQueryTickCount
943(1)
KeQueryTimeIncrement
943(1)
KeRaiseIrql
943(1)
KeReadStateEvent
944(1)
KeReadStateMutex
944(1)
KeReadStateSemaphore
944(1)
KeReadStateTimer
944(1)
KeRegisterBugCheckCallback
945(1)
KeReleaseMutex
945(1)
KeReleaseSemaphore
945(1)
KeReleaseSpinLock
946(1)
KeReleaseSpinLockFromDpcLevel
946(1)
KeRemoveByKeyDeviceQueue
947(1)
KeRemoveDeviceQueue
947(1)
KeRemoveEntryDeviceQueue
947(1)
KeRemoveQueueDpc
947(1)
KeResetEvent
948(1)
KeSetEvent
948(1)
KeSetPriorityThread
948(1)
KeSetTimer
948(1)
KeSetTimerEx
949(1)
KeStallExecutionProcessor
950(1)
KeSynchronizeExecution
950(1)
KeWaitForMultipleObjects
951(2)
KeWaitForMutexObject
953(1)
KeWaitForSingleObject
954(1)
Key_Basic_Information
955(1)
Key_Full_Information
956(1)
Key_Node_Information
957(1)
Key_Value_Basic_Information
958(1)
Key_Value_Full_Information
959(2)
Key_Value_Partial_Information
961(1)
Kirql
962(1)
Ksynchronize_Routine
962(1)
Large_Integer
963(1)
MmAllocateContiguousMemory
963(1)
MmAllocateNonCachedMemory
964(1)
MmCreateMdl
964(1)
MmFreeContiguousMemory
964(1)
MmFreeNonCachedMemory
964(1)
MmGetMdlByteCount
965(1)
MmGetMdlByteOffset
965(1)
MmGetMdlVirtualAddress
965(1)
MmGetPhysicalAddress
965(1)
MmGetSystemAddressForMdl
965(1)
MmInitializeMdl
966(1)
MmIsAddressValid
966(1)
MmMapIoSpace
966(1)
MmMapLockedPages
967(1)
MmPrepareMdlForReuse
967(1)
MmProbeAndLockPages
967(1)
MmQuerySystemSize
968(1)
MmSizeOfMdl
968(1)
MmUnlockPages
969(1)
MmUnlockPagableImageSection
969(1)
MmUnmapIoSpace
969(1)
MmUnmapLockedPages
969(1)
NtStatus
969(1)
ObDereferenceObject
970(1)
ObReferenceObjectByHandle
970(1)
ObReferenceObjectByPointer
970(1)
Pci_Common_Config
971(2)
Pci_Slot_Number
973(1)
Pdriver_Control
973(1)
Pio_Dpc_Routine
973(1)
Pio-Timer-Routine
974(1)
Pkdefferred_Routine
974(1)
Pkstart_Routine
974(1)
PsCreateSystemThread
974(1)
PsGetCurrentProcess
975(1)
PsGetCurrentThread
975(1)
PsTerminateSystemThread
975(1)
Read_Port_Buffer_type
975(1)
Read_Port_type
976(1)
Read_Register_Buffer-type
976(1)
Read_Register_type
976(1)
RemoveEntryList
977(1)
RemoveHeadList
977(1)
RemoveTailList
977(1)
RtlCopyMemory
977(1)
RtlInitUnicodeString
977(1)
RtlMoveMemory
978(1)
Rtl_Query_Registry_Routine
978(1)
Rtl_Query_Registry_Table
978(1)
RtlQueryRegistryValues
979(1)
RtlUnicodeStringToAnsiString
980(1)
RtlZeroMemory
980(1)
Unicode_String
980(1)
_Urb_Control_Descriptor_Request
981(1)
_Urb_Header
982(1)
UsbBuildGetDescriptorRequest
982(1)
Write_Port_Buffer_type
983(1)
Write_Port_type
983(1)
Write_Register_Buffer_type
984(1)
Write_Register_type
984(1)
ZwClose
984(1)
ZwCreateFile
984(7)
ZwCreatekey
991(1)
ZwDeleteKey
991(1)
ZwEnumerateKey
992(1)
ZwEnumerateValueKey
992(1)
ZeFlushKey
992(1)
ZwMapViewOfSection
993(1)
ZwOpenKey
994(1)
ZwOpenSection
995(1)
ZwQueryKey
995(1)
ZwQueryValueKey
996(1)
ZwSetInformationThread
996(2)
ZwSetValueKey
998(1)
ZwUnmapViewOfSection
998(1)
Further Reading
998(3)
Apendix B Error Codes and NtStatus Codes
1001(106)
GetLastError Codes (alphabetic) to NtStatus Codes
1002(26)
GetLastError Codes (numeric) to NtStatus Values
1028(25)
NtStatus Codes (alphabetic) to GetLastError Codes
1053(28)
NtStatus Codes (numeric) with Explanations
1081(22)
The NtStatus Explorer
1103(2)
The Statusr Driver
1105(2)
Appendix C BugCheck Codes
1107(12)
Index 1119

Excerpts

Welcome to the World of Device DriversThis is a book on how to write Device Drivers. Device Drivers are those very specialized pieces of software that live inside the operating system and allow it, and thus your programs, to communicate to the outside world. Every communication NT makes to the outside world, including the keyboard, mouse, display, disks, CD-ROMS, and printers requires a Device Driver. Most of the key ones have been written by Microsoft, and NT supports all the "standard" devices.But what about "nonstandard" devices? This doesn't mean the devices don't conform to a standard; what it means is that these are devices that are not found on "standard" PCs. Often they are specialized devices whose market is far too small for Microsoft to devote any energy to supporting. These could be devices such as drivers that support IEEE-488 communications (used for laboratory equipment and test equipment), analog-to-digital data input boards, digital-to-analog data output boards, specialized communications boards, and the like.The core problem in Windows NT is that if you don't have a Device Driver you can't talk to a device. In Windows 3.x and Windows 9x you can cheat; you can write an application program that goes "for the bare metal" and directly manipulates the hardware interface to the device. But in Windows NT, because of the requirements for being certified at C2 Security (an important certification commercially and for government sales), an application program is simply not permitted to manipulate the hardware directly. So you are confronted with the problem of writing a device driver.That's what this book is all about. How This Book HappenedOne evening after a long day at Comdex, Ed and I (jmn) were sitting around discussing our Latest Adventures. Ed was telling me about all the really cool, largely non-obvious (not undocumented, but obscurely documented) things he'd learned about writing device drivers. I said to him, "Ed, you should write a book". (At this point I was well into the writing of Win32 Programming, so writing books was at the top of my consciousness). He looked at me and said "Joe, I don't know how to write a book". I immediately responded "Well, I don't know how to write a device driver!" The conclusion was obvious. So we wrote a proposal to Addison-Wesley, and you are holding the result. What We CoverThe purpose of this book is to allow you to write NT Device Drivers for a new device that you would want to connect to an NT machine. These include polled, programmed I/O, interrupt-driven, and DMA devices. Modern interrupt drivers add complexity, because interrupts may be shared by several devices. DMA has changed from the use of the PC's onboard DMA controller to external DMA controllers and Bus Mastering controllers. Many drivers for modern devices need access to onboard memory, and we show how to do that. In some cases, you might want to write a "user level" system that does most of the work, calling the I/O subsystem only to initiate certain input or output transactions, and using it to handle interrupts. We show how to construct these drivers.We talk about how to build robust, portable, multithread- and multiprocessor-safe drivers. We talk about what you have to do to ensure that your driver won't bring the system crashing down around the user. We lay out the protocols you must use in communicating to the rest of the system; if you don't follow these fairly exactly, the system won't work as expected. It may crash, it may corrupt the disk, it may ignore the device, it may lose information on input or output, or it may misinterpret the intention of the application programmer who calls the services of the driver. Writing a Device Driver is fairly exacting. We try to capture much of the Art of building a device driver here, as well as the Technology.In addition, we talk about how to actually build drivers, that is, the mechanics

An electronic version of this book is available through VitalSource.

This book is viewable on PC, Mac, iPhone, iPad, iPod Touch, and most smartphones.

By purchasing, you will be able to view this book online, as well as download it, for the chosen number of days.

Digital License

You are licensing a digital product for a set duration. Durations are set forth in the product description, with "Lifetime" typically meaning five (5) years of online access and permanent download to a supported device. All licenses are non-transferable.

More details can be found here.

A downloadable version of this book is available through the eCampus Reader or compatible Adobe readers.

Applications are available on iOS, Android, PC, Mac, and Windows Mobile platforms.

Please view the compatibility matrix prior to purchase.