Thanks for the pointer, Frank. I looked into the ctx sample and now I get only one scan message.
However, I am having problem unloading the scanner(hang). The code below should release all ref counts for the context.
ScannerPostCreate (
__inout PFLT_CALLBACK_DATA Data,
__in PCFLT_RELATED_OBJECTS FltObjects,
__in_opt PVOID CompletionContext,
__in FLT_POST_OPERATION_FLAGS Flags
)
{
PSCANNER_STREAM_CONTEXT scannerContext;
FLT_POSTOP_CALLBACK_STATUS returnStatus = FLT_POSTOP_FINISHED_PROCESSING;
PFLT_FILE_NAME_INFORMATION Name;
PFLT_FILE_NAME_INFORMATION tunnelName;
PUNICODE_STRING scanName;
int i;
NTSTATUS status;
BOOLEAN safeToOpen=TRUE, Scanned =FALSE, scanFile;
int ref_count=0;
UNREFERENCED_PARAMETER( CompletionContext );
UNREFERENCED_PARAMETER( Flags );
// If this create was failing anyway, don’t bother scanning now.
if (!NT_SUCCESS( Data->IoStatus.Status ) ||
(STATUS_REPARSE == Data->IoStatus.Status)) {
return FLT_POSTOP_FINISHED_PROCESSING;
}
//Get File Name
status = FltGetStreamContext( FltObjects->Instance,
FltObjects->FileObject,
&scannerContext );
if (!(NT_SUCCESS(status)) && (status == STATUS_NOT_FOUND)) //No scannerContext exists
{
DbgPrint( “!!! scanner.sys --PostCreate: Error getting Stream context %d \n”, status );
//Create a stream context
status = FltAllocateContext( ScannerData.Filter,
FLT_STREAM_CONTEXT,
sizeof(SCANNER_STREAM_CONTEXT),
PagedPool,
&scannerContext );
if (! (NT_SUCCESS(status)))
{
DbgPrint( “!!! scanner.sys --PostCreate: Error allocating Stream context %d \n”, status );
FltReleaseFileNameInformation(Name);
if (scannerContext != NULL)
FltReleaseContext(scannerContext);
return returnStatus;
}
DbgPrint( “!!! scanner.sys --PostCreate: Success allocating Stream context %d \n”, status );
RtlZeroMemory(scannerContext, sizeof(SCANNER_STREAM_CONTEXT));
scannerContext->AlreadyScanned = FALSE;
status = FltSetStreamContext( FltObjects->Instance,
FltObjects->FileObject,
FLT_SET_CONTEXT_KEEP_IF_EXISTS,
scannerContext,
NULL );
if (!NT_SUCCESS(status))
{
FltReleaseContext(scannerContext);
FltReleaseFileNameInformation(Name);
if (scannerContext != NULL)
FltReleaseContext(scannerContext);
if (status != STATUS_FLT_CONTEXT_ALREADY_DEFINED)
return status;
}
}
if (scannerContext->AlreadyScanned == FALSE)
{
scanFile = ScannerpCheckExtension( &Name->Extension );
if (!scanFile) {
DbgPrint( “!!! scanner.sys --PostCreate: AlreadyScanned is set to false. Not interested \n” );
// Not an extension we are interested in
FltReleaseFileNameInformation(Name);
if (scannerContext != NULL)
FltReleaseContext(scannerContext);
return FLT_POSTOP_FINISHED_PROCESSING;
}
DbgPrint( “!!! scanner.sys – Calling ScannerpScanFileInUserMode in postcreate !!!\n” );
status = ScannerpScanFileInUserMode( Data,
FltObjects->Instance,
FltObjects->FileObject,
&Name->FinalComponent,
&safeToOpen,
&Scanned);
if (!Scanned)
{
scannerContext->AlreadyScanned=FALSE;
status = FltSetStreamContext( FltObjects->Instance,
FltObjects->FileObject,
FLT_SET_CONTEXT_KEEP_IF_EXISTS,
scannerContext,
NULL );
if (!NT_SUCCESS(status))
{
FltReleaseContext(scannerContext);
FltReleaseFileNameInformation(Name);
if (scannerContext != NULL)
FltReleaseContext(scannerContext);
}
// FltCancelFileOpen( FltObjects->Instance, FltObjects->FileObject );
DbgPrint( “!!! scanner.sys – Not scanned - undoing create \n” );
}
else if ( (!safeToOpen) && Scanned)
{
scannerContext->AlreadyScanned=TRUE;
status = FltSetStreamContext( FltObjects->Instance,
FltObjects->FileObject,
FLT_SET_CONTEXT_KEEP_IF_EXISTS,
scannerContext,
NULL );
if (!NT_SUCCESS(status))
{
FltReleaseContext(scannerContext);
FltReleaseFileNameInformation(Name);
if (scannerContext != NULL)
FltReleaseContext(scannerContext);
}
// Ask the filter manager to undo the create.
DbgPrint( “!!! scanner.sys --virus detected in postcreate !!!\n” );
DbgPrint( “!!! scanner.sys – undoing create \n” );
FltCancelFileOpen( FltObjects->Instance, FltObjects->FileObject );
Data->IoStatus.Status = STATUS_ACCESS_DENIED;
Data->IoStatus.Information = 0;
returnStatus = FLT_POSTOP_FINISHED_PROCESSING;
}
else if (FltObjects->FileObject->WriteAccess)
{
DbgPrint( “!!! scanner.sys – No foul language in the file \n” );
// The create has requested write access, mark to rescan the file.
// Allocate the context.
scannerContext->AlreadyScanned=TRUE;
// scannerContext->RescanRequired = TRUE;
status = FltSetStreamContext( FltObjects->Instance,
FltObjects->FileObject,
FLT_SET_CONTEXT_KEEP_IF_EXISTS,
scannerContext,
NULL );
if (!NT_SUCCESS(status))
{
FltReleaseContext(scannerContext);
FltReleaseFileNameInformation(Name);
if (scannerContext != NULL)
FltReleaseContext(scannerContext);
}
}//if
else
{
scannerContext->AlreadyScanned=TRUE;
status = FltSetStreamContext( FltObjects->Instance,
FltObjects->FileObject,
FLT_SET_CONTEXT_KEEP_IF_EXISTS,
scannerContext,
NULL );
if (!NT_SUCCESS(status))
{
FltReleaseContext(scannerContext);
FltReleaseFileNameInformation(Name);
if (scannerContext != NULL)
FltReleaseContext(scannerContext);
}
}
}//AlreadyScanned
if(scannerContext != NULL)
FltReleaseContext(scannerContext);
FltReleaseFileNameInformation(Name);
return returnStatus;
}