Microsoft

IO Subsystem Architecture

On this page

Introduction

The Windows I/O subsystem provides a uniform interface for user‑mode applications to access a wide range of devices. It abstracts device‑specific details and manages request queuing, cancellation, and completion. This article describes the high‑level architecture of the kernel‑mode I/O stack, focusing on the components that collaborate to process I/O requests.

Core Components

Request Processing Flow

The following diagram illustrates the typical path an IRP follows from creation to completion:

User Mode → I/O Manager → Driver Stack (Filter Drivers → Function Driver → Device Driver) → Device
           ↑                                                            ↓
       Completion Routine ←——————————————— Completion Queue ←———

Key stages:

  1. IRP Creation: The I/O manager allocates an IRP and initializes its fields based on the user request.
  2. Dispatch: The IRP is sent to the topmost driver in the stack; each driver may handle, forward, or complete the request.
  3. IO Completion: Once the lowest driver finishes processing, the IRP is propagated back up, invoking any registered completion routines.
  4. Cleanup: The I/O manager deallocates the IRP and notifies the originating thread.

Synchronization Mechanisms

To protect shared resources, the I/O subsystem uses a combination of:

Performance Considerations

Optimizing I/O performance typically involves:

Sample Code

The snippet below demonstrates how a driver creates and sends a read IRP to a lower driver:

NTSTATUS
MyReadDispatch(
    _In_ PDEVICE_OBJECT DeviceObject,
    _Inout_ PIRP Irp
)
{
    PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation(Irp);
    PDEVICE_OBJECT lowerDev = ((PDEVICE_EXTENSION)DeviceObject->DeviceExtension)->LowerDeviceObject;

    IoCopyCurrentIrpStackLocationToNext(Irp);
    IoSetCompletionRoutine(Irp, MyReadComplete, nullptr, TRUE, TRUE, TRUE);
    return IoCallDriver(lowerDev, Irp);
}

NTSTATUS
MyReadComplete(
    _In_ PDEVICE_OBJECT DeviceObject,
    _In_ PIRP Irp,
    _In_ PVOID Context
)
{
    UNREFERENCED_PARAMETER(DeviceObject);
    UNREFERENCED_PARAMETER(Context);
    // Process data or forward status to user mode
    return STATUS_SUCCESS;
}

For a full driver example, see Sample Driver Code.