I’ve checked the Microsoft examples, such as Scanner, it implements cancel the IRP at the post CREATE:
FLT_POSTOP_CALLBACK_STATUS
ScannerPostCreate (
__inout PFLT_CALLBACK_DATA Data,
__in PCFLT_RELATED_OBJECTS FltObjects,
__in_opt PVOID CompletionContext,
__in FLT_POST_OPERATION_FLAGS Flags
)
/*++
Routine Description:
Post create callback. We can’t scan the file until after the create has
gone to the filesystem, since otherwise the filesystem wouldn’t be ready
to read the file for us.
Arguments:
Data - The structure which describes the operation parameters.
FltObject - The structure which describes the objects affected by this
operation.
CompletionContext - The operation context passed fron the pre-create
callback.
Flags - Flags to say why we are getting this post-operation callback.
Return Value:
FLT_POSTOP_FINISHED_PROCESSING - ok to open the file or we wish to deny
access to this file, hence undo the open
–*/
{
PSCANNER_STREAM_HANDLE_CONTEXT scannerContext;
FLT_POSTOP_CALLBACK_STATUS returnStatus = FLT_POSTOP_FINISHED_PROCESSING;
PFLT_FILE_NAME_INFORMATION nameInfo;
NTSTATUS status;
BOOLEAN safeToOpen, scanFile;
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;
}
//
// Check if we are interested in this file.
//
status = FltGetFileNameInformation( Data,
FLT_FILE_NAME_NORMALIZED |
FLT_FILE_NAME_QUERY_DEFAULT,
&nameInfo );
if (!NT_SUCCESS( status )) {
return FLT_POSTOP_FINISHED_PROCESSING;
}
FltParseFileNameInformation( nameInfo );
//
// Check if the extension matches the list of extensions we are interested in
//
scanFile = ScannerpCheckExtension( &nameInfo->Extension );
//
// Release file name info, we’re done with it
//
FltReleaseFileNameInformation( nameInfo );
if (!scanFile) {
//
// Not an extension we are interested in
//
return FLT_POSTOP_FINISHED_PROCESSING;
}
status = ScannerpScanFileInUserMode( FltObjects->Instance,
FltObjects->FileObject,
&safeToOpen );
if (!safeToOpen) {
//
// Ask the filter manager to undo the create.
//
DbgPrint( “!!! scanner.sys – foul language 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) {
//
//
// The create has requested write access, mark to rescan the file.
// Allocate the context.
//
status = FltAllocateContext( ScannerData.Filter,
FLT_STREAMHANDLE_CONTEXT,
sizeof(SCANNER_STREAM_HANDLE_CONTEXT),
PagedPool,
&scannerContext );
if (NT_SUCCESS(status)) {
//
// Set the handle context.
//
scannerContext->RescanRequired = TRUE;
status = FltSetStreamHandleContext( FltObjects->Instance,
FltObjects->FileObject,
FLT_SET_CONTEXT_REPLACE_IF_EXISTS,
scannerContext,
NULL );
//
// The only error status that could be returned would tell us that
// contexts are not supported. Even if we got this error,
// we just want to release the context now and that will free
// this memory if it was not successfully set.
//
//
// Release our reference on the context (the set adds a reference)
//
FltReleaseContext( scannerContext );
}
}
return returnStatus;
}
I have to get the file name at post CREATE, check the file name to do appropriate operations. At the pre CREATE, I’m not sure to get exactly file name.
Do you have any idea if I move the code to check file name at pre CREATE?
–Thanks