Although not the end goal, the best way of describing what I'm doing is tracking file creations like Sysinternals Sysmon does. I copied the nullfilter sample from here and made adjustments. The following code is truncated to show only changes to the sample:
nullfilter.c
// ...
FLT_POSTOP_CALLBACK_STATUS
FLTAPI CheckPathLengthPost(
_Inout_ PFLT_CALLBACK_DATA Data,
_In_ PCFLT_RELATED_OBJECTS FltObjects,
_In_ PVOID CompletionContext,
_In_ FLT_POST_OPERATION_FLAGS Flags
);
// ...
CONST FLT_OPERATION_REGISTRATION callback[] =
{
{
IRP_MJ_CREATE,
0,
CheckPathLengthPre,
CheckPathLengthPost
},
{IRP_MJ_OPERATION_END}
};
CONST FLT_REGISTRATION FilterRegistration = {
sizeof( FLT_REGISTRATION ), // Size
FLT_REGISTRATION_VERSION, // Version
0, // Flags
NULL, // Context
callback, // Operation callbacks
NullUnload, // FilterUnload
NULL, // InstanceSetup
NullQueryTeardown, // InstanceQueryTeardown
NULL, // InstanceTeardownStart
NULL, // InstanceTeardownComplete
NULL, // GenerateFileName
NULL, // GenerateDestinationFileName
NULL // NormalizeNameComponent
};
// ...
FLT_PREOP_CALLBACK_STATUS
FLTAPI CheckPathLengthPre(
_Inout_ PFLT_CALLBACK_DATA Data,
_In_ PCFLT_RELATED_OBJECTS FltObjects,
_Flt_CompletionContext_Outptr_ PVOID* CompletionContext
)
{
UNREFERENCED_PARAMETER(FltObjects);
UNREFERENCED_PARAMETER(CompletionContext);
if (Data->RequestorMode == KernelMode)
return FLT_PREOP_SUCCESS_NO_CALLBACK;
PFLT_FILE_NAME_INFORMATION info = NULL;
NTSTATUS status = FltGetFileNameInformation(Data, FLT_FILE_NAME_OPENED | FLT_FILE_NAME_QUERY_DEFAULT | FLT_FILE_NAME_DO_NOT_CACHE, &info);
if (!(NT_SUCCESS(status))) {
DbgPrint("nullfilter|CheckPathLengthPre: FltGetFileNameInformation failed: %#x", status);
return FLT_PREOP_SUCCESS_NO_CALLBACK;
}
ULONG createDisp = (Data->Iopb->Parameters.Create.Options >> 24) & 0x000000FF;
BOOLEAN isCreation = ((createDisp == FILE_CREATE) ||
(createDisp == FILE_SUPERSEDE) ||
(createDisp == FILE_OVERWRITE) ||
(createDisp == FILE_OVERWRITE_IF) ||
(createDisp == FILE_OPEN_IF));
// File or folder is being created
if ((Data->Iopb->Parameters.Create.Options) & FILE_NON_DIRECTORY_FILE) {
if (isCreation == 1) {
DbgPrint("nullfilter: isFile: %d, isDir: %d, createDisp: <%08x>, Path: %wZ", 1, 0, createDisp, info->Name);
}
}
else if ((Data->Iopb->Parameters.Create.Options) & FILE_DIRECTORY_FILE) {
if (isCreation == 1) {
DbgPrint("nullfilter: isFile: %d, isDir: %d, createDisp: <%08x>, Path: %wZ", 0, 1, createDisp, info->Name);
}
}
return FLT_PREOP_SUCCESS_WITH_CALLBACK;
}
nullfilter.inf
[Version]
Signature = "$Windows NT$"
Class = "Bottom" ;This is determined by the work this filter driver does
ClassGuid = {21D41938-DAA8-4615-86AE-E37344C18BD8} ;This value is determined by the Class
Provider = %ProviderString%
DriverVer = 06/16/2007,1.0.0.0
CatalogFile = nullfilter.cat
; ...
[NullFilter.Service]
DisplayName = %ServiceName%
Description = %ServiceDescription%
ServiceBinary = %12%\%DriverName%.sys ;%windir%\system32\drivers\
Dependencies = "FltMgr"
ServiceType = 2 ;SERVICE_FILE_SYSTEM_DRIVER
StartType = 3 ;SERVICE_DEMAND_START
ErrorControl = 1 ;SERVICE_ERROR_NORMAL
LoadOrderGroup = "FSFilter Bottom"
AddReg = NullFilter.AddRegistry
; ...
[Strings]
; ...
DefaultInstance = "Null Instance"
Instance1.Name = "Null Instance"
Instance1.Altitude = "47777"
Instance1.Flags = 0
This was probably the best question I found in terms of providing source: Minifilter Check new file create on harddisk?
Issue is that it tracks opens and creations. I can't find anything additional to narrow it down. This is the issue with any other discussion I've found on this:
- minifilter driver | tracking changes in files
- https://community.osr.com/discussion/283813/file-creation-and-modification-detection-can-a-mini-filter-get-me-there
- Block file creation
- Block file creation in Windows10
- Minifilter prevent new file created with warning dialog
- Can I catch file CREATION the operation in minifilter driver?
Most of these are discussion with limited code. They all appear to suggest what I've already tried above. Perhaps I'm in the wrong spot, perhaps at this-low level there is no distinction?
Looked at https://learn.microsoft.com/en-us/windows-hardware/drivers/ifs/irp-mj-create (again?) and I think I'm onto something.
nullfilter.c
After thinking about my question, I wondered why again do I believe this "isn't working". DbgView was showing far too much activity, certainly thousands of files aren't being created a second. I determined my create disposition was too wide. For this test, I only care about new files. Additionally, I added a post-create callback as, I believe,
IOStatuswill not be correct in pre-create.Since the change, DbgView has significantly less output. The files listed are cache or journal files, both of which are definitely new files. Opening files is not treated "incorrectly".