What Is a File System Filter Driver?
A file system filter driver sits between the I/O Manager and the file system (e.g., NTFS, ReFS) to observe or modify the system activity.
Instead of directly managing file systems, filter drivers attach to the stack to:
- Monitor file operations (audit or log)
- Block certain I/O (e.g., writes to protected files)
- Modify data on-the-fly (e.g., encryption)
Microsoft provides a robust framework called the Filter Manger, allowing developers to write Minifilters rather than complex legacy file system drivers.
Minifilter Architecture Overview
Minifilers work within the Filer Manager (FltMgr) system component. The OS supports stacking multiple Minifilters at different altitudes (priorities).
I/O Flow:
[ User Application ]
↓
[ I/O Manager ]
↓
[ Filter Manager (FltMgr) ]
↓
[ Minifilter A ]
↓
[ Minifilter B ]
↓
[ File System Driver (e.g., NTFS) ]
↓
[ Storage Stack (disk drivers) ]Each I/O request from a user-mode application is packaged into an IRP (I/O Request Packet) and passed down a stack of drivers.
Each driver in the stack can choose to:
- Handle the IRP
- Pass it down unchanged
- Modify it before passing
- Complete it immediately
IRPs and Callback Model
An IRP (I/P Request Packet) is a kernel-allocated structure that represents an I/O operation (e.g., read, write, create, close, etc.).
Filter drivers interact with IRPs via callbacks, which are registered per operation code (e.g., IRP_MJ_CREATE).
In Minifilters:
- We define Pre-Operation and Post-Operation callbacks
- The Filter Manger (FltMgr) calls these before and after the file system processes the IRP
Example IRP operations:
| Operation | Description |
|---|---|
IRP_MJ_CREATE | File open/create |
IRP_MJ_READ | Reading from a file |
IRP_MJ_WRITE | Writing to a file |
IRP_MJ_SET_INFORMATION | File delete, rename |
Each Minifilter registers callback functions for specific IRPs (I/O operations), such as:
IRP_MJ_CREATE→ File openIRP_MJ_WRITE→ File writeIRP_MJ_SET_INFORMATION→ File rename/delete
Filter Manager (FltMgr)
FltMgr.sys is a Microsoft-provided system driver that coordinates Minifilter drivers.
Key responsibilities:
- Registers Minifilters
- Manages load order via altitude
- Routes IRPs to appropriate Minifilter callbacks
- Provides communication APIs (
FltSendMessage,FltCreateCommunicationPort)
Developers do not interact directly with IRPs. Instead, you write PreOperation and PostOperation callbacks, and FltMgr invokes them.
Key Components of a Minifilter
1 DriverEntry
- Initializes the Minifilter
- Calls
FltRegisterFilter - Registers the Minifilter's operations
2 Operation Registration Table
Defines which IRPs your driver will handle and whether it intercepts pre-operation, post-operation, or both.
CONST FLT_OPERATION_REGISTRATION Callbacks[] = {
{ IRP_MJ_CREATE, 0, PreCreate, PostCreate },
{ IRP_MJ_WRITE, 0, PreWrite, NULL },
{ IRP_MJ_OPERATION_END }
};
3 Callback Functions
Each callback receives:
- A
PFLT_CALLBACK_DATAstructure (the IRP info) - A
PCFLT_RELATED_OBJECTScontext (device, volume, file) - A pointer to context data
Sample PreCreate:
FLT_PREOP_CALLBACK_STATUS
PreCreate(PFLT_CALLBACK_DATA Data, PCFLT_RELATED_OBJECTS FltObjects, PVOID *CompletionContext) {
UNREFERENCED_PARAMETER(FltObjects);
PFLT_FILE_NAME_INFORMATION nameInfo;
FltGetFileNameInformation(Data, FLT_FILE_NAME_NORMALIZED, &nameInfo);
if (wcsstr(nameInfo->Name.Buffer, L".exe")) {
return FLT_PREOP_COMPLETE;
}
return FLT_PREOP_SUCCESS_NO_CALLBACK;
}
Installing and Managing Minifilters
INF File Setup
INF files for Minifilters must:
- Register the driver under
Class=ActivityMonitoror similar - Define
Altitude(e.g.,370000for antivirus) - Reference
FltMgr.sysas a dependency
Loading and Testing
Use the following tools:
fltmc load <drivername>– load the Minifilterfltmc instances– view attached filters and altituesfltmc unload <drivername>– safely unload the driver
Ensure Test Signing is enabled for development builds.
Altitude Values
Minifilter drivers are loaded in order of altitude – a numeric value assigned to each driver.
The altitude determines the Minifilter's position in the filter stack.
| Altitude Range | Typical Use |
|---|---|
| 320000–329999 | Antivirus / Anti-malware |
| 360000–369999 | Backup and shadow copy drivers |
| 400000–409999 | Encryption / DRM |
| Custom drivers | Use private altitudes from Microsoft |
Register your driver's altitude with Microsoft to avoid conflicts.
Why Altitude Matters:
- Determines when your driver sees a request
- High filters see IRPs before lower ones
- Filters with the same altitude must cooperate carefully
Useful Commands
fltmc
fltmc load MyFilter
fltmc instances
fltmc unload MyFilterLeave a comment
Your email address will not be published. Required fields are marked *
