|
|
xxv | |
|
|
xxxi | |
|
|
xxxv | |
Preface |
|
xxxix | |
|
|
1 | (30) |
|
|
1 | (8) |
|
Overview of the NT Architecture |
|
|
9 | (1) |
|
|
10 | (3) |
|
|
13 | (7) |
|
|
14 | (1) |
|
The Hardware Abstraction Layer |
|
|
14 | (1) |
|
|
15 | (1) |
|
|
15 | (1) |
|
|
15 | (1) |
|
Getting from Here to There |
|
|
16 | (1) |
|
|
17 | (3) |
|
Overview of Device Drivers |
|
|
20 | (4) |
|
|
24 | (1) |
|
Driver Writing: Getting Started |
|
|
24 | (3) |
|
|
27 | (2) |
|
|
29 | (1) |
|
|
29 | (2) |
|
|
31 | (14) |
|
|
31 | (12) |
|
Synchronous versus Asynchronous I/O |
|
|
31 | (2) |
|
|
33 | (9) |
|
|
42 | (1) |
|
|
43 | (2) |
|
|
45 | (26) |
|
Planning the User-Level Interface |
|
|
45 | (3) |
|
|
46 | (1) |
|
|
47 | (1) |
|
|
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) |
|
|
52 | (6) |
|
Choosing among ReadFile, WriteFile, DeviceIoControl, and CancelIo |
|
|
53 | (1) |
|
|
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) |
|
|
58 | (1) |
|
|
59 | (1) |
|
|
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) |
|
|
62 | (1) |
|
|
62 | (1) |
|
|
63 | (1) |
|
|
63 | (1) |
|
|
64 | (1) |
|
|
64 | (1) |
|
Event Logging and Journaling |
|
|
64 | (2) |
|
|
66 | (1) |
|
|
67 | (1) |
|
|
68 | (1) |
|
|
69 | (2) |
|
I/O Hardware: Internal Busses |
|
|
71 | (24) |
|
|
72 | (2) |
|
Memory-Mapped Device Registers |
|
|
74 | (1) |
|
|
75 | (1) |
|
|
76 | (16) |
|
|
76 | (3) |
|
The MicroChannel (MCA) Bus |
|
|
79 | (1) |
|
|
80 | (3) |
|
|
83 | (6) |
|
|
89 | (3) |
|
Basic Questions About the Device |
|
|
92 | (1) |
|
|
92 | (1) |
|
|
93 | (2) |
|
|
95 | (12) |
|
A Taxonomy of Kernel-Mode Drivers |
|
|
96 | (1) |
|
|
96 | (1) |
|
|
97 | (1) |
|
Drivers: Always Preemptible, Always Interruptible |
|
|
98 | (1) |
|
Multithreading and Multiprocessor Considerations |
|
|
99 | (2) |
|
|
101 | (4) |
|
|
104 | (1) |
|
|
105 | (1) |
|
Object-Oriented Structures |
|
|
106 | (1) |
|
|
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) |
|
|
119 | (1) |
|
|
120 | (5) |
|
The Least-Recently-Used Algorithm, Working Set, and Thrashing |
|
|
122 | (2) |
|
|
124 | (1) |
|
Memory Management for Device Drivers: Overview |
|
|
125 | (1) |
|
|
126 | (1) |
|
|
126 | (3) |
|
|
129 | (22) |
|
Loading and Starting a Driver |
|
|
129 | (5) |
|
|
134 | (4) |
|
|
134 | (1) |
|
|
135 | (1) |
|
|
136 | (1) |
|
|
136 | (2) |
|
|
138 | (3) |
|
|
139 | (2) |
|
|
141 | (1) |
|
|
141 | (1) |
|
|
141 | (1) |
|
|
141 | (1) |
|
|
142 | (1) |
|
|
142 | (2) |
|
Event, Semaphore, and Mutex Objects |
|
|
144 | (1) |
|
|
144 | (5) |
|
|
145 | (1) |
|
|
145 | (1) |
|
|
146 | (1) |
|
|
147 | (1) |
|
|
147 | (1) |
|
IRP_MJ_Internal_Device_Control |
|
|
148 | (1) |
|
|
149 | (1) |
|
|
149 | (1) |
|
|
149 | (1) |
|
|
149 | (2) |
|
|
151 | (18) |
|
The ``Hello World'' Driver |
|
|
151 | (9) |
|
|
151 | (3) |
|
|
154 | (1) |
|
|
154 | (1) |
|
The ``Hello World'' DriverEntry Routine |
|
|
155 | (2) |
|
|
157 | (1) |
|
|
158 | (1) |
|
|
159 | (1) |
|
|
160 | (2) |
|
|
162 | (3) |
|
The Checked and Free Build Environments |
|
|
162 | (1) |
|
|
162 | (2) |
|
Output from the BUILD Process |
|
|
164 | (1) |
|
Registry Entries for ``Hello World'' |
|
|
165 | (1) |
|
The REGEDIT/REGEDT32 Programs |
|
|
165 | (1) |
|
|
165 | (1) |
|
Running the ``Hello World'' Test Program and Driver |
|
|
165 | (1) |
|
|
165 | (1) |
|
|
166 | (1) |
|
|
166 | (1) |
|
|
167 | (2) |
|
Debugging a Device Driver |
|
|
169 | (52) |
|
Application Level: The IDE Debugger |
|
|
169 | (1) |
|
Application Level: Bounds Checker for Windows |
|
|
169 | (1) |
|
|
170 | (1) |
|
|
170 | (1) |
|
|
171 | (1) |
|
Retail and Checked Builds |
|
|
171 | (2) |
|
|
171 | (1) |
|
|
172 | (1) |
|
Using the Debugging Tools |
|
|
173 | (33) |
|
|
174 | (2) |
|
|
176 | (2) |
|
|
178 | (1) |
|
Modifying the BOOT.INI File |
|
|
179 | (5) |
|
Setting Parameters on the Alpha |
|
|
184 | (1) |
|
|
184 | (4) |
|
|
188 | (1) |
|
|
189 | (2) |
|
|
191 | (13) |
|
Restarting After an Error |
|
|
204 | (1) |
|
|
205 | (1) |
|
|
206 | (1) |
|
|
206 | (4) |
|
If in Doubt, Get Hardware Debug Assistance |
|
|
210 | (8) |
|
|
210 | (2) |
|
|
212 | (3) |
|
|
215 | (1) |
|
|
215 | (2) |
|
If Still in Doubt, Rent an ICE---It's Expensive, but So Are You |
|
|
217 | (1) |
|
|
218 | (1) |
|
|
218 | (1) |
|
|
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) |
|
|
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) |
|
|
245 | (2) |
|
Approaching Reality: Synchronization |
|
|
247 | (18) |
|
|
247 | (3) |
|
|
249 | (1) |
|
|
249 | (1) |
|
|
249 | (1) |
|
KeAcquireSpinLockAtDpcLevel |
|
|
249 | (1) |
|
KeReleaseSpinLockFromDpcLevel |
|
|
250 | (1) |
|
|
250 | (3) |
|
|
251 | (1) |
|
|
252 | (1) |
|
|
253 | (2) |
|
|
254 | (1) |
|
|
255 | (4) |
|
Executive Resource Operations |
|
|
256 | (3) |
|
|
259 | (2) |
|
|
260 | (1) |
|
|
260 | (1) |
|
|
261 | (1) |
|
Device Consistency: KeSynchronizeExecution |
|
|
261 | (1) |
|
|
262 | (1) |
|
|
262 | (1) |
|
|
263 | (2) |
|
Achieving Reality: Memory Management |
|
|
265 | (14) |
|
Memory Allocation/Management Operations |
|
|
266 | (5) |
|
Basic Kernel Memory Allocation Operations |
|
|
266 | (3) |
|
|
269 | (2) |
|
|
271 | (1) |
|
Mapping Device Memory and I/O Space |
|
|
271 | (3) |
|
Functions to Manage Device Memory |
|
|
272 | (2) |
|
|
274 | (3) |
|
Functions to manage User Memory |
|
|
274 | (3) |
|
|
277 | (2) |
|
Achieving Reality: Touching the Hardware |
|
|
279 | (12) |
|
|
280 | (3) |
|
|
280 | (1) |
|
Reading and Writing Ports |
|
|
281 | (2) |
|
|
283 | (5) |
|
Reading and Writing Device Memory |
|
|
284 | (4) |
|
|
288 | (2) |
|
|
290 | (1) |
|
Achieving Reality: Interrupts and the Driver |
|
|
291 | (20) |
|
Role of the Low-Level Driver |
|
|
291 | (1) |
|
|
292 | (1) |
|
|
292 | (3) |
|
|
293 | (1) |
|
ISR Synchronization: the ISR Spin Lock |
|
|
293 | (2) |
|
ISR Levels and Device Priority |
|
|
295 | (1) |
|
|
295 | (8) |
|
|
296 | (1) |
|
Interrupt Service Routine Requirements |
|
|
296 | (1) |
|
|
297 | (1) |
|
|
297 | (2) |
|
Deferred Procedure Call Overview |
|
|
299 | (1) |
|
DPC for ISR versus Custom DPC |
|
|
300 | (1) |
|
|
300 | (1) |
|
|
301 | (1) |
|
|
302 | (1) |
|
|
303 | (4) |
|
|
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) |
|
|
310 | (1) |
|
Achieving Reality: Timers |
|
|
311 | (14) |
|
|
311 | (1) |
|
|
311 | (10) |
|
|
312 | (1) |
|
|
313 | (1) |
|
|
314 | (1) |
|
|
314 | (3) |
|
|
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) |
|
|
321 | (2) |
|
|
322 | (1) |
|
Time-of-Day Conversion Functions |
|
|
322 | (1) |
|
|
323 | (2) |
|
Achieving Reality: Driver Initialization |
|
|
325 | (12) |
|
|
325 | (2) |
|
Driver Initialization Prototype |
|
|
327 | (9) |
|
|
331 | (1) |
|
Functions Used by Initialization |
|
|
332 | (3) |
|
|
335 | (1) |
|
|
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) |
|
|
338 | (4) |
|
|
340 | (2) |
|
Using Adapter Objects to Represent DMA Adapters |
|
|
342 | (3) |
|
|
343 | (2) |
|
Overview of DMA Processing |
|
|
345 | (5) |
|
|
345 | (1) |
|
Dispatch Routine Processing |
|
|
345 | (1) |
|
|
345 | (2) |
|
|
347 | (1) |
|
|
347 | (1) |
|
Optimizations and Simplifications |
|
|
347 | (1) |
|
Maintaining Cache Consistency |
|
|
348 | (1) |
|
|
348 | (2) |
|
|
350 | (2) |
|
Multiple Synchronization Objects and Deadlock |
|
|
350 | (1) |
|
Creating and Managing Controller Objects |
|
|
351 | (1) |
|
|
352 | (1) |
|
Achieving Reality: The Rest of the Details |
|
|
353 | (10) |
|
|
353 | (2) |
|
Parameterizing a Driver: The Registry |
|
|
355 | (7) |
|
|
356 | (2) |
|
Using the Registry Values |
|
|
358 | (1) |
|
Initializing the Driver Object |
|
|
359 | (2) |
|
|
361 | (1) |
|
|
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) |
|
|
365 | (1) |
|
|
365 | (1) |
|
Using the Registry Values |
|
|
366 | (1) |
|
Initializing the Driver Object |
|
|
367 | (2) |
|
The MapMem IRP_MJ_Create Handler |
|
|
369 | (1) |
|
|
369 | (1) |
|
The MJ_IRP_Device_Control Handler |
|
|
370 | (5) |
|
The MapMem Unload Handler |
|
|
375 | (1) |
|
The mapSystemLogicalMemory Function |
|
|
375 | (6) |
|
|
381 | (1) |
|
|
381 | (2) |
|
I/O Hardware: The ISA Bus |
|
|
383 | (12) |
|
Problems with the ISA Bus |
|
|
383 | (1) |
|
|
384 | (1) |
|
Overview of the ISA Architecture |
|
|
385 | (3) |
|
More about ISA Bus Problems |
|
|
387 | (1) |
|
|
388 | (4) |
|
|
390 | (1) |
|
|
390 | (2) |
|
|
392 | (1) |
|
|
393 | (1) |
|
|
393 | (2) |
|
I/O Hardware: The PCI Bus |
|
|
395 | (38) |
|
|
395 | (4) |
|
|
396 | (2) |
|
|
398 | (1) |
|
Windows NT Support of the PCI Bus |
|
|
399 | (20) |
|
|
399 | (1) |
|
|
400 | (6) |
|
HalGetBusData in More Detail |
|
|
406 | (1) |
|
|
407 | (1) |
|
Using HalAssignSlotResources |
|
|
408 | (5) |
|
|
413 | (2) |
|
|
415 | (2) |
|
|
417 | (1) |
|
|
417 | (2) |
|
|
419 | (11) |
|
|
421 | (7) |
|
|
428 | (2) |
|
|
430 | (1) |
|
|
430 | (3) |
|
Serialization within the Driver |
|
|
433 | (28) |
|
Introduction to Serialization |
|
|
433 | (1) |
|
Basic Serialization: StartIo |
|
|
434 | (5) |
|
|
439 | (7) |
|
|
439 | (4) |
|
|
443 | (3) |
|
|
446 | (1) |
|
|
446 | (8) |
|
|
454 | (1) |
|
Canceling and I/O Request |
|
|
455 | (4) |
|
Cancel and Layered Drivers |
|
|
456 | (1) |
|
|
456 | (1) |
|
Cancel Routine and Cancel Spin Lock |
|
|
457 | (1) |
|
Cancelling IRPs Managed by StartIo |
|
|
457 | (2) |
|
Cancelling Device-Managed IRPs |
|
|
459 | (1) |
|
|
459 | (2) |
|
|
461 | (30) |
|
Layered Driver Architecture |
|
|
461 | (1) |
|
|
462 | (4) |
|
|
466 | (9) |
|
|
467 | (1) |
|
Object Manager Name Space |
|
|
468 | (3) |
|
|
471 | (1) |
|
Creating Object Manager Entries |
|
|
471 | (3) |
|
|
474 | (1) |
|
Implementation of Layered Drivers |
|
|
475 | (1) |
|
|
475 | (1) |
|
|
476 | (1) |
|
Implementation of Filter Drivers |
|
|
476 | (1) |
|
|
477 | (1) |
|
|
477 | (1) |
|
Implementation Techniques |
|
|
477 | (9) |
|
|
478 | (1) |
|
|
478 | (3) |
|
Calling Lower-Level Drivers |
|
|
481 | (1) |
|
Passing Buffers to Lower-Level Drivers |
|
|
481 | (1) |
|
|
481 | (4) |
|
|
485 | (1) |
|
Direct Calls from Driver to Driver |
|
|
486 | (1) |
|
|
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) |
|
|
489 | (2) |
|
|
491 | (34) |
|
The Need for Driver Threads |
|
|
491 | (2) |
|
System Worker Thread WorkItems |
|
|
493 | (1) |
|
|
494 | (2) |
|
Multiprocessor Systems and Threads |
|
|
496 | (1) |
|
|
497 | (2) |
|
Alertable and Nonalertable Waits |
|
|
497 | (1) |
|
Asynchronous Procedure Call |
|
|
497 | (1) |
|
|
498 | (1) |
|
|
499 | (1) |
|
|
500 | (1) |
|
|
501 | (1) |
|
|
501 | (1) |
|
|
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) |
|
|
523 | (2) |
|
Specialized Drivers in NT: An Overview |
|
|
525 | (28) |
|
|
525 | (2) |
|
|
527 | (15) |
|
|
529 | (2) |
|
|
531 | (9) |
|
|
540 | (1) |
|
|
541 | (1) |
|
|
542 | (2) |
|
|
544 | (7) |
|
|
544 | (1) |
|
|
545 | (1) |
|
|
546 | (2) |
|
|
548 | (3) |
|
|
551 | (1) |
|
|
551 | (2) |
|
|
553 | (52) |
|
|
553 | (5) |
|
Threads and DPC Queueing: A Fatal Problem |
|
|
554 | (1) |
|
Example: DPC Queueing Failure |
|
|
554 | (4) |
|
Deferred and Multiphase Driver Initialization |
|
|
558 | (1) |
|
|
559 | (6) |
|
Registry Access Functions |
|
|
562 | (3) |
|
|
565 | (12) |
|
|
565 | (1) |
|
|
566 | (5) |
|
|
571 | (6) |
|
|
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) |
|
|
590 | (5) |
|
|
590 | (1) |
|
Creating a Pageable Driver |
|
|
591 | (2) |
|
|
593 | (1) |
|
|
593 | (1) |
|
Improving Performance by Locking Down Code |
|
|
594 | (1) |
|
|
595 | (1) |
|
Product Driver Installation |
|
|
595 | (7) |
|
The Service Control Manager |
|
|
596 | (1) |
|
|
596 | (1) |
|
|
596 | (6) |
|
|
602 | (1) |
|
|
603 | (1) |
|
|
603 | (2) |
|
|
605 | (30) |
|
|
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) |
|
|
619 | (1) |
|
|
620 | (14) |
|
Testing State: Macros, Bitmaps, and Offsets |
|
|
621 | (2) |
|
|
623 | (5) |
|
A Simple Interrupt-Driven Device Driver |
|
|
628 | (6) |
|
|
634 | (1) |
|
|
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) |
|
|
641 | (3) |
|
|
644 | (1) |
|
|
645 | (1) |
|
The Hardware Installer Wizard |
|
|
645 | (1) |
|
|
646 | (1) |
|
The Windows 2000 DriverEntry (and Friends) |
|
|
646 | (3) |
|
|
649 | (6) |
|
The DEVICE_CAPABILITIES Structure |
|
|
651 | (1) |
|
The PoCallDriver Function |
|
|
652 | (1) |
|
The PoSetPowerSate Function |
|
|
652 | (1) |
|
The PoRegisterDeviceForIdleDetection Function |
|
|
652 | (1) |
|
|
653 | (1) |
|
|
653 | (2) |
|
A ``Simple'' Windows 2000 Driver |
|
|
655 | (1) |
|
Publishing Books and Software Releases |
|
|
655 | (26) |
|
|
656 | (1) |
|
|
657 | (2) |
|
|
659 | (17) |
|
|
676 | (5) |
|
|
681 | (1) |
|
|
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) |
|
|
685 | (1) |
|
|
686 | (2) |
|
|
687 | (1) |
|
|
687 | (1) |
|
|
687 | (1) |
|
|
688 | (6) |
|
|
688 | (2) |
|
|
690 | (1) |
|
|
691 | (1) |
|
|
692 | (1) |
|
|
693 | (1) |
|
|
694 | (3) |
|
|
695 | (1) |
|
|
695 | (1) |
|
|
695 | (1) |
|
|
695 | (1) |
|
|
696 | (1) |
|
Handshake Packets: ACK, NAK, and STALL |
|
|
696 | (1) |
|
|
696 | (1) |
|
|
697 | (6) |
|
|
697 | (1) |
|
|
698 | (1) |
|
|
698 | (1) |
|
|
698 | (2) |
|
|
700 | (1) |
|
SETUP Transactions and Control Transfers |
|
|
700 | (3) |
|
|
703 | (2) |
|
|
705 | (1) |
|
|
706 | (3) |
|
|
709 | (9) |
|
|
710 | (8) |
|
|
718 | (11) |
|
|
719 | (3) |
|
|
722 | (2) |
|
|
724 | (1) |
|
|
725 | (1) |
|
|
726 | (1) |
|
|
727 | (2) |
|
|
729 | (5) |
|
|
732 | (2) |
|
|
734 | (1) |
|
|
734 | (3) |
|
|
737 | (2) |
|
|
739 | (40) |
|
How the WDM Extends the basic Driver Model |
|
|
739 | (1) |
|
|
739 | (2) |
|
|
741 | (4) |
|
|
742 | (1) |
|
|
743 | (2) |
|
|
745 | (1) |
|
|
745 | (1) |
|
|
745 | (1) |
|
|
745 | (1) |
|
|
746 | (6) |
|
Important Differences Between Drivers |
|
|
746 | (1) |
|
Design of a Monolithic USB Driver |
|
|
746 | (2) |
|
Creating a WDM Device Object |
|
|
748 | (2) |
|
|
750 | (2) |
|
|
752 | (1) |
|
|
752 | (3) |
|
|
753 | (1) |
|
|
753 | (1) |
|
|
753 | (1) |
|
|
753 | (1) |
|
|
754 | (1) |
|
Communicating to the USBDI |
|
|
754 | (1) |
|
|
754 | (1) |
|
The USB and Power Management |
|
|
755 | (1) |
|
|
755 | (18) |
|
|
756 | (1) |
|
|
757 | (2) |
|
|
759 | (1) |
|
|
759 | (2) |
|
|
761 | (1) |
|
|
762 | (1) |
|
|
763 | (1) |
|
The Power Dispatch Function |
|
|
763 | (1) |
|
The Plug-and-Play Handler |
|
|
764 | (4) |
|
The Plug-and-Play Completion Routine |
|
|
768 | (1) |
|
|
769 | (1) |
|
|
770 | (1) |
|
Sending Down the USB Request |
|
|
771 | (1) |
|
The USB Completion Handler |
|
|
772 | (1) |
|
Processing the USB Descriptor |
|
|
772 | (1) |
|
|
773 | (3) |
|
The IRP_MJ_Internal_Device_Control Handler |
|
|
773 | (2) |
|
The URB Handler Completion Routine |
|
|
775 | (1) |
|
|
775 | (1) |
|
USB Support Functions and Structures |
|
|
776 | (1) |
|
UsbBuildGetDescriptorRequest |
|
|
776 | (1) |
|
|
777 | (2) |
|
|
779 | (222) |
|
Support Function Overview |
|
|
779 | (2) |
|
|
781 | (1) |
|
Support Function and Data Structure Reference |
|
|
781 | (217) |
|
|
864 | (1) |
|
|
864 | (1) |
|
|
865 | (1) |
|
CM-Full_Resource_Descriptor |
|
|
865 | (1) |
|
CM-Partial_Resource_Descriptor |
|
|
866 | (1) |
|
|
867 | (1) |
|
|
868 | (1) |
|
Configuration_Information |
|
|
868 | (1) |
|
|
869 | (1) |
|
|
869 | (1) |
|
|
870 | (1) |
|
|
870 | (1) |
|
|
870 | (2) |
|
|
872 | (3) |
|
|
875 | (1) |
|
|
875 | (1) |
|
|
875 | (1) |
|
|
876 | (1) |
|
|
876 | (1) |
|
ExAcquireResourceExclusiveLite |
|
|
877 | (1) |
|
ExAcquireResourceSharedLite |
|
|
877 | (1) |
|
ExAcquireSharedStarveExclusive |
|
|
877 | (1) |
|
ExAcquireSharedWaitForExclusive |
|
|
878 | (1) |
|
ExAllocateFromNPagedLookasideList |
|
|
879 | (1) |
|
ExAllocateFromPagedLookasideList |
|
|
879 | (1) |
|
|
879 | (1) |
|
|
880 | (1) |
|
ExAllocatePoolWithQuotaTag |
|
|
881 | (1) |
|
|
882 | (1) |
|
ExConvertExclusiveToSharedLite |
|
|
883 | (1) |
|
ExDeleteNPagedLookasideList |
|
|
883 | (1) |
|
ExDeletePagedLookasideList |
|
|
884 | (1) |
|
|
884 | (1) |
|
|
884 | (1) |
|
ExFreeToNPagedLookasideList |
|
|
884 | (1) |
|
ExFreeToPagedLookasideList |
|
|
884 | (1) |
|
ExGetCurrentResourceThread |
|
|
885 | (1) |
|
|
885 | (1) |
|
ExInitializeNPagedLookasideList |
|
|
885 | (1) |
|
ExInitializePagedLookasideList |
|
|
886 | (1) |
|
|
886 | (1) |
|
|
887 | (1) |
|
ExInterlockedInsertHeadList |
|
|
887 | (1) |
|
ExtInterlockedInsertTailList |
|
|
887 | (1) |
|
ExInterlockedRemoveHeadList |
|
|
887 | (1) |
|
ExIsResourceAcquiredExclusiveLite |
|
|
888 | (1) |
|
ExIsResourceAcquiredSharedLite |
|
|
888 | (1) |
|
|
888 | (1) |
|
|
888 | (1) |
|
|
889 | (1) |
|
ExReleaseResourceForThreadLite |
|
|
889 | (1) |
|
|
889 | (1) |
|
ExTryToAcquireResourceExclusiveLite |
|
|
889 | (1) |
|
|
890 | (1) |
|
|
891 | (1) |
|
|
891 | (1) |
|
|
891 | (1) |
|
|
892 | (1) |
|
|
892 | (1) |
|
|
893 | (1) |
|
|
893 | (1) |
|
|
894 | (1) |
|
|
894 | (1) |
|
|
895 | (2) |
|
|
897 | (1) |
|
InitializeObjectAttributes |
|
|
898 | (1) |
|
|
898 | (1) |
|
|
898 | (1) |
|
|
899 | (1) |
|
|
899 | (1) |
|
|
899 | (1) |
|
|
899 | (1) |
|
|
900 | (1) |
|
|
900 | (1) |
|
|
900 | (1) |
|
|
900 | (1) |
|
|
901 | (1) |
|
|
901 | (1) |
|
|
902 | (1) |
|
|
902 | (1) |
|
|
902 | (1) |
|
IoAttachDeviceToDeviceStack |
|
|
903 | (1) |
|
IoBuildAsynchronousFsdRequest |
|
|
904 | (1) |
|
IoBuildDeviceIoControlRequest |
|
|
905 | (1) |
|
|
906 | (1) |
|
IoBuildSynchronousFsdRequest |
|
|
906 | (1) |
|
|
907 | (1) |
|
|
907 | (1) |
|
|
908 | (1) |
|
|
908 | (1) |
|
IoCopyCurrentIrpStackLocationToNext |
|
|
909 | (1) |
|
|
909 | (1) |
|
|
909 | (1) |
|
IoCreateNotificationEvent |
|
|
910 | (1) |
|
|
911 | (1) |
|
IoCreateSynchronizationEvent |
|
|
911 | (1) |
|
|
912 | (1) |
|
|
912 | (1) |
|
|
913 | (1) |
|
|
913 | (1) |
|
|
913 | (1) |
|
|
913 | (1) |
|
|
914 | (2) |
|
|
916 | (1) |
|
|
916 | (1) |
|
|
916 | (1) |
|
|
916 | (1) |
|
|
917 | (1) |
|
IoGetConfiguationInformation |
|
|
917 | (1) |
|
IoGetCurrentIrpStackLocation |
|
|
917 | (1) |
|
|
917 | (1) |
|
|
918 | (1) |
|
InGoetNextIrpStackLocation |
|
|
918 | (1) |
|
|
918 | (1) |
|
|
918 | (1) |
|
|
919 | (1) |
|
|
919 | (1) |
|
|
920 | (1) |
|
|
920 | (1) |
|
IoRegisterShutdownNotification |
|
|
920 | (1) |
|
|
921 | (1) |
|
|
921 | (1) |
|
|
921 | (2) |
|
|
923 | (1) |
|
Io_Resource_Requirements_List |
|
|
923 | (1) |
|
|
924 | (1) |
|
|
924 | (1) |
|
IoSetNextIrpStackLocation |
|
|
925 | (1) |
|
|
925 | (1) |
|
IoSkipCurrentIrpStackLocation |
|
|
926 | (1) |
|
|
926 | (5) |
|
|
931 | (1) |
|
|
931 | (1) |
|
|
931 | (1) |
|
|
931 | (1) |
|
|
931 | (1) |
|
|
932 | (1) |
|
IoUnregisterShutdownNotification |
|
|
932 | (1) |
|
|
932 | (1) |
|
|
932 | (1) |
|
|
932 | (2) |
|
|
934 | (1) |
|
|
934 | (1) |
|
KeAcquireSpinLockAtDpcLevel |
|
|
935 | (1) |
|
|
935 | (1) |
|
|
936 | (1) |
|
|
936 | (1) |
|
|
936 | (1) |
|
|
936 | (1) |
|
KeDeregisterBugCheckCallback |
|
|
937 | (1) |
|
|
937 | (1) |
|
|
937 | (1) |
|
KeGetCurrentProcessorNumber |
|
|
938 | (1) |
|
|
938 | (1) |
|
KeInitializeCallbackRecord |
|
|
938 | (1) |
|
|
938 | (1) |
|
|
938 | (1) |
|
|
939 | (1) |
|
|
939 | (1) |
|
|
940 | (1) |
|
|
940 | (1) |
|
|
940 | (1) |
|
|
940 | (1) |
|
|
941 | (1) |
|
|
941 | (1) |
|
|
941 | (1) |
|
|
942 | (1) |
|
|
942 | (1) |
|
KeQueryPerformanceCounter |
|
|
942 | (1) |
|
|
943 | (1) |
|
|
943 | (1) |
|
|
943 | (1) |
|
|
943 | (1) |
|
|
944 | (1) |
|
|
944 | (1) |
|
|
944 | (1) |
|
|
944 | (1) |
|
KeRegisterBugCheckCallback |
|
|
945 | (1) |
|
|
945 | (1) |
|
|
945 | (1) |
|
|
946 | (1) |
|
KeReleaseSpinLockFromDpcLevel |
|
|
946 | (1) |
|
|
947 | (1) |
|
|
947 | (1) |
|
|
947 | (1) |
|
|
947 | (1) |
|
|
948 | (1) |
|
|
948 | (1) |
|
|
948 | (1) |
|
|
948 | (1) |
|
|
949 | (1) |
|
KeStallExecutionProcessor |
|
|
950 | (1) |
|
|
950 | (1) |
|
|
951 | (2) |
|
|
953 | (1) |
|
|
954 | (1) |
|
|
955 | (1) |
|
|
956 | (1) |
|
|
957 | (1) |
|
Key_Value_Basic_Information |
|
|
958 | (1) |
|
Key_Value_Full_Information |
|
|
959 | (2) |
|
Key_Value_Partial_Information |
|
|
961 | (1) |
|
|
962 | (1) |
|
|
962 | (1) |
|
|
963 | (1) |
|
MmAllocateContiguousMemory |
|
|
963 | (1) |
|
MmAllocateNonCachedMemory |
|
|
964 | (1) |
|
|
964 | (1) |
|
|
964 | (1) |
|
|
964 | (1) |
|
|
965 | (1) |
|
|
965 | (1) |
|
|
965 | (1) |
|
|
965 | (1) |
|
|
965 | (1) |
|
|
966 | (1) |
|
|
966 | (1) |
|
|
966 | (1) |
|
|
967 | (1) |
|
|
967 | (1) |
|
|
967 | (1) |
|
|
968 | (1) |
|
|
968 | (1) |
|
|
969 | (1) |
|
MmUnlockPagableImageSection |
|
|
969 | (1) |
|
|
969 | (1) |
|
|
969 | (1) |
|
|
969 | (1) |
|
|
970 | (1) |
|
ObReferenceObjectByHandle |
|
|
970 | (1) |
|
ObReferenceObjectByPointer |
|
|
970 | (1) |
|
|
971 | (2) |
|
|
973 | (1) |
|
|
973 | (1) |
|
|
973 | (1) |
|
|
974 | (1) |
|
|
974 | (1) |
|
|
974 | (1) |
|
|
974 | (1) |
|
|
975 | (1) |
|
|
975 | (1) |
|
|
975 | (1) |
|
|
975 | (1) |
|
|
976 | (1) |
|
Read_Register_Buffer-type |
|
|
976 | (1) |
|
|
976 | (1) |
|
|
977 | (1) |
|
|
977 | (1) |
|
|
977 | (1) |
|
|
977 | (1) |
|
|
977 | (1) |
|
|
978 | (1) |
|
Rtl_Query_Registry_Routine |
|
|
978 | (1) |
|
|
978 | (1) |
|
|
979 | (1) |
|
RtlUnicodeStringToAnsiString |
|
|
980 | (1) |
|
|
980 | (1) |
|
|
980 | (1) |
|
_Urb_Control_Descriptor_Request |
|
|
981 | (1) |
|
|
982 | (1) |
|
UsbBuildGetDescriptorRequest |
|
|
982 | (1) |
|
|
983 | (1) |
|
|
983 | (1) |
|
Write_Register_Buffer_type |
|
|
984 | (1) |
|
|
984 | (1) |
|
|
984 | (1) |
|
|
984 | (7) |
|
|
991 | (1) |
|
|
991 | (1) |
|
|
992 | (1) |
|
|
992 | (1) |
|
|
992 | (1) |
|
|
993 | (1) |
|
|
994 | (1) |
|
|
995 | (1) |
|
|
995 | (1) |
|
|
996 | (1) |
|
|
996 | (2) |
|
|
998 | (1) |
|
|
998 | (1) |
|
|
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) |
|
|
1103 | (2) |
|
|
1105 | (2) |
|
Appendix C BugCheck Codes |
|
|
1107 | (12) |
Index |
|
1119 | |