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 *


