Microsoft Docs

Overview

The Windows kernel provides a comprehensive file system interface that allows drivers and system components to interact with storage devices and file objects. This documentation covers the key structures, functions, and best practices for working with the Windows file system within kernel-mode drivers.

  • File objects (FILE_OBJECT)
  • Device objects (DEVICE_OBJECT)
  • IRP handling for read/write operations
  • Cache manager integration
  • Security and access control

Key Structures

NameDefinitionDescription
FILE_OBJECT
typedef struct _FILE_OBJECT {
    CSHORT Type;
    CSHORT Size;
    PDEVICE_OBJECT DeviceObject;
    PVOID FsContext;
    PVOID FsContext2;
    // ... many more members
} FILE_OBJECT, *PFILE_OBJECT;
Represents an open instance of a file or device.
DEVICE_OBJECT
typedef struct _DEVICE_OBJECT {
    CSHORT Type;
    CSHORT Size;
    LONG ReferenceCount;
    struct _DRIVER_OBJECT *DriverObject;
    // ... many more members
} DEVICE_OBJECT, *PDEVICE_OBJECT;
Describes a device supplied by a driver.
IRP
typedef struct _IRP {
    CSHORT Type;
    USHORT Size;
    PMDL MdlAddress;
    // ... many more members
} IRP, *PIRP;
Represents an I/O request packet.

Core Functions

Creating a File Object

NTSTATUS IoCreateFile(
    PHANDLE            FileHandle,
    ACCESS_MASK       DesiredAccess,
    POBJECT_ATTRIBUTES ObjectAttributes,
    PIO_STATUS_BLOCK  IoStatusBlock,
    PLARGE_INTEGER    AllocationSize,
    ULONG             FileAttributes,
    ULONG             ShareAccess,
    ULONG             CreateDisposition,
    ULONG             CreateOptions,
    PVOID             EaBuffer,
    ULONG             EaLength
);

Creates or opens a file and returns a handle that can be used by kernel-mode components.

Reading from a File

NTSTATUS ZwReadFile(
    HANDLE            FileHandle,
    HANDLE            Event,
    PIO_APC_ROUTINE   ApcRoutine,
    PVOID             ApcContext,
    PIO_STATUS_BLOCK  IoStatusBlock,
    PVOID             Buffer,
    ULONG             Length,
    PLARGE_INTEGER    ByteOffset,
    PULONG            Key
);

Reads data from an opened file.

Writing to a File

NTSTATUS ZwWriteFile(
    HANDLE            FileHandle,
    HANDLE            Event,
    PIO_APC_ROUTINE   ApcRoutine,
    PVOID             ApcContext,
    PIO_STATUS_BLOCK  IoStatusBlock,
    PVOID             Buffer,
    ULONG             Length,
    PLARGE_INTEGER    ByteOffset,
    PULONG            Key
);

Writes data to an opened file.

Example: Simple Kernel Driver Reading a File

#include <ntddk.h>

VOID DriverUnload(PDRIVER_OBJECT DriverObject) {
    UNREFERENCED_PARAMETER(DriverObject);
    DbgPrint("FileSysDemo: Unloaded\n");
}

NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath) {
    UNREFERENCED_PARAMETER(RegistryPath);
    DriverObject->DriverUnload = DriverUnload;
    DbgPrint("FileSysDemo: Loaded\n");

    UNICODE_STRING fileName;
    RtlInitUnicodeString(&fileName, L"\\??\\C:\\Temp\\sample.txt");

    OBJECT_ATTRIBUTES objAttr;
    InitializeObjectAttributes(&objAttr, &fileName, OBJ_KERNEL_HANDLE, NULL, NULL);

    HANDLE fileHandle;
    IO_STATUS_BLOCK ioStatus;
    NTSTATUS status = IoCreateFile(
        &fileHandle,
        GENERIC_READ,
        &objAttr,
        &ioStatus,
        NULL,
        FILE_ATTRIBUTE_NORMAL,
        FILE_SHARE_READ,
        FILE_OPEN,
        FILE_SYNCHRONOUS_IO_NONALERT,
        NULL,
        0
    );

    if (NT_SUCCESS(status)) {
        CHAR buffer[256];
        RtlZeroMemory(buffer, sizeof(buffer));
        status = ZwReadFile(
            fileHandle,
            NULL,
            NULL,
            NULL,
            &ioStatus,
            buffer,
            sizeof(buffer)-1,
            NULL,
            NULL
        );
        if (NT_SUCCESS(status)) {
            DbgPrint("File content: %s\\n", buffer);
        } else {
            DbgPrint("Read failed: 0x%08X\\n", status);
        }
        ZwClose(fileHandle);
    } else {
        DbgPrint("CreateFile failed: 0x%08X\\n", status);
    }

    return STATUS_SUCCESS;
}

This driver opens C:\\Temp\\sample.txt, reads its content, and prints it to the debugger.