Hello,
I’m working on a minifilter that suppose to write a log message to a log file for every IRP_MJ_WRITE and IRP_MJ_SET_INFORMATION. My code is based on the minispy sample.
I’m using FltCreateFile to create the log file, and FltWriteFile to write to log records into it.
The requirement is that every IRP_MJ_WRITE & IRP_MJ_SET_INFORMATION request are logged into a file, even in case of unexpected system crash or power down – thus the log info must be update immediately into the log file.
My code is running fine for a while but when a large number of threads are trying to update file the system freeze! I tried adding the FILE_WRITE_THROUGH flag on create - it holds the system running for a bit longer but eventually the problem repeats. Need help – what should I do to make this work?
I’m also wondering if the IRQL requirement for driver initiated I/O (must be PASSIVE_LEVEL) can result in having inaccurate log (in which cases the filter my get IRP with a higher IRQL)?
Thank you.
Here are the relevant parts of the code:
// Create file routine – called from the instance setup callback
NTSTATUS
OpenTraceFile (
__in PCFLT_RELATED_OBJECTS pFltObjects
)
OBJECT_ATTRIBUTES objAttr;
HANDLE handle;
NTSTATUS ntstatus;
IO_STATUS_BLOCK ioStatusBlock;
UNICODE_STRING logFileName;
if(KeGetCurrentIrql() != PASSIVE_LEVEL)
return STATUS_INVALID_DEVICE_STATE;
if (!MiniSpyData.LoggingEnabled) {
RtlInitUnicodeString(&logFileName, L"\??\C:\temp\logdata.log");
InitializeObjectAttributes(
&objAttr,
&logFileName,
OBJ_CASE_INSENSITIVE|OBJ_KERNEL_HANDLE,
NULL,
NULL);
ntstatus = FltCreateFile(
MiniSpyData.Filter,
pFltObjects->Instance,
&handle,
GENERIC_WRITE,
&objAttr,
&ioStatusBlock,
0,
FILE_ATTRIBUTE_NORMAL,
FILE_SHARE_READ,
FILE_OPEN_IF,
FILE_SYNCHRONOUS_IO_NONALERT | FILE_WRITE_THROUGH,
NULL,
0,
0);
if (!NT_SUCCESS(ntstatus)) {
return(ntstatus);
}
// Get file object from the handle
ntstatus = ObReferenceObjectByHandle(
handle, //Handle
0, //DesiredAccess
NULL, //ObjectType
KernelMode, //AccessMode
&MiniSpyData.LogFileHandle, //File Handle
NULL);
if (!NT_SUCCESS(ntstatus)) {
return(ntstatus);
}
MiniSpyData.LoggingEnabled = TRUE;
}
return STATUS_SUCCESS;
}
// This rountine insert the log info into the log file
// It is called from the pre operation callback if
// MajorFunction == IRP_MJ_WRITE or IRP_MJ_SET_INFORMATION
NTSTATUS
InsertToLogFile (
__in PCFLT_RELATED_OBJECTS pFltObjects
)
{
NTSTATUS ntstatus;
ULONG BytesWritten;
if (MiniSpyData.LoggingEnabled) {
if(KeGetCurrentIrql() != PASSIVE_LEVEL) {
return STATUS_INVALID_DEVICE_STATE;
}
ntstatus = FltWriteFile(pFltObjects->Instance,
MiniSpyData.LogFileHandle,
NULL,
strlen(“log info…\r\n”),
“log info…\r\n”,
0,
&BytesWritten,
NULL,
NULL);
if (!NT_SUCCESS(ntstatus)) {
return(ntstatus);
}
}
return STATUS_SUCCESS;
}