IRP

typedef struct _IRP {
    .
    .
    PMDL MdlAddress;
    ULONG Flags;
    union {
        struct _IRP *MasterIrp;
        .
        .
        PVOID SystemBuffer;
    } AssociatedIrp;
    .
    .
    IO_STATUS_BLOCK IoStatus;
    KPROCESSOR_MODE RequestorMode;
    .
    .
    BOOLEAN Cancel;
    KIRQL CancelIrql;
    .
    .
    PDRIVER_CANCEL CancelRoutine;
    PVOID UserBuffer;
    union {
        struct {
        .
        .
        union {
            KDEVICE_QUEUE_ENTRY DeviceQueueEntry;
            struct {
                PVOID DriverContext[4];
            };
        };
        .
        .
        PETHREAD Thread;
        .
        .
        LIST_ENTRY ListEntry;
        .
        .
        } Overlay;
    .
    .
    } Tail;
} IRP, *PIRP;

In addition to the request-specific parameters in each driver’s I/O stack location in an IRP, drivers also can use the following members of the IRP structure for various purposes.

Members

MdlAddress
Points to an MDL describing a user buffer for an IRP_MJ_READ or IRP_MJ_WRITE request if the driver set up its device object(s) for direct I/O. Drivers that handle IRP_MJ_INTERNAL_DEVICE_CONTROL requests also use this field if the I/O control code was defined with METHOD_DIRECT. For more information about IOCTLs, see Part II of this manual.
Flags
File system drivers use this field, which is read-only for all drivers. Network and, possibly, highest-level device drivers also might read this field, which can be set with one or more of the following system-defined masks:

IRP_NOCACHE
IRP_PAGING_IO
IRP_MOUNT_COMPLETION
IRP_SYNCHRONOUS_API
IRP_ASSOCIATED_IRP
IRP_BUFFERED_IO
IRP_DEALLOCATE_BUFFER
IRP_INPUT_OPERATION
IRP_SYNCHRONOUS_PAGING_IO
IRP_CREATE_OPERATION
IRP_READ_OPERATION
IRP_WRITE_OPERATION
IRP_CLOSE_OPERATION
IRP_DEFER_IO_COMPLETION

AssociatedIrp.MasterIrp
Points to the master IRP in an IRP that was created by a highest-level driver’s call to IoMakeAssociatedIrp.
AssociatedIrp.SystemBuffer
Points to a system-space buffer for one of the following: (1) a transfer request to a driver that set up its device object(s) requesting buffered I/O; (2) an IRP_MJ_DEVICE_CONTROL request, (3) an IRP_MJ_INTERNAL_DEVICE_CONTROL request with an I/O control code that was defined with METHOD_BUFFERED. In any case, the underlying device driver usually transfers data to or from this buffer.
IoStatus
Is the I/O status block in which a driver stores status and information before calling IoCompleteRequest.
RequestorMode
Indicates the execution mode of the original requestor of the operation, one of UserMode or KernelMode.
Cancel
If set to TRUE, the IRP either is or should be cancelled.
CancelIrql
Is the IRQL at which a driver is running when IoAcquireCancelSpinLock is called.
CancelRoutine
Is the entry point for a driver-supplied Cancel routine to be called if the IRP is cancelled. NULL indicates that the IRP is not currently cancelable.
UserBuffer
Contains the address of an output buffer if the major function code in the I/O stack location is IRP_MJ_INTERNAL_DEVICE_CONTROL and the I/O control code was defined with METHOD_NEITHER.
Tail.Overlay.DeviceQueueEntry
If IRPs are queued in the device queue associated with the driver’s device object, this field links IRPs in the device queue. These links can be used only while the driver is processing the IRP.
Tail.Overlay.DriverContext
If IRPs are not queued in the device queue associated with the driver’s device object, this field can be used by the driver to store up to four pointers. This field can be used only while the driver owns the IRP.
Tail.Overlay.Thread
Is a pointer to the caller’s thread control block. Higher-level drivers that allocate IRPs for lower-level removable-media drivers must set this field in the IRPs they allocate. Otherwise, the FSD cannot determine which thread to notify if the underlying device driver indicates that the media requires verification.
Tail.Overlay.ListEntry
If a driver manages its own internal queue(s) of IRPs, it uses this field to link one IRP to the next. These links can be used only while the driver is holding the IRP in its queue or is processing the IRP.

Comments

Undocumented members of the IRP are reserved, used only by the I/O Manager or, in some cases, by FSDs.

Each IRP also has one or more I/O stack locations for the driver(s) that process the request. A driver must call IoGetCurrentIrpStackLocation to get a pointer to its own stack location in each IRP. Higher-level drivers must call IoGetNextIrpStackLocation to get a pointer to the next-lower driver’s stack location so the higher-level driver can set it up before calling IoCallDriver with the IRP.

While a higher-level driver might check the value of the Cancel Boolean in an IRP, that driver cannot assume the IRP will be completed with STATUS_CANCELLED by a lower-level driver even if the value is TRUE.

See Also

IoCreateDevice, IoGetCurrentIrpStackLocation, IoGetNextIrpStackLocation, IoSetCancelRoutine, IoSetNextIrpStackLocation, IO_STACK_LOCATION, IO_STATUS_BLOCK