or am I finding too many FltMgr bugs lately?
The attached sample is a ridiculously basic mini-filter which
“achieves” BSODs not only often enough to wonder, but often enough to be
useless ![]()
The sample (has nothing to do with Scanner sample, I only used it as
a skeleton) queries file name during pre-create, file name during
post-create (just for test) and file ID and directory flag during post
create.
I’ve posted some cases where this code crashes in the last few
weeks, here’s another:
Remote Desktop on Srv03, with Local Drives brought to the terminal.
When accessing “local drives” the remote machine bug checks with 0x7E in
RDP drivers.
For this bugcheck, the GetDirectoryFlag is at fault. Even though the
code is so simple, I’ve gone through it a dozen times, and it’s good.
What is the problem with getting the FileStandardInformation during RD
session?
#include <winerror.h>
#include <fltkernel.h>
#include “scanner.h”
PFLT_FILTER gFilter;
const FLT_OPERATION_REGISTRATION Callbacks = {
{ IRP_MJ_CREATE, 0, ScannerPreCreate, ScannerPostCreate},
{ IRP_MJ_FAST_IO_CHECK_IF_POSSIBLE, 0, ScannerPreCreate,
ScannerPostCreate},
{ IRP_MJ_NETWORK_QUERY_OPEN, 0, ScannerPreCreate,
ScannerPostCreate},
{ IRP_MJ_OPERATION_END}
};
const FLT_CONTEXT_REGISTRATION ContextRegistration = {
{ FLT_CONTEXT_END }
};
const FLT_REGISTRATION FilterRegistration = {
sizeof( FLT_REGISTRATION ), // Size
FLT_REGISTRATION_VERSION, // Version
0, // Flags
ContextRegistration, // Context Registration.
Callbacks, // Operation callbacks
ScannerUnload, // FilterUnload
ScannerInstanceSetup, // InstanceSetup
ScannerQueryTeardown, // InstanceQueryTeardown
NULL, // InstanceTeardownStart
NULL, // InstanceTeardownComplete
NULL, // GenerateFileName
NULL, // GenerateDestinationFileName
NULL // NormalizeNameComponent
};
NTSTATUS
DriverEntry (
IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath
)
{
OBJECT_ATTRIBUTES oa;
UNICODE_STRING uniString;
PSECURITY_DESCRIPTOR sd;
NTSTATUS status;
FltRegisterFilter(DriverObject,
&FilterRegistration,
&gFilter );
FltStartFiltering( gFilter );
return STATUS_SUCCESS;
}
NTSTATUS
ScannerUnload (
FLT_FILTER_UNLOAD_FLAGS Flags
)
{
FltUnregisterFilter( gFilter );
return STATUS_SUCCESS;
}
NTSTATUS
ScannerInstanceSetup (
IN PCFLT_RELATED_OBJECTS FltObjects,
IN FLT_INSTANCE_SETUP_FLAGS Flags,
IN DEVICE_TYPE VolumeDeviceType,
IN FLT_FILESYSTEM_TYPE VolumeFilesystemType
)
{
return STATUS_SUCCESS;
}
NTSTATUS
ScannerQueryTeardown (
IN PCFLT_RELATED_OBJECTS FltObjects,
IN FLT_INSTANCE_QUERY_TEARDOWN_FLAGS Flags
)
{
return STATUS_SUCCESS;
}
FLT_PREOP_CALLBACK_STATUS
ScannerPreCreate (
IN OUT PFLT_CALLBACK_DATA Data,
IN PCFLT_RELATED_OBJECTS FltObjects,
OUT PVOID *CompletionContext
)
{
PFLT_FILE_NAME_INFORMATION lpFileNameInfo;
NTSTATUS ntRes;
ntRes = FltGetFileNameInformation(Data,
FLT_FILE_NAME_NORMALIZED |
FLT_FILE_NAME_QUERY_ALWAYS_ALLOW_CACHE_LOOKUP,
&lpFileNameInfo);
if(!NT_SUCCESS(ntRes))
ntRes = FltGetFileNameInformation(Data,
FLT_FILE_NAME_OPENED |
FLT_FILE_NAME_QUERY_ALWAYS_ALLOW_CACHE_LOOKUP,
&lpFileNameInfo);
if(NT_SUCCESS(ntRes))
FltReleaseFileNameInformation(lpFileNameInfo);
return FLT_PREOP_SUCCESS_WITH_CALLBACK;
}
__int64 GetFileID(PFLT_CALLBACK_DATA Data,
PCFLT_RELATED_OBJECTS FltObjects)
{
FILE_INTERNAL_INFORMATION FileData;
NTSTATUS ntRes;
FileData.IndexNumber.QuadPart = 0;
ntRes = FltQueryInformationFile(FltObjects->Instance,
FltObjects->FileObject,
&FileData,
sizeof(FileData),
FileInternalInformation,
NULL);
if(!NT_SUCCESS(ntRes))
{
return 0;
}
return (FileData.IndexNumber.QuadPart & 0x0000FFFFFFFFFFFF);
}
void GetDirectoryFlag(PFLT_CALLBACK_DATA Data,
PCFLT_RELATED_OBJECTS FltObjects)
{
FILE_STANDARD_INFORMATION FileData;
NTSTATUS ntRes;
FileData.Directory = FALSE;
ntRes = FltQueryInformationFile(FltObjects->Instance,
FltObjects->FileObject,
&FileData,
sizeof(FileData),
FileStandardInformation,
NULL);
}
FLT_POSTOP_CALLBACK_STATUS
ScannerPostCreate (
IN OUT PFLT_CALLBACK_DATA Data,
IN PCFLT_RELATED_OBJECTS FltObjects,
IN PVOID CompletionContext,
IN FLT_POST_OPERATION_FLAGS Flags
)
{
FLT_POSTOP_CALLBACK_STATUS returnStatus =
FLT_POSTOP_FINISHED_PROCESSING;
PFLT_FILE_NAME_INFORMATION lpFileNameInfo;
NTSTATUS ntRes;
if (!NT_SUCCESS( Data->IoStatus.Status ) ||
(STATUS_REPARSE == Data->IoStatus.Status)) {
return FLT_POSTOP_FINISHED_PROCESSING;
}
ntRes = FltGetFileNameInformation(Data,
FLT_FILE_NAME_NORMALIZED |
FLT_FILE_NAME_QUERY_ALWAYS_ALLOW_CACHE_LOOKUP,
&lpFileNameInfo);
if(NT_SUCCESS(ntRes))
FltReleaseFileNameInformation(lpFileNameInfo);
GetFileID(Data, FltObjects);
GetDirectoryFlag(Data, FltObjects);
return returnStatus;
}
–
Kind regards, Dejan
http://www.alfasp.com
File system audit, security and encryption kits.</fltkernel.h></winerror.h>