[oR]
SummaryThis completes the implementation of an initial Windows 2000 device driver. Granted, this Minimal driver is kernel-mode only. Converting it to a WDM driver must wait until chapter 9. Nevertheless, tools to build and install a driver are now ready to go. Additionally, the beginning structure of the kernel-mode device driver is forming. The next chapter discusses the Dispatch routines necessary to make the driver useful. Read, Write, and I/O Control functions are implemented. Coding shown in the next chapter builds upon the minimal driver built in this chapter.
|
[oR]
Chapter 7. Driver Dispatch RoutinesCHAPTER OBJECTIVES
Getting a driver to load is the first step, but ultimately the job of a driver is to respond to I/O requests -from
|
[oR]
Announcing Driver Dispatch Routines
Before a driver can process I/O
I/O Request Dispatching MechanismWindows 2000 I/O operations are packet-driven. When an I/O request is initiated, the I/O Manager first builds an IRP work-order to keep track of the request. Among other things, it stores a function code in the MajorField field of the IRP's I/O stack location to uniquely identify the type of request.
The
MajorField
code is used by the I/O Manager to index the Driver object's
MajorFunction
table. The table contains a function pointer to a Dispatch routine specific to the I/O request. If a driver does not support the
Figure 7.1. Dispatch routine selection.
Enabling Specific Function CodesTo enable specific I/O function codes, a driver must first "announce" the Dispatch routine that responds to such a request. The announcement mechanism is simply the work performed by DriverEntry that stores the Dispatch routine function address into the appropriate slot of the MajorFunction table of the driver object. The I/O function code is the index used for the table. The following code fragment illustrates the process of announcement.
NTSTATUS DriverEntry( IN PDRIVER_OBJECT pDO,
IN PUNICODE_STRING pRegPath ) {
:
pDO->MajorFunction[ IRP_MJ_CREATE ] = DispCreate;
pDO->MajorFunction[ IRP_MJ_CLOSE ] = DispClose;
pDO->MajorFunction[ IRP_MJ_CLEANUP ] = DispCleanup;
pDO->MajorFunction[ IRP_MJ_READ ]= DispRead;
pDO->MajorFunction[ IRP_MJ_WRITE ] = DispWrite;
:
return STATUS_SUCCESS;
}
Notice that each I/O function code (table index) is identified by a unique symbol of the form IRP_MJ_XXX, defined by the NTDDK.h (and WDM.h) include file. Of course, these symbolic constants should always be used in lieu of hard-coded constants.
The announcement technique also allows for a single routine to be used to handle multiple request types. DriverEntry would place the common Dispatch routine address in multiple table slots. Since the IRP
Finally, it should be noted that function codes drivers do not support should be left untouched by DriverEntry. The I/O Manager fills the entire MajorFunction table of the Driver object with pointers to _IopInvalidDeviceRequest before calling DriverEntry. Deciding Which Function Codes to Support
All drivers must support the function code IRP_MJ_CREATE since this code is generated in response to the Win32
CreateFile
call. Without support for this code, Win32 applications would have no way to obtain a handle to the device. Similarly, the IRP_MJ_CLOSE must also be supported to handle the Win32
CloseHandle
call. Incidentally, the CloseHandle call is made automatically by the system for all handles left
The other function codes that a driver should support depend on the nature of the device it controls. Table 7.1
Table 7.1. IRP Function Codes
|