MSDN Documentation

IRP Handling in Windows Kernel

An I/O Request Packet (IRP) is the primary data structure used by the Windows kernel to communicate I/O requests between the I/O manager and driver stacks. Proper handling of IRPs is essential for driver stability, performance, and security.

Key Concepts

Typical IRP Dispatch Routine

NTSTATUS
MyDriverDispatch(
    _In_ PDEVICE_OBJECT DeviceObject,
    _Inout_ PIRP Irp
)
{
    PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation(Irp);
    switch (irpSp->MajorFunction) {
        case IRP_MJ_CREATE:
            // Handle create/open
            break;
        case IRP_MJ_READ:
            // Process read request
            break;
        case IRP_MJ_WRITE:
            // Process write request
            break;
        default:
            // Pass down unhandled IRPs
            IoSkipCurrentIrpStackLocation(Irp);
            return IoCallDriver(DeviceExtension->LowerDeviceObject, Irp);
    }
    // Complete IRP if handled here
    Irp->IoStatus.Status = STATUS_SUCCESS;
    Irp->IoStatus.Information = 0;
    IoCompleteRequest(Irp, IO_NO_INCREMENT);
    return STATUS_SUCCESS;
}

Common Pitfalls

IssueConsequenceFix
Failing to set IoStatus.StatusUndefined behavior, possible system crashAlways assign a valid NTSTATUS before completion
Missing IoCompleteRequestIRP leak, driver hangComplete every IRP you fully handle
Improper reference countingPremature deletion of IRPUse IoMarkIrpPending when necessary

IRP Completion Routines

When a lower driver processes an IRP asynchronously, you can attach a completion routine:

IoCopyCurrentIrpStackLocationToNext(Irp);
IoSetCompletionRoutine(
    Irp,
    MyCompletionRoutine,
    Context,
    TRUE,
    TRUE,
    TRUE);
return IoCallDriver(DeviceExtension->LowerDeviceObject, Irp);

Further Reading