Hello Forumers,
I am trying to learn WDM to possibly implement EFS at some point in the future.
I found the scanner sample as part of the WDM the place to start.
I removed certain pieces of code that communicate with the user mode and certain pre and post operations, added a postRead operation.
What I am trying to do is change all ‘a’ to ‘b’ and ‘b’ to ‘c’ on write and on read revert the change.
While running the code, I found the write pre operation is being called twice. (all ‘a’ converted to ‘c’). The read post operation is not doing anything(when i open the file again the changes are not reverted).
The following are the callbacks I have registered, the other callbacks have been removed from the scanner sample
ScannerPostCreate, ScannerPostRead, ScannerPreWrite
I am pasting the code here the other parts are same as the scanner sample.
Can some one please tell me what I am doing wrong? I don’t have two systems that I can use to debug!
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
)
/*++
{
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 (!NT_SUCCESS( Data->IoStatus.Status ) ||
(STATUS_REPARSE == Data->IoStatus.Status)) {
return FLT_POSTOP_FINISHED_PROCESSING;
}
status = FltGetFileNameInformation( Data,
FLT_FILE_NAME_NORMALIZED |
FLT_FILE_NAME_QUERY_DEFAULT,
&nameInfo );
if (!NT_SUCCESS( status )) {
return FLT_POSTOP_FINISHED_PROCESSING;
}
FltParseFileNameInformation( nameInfo );
scanFile = ScannerpCheckExtension( &nameInfo->Extension );
if (!scanFile) {
return FLT_POSTOP_FINISHED_PROCESSING;
}
//do only for read or write
if ((FltObjects->FileObject->WriteAccess)||(FltObjects->FileObject->ReadAccess)) {
status = FltAllocateContext( ScannerData.Filter,
FLT_STREAMHANDLE_CONTEXT,
sizeof(SCANNER_STREAM_HANDLE_CONTEXT),
PagedPool,
&scannerContext );
if (NT_SUCCESS(status)) {
(VOID) FltSetStreamHandleContext( FltObjects->Instance,
FltObjects->FileObject,
FLT_SET_CONTEXT_REPLACE_IF_EXISTS,
scannerContext,
NULL );
FltReleaseContext( scannerContext );
}
}
return returnStatus;
}
FLT_PREOP_CALLBACK_STATUS
ScannerPreWrite (
__inout PFLT_CALLBACK_DATA Data,
__in PCFLT_RELATED_OBJECTS FltObjects,
__deref_out_opt PVOID *CompletionContext
)
{
FLT_PREOP_CALLBACK_STATUS returnStatus = FLT_PREOP_SUCCESS_NO_CALLBACK;
NTSTATUS status;
PSCANNER_NOTIFICATION notification = NULL;
PSCANNER_STREAM_HANDLE_CONTEXT context = NULL;
ULONG replyLength;
BOOLEAN safe = TRUE;
PUCHAR buffer;
ULONG i;
UNREFERENCED_PARAMETER( CompletionContext );
status = FltGetStreamHandleContext( FltObjects->Instance,
FltObjects->FileObject,
&context );
if (!NT_SUCCESS( status )) {
return FLT_PREOP_SUCCESS_NO_CALLBACK;
}
try { //get buffer
if (Data->Iopb->Parameters.Write.Length != 0) {
if (Data->Iopb->Parameters.Write.MdlAddress != NULL) {
buffer = MmGetSystemAddressForMdlSafe( Data->Iopb->Parameters.Write.MdlAddress,
NormalPagePriority );
if (buffer == NULL) {
Data->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
Data->IoStatus.Information = 0;
returnStatus = FLT_PREOP_COMPLETE;
leave;
}
} else {
buffer = Data->Iopb->Parameters.Write.WriteBuffer;
}
//change a to b , b to c
for (i=0;i<(Data->Iopb->Parameters.Write.Length);i++)
{
if (*(buffer+i)==‘a’)
*(buffer+i)=‘b’;
else if (*(buffer+i)==‘b’)
*(buffer+i)=‘c’;
}
}
} finally {
if (context) {
FltReleaseContext( context );
}
}
return returnStatus;
}
FLT_POSTOP_CALLBACK_STATUS
ScannerPostRead (
__inout PFLT_CALLBACK_DATA Data,
__in PCFLT_RELATED_OBJECTS FltObjects,
__in_opt PVOID CompletionContext,
__in FLT_POST_OPERATION_FLAGS Flags
)
{
NTSTATUS status;
PSCANNER_STREAM_HANDLE_CONTEXT context = NULL;
PUCHAR buffer;
FLT_POSTOP_CALLBACK_STATUS returnStatus =FLT_POSTOP_FINISHED_PROCESSING;
ULONG i;
status = FltGetStreamHandleContext( FltObjects->Instance,
FltObjects->FileObject,
&context );
if (!NT_SUCCESS( status )) {
return FLT_POSTOP_FINISHED_PROCESSING;
}
try{
if (Data->IoStatus.Information!=0)
{
if (Data->Iopb->Parameters.Read.MdlAddress != NULL) {
buffer = MmGetSystemAddressForMdlSafe( Data->Iopb->Parameters.Read.MdlAddress,
NormalPagePriority );
if (buffer == NULL) {
Data->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
Data->IoStatus.Information = 0;
returnStatus = FLT_POSTOP_FINISHED_PROCESSING;
leave;
}
} else {
buffer = Data->Iopb->Parameters.Read.ReadBuffer;
}
//revert changes
for (i=0;i<(Data->IoStatus.Information);i++)
{
if (*(buffer+i)==‘b’)
*(buffer+i)=‘a’;
else if (*(buffer+i)==‘c’)
*(buffer+i)=‘b’;
}
}
}//try
finally
{
if (context) {
FltReleaseContext( context );
}
}
return FLT_POSTOP_FINISHED_PROCESSING;
}