typedef struct _IO_STACK_LOCATION {
UCHAR MajorFunction;
UCHAR MinorFunction;
UCHAR Flags;
UCHAR Control;
//
// The following Parameters depend on the IRP_MJ_XXX that is set
// in MajorFunction. This declaration shows examples for IRP_MJ_READ,
// IRP_MJ_WRITE, and IRP_MJ_DEVICE_CONTROL or, possibly,
// IRP_MJ_INTERNAL_DEVICE_CONTROL requests, as well as for IRP_MJ_SCSI,
// which is equivalent to IRP_MJ_INTERNAL_DEVICE_CONTROL.
//
union {
.
.
struct {
ULONG Length;
ULONG Key;
LARGE_INTEGER ByteOffset;
} Read;
struct {
ULONG Length;
ULONG Key;
LARGE_INTEGER ByteOffset;
} Write;
.
.
struct {
ULONG OutputBufferLength;
ULONG InputBufferLength;
ULONG IoControlCode; // IOCTL_XXX
PVOID Type3InputBuffer;
} DeviceIoControl;
.
.
struct {
struct _SCSI_REQUEST_BLOCK *Srb;
} Scsi;
.
.
} Parameters;
PDEVICE_OBJECT DeviceObject;
PFILE_OBJECT FileObject;
.
.
} IO_STACK_LOCATION, *PIO_STACK_LOCATION;
Each I/O stack location in a given IRP has some common members and some request-type-specific members. The following summarizes the general structure of every stack location.
Members
MajorFunction
Is the IRP_MJ_XXX telling the driver what I/O operation is requested.
MinorFunction
Is a subfunction code for MajorFunction, which is used almost exclusively by file system drivers. SCSI class drivers also set this member for some requests. For more information about SCSI class drivers, see the Kernel-mode Driver Design Guide and Part II of this manual.
Flags
Is set with request-type-specific values and used almost exclusively by file system drivers. However, removable-media device drivers check whether this member is set with SL_OVERRIDE_VERIFY_VOLUME for read requests to determine whether to continue the read operation even if the device object's Flags is set with DO_VERIFY_VOLUME. Intermediate drivers layered over a removable-media device driver must copy this member into the I/O stack location of the next-lower driver in all incoming IRP_MJ_READ requests.
Control
Drivers can check this member to determine whether it is set with SL_PENDING_RETURNED. Drivers have read-only access to this member.
Parameters.Xxx
Depends on the value of MajorFunction. For more detailed information about which IRP_MJ_XXX different types of drivers must handle, and for the Parameters.Xxx for each IRP_MJ_XXX, see Part II of this manual.
DeviceObject
Is a pointer to the driver-created device object representing the target physical, logical, or virtual device for which this driver is to handle the IRP.
FileObject
Is a pointer to the file object, if any, associated with DeviceObject.
Comments
Every higher-level driver is responsible for setting up the I/O stack location for the next-lower driver in each IRP.
In some cases, a higher-level driver layered over a mass-storage device driver is responsible for splitting up large transfer requests for the underlying device driver. In particular, SCSI class drivers must check the Parameters.Read.Length and Parameters.Write.Length, determine whether the size of the requested transfer exceeds the underlying HBA's transfer capabilities, and, if so, split the Length of the original request into a sequence of partial transfers to satisfy the original IRP.
A higher-level driver's call to IoCallDriver sets up the DeviceObject pointer to the next-lower-level driver's target device object in the I/O stack location of the lower driver. The I/O Manager passes each higher-level driver's IoCompletion routine a pointer to its own DeviceObject when or if the IoCompletion routine is called on completion of the IRP.
If a higher-level driver allocates IRPs to make requests of its own, its IoCompletion routine is passed a NULL DeviceObject pointer if that driver neither allocates a stack location for itself nor sets up the DeviceObject pointer in its own stack location of the newly allocated IRP.
See Also
IoCallDriver, IoGetCurrentIrpStackLocation, IoGetNextIrpStackLocation, IoSetCompletionRoutine, IoSetNextIrpStackLocation, IO_STATUS_BLOCK, IRP