IRP_MJ_PNP Dispatch Function

IRP_MJ_PNP Dispatch Function

A simplified version of the dispatch function for IRP_MJ_PNP might look like the following:

NTSTATUS DispatchPnp(PDEVICE_OBJECT fdo, PIRP Irp) { 

PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(Irp);

ULONG fcn = stack->MinorFunction;

static NTSTATUS (*fcntab[])(PDEVICE_OBJECT, PIRP) = { HandleStartDevice, // IRP_MN_START_DEVICE HandleQueryRemove, // IRP_MN_QUERY_REMOVE_DEVICE <etc.>, };

if (fcn >= arraysize(fcntab)) return DefaultPnpHandler(fdo, Irp);

return (*fcntab[fcn])(fdo, Irp); } NTSTATUS DefaultPnpHandler(PDEVICE_OBJECT fdo, PIRP Irp) {

IoSkipCurrentIrpStackLocation(Irp); PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension; return IoCallDriver(pdx->LowerDeviceObject, Irp); }

  1. All the parameters for the IRP, including the all-important minor function code, are in the stack location. Hence, we obtain a pointer to the stack location by calling IoGetCurrentIrpStackLocation.

  2. We expect the IRP s minor function code to be one of those listed in Table 6 1.

  3. A method of handling the two dozen possible minor function codes is to write a subdispatch function for each one we re going to handle and then to define a table of pointers to those subdispatch functions. Many of the entries in the table will be DefaultPnpHandler. Subdispatch functions such as HandleStartDevice will take pointers to a device object and an IRP as parameters and will return an NTSTATUS code.

  4. If we get a minor function code we don t recognize, it s probably because Microsoft defined a new one in a release of the DDK after the DDK with which we built our driver. The right thing to do is to pass the minor function code down the stack by calling the default handler. By the way, arraysize is a macro in one of my own header files that returns the number of elements in an array. It s defined as #define arraysize(p) (sizeof(p)/sizeof((p)[0])).

  5. This is the operative statement in the dispatch routine, in which we index the table of subdispatch functions and call the right one.

  6. The DefaultPnpHandler routine is essentially the ForwardAndForget function I showed in connection with IPR-handling scenario 2 in the preceding chapter. We re passing the IRP down without a completion routine and therefore use IoSkipCurrentIrpStackLocation to retard the IRP stack pointer in anticipation that IoCallDriver will immediately advance it.

Using a Function Pointer Table

Using a table of function pointers to dispatch handlers for minor function codes as I m showing you in DispatchPnp entails some slight danger. A future version of the operating system might change the meaning of some of the codes. That s not a practical worry except during the beta test phase of a system, though, because a later change would invalidate an unknown number of existing drivers. I like using a table of pointers to subdispatch functions because having separate functions for the minor function codes seems like the right engineering solution to me. If I were designing a C++ class library, for instance, I d define a base class that used virtual functions for each of the minor function codes.

Most programmers would probably place a switch statement in their DispatchPnp routine. You can simply recompile your driver to conform to any reassignment of minor function codes. Recompilation will also highlight by producing compilation errors! name changes that might signal functionality shifts. That happened a time or two during the Microsoft Windows 98 and Windows 2000 betas, in fact. Furthermore, an optimizing compiler should be able to use a jump table to produce slightly faster code for a switch statement than for calls to subdispatch functions.

I think the choice between a switch statement and a table of function pointers is mostly a matter of taste, with readability and modularity winning over efficiency in my own evaluation. You can avoid uncertainty during a beta test by placing appropriate assertions in your code. For example, the HandleStartDevice function can assert that stack->MinorFunction == IRP_MN_START_DEVICE. If you recompile your driver with each new beta DDK, you ll catch any number reassignments or name changes.



Programming the Microsoft Windows Driver Model
Programming the Microsoft Windows Driver Model
ISBN: 0735618038
EAN: 2147483647
Year: 2003
Pages: 119
Authors: Walter Oney

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