What is an IRP?
An IRP
(I/O Request Packet) is a kernel-mode data structure used by the I/O Manager in Windows to represent and track I/O operations such as file reads, writes, device commands, and more.
Every time a user-mode or kernel mode component initiates an I/O request (e.g. ReadFile
, WriteFile
, DeviceIoControl
), the OS creates an IRP and sends it down the driver stack associated with the target device or file system.
IRPs are central to Windows driver communication – especially for filter drivers, which exist to observe, modify, or block IRPs.
Structure of an IRP
An IRP is defined in the kernel by the _IRP
structure (in wdm.h
) and contains:
General Fields are as follows:
Type
,Size
: Used internally by the kernelIoStatus
: Holds the final status and information returned to the callerRequestorMode
: Indicates if the request originated in user or kernel modeUserBuffer
: Pointer to user-mode buffer, if applicable
Stack Locations (IO_STACK_LOCATION
)
An IRP is composed of a stack IO_STACK_LOCATION
structures – one per driver in the device stack.
Each driver accesses its own stack location, retrieved using:
PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(Irp);
Each stack location contains:
- MajorFunction: e.g.,
IRP_MJ_READ
,IRP_MJ_WRITE
,IRP_MJ_DEVICE_CONTROL
- MinorFunction: Context-dependent sub-function
- Parameters: Unions of fields specific to the operation (e.g.,
Read.Length
,Create.SecurityContext
) - FileObject: File handle used for this I/O
- DeviceObject: Target device
IRP Lifecycle: From User to Kernel and Back
Here' s simplified flow of how an IRP is processed:
- User Mode Call
- e.g.,
WriteFile(hFile, buffer, size, …)
- The I/O manager creates an IRP to describe this request.
- e.g.,
- IRP Initialization
- OS sets up IRP header and stack locations for each driver in the stack.
- Passes IRP to the topmost driver in the stack.
- Driver Processing
- Each driver receives the IRP through a dispatch routine like
DispatchRead
,DispatchWrite
, etc. - The driver can:
- Process it
- Modify it
- Pass it down using
IoCallDriver
- Complete it using
IoCompleteRequest
- Each driver receives the IRP through a dispatch routine like
- Completion
- When the IRP is completed, the I/O Manager collects the result and returns it to the caller.
Major IRP Function Codes (IRP_MJ_XXX)
Function Code | Description | Used In |
---|---|---|
IRP_MJ_CREATE | Open file/device | File system, device drivers |
IRP_MJ_READ | Read from file/device | Storage, USB, sensors |
IRP_MJ_WRITE | Write to file/device | Storage, network |
IRP_MJ_CLOSE | Close file handle | File systems, filters |
IRP_MJ_DEVICE_CONTROL | Send custom commands (IOCTLs) | Drivers with control logic |
IRP_MJ_SET_INFORMATION | Rename/delete file | File system filters |
IRP_MJ_CLEANUP | Handle cleanup (flush buffers, etc.) | File systems, filters |
Filter drivers typically intercept:
IRP_MJ_CREATE
: to block/monitor file accessIRP_MJ_WRITE
: to detect data exfiltrationIRP_MJ_DEVICE_CONTROL
: to inspect control commandsIRP_MJ_SET_INFORMATION
: to block renames or deletes
IRP Handling in Filter Drivers
Leave a comment
Your email address will not be published. Required fields are marked *