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_DATA
structure (the IRP info) - A
PCFLT_RELATED_OBJECTS
context (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=ActivityMonitor
or similar - Define
Altitude
(e.g.,370000
for antivirus) - Reference
FltMgr.sys
as 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 MyFilter
Leave a comment
Your email address will not be published. Required fields are marked *