And this is my code: in WinDbg
FILTER VERIFIER WARNING: A filter has set a completion context for a callback data which will be
lost. Probable cause of this is that no post-operation callback was requested
or routine was registered for this operation or the request was being pended
or completed.
BUT WORKS WELL!
FLT_PREOP_CALLBACK_STATUS
ScannerPreCreate(
_Inout_ PFLT_CALLBACK_DATA Data,
_In_ PCFLT_RELATED_OBJECTS FltObjects,
_Flt_CompletionContext_Outptr_ PVOID* CompletionContext
)
{
UNREFERENCED_PARAMETER(FltObjects);
UNREFERENCED_PARAMETER(CompletionContext = NULL);
if (IoThreadToProcess(Data->Thread) == ScannerData.UserProcess) {
return FLT_PREOP_SUCCESS_NO_CALLBACK;
}
return FLT_PREOP_SUCCESS_WITH_CALLBACK;
}
FLT_POSTOP_CALLBACK_STATUS ScannerPostOpCreate(PFLT_CALLBACK_DATA Data,
PCFLT_RELATED_OBJECTS FltObjects,
PVOID CompletionContext,
FLT_POST_OPERATION_FLAGS Flags)
{
PFLT_FILE_NAME_INFORMATION FileNameInfo = NULL;
POBJECT_NAME_INFORMATION name = NULL;
NTSTATUS status;
PSCANNER_NOTIFICATION notification = NULL;
ULONG replyLen = 0;
UNICODE_STRING extension = RTL_CONSTANT_STRING(L"exe");
PSCANNER_CONTEXT scannerContext = NULL;
if (!NT_SUCCESS(Data->IoStatus.Status) ||
(STATUS_REPARSE == Data->IoStatus.Status)) {
return FLT_POSTOP_FINISHED_PROCESSING;
}
if (ScannerData.ClientPort == NULL)
{
return FLT_POSTOP_FINISHED_PROCESSING;
}
status = FltGetFileNameInformation(Data, FLT_FILE_NAME_NORMALIZED | FLT_FILE_NAME_QUERY_DEFAULT, &FileNameInfo);
if (!NT_SUCCESS(status))
{
return FLT_POSTOP_FINISHED_PROCESSING;
}
status = FltParseFileNameInformation(FileNameInfo);
if (!NT_SUCCESS(status))
{
FltReleaseFileNameInformation(FileNameInfo);
return FLT_POSTOP_FINISHED_PROCESSING;
}
if (FileNameInfo->Extension.Length == 0)
{
FltReleaseFileNameInformation(FileNameInfo);
return FLT_POSTOP_FINISHED_PROCESSING;
}
if (RtlCompareUnicodeString(&extension, &FileNameInfo->Extension, TRUE) != 0)
{
FltReleaseFileNameInformation(FileNameInfo);
return FLT_POSTOP_FINISHED_PROCESSING;
}
FltReleaseFileNameInformation(FileNameInfo);
if (FltObjects->FileObject->WriteAccess)
{
status = IoQueryFileDosDeviceName(FltObjects->FileObject, &name);
if (NT_SUCCESS(status))
{
status = FltAllocateContext(ScannerData.Filter,
FLT_STREAMHANDLE_CONTEXT,
sizeof(SCANNER_CONTEXT),
NonPagedPool,
&scannerContext);
if (NT_SUCCESS(status))
{
RtlCopyMemory(scannerContext->Path, name->Name.Buffer, name->Name.MaximumLength);
scannerContext->Len = name->Name.MaximumLength;
scannerContext->Rescan = FALSE;
status = FltSetStreamHandleContext(FltObjects->Instance,
FltObjects->FileObject,
FLT_SET_CONTEXT_REPLACE_IF_EXISTS,
scannerContext,
NULL);
if (!NT_SUCCESS(status))
{
DbgPrint("Error set setram context");
FltReleaseContext(scannerContext);
ExFreePool(name);
return FLT_POSTOP_FINISHED_PROCESSING;
}
DbgPrint("Context yaradildi\n");
FltReleaseContext(scannerContext);
}
else {
DbgPrint("Cant allocate memory\n");
}
ExFreePool(name);
}
}
return FLT_POSTOP_FINISHED_PROCESSING;
}
FLT_PREOP_CALLBACK_STATUS
ScannerPreWrite(
_Inout_ PFLT_CALLBACK_DATA Data,
_In_ PCFLT_RELATED_OBJECTS FltObjects,
_Flt_CompletionContext_Outptr_ PVOID* CompletionContext
)
{
NTSTATUS status;
PSCANNER_CONTEXT scannerContext = NULL;
/*POBJECT_NAME_INFORMATION name = NULL;*/
status = FltGetStreamHandleContext(FltObjects->Instance, FltObjects->FileObject, &scannerContext);
if (NT_SUCCESS(status))
{
if (scannerContext->Rescan == FALSE)
{
scannerContext->Rescan = TRUE;
FltSetStreamHandleContext(FltObjects->Instance, FltObjects->FileObject, FLT_SET_CONTEXT_REPLACE_IF_EXISTS, scannerContext, NULL);
FltReleaseContext(scannerContext);
return FLT_PREOP_SUCCESS_WITH_CALLBACK;
}
FltReleaseContext(scannerContext);
}
return FLT_PREOP_SUCCESS_NO_CALLBACK;
}
FLT_PREOP_CALLBACK_STATUS
ScannerPreCleanup(
_Inout_ PFLT_CALLBACK_DATA Data,
_In_ PCFLT_RELATED_OBJECTS FltObjects,
_Flt_CompletionContext_Outptr_ PVOID* CompletionContext
)
{
NTSTATUS status;
PSCANNER_CONTEXT scannerContext = NULL;
status = FltGetStreamHandleContext(FltObjects->Instance, FltObjects->FileObject, &scannerContext);
if (!NT_SUCCESS(status))
{
return FLT_PREOP_SUCCESS_NO_CALLBACK;
}
FltReleaseContext(scannerContext);
return FLT_PREOP_SYNCHRONIZE;
}
FLT_POSTOP_CALLBACK_STATUS ScannerPostCleanup(PFLT_CALLBACK_DATA Data,
PCFLT_RELATED_OBJECTS FltObjects,
PVOID CompletionContext,
FLT_POST_OPERATION_FLAGS Flags)
{
NTSTATUS status;
PSCANNER_CONTEXT scannerContext = NULL;
PSCANNER_NOTIFICATION notification = NULL;
ULONG replyLen = 0;
if (ScannerData.ClientPort == NULL)
{
return FLT_POSTOP_FINISHED_PROCESSING;
}
status = FltGetStreamHandleContext(FltObjects->Instance, FltObjects->FileObject, &scannerContext);
if (NT_SUCCESS(status))
{
if (scannerContext->Rescan == TRUE)
{
notification = ExAllocatePoolWithTag(NonPagedPool, sizeof(SCANNER_NOTIFICATION), 'LFC');
if (notification == NULL)
{
FltReleaseContext(scannerContext);
return FLT_POSTOP_FINISHED_PROCESSING;;
}
replyLen = sizeof(SCANNER_REPLY);
RtlCopyMemory(notification->PathName, scannerContext->Path, scannerContext->Len);
status = FltSendMessage(ScannerData.Filter,
&ScannerData.ClientPort,
notification,
sizeof(SCANNER_NOTIFICATION),
notification,
&replyLen,
NULL
);
if (!NT_SUCCESS(status))
{
DbgPrint("Error FltSendMessage\n");
}
ExFreePoolWithTag(notification, 'LFC');
}
scannerContext->Rescan = FALSE;
FltSetStreamHandleContext(FltObjects->Instance, FltObjects->FileObject, FLT_SET_CONTEXT_REPLACE_IF_EXISTS, scannerContext, NULL);
FltReleaseContext(scannerContext);
}
return FLT_POSTOP_FINISHED_PROCESSING;
}
FLT_PREOP_CALLBACK_STATUS ScannerPreSetInformation(
PFLT_CALLBACK_DATA Data,
PCFLT_RELATED_OBJECTS FltObjects,
PVOID CompletionContext
)
{
NTSTATUS status = FLT_PREOP_SUCCESS_NO_CALLBACK;
PFILE_RENAME_INFORMATION renameInfo = NULL;
PFLT_FILE_NAME_INFORMATION FileNameInfo = NULL;
PSCANNER_CONTEXT scannerContext = NULL;
PSCANNER_NOTIFICATION notification = NULL;
ULONG replyLen = 0;
UNICODE_STRING extension = RTL_CONSTANT_STRING(L"exe");
if (FltObjects->FileObject == NULL)
{
return status;
}
if (Data->Iopb->Parameters.SetFileInformation.FileInformationClass == FileRenameInformation ||
Data->Iopb->Parameters.SetFileInformation.FileInformationClass == FileRenameInformationEx)
{
renameInfo = Data->Iopb->Parameters.SetFileInformation.InfoBuffer;
status = FltGetDestinationFileNameInformation(FltObjects->Instance,
FltObjects->FileObject,
renameInfo->RootDirectory,
renameInfo->FileName,
renameInfo->FileNameLength,
FLT_FILE_NAME_NORMALIZED | FLT_FILE_NAME_QUERY_DEFAULT,
&FileNameInfo);
if (NT_SUCCESS(status))
{
FltParseFileNameInformation(FileNameInfo);
if (FileNameInfo->Extension.Length == 0)
{
FltReleaseFileNameInformation(FileNameInfo);
return FLT_PREOP_SUCCESS_NO_CALLBACK;
}
if (RtlCompareUnicodeString(&extension, &FileNameInfo->Extension, TRUE) != 0)
{
FltReleaseFileNameInformation(FileNameInfo);
return FLT_PREOP_SUCCESS_NO_CALLBACK;
}
/*DbgPrint("%wZ\n", FileNameInfo->Name);*/
notification = ExAllocatePoolWithTag(NonPagedPool, sizeof(SCANNER_NOTIFICATION), 'LFC');
if (notification == NULL)
{
FltReleaseFileNameInformation(FileNameInfo);
return FLT_PREOP_SUCCESS_NO_CALLBACK;
}
replyLen = sizeof(SCANNER_REPLY);
RtlCopyMemory(notification->PathName, FileNameInfo->Name.Buffer, FileNameInfo->Name.MaximumLength);
status = FltSendMessage(ScannerData.Filter,
&ScannerData.ClientPort,
notification,
sizeof(SCANNER_NOTIFICATION),
notification,
&replyLen,
NULL
);
if (!NT_SUCCESS(status))
{
DbgPrint("Error FltSendMessage\n");
}
ExFreePoolWithTag(notification, 'LFC');
FltReleaseFileNameInformation(FileNameInfo);
}
}
return FLT_PREOP_SUCCESS_NO_CALLBACK;
}