Programming the Microsoft Windows Driver Model with CDROM


This example-packed book details the Microsoft Win32 Driver Model (WDM) with practical advice and authoritative insights-from the source. A device driver is the code interface that enables a CPU to communicate to peripherals such as keyboards, mice, scanners, monitors, printers, and speakers. WDM provides a common set of input/output (I/O) services and binary-compatible device drivers for both current and future generations of the Windows operating system. By providing standardized driver classes and mini- ...
See more details below
Available through our Marketplace sellers.
Other sellers (Paperback)
  • All (21) from $1.99   
  • New (3) from $61.92   
  • Used (18) from $1.99   
Sort by
Page 1 of 1
Showing All
Note: Marketplace items are not eligible for any coupons and promotions
Seller since 2008

Feedback rating:



New — never opened or used in original packaging.

Like New — packaging may have been opened. A "Like New" item is suitable to give as a gift.

Very Good — may have minor signs of wear on packaging but item works perfectly and has no damage.

Good — item is in good condition but packaging may have signs of shelf wear/aging or torn packaging. All specific defects should be noted in the Comments section associated with each item.

Acceptable — item is in working order but may show signs of wear such as scratches or torn packaging. All specific defects should be noted in the Comments section associated with each item.

Used — An item that has been opened and may show signs of wear. All specific defects should be noted in the Comments section associated with each item.

Refurbished — A used item that has been renewed or updated and verified to be in proper working condition. Not necessarily completed by the original manufacturer.


Ships from: Chicago, IL

Usually ships in 1-2 business days

  • Standard, 48 States
  • Standard (AK, HI)
Seller since 2015

Feedback rating:


Condition: New
Brand new.

Ships from: acton, MA

Usually ships in 1-2 business days

  • Standard, 48 States
  • Standard (AK, HI)
Seller since 2015

Feedback rating:


Condition: New
Brand new.

Ships from: acton, MA

Usually ships in 1-2 business days

  • Standard, 48 States
  • Standard (AK, HI)
Page 1 of 1
Showing All
Sort by
Sending request ...


This example-packed book details the Microsoft Win32 Driver Model (WDM) with practical advice and authoritative insights-from the source. A device driver is the code interface that enables a CPU to communicate to peripherals such as keyboards, mice, scanners, monitors, printers, and speakers. WDM provides a common set of input/output (I/O) services and binary-compatible device drivers for both current and future generations of the Windows operating system. By providing standardized driver classes and mini- drivers, WDM can help create tremendous efficiencies in device development and support. Developed in cooperation with the WDM team at Microsoft, PROGRAMMING THE MICROSOFT WIN32 DRIVER MODEL provides the definitive WDM coverage professional developers and VARs need to fully exploit this technology. NOTE: The Windows 2000 content in the book is being written to Microsoft Windows 2000 Beta 3. END:
Read More Show Less

Product Details

  • ISBN-13: 9780735605886
  • Publisher: Microsoft Press
  • Publication date: 10/1/1999
  • Series: Microsoft Programming Series
  • Edition description: BK&CD ROM
  • Pages: 626
  • Product dimensions: 7.42 (w) x 9.20 (h) x 1.73 (d)

Meet the Author

Walt Oney has 30 years' experience in systems-level programming and has been teaching Windows device driver classes for eight years. He is a contributing editor to Microsoft Systems Journal and a Microsoft MVP, based in Boston, Massachusetts.
Read More Show Less

Read an Excerpt

Chapter 5:The I/O Request Packet

The I/O Request Packet

The operating system uses a data structure known as an I/O request packet, or IRP, to communicate with a kernel-mode device driver. In this chapter, I'll discuss this important data structure and the means by which it's created, sent, processed, and ultimately destroyed. I'll end with a discussion of the relatively complex subject of IRP cancellation. This chapter is rather abstract, I'm afraid, because I haven't yet talked about any of the concepts that surround specific types of IRPs. You might, therefore, want to skim this chapter and refer back to it while you're reading later chapters.

Data Structures

Two data structures are crucial to the handling of I/O requests: the I/O request packet itself and the IO_STACK_LOCATION structure. I'll describe both structures in this section.

Structure of an IRP

Figure 5-1 illustrates the IRP data structure, with opaque fields shaded in the usual convention of this book. A brief description of the important fields follows.

MdlAddress (PMDL) is the address of a memory descriptor list (MDL) describing the user-mode buffer associated with this request. The I/O Manager creates this MDL for IRP_MJ_READ and IRP_MJ_WRITE requests if the topmost device object's flags indicate DO_DIRECT_IO. It creates an MDL for the output buffer used with an IRP_MJ_DEVICE_CONTROL request if the control code indicates METHOD_IN_DIRECT or METHOD_OUT_DIRECT. The MDL itself describes the user-mode virtual buffer and also contains the physical addresses of locked pages containing that buffer. A driver has to do additional work, which can be quite minimal, to actually access the user-mode buffer.

Figure 5-1. I/O request packet data structure. (Image unavailable)

Flags (ULONG) contains flags that a device driver can read but not directly alter. None of these flags are relevant to a Windows Driver Model driver.

AssociatedIrp (union) is a union of three possible pointers. The alternative that a typical WDM driver might want to access is named AssociatedIrp.SystemBuffer. The SystemBuffer pointer holds the address of a data buffer in nonpaged kernel-mode memory. For IRP_MJ_READ and IRP_MJ_WRITE operations, the I/O Manager creates this data buffer if the topmost device object's flags specify DO_BUFFERED_IO. For IRP_MJ_DEVICE_CONTROL operations, the I/O Manager creates this buffer if the I/O control function code indicates that it should. (See Chapter 9, "Specialized Topics.") The I/O Manager copies data sent by user-mode code to the driver into this buffer as part of the process of creating the IRP. Such data includes the data involved in a WriteFile call or the so-called input data for a call to DeviceIoControl. For read requests, the device driver fills this buffer with data; the I/O Manager later copies the buffer back to the user-mode buffer. For control operations that specify METHOD_BUFFERED, the driver places the so-called output data in this buffer, and the I/O Manager copies it to the user-mode output buffer.

IoStatus (IO_STATUS_BLOCK) is a structure containing two fields that drivers set when they ultimately complete a request. IoStatus.Status will receive an NTSTATUS code, while IoStatus.Information is a ULONG_PTR that will receive an information value whose exact content depends on the type of IRP and the completion status. A common use of the Information field is to hold the total number of bytes transferred by an operation like IRP_MJ_READ that transfers data. Certain Plug and Play (PnP) requests use this field as a pointer to a structure that you can think of as the answer to a query.

RequestorMode will equal one of the enumeration constants UserMode or KernelMode, depending on where the original I/O request originated. Drivers sometimes inspect this value to know whether to trust some parameters.

PendingReturned (BOOLEAN) is TRUE if the lowest-level dispatch routine to process this IRP returned STATUS_PENDING. Completion routines reference this field to avoid a potential race condition between completion and dispatch routines.

Cancel (BOOLEAN) is TRUE if IoCancelIrp has been called to cancel this request and FALSE if it hasn't (yet) been called. IRP cancellation is a relatively complex topic that I'll discuss fully later on in this chapter (in "Cancelling I/ORequests").

CancelIrql (KIRQL) is the interrupt request level (IRQL) at which the special cancel spin lock was acquired. You reference this field in a cancel routine when you release the spin lock.

CancelRoutine (PDRIVER_CANCEL) is the address of an IRP cancellation routine in your driver. You use IoSetCancelRoutine to set this field instead of modifying it directly.

UserBuffer (PVOID) contains the user-mode virtual address of the output buffer for an IRP_MJ_DEVICE_CONTROL request for which the control code specifies METHOD_NEITHER. It also holds the user-mode virtual address of the buffer for read and write requests, but a driver should usually specify one of the device flags DO_BUFFERED_IO or DO_DIRECT_IO and should therefore not usually need to access the field for reads or writes. When handling a METHOD_NEITHER control operation, the driver can create its own MDL using this address.

Tail.Overlay is a structure within a union that contains several members potentially useful to a WDM driver. Refer to Figure 5-2 for a map of the Tail union. In the figure, items at the same level as you read left to right are alternatives within a union, while the vertical dimension portrays successive locations within a structure. Tail.Overlay.DeviceQueueEntry (KDEVICE_QUEUE_ENTRY) and Tail.Overlay.DriverContext (PVOID[4]) are alternatives within an unnamed union within Tail.Overlay. The I/O Manager uses DeviceQueueEntry as a linking field within the standard queue of requests for a device. At moments when the IRP is not on some queue that uses this field and when you own the IRP, you can use the four pointers in DriverContext in any way you please. Tail.Overlay.ListEntry (LIST_ENTRY) is available for you to use as a linking field for IRPs on any private queue you choose to implement.

Figure 5-2. Map of the Tail union in an IRP. (Image unavailable)

CurrentLocation (CHAR) and Tail.Overlay.CurrentStackLocation (PIO_STACK_LOCATION) are not documented for use by drivers because support functions like IoGetCurrentIrpStackLocation can be used instead. During debugging, however, it might help you to realize that CurrentLocation is the index of the current I/O stack location and CurrentStackLocation is a pointer to it.

The I/O Stack

Whenever any kernel-mode program creates an IRP, it also creates an associated array of IO_STACK_LOCATION structures: one stack location for each of the drivers that will process the IRP and often one more stack location for the use of the originator of the IRP. (See Figure 5-3.) A stack location contains type codes and parameter information for the IRP as well as the address of a completion routine. Refer to Figure 5-4 for an illustration of the stack structure.

Figure 5-3. Parallelism between driver and I/O stacks. (Image unavailable)

I'll discuss the mechanics of creating IRPs a bit further on in this chapter. It helps to know right now that the StackCount field of a DEVICE_OBJECT indicates how many locations to reserve for an IRP sent to that device's driver.

Figure 5-4. I/O stack location data structure. (Image unavailable)

MajorFunction (UCHAR) is the major function code associated with this IRP. This would be a value like IRP_MJ_READ that corresponds to one of the dispatch function pointers in the MajorFunction table of a driver object. Since this code is in the I/O stack location for a particular driver, it's conceivable that an IRP could start life as an IRP_MJ_READ (for example) and be transformed into something else as it progresses down the stack of drivers. I'll show you examples in Chapter 11, "The Universal Serial Bus," of how a USB driver changes the personality of a read or write request into an internal control operation in order to submit the request to the USB bus driver.

MinorFunction (UCHAR) is a minor function code that further identifies an IRP belonging to a few major function classes. IRP_MJ_PNP requests, for example, are divided into a dozen or so subtypes with minor function codes such as IRP_MN_START_DEVICE, IRP_MN_REMOVE_DEVICE, and so on.

Parameters (union) is a union of substructures, one for each type of request that has specific parameters. The substructures include, for example, Create (for IRP_MJ_CREATE requests), Read (for IRP_MJ_READ requests), and StartDevice (for the IRP_MN_START_DEVICE subtype of IRP_MJ_PNP).

DeviceObject (PDEVICE_OBJECT) is the address of the device object that corresponds to this stack entry. IoCallDriver fills in this field.

FileObject (PFILE_OBJECT) is the address of the kernel file object to which the IRP is directed. Drivers often use the FileObject pointer to correlate IRPs in a queue with a request (in the form of an IRP_MJ_CLEANUP) to cancel all queued IRPs in preparation for closing the file object.

CompletionRoutine (PIO_COMPLETION_ROUTINE) is the address of an I/O completion routine installed by the driver above the one to which this stack location corresponds. You never set this field directly—instead, you call IoSetCompletionRoutine, which knows to reference the stack location below the one that your driver owns. The lowest-level driver in the hierarchy of drivers for a given device never needs a completion routine because it must complete the request. The originator of a request, however, sometimes does need a completion routine but doesn't usually have its own stack location. That's why each level in the hierarchy uses the next lower stack location to hold its own completion routine pointer.

Context (PVOID) is an arbitrary context value that will be passed as an argument to the completion routine. You never set this field directly; it's set automatically from one of the arguments to IoSetCompletionRoutine.

The "Standard Model" for IRP Processing

Particle physics has its "standard model" for the universe, and so does WDM. Figure 5-5 illustrates a typical flow of ownership for an IRP as it progresses through various stages in its life. Not every type of IRP would go through these steps, and some of the steps might be missing or altered depending on the type of device and the type of IRP. Notwithstanding the possible variability, however, the picture provides a useful starting point for discussion.

Figure 5-5. The "standard model" for IRP processing. (Image unavailable)

It's Even More Complicated than You Thought…

The first time you encounter the concepts that make up the standard model for IRP processing, they'll probably seem pretty complicated. Unfortunately, the standard model is also not quite sufficient to handle all the problems that can arise in a regime that includes hot pluggable devices, dynamic resource reconfiguration, and power management. In later chapters, I'll describe another way of queuing and cancelling IRPs that deals with these extra problems. The standard model will seem like a model of clarity when you're done reading about that!

Despite the problems that some devices present, many devices can still employ the standard model (which is, of course, why I'm bothering to explain it here). If your device cannot be removed or reconfigured while the system is running and can reject I/O requests while in a low-power state, you can use the standard model.

Creating an IRP

The IRP begins life when some entity calls an I/O Manager function to create it. In the figure, I used the term I/O Manager to describe this entity, as though there were a single system component responsible for creating IRPs. In reality, no such single actor in the population of operating system routines exists, and it would have been more accurate to just say that something creates the IRP. Your own driver will be creating IRPs from time to time, for example, and you will occupy the initial ownership box for those particular IRPs.

You can use any of four functions to create a new IRP:

  • iobuildasynchronousfsdrequest builds an irp on whose completion you don't plan to wait. this function and the next are appropriate for building only certain types of irp.
  • iobuildsynchronousfsdrequest builds an irp on whose completion you do plan to wait.
  • iobuilddeviceiocontrolrequest builds a synchronous irp_mj_device_control or irp_mj_internal_device_control request.
  • ioallocateirp builds an irp that is not one of the types supported by the preceding three functions.

The Fsd in the first two of these function names stands for file system driver (FSD). Although FSDs are the primary users of the functions, any driver is allowed to call them. The DDK also documents a function named IoMakeAssociatedIrp for building an IRP that's subordinate to some other IRP. WDM drivers should not call this function. Indeed, completion of associated IRPs doesn't work correctly in Microsoft Windows 98 anyway.

Deciding which of these functions to call and determining what additional initialization you need to perform on an IRP is a rather complicated matter. I'll come back to this subject, therefore, at the end of this chapter...

Read More Show Less

Table of Contents

Foreword viii
Acknowledgments ix
Chapter 1 Introduction 1
An Overview of the Operating Systems 1
Windows 2000 Drivers 5
Sample Code 12
Organization of This Book 14
Other Resources 17
Warning 18
Chapter 2 Basic Structure of a WDM Driver 19
Device and Driver Layering 19
The DriverEntry Routine 44
The AddDevice Routine 48
Windows 98 Compatibility Notes 69
Chapter 3 Basic Programming Techniques 71
The Kernel-Mode Programming Environment 71
Error Handling 74
Memory Management 90
String Handling 111
Miscellaneous Programming Techniques 115
Windows 98 Compatibility Notes 129
Chapter 4 Synchronization 131
An Archetypal Synchronization Problem 132
Interrupt Request Level 134
Spin Locks 139
Kernel Dispatcher Objects 141
Other Kernel-Mode Synchronization Primitives 162
Chapter 5 The I/O Request Packet 173
Data Structures 173
The "Standard Model" for IRP Processing 179
Completing I/O Requests 189
Passing Requests Down to Lower Levels 197
Cancelling I/O Requests 200
Managing Your Own IRPs 211
Loose Ends 217
Chapter 6 Plug and Play 221
IRP_MJ_PNP Dispatch Function 223
Starting and Stopping Your Device 225
Managing PnP State Transitions 236
Other Configuration Functionality 260
Windows 98 Compatibility Notes 287
Chapter 7 Reading and Writing Data 289
Configuring Your Device 289
Addressing a Data Buffer 293
Ports and Registers 298
Servicing an Interrupt 303
Direct Memory Access 320
Chapter 8 Power Management 345
The WDM Power Model 346
Managing Power Transitions 353
Additional Power Management Details 387
Windows 98 Compatibility Notes 396
Chapter 9 Specialized Topics 399
Filter Drivers 399
Logging Errors 406
I/O Control Operations 414
System Threads 436
Executive Work Items 442
Watchdog Timers 446
Windows 98 Compatibility Notes 449
Chapter 10 Windows Management Instrumentation 451
WMI Concepts 452
WDM Drivers and WMI 456
User-Mode Applications and WMI 475
Windows 98 Compatibility Notes 485
Chapter 11 The Universal Serial Bus 487
Programming Architecture 489
Working with the Bus Driver 510
Chapter 12 Installing Device Drivers 557
The INF File 558
Defining a Device Class 575
Launching an Application 581
Windows 98 Compatibility Notes 587
Appendix A Coping with Windows 98 Incompatibilities 589
Defining Stubs for Kernel-Mode Routines 589
Determining the Operating System Version 594
Appendix B Using GENERIC.SYS 595
Appendix C Using WDMWIZ.AWX 597
Basic Driver Information 597
DeviceloControl Codes 599
I/O Resources 600
Power Capabilities 601
USB Endpoints 602
WMI Support 603
Parameters for the INF File 604
Now What? 605
Index 607
Read More Show Less

Customer Reviews

Be the first to write a review
( 0 )
Rating Distribution

5 Star


4 Star


3 Star


2 Star


1 Star


Your Rating:

Your Name: Create a Pen Name or

Barnes & Review Rules

Our reader reviews allow you to share your comments on titles you liked, or didn't, with others. By submitting an online review, you are representing to Barnes & that all information contained in your review is original and accurate in all respects, and that the submission of such content by you and the posting of such content by Barnes & does not and will not violate the rights of any third party. Please follow the rules below to help ensure that your review can be posted.

Reviews by Our Customers Under the Age of 13

We highly value and respect everyone's opinion concerning the titles we offer. However, we cannot allow persons under the age of 13 to have accounts at or to post customer reviews. Please see our Terms of Use for more details.

What to exclude from your review:

Please do not write about reviews, commentary, or information posted on the product page. If you see any errors in the information on the product page, please send us an email.

Reviews should not contain any of the following:

  • - HTML tags, profanity, obscenities, vulgarities, or comments that defame anyone
  • - Time-sensitive information such as tour dates, signings, lectures, etc.
  • - Single-word reviews. Other people will read your review to discover why you liked or didn't like the title. Be descriptive.
  • - Comments focusing on the author or that may ruin the ending for others
  • - Phone numbers, addresses, URLs
  • - Pricing and availability information or alternative ordering information
  • - Advertisements or commercial solicitation


  • - By submitting a review, you grant to Barnes & and its sublicensees the royalty-free, perpetual, irrevocable right and license to use the review in accordance with the Barnes & Terms of Use.
  • - Barnes & reserves the right not to post any review -- particularly those that do not follow the terms and conditions of these Rules. Barnes & also reserves the right to remove any review at any time without notice.
  • - See Terms of Use for other conditions and disclaimers.
Search for Products You'd Like to Recommend

Recommend other products that relate to your review. Just search for them below and share!

Create a Pen Name

Your Pen Name is your unique identity on It will appear on the reviews you write and other website activities. Your Pen Name cannot be edited, changed or deleted once submitted.

Your Pen Name can be any combination of alphanumeric characters (plus - and _), and must be at least two characters long.

Continue Anonymously

    If you find inappropriate content, please report it to Barnes & Noble
    Why is this product inappropriate?
    Comments (optional)