Write file problem

Hello all!

I am writing a minifilter to redirect file access. In a previous post (http://www.osronline.com/showThread.cfm?link=216731) I tried to explain the problem I am facing, but I think this was too confused, so I have isolated the problem as much as I could.

In the following piece of code I am trying to redirect disk writes from file “temp\abc.tst” to “c:\temp\abc.rps”. The result from PostWrite is that Data->IoStatus.Information is 0 (as well as status), so nothing is actually written to the file but it succeeded, which is driving me mad…

This piece of code is made to isolate my problem, I know FltCreateFile should not be called in PreWrite and names might not be valid, but I have checked they are.

FLT_PREOP_CALLBACK_STATUS SwapPreWriteBuffers(__inout PFLT_CALLBACK_DATA Data, __in PCFLT_RELATED_OBJECTS FltObjects, __deref_out_opt PVOID *CompletionContext)
{
FLT_PREOP_CALLBACK_STATUS retValue = FLT_PREOP_SUCCESS_NO_CALLBACK;
NTSTATUS status = 0;
UNICODE_STRING origFileName, destFileName;
PFILE_OBJECT fObj=NULL;
HANDLE hdl=0;
IO_STATUS_BLOCK ioStatus;
OBJECT_ATTRIBUTES fAttributes;
PPRE_2_POST_CONTEXT p2pCtx;

try
{
RtlInitUnicodeString(&destFileName, L"\Device\HarddiskVolume1\temp\abc.rps");
RtlInitUnicodeString(&origFileName, L"temp\abc.tst");

// Check this is a NON_CACHED request
if (!FlagOn(IRP_NOCACHE, Data->Iopb->IrpFlags))
leave;

//Check the filename is “\temp\abc.tst”
if(!UnicodeStringEndWith(&Data->Iopb->TargetFileObject->FileName, &origFileName))
leave;

//Do not to call FltCreateFile at irql > PASSIVE
if(PASSIVE_LEVEL != KeGetCurrentIrql() )
{
ASSERT(FALSE);
leave;
}

//Open the target file
InitializeObjectAttributes(&fAttributes, &destFileName, OBJ_KERNEL_HANDLE, NULL, NULL);
status = FltCreateFile(gFilterHandle, Data->Iopb->TargetInstance, &hdl, GENERIC_READ | GENERIC_WRITE,
&fAttributes, &ioStatus, (PLARGE_INTEGER) NULL, FILE_ATTRIBUTE_NORMAL,
FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN_IF , FILE_COMPLETE_IF_OPLOCKED | FILE_WRITE_THROUGH,
NULL, 0L, IO_IGNORE_SHARE_ACCESS_CHECK);
if(!NT_SUCCESS(status))
{
ASSERT(FALSE);
leave;
}

//Get FO
status = ObReferenceObjectByHandle(hdl, FILE_ALL_ACCESS, NULL, KernelMode, &fObj, NULL);
if(!NT_SUCCESS(status))
{
ASSERT(FALSE);
leave;
}

//Use p2pContext to pass FO and handle to PostWrite and close them there.
p2pCtx = ExAllocateFromNPagedLookasideList( &Pre2PostContextList );
p2pCtx->FObj = fObj;
p2pCtx->Hdl = hdl;
*CompletionContext = p2pCtx;

//Redirect FOs
Data->Iopb->TargetFileObject = fObj;
FltSetCallbackDataDirty(Data);

retValue = FLT_PREOP_SUCCESS_WITH_CALLBACK;
}
finally
{
if(!NT_SUCCESS(status))
{
if(NULL != fObj)
ObDereferenceObject(fObj);
if(0 < hdl)
FltClose(hdl);
}
}

return retValue;
}

FLT_POSTOP_CALLBACK_STATUS SwapPostWriteBuffers(__inout PFLT_CALLBACK_DATA Data,__in PCFLT_RELATED_OBJECTS FltObjects,__in PVOID CompletionContext,__in FLT_POST_OPERATION_FLAGS Flags)
{
PPRE_2_POST_CONTEXT p2pCtx = CompletionContext;

if(NULL != p2pCtx)
{
if(NULL != p2pCtx->FObj)
ObDereferenceObject(p2pCtx->FObj);
if(0 < p2pCtx->Hdl)
FltClose(p2pCtx->Hdl);

ExFreeToNPagedLookasideList( &Pre2PostContextList, p2pCtx );
}
return FLT_POSTOP_FINISHED_PROCESSING;
}

[UnicodeStringEndWith(str1, str2) just checks if str1 ending is equal to str2.]

Any information is very appreciated,
Thank you very much!!,
Santi