6.2.1 When to Check the I/O Stack Location

An NT driver’s Dispatch routine must check its own I/O stack location of the IRP to determine what to do if any of the following conditions hold:

To determine which operation is requested and what parameters to use, if the particular IRP_MJ_XXX  has any, the Dispatch routine calls IoGetCurrentIrpStackLocation to get a pointer to its own I/O stack location in the input IRP.

Higher-level NT drivers’ Dispatch routines always call IoGetCurrentIrpStackLocation and also call IoGetNextIrpStackLocation to get a pointer to the next-lower driver’s I/O stack location in the IRPs that they set up for the next-lower driver, as mentioned in Chapter 4.

The Dispatch(Internal)DeviceControl routine of a device driver, or possibly of its closely coupled class driver(s), must determine which I/O control code is set in the driver’s I/O stack location at Parameters.DeviceIoControl.IoControlCode for each request. Such a driver’s Dispatch(Internal)DeviceControl routine frequently features a switch statement, as described later in Section 6.3.4.

In most cases, the Dispatch(Internal)DeviceControl routine of a higher-level NT driver simply passes an IRP_MJ_DEVICE_CONTROL or IRP_MJ_INTERNAL_DEVICE_CONTROL request on to the next-lower driver, after setting up its stack location in the IRP. However, NT SCSI class drivers must check for certain IOCTL_SCSI_XXX  control codes in order to set up the SCSI port driver’s I/O stack location correctly before they pass on these requests. For more information about these requirements for SCSI class drivers, see Appendix A.