Announcing Driver Dispatch Routines

< BACK  NEXT >
[oR]

Before a driver can process I/O requests, it must announce what kinds of operations it supports. This section describes the I/O Manager's dispatching mechanism and explains how to enable receipt of appropriate I/O function codes. It also presents guidelines for deciding which function codes should be supported for different device types.

I/O Request Dispatching Mechanism

Windows 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 requested operation, the MajorFunction table entry points to an entry within the I/O Manager, _IopInvalidDeviceRequest, which returns an error to the original caller. Thus, it is the responsibility of the driver author to provide Dispatch routines for each I/O function code that it supports. Figure 7.1 illustrates this process.

Figure 7.1. Dispatch routine selection.
graphics/07fig01.gif

Enabling Specific Function Codes

To 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 workorder contains the requested code, the common function could dispatch internally as appropriate.

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 open at the time of application termination.

The other function codes that a driver should support depend on the nature of the device it controls. Table 7.1 associates I/O function codes with the Win32 calls that generate them. When writing layered drivers, the higher driver must support a superset of the lower driver(s) since the user request dispatches through the higher driver first.

Table 7.1. IRP Function Codes
IRP MajorFunction Codes
Function Code Description
IRP_MJ_CREATE Request for a handle
CreateFile
IRP_MJ_CLEANUP Cancel pending IRPs on handle close
CloseHandle
IRP_MJ_CLOSE Close the handle
CloseHandle
IRP_MJ_READ Get data from device
ReadFile
IRP_MJ_WRITE Send data to device
WriteFile
IRP_MJ_DEVICE_CONTROL Control operation
DeviceIoControl
IRP_MJ_INTERNAL_DEVICE_CONTROL Control operation available only to kernel-mode clients (no Win32 call)
IRP_MJ_QUERY_INFORMATION Get length of file
GetFileSize
IRP_MJ_SET_INFORMATION Set length of file
SetFileSize
IRP_MJ_FLUSH_BUFFERS Write or discard buffers
FlushFileBuffers
FlushConsoleInputBuffer
PurgeComm
IRP_MJ_SHUTDOWN System shutting down
InitiateSystemShutdown

< BACK  NEXT >


The Windows 2000 Device Driver Book(c) A Guide for Programmers
The Windows 2000 Device Driver Book: A Guide for Programmers (2nd Edition)
ISBN: 0130204315
EAN: 2147483647
Year: 2000
Pages: 156

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net