File System Filter Driver Tutorial | CodeGuru

File System Filter Driver Tutorial

Contents 1.      Introduction 2.      Creating a Simple File System Filter Driver 3.      How to install a driver 4.      Running a Sample 5.      Improvements 6.      Conclusion 7.      Useful references Introduction This tutorial will show you how to develop a simple file system filter driver. The demo driver will print the names of opening files to debug […]

Written By
CodeGuru Staff
CodeGuru Staff
Nov 9, 2009
2 minute read
CodeGuru content and product recommendations are editorially independent. We may make money when you click on links to our partners. Learn More

Contents

1.      Introduction
2.      Creating a Simple File System Filter Driver
3.      How to install a driver
4.      Running a Sample
5.      Improvements
6.      Conclusion
7.      Useful references

Introduction

This tutorial will show you how to develop a simple file system filter driver. The demo driver will print the names of opening files to debug output.

The article requires basic windows driver and C/C++ knowledge. However it may be interesting to the people without windows driver experience.

What is a file system filter driver?

A file system filter driver is called on every file system I/O operation (create, read, write, rename and etc) and thus it can modify a file system behavior. File system filter drivers are almost similar to legacy drivers but they require some special steps to do.  Such drivers are used by anti-viruses, security, backup and snapshot software.

Creating a Simple File System Filter Driver

Before starting

To build a driver you need WDK or IFS Kit. You can get them from the Microsoft’s website. Also you have to set an environment variable %WINDDK% to the path where you have installed WDK/IFS Kit.

Be careful: Even a small error in driver may cause BSOD or system instability.

Advertisement

Main.c

Driver entry

This is an entry point of any driver. The first thing that we do is to store DriverObject to a global variable (we will need it later).

////////////////////////////////////////////////////////////////
// Global data

PDRIVER_OBJECT   g_fsFilterDriverObject = NULL;

///////////////////////////////////////////////////////////////
// DriverEntry - Entry point of the driver

NTSTATUS DriverEntry(
    __inout PDRIVER_OBJECT  DriverObject,
    __in    PUNICODE_STRING RegistryPath
    )
{
    NTSTATUS status = STATUS_SUCCESS;
    ULONG    i      = 0;

    //ASSERT(FALSE); // This will break to debugger

    //
    // Store our driver object.
    //

    g_fsFilterDriverObject = DriverObject;
    ...
}

Set IRP dispatch table

The next step is to populate the IRP dispatch table with function pointers to IRP handlers. In our filter driver there is a generic pass-through IRP handler (which sends request further).  And we will need a handler for IRP_MJ_CREATE to retrieve names of the opening files. Implementation of the IRP handlers will be described later.

//////////////////////////////////////////////////////////////////////////
// DriverEntry - Entry point of the driver

NTSTATUS DriverEntry(
    __inout PDRIVER_OBJECT  DriverObject,
    __in    PUNICODE_STRING RegistryPath
    )
{
    ...
    //
    //  Initialize the driver object dispatch table.
    //

    for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; ++i)
    {
        DriverObject->MajorFunction[i] = FsFilterDispatchPassThrough;
    }

    DriverObject->MajorFunction[IRP_MJ_CREATE] = FsFilterDispatchCreate;
    ...
}

Set Fast-IO dispatch table

A file system filter driver must have the fast-io dispatch table. If you’ve forgot to set up the fast-io dispatch table it will lead system to crash. Fast-io is an alternative way to initiate I/O operation (and it’s faster than IRP). Fast-io operations are always synchronous. If fast-io handler returns FALSE then fast-io way is imposible and IRP will be created.

//////////////////////////////////////////////////////////////////////////
// Global data

FAST_IO_DISPATCH g_fastIoDispatch =
{
    sizeof(FAST_IO_DISPATCH),
    FsFilterFastIoCheckIfPossible,
    ...
};
//////////////////////////////////////////////////////////////////////////
// DriverEntry - Entry point of the driver

NTSTATUS DriverEntry(
    __inout PDRIVER_OBJECT  DriverObject,
    __in    PUNICODE_STRING RegistryPath
    )
{
    ...
    //
    // Set fast-io dispatch table.
    //

    DriverObject->FastIoDispatch = &g_fastIoDispatch;
    ...
}

Register a notification for file system changes

We should track file system being activated/deactivated to perform attaching/detaching of our file system filter driver.  How to start tracking file system changes is shown below.

//////////////////////////////////////////////////////////////////////////
// DriverEntry - Entry point of the driver

NTSTATUS DriverEntry(
    __inout PDRIVER_OBJECT  DriverObject,
    __in    PUNICODE_STRING RegistryPath
    )
{
    ...
    //
    //  Registered callback routine for file system changes.
    //

    status = IoRegisterFsRegistrationChange(DriverObject, FsFilterNotificationCallback);
    if (!NT_SUCCESS(status))
    {
        return status;
    }
    ...
}

Set driver unload routine

Advertisement

The last part of the driver initialization sets an unload routine. Setting the driver unload routine makes the driver unloadable and you can load/unload it multiple times without system restart. However this driver is made unloadable only for debugging purpose because file system filters can’t be unloaded safely. Never do this in production code.

//////////////////////////////////////////////////////////////////////////
// DriverEntry - Entry point of the driver

NTSTATUS DriverEntry(
    __inout PDRIVER_OBJECT  DriverObject,
    __in    PUNICODE_STRING RegistryPath
    )
{
    ...
    //
    // Set driver unload routine (debug purpose only).
    //

    DriverObject->DriverUnload = FsFilterUnload;

    return STATUS_SUCCESS;
}
CodeGuru Logo

CodeGuru covers topics related to Microsoft-related software development, mobile development, database management, and web application programming. In addition to tutorials and how-tos that teach programmers how to code in Microsoft-related languages and frameworks like C# and .Net, we also publish articles on software development tools, the latest in developer news, and advice for project managers. Cloud services such as Microsoft Azure and database options including SQL Server and MSSQL are also frequently covered.

Property of TechnologyAdvice. © 2026 TechnologyAdvice. All Rights Reserved

Advertiser Disclosure: Some of the products that appear on this site are from companies from which TechnologyAdvice receives compensation. This compensation may impact how and where products appear on this site including, for example, the order in which they appear. TechnologyAdvice does not include all companies or all types of products available in the marketplace.