Strange problem in STATUS_REPASS

i have created a function to handle the write requests(IRP_MJ_WRITE)in my
filter driver.

In my function when a text file(e.g a.txt) is modified the first time, i
make a copy in another directory “BUFF”(e.g. c:\BUFF\0 via KFC copy) and
change the current file object(which was originally for 1.txt) with the
file object of the copied file(i.e. the fileobject of c:\BUFF\0).

So that the original file is never modified and all the changes are
redirected(by STATUS_REPARSE in my create routine) to the corresponding
file in the buffer, to achieve this i am maintaining a link list of all
the files which are modified. When the file gets modified again i
STATUS_REPARSE it to the same file in BUFF again.

My routine works just fine in all cases except in one case :

When i open a text file the first time after attaching my driver and i
delete the contents,save,close the file, open the file again , the
contents are unchanged. Why?

But if i add contents to original file ,save , close , open again, it
gives the modified contents correctly. Also if i again delete the contents
of a previously modified text file (the one which is there in the link
list and BUFF), save and open again,it shows the deleted contents(which is
expected).

So what i am trying to make a point here is , why is it that only deletion
of contents on text file the very first time not happening and getting
saved in file.

When i check BUFF for the correspoinding file the file shows the none
deleted contents.

I am also showing the code below:

------------------------XXXXXXXXXXX---------------

//FileName->Length &&
if(Irp->RequestorMode == UserMode) {

int i=0;
DbgPrint(“spywrite:Checking length of FN = %wZ, Length:%d”,
FileName,FileName->Length);
for(i=0; i < FileName->Length/2; i++) {

whetherInBuffer[i] = FileName->Buffer[i];
}

whetherInBuffer[i] = L’\0’;
_wcsupr(whetherInBuffer);

if( wcsstr(whetherInBuffer, L"\LALIT")) {

;
} else {

return SpyPassThrough(DeviceObject, Irp);
}

if(FileName->MaximumLength >= FileName->Length+2)
FileName->Buffer[FileName->Length/2] = L’\0’;

FullFileName.MaximumLength = FileName->MaximumLength +
devExt->DeviceName.MaximumLength + 2;
FullFileName.Buffer = ExAllocatePoolWithTag(NonPagedPool,
FullFileName.MaximumLength,‘2leM’);
RtlCopyUnicodeString(&FullFileName,&devExt->DeviceName);
RtlAppendUnicodeStringToString(&FullFileName, FileName);

// Traverse the whole list to check whether the file is modified.
// If file present then status_reparse it.
if(NULL==ModListHead)
goto JumpLittleMonkey;

do {

if(RtlEqualUnicodeString(&(theModListHead->ModFName),&FullFileName,
TRUE)) {

// the entry available in the linked list, now status_reparse to open
the
// file in the Buffer

if(theModListHead->tag[0] == ‘r’) {
return SpyPassThrough( DeviceObject, Irp );
} else {

// Not from reparse the original content.
// 1. Copy the file in Buffer.(NOT IN THIS CASE)
// 2. Add the file in linked list. (NOT IN THIS CASE)
// 3. Change the file Object. (TO DO)

InitializeObjectAttributes(&objectAttributes,
&(theModListHead->LinkName),OBJ_CASE_INSENSITIVE, NULL, NULL );
status = ZwOpenFile(&ntFileHandle,
FILE_ALL_ACCESS,
&objectAttributes,
&ioStatus,
FILE_SHARE_VALID_FLAGS,
FILE_SYNCHRONOUS_IO_NONALERT
);

if( !NT_SUCCESS( status ) ) {

DbgPrint(“\n2. ERROR :frowning: Opening file”);
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0 ;
IoCompleteRequest (Irp, IO_NO_INCREMENT);
return STATUS_SUCCESS;
} else {
;
}

status = ObReferenceObjectByHandle( ntFileHandle,
FILE_READ_DATA||FILE_WRITE_DATA,
NULL,
KernelMode,
&FileObject,
NULL
);

if( !NT_SUCCESS( status ) )
DbgPrint(“\n4. ERROR :frowning: Creating Reference”);
else {
;
}

Current->FileObject = FileObject;
DbgPrint(“&&&&&&&&& CHANGING THE FILE_OBJECT &&&&&&&&&&&&”);
status = SpyPassThrough( DeviceObject, Irp );
ObDereferenceObject(FileObject);
ZwClose(ntFileHandle);
return status;
}
}
}while((theModListHead=theModListHead->Next) != NULL);

// This case implies that the file is not in the buffer, which means
that
// we have to
// 1. Copy the file in Buffer.(NOT IN THIS CASE)
// 2. Add the file in linked list. (NOT IN THIS CASE)
// 3. Change the file Object. (TO DO)
// 4. Make the tag = ‘n’
//PMODFILES theModListHead = ModListHead;

JumpLittleMonkey:
{
PMODFILES psElement;
WCHAR linkFileName[30];
PFILE_OBJECT OurFileObject;
WCHAR theFileInBuffer[100];
unsigned int i=0;
int len;
theModListHead = ModListHead;

psElement = ExAllocatePool(NonPagedPool, sizeof(MODFILES));
psElement->ModFName.MaximumLength = FullFileName.MaximumLength;
psElement->ModFName.Buffer = ExAllocatePoolWithTag(NonPagedPool,
FullFileName.MaximumLength,‘2leM’);
RtlCopyUnicodeString(&psElement->ModFName,&FullFileName);
psElement->tag[0] =‘n’;
psElement->Next = NULL;

// The file name is a numeral plus the extension
//wchar_t * _itow( int value, wchar_t *string, int radix );
//DbgPrint(“\nThe link Number = %d”,theLinkNo);

_itow(theLinkNo++,linkFileName, 10);

wcscpy(theFileInBuffer,L"\??\e:\EZBuf\");
len = wcslen(theFileInBuffer);

while(i < wcslen(linkFileName)) {

theFileInBuffer[len+i] = linkFileName[i];
i++;
}

theFileInBuffer[len+i] = L’\0’;
DbgPrint(“\nNew theFileInBuffer = %ws”, theFileInBuffer);
RtlInitUnicodeString(&fileNameUnicodeString,theFileInBuffer);

psElement->LinkName.MaximumLength =
fileNameUnicodeString.MaximumLength;
psElement->LinkName.Buffer = ExAllocatePoolWithTag(NonPagedPool,
fileNameUnicodeString.MaximumLength,‘2leM’);
RtlCopyUnicodeString(&psElement->LinkName,&fileNameUnicodeString);

InitializeObjectAttributes(&objectAttributes,
&fileNameUnicodeString,OBJ_CASE_INSENSITIVE, NULL, NULL );
DbgPrint(“231. No Error”);

status = ZwCreateFile ( &ntFileHandle,
DELETE|FILE_GENERIC_WRITE|FILE_GENERIC_READ,
&objectAttributes, &ioStatus,
NULL,
FILE_ATTRIBUTE_NORMAL,
FILE_SHARE_VALID_FLAGS,
FILE_WRITE_THROUGH,
FILE_SYNCHRONOUS_IO_NONALERT|FILE_WRITE_THROUGH,
NULL, 0
);

DbgPrint(“31. No Error”);

if( !NT_SUCCESS( status ) ) {

DbgPrint(“\nFirst Time ERROR :frowning: Creating file at reference”);

status = ZwOpenFile(&ntFileHandle,
FILE_ALL_ACCESS,
&objectAttributes,
&ioStatus,
FILE_SHARE_VALID_FLAGS,FILE_SYNCHRONOUS_IO_NONALERT
);

if(!NT_SUCCESS(status))
DbgPrint(“\n*****2 Problem IN Write Packet************\n”);
}

status = ObReferenceObjectByHandle( ntFileHandle,
FILE_WRITE_DATA,
NULL,
KernelMode,
&OurFileObject,
NULL
);

if( !NT_SUCCESS( status ) )
DbgPrint(“\nSecond Time ERROR :frowning: Creating Reference”);

KfcCopyFile(OurFileObject, FileObject);
Current->FileObject = OurFileObject;

status = SpyPassThrough( DeviceObject, Irp );
ObDereferenceObject(OurFileObject);
ZwClose(ntFileHandle);

DbgPrint(“\nPutting the value onto the List”);
DbgPrint(“\n***********************************************”);
DbgPrint(“\nModified File Name = %wZ”,&psElement->ModFName);
DbgPrint(“\nLink Name is = %wZ”, &psElement->LinkName);
DbgPrint(“\n***********************************************”);

if(NULL == ModListHead) {

ModListHead = psElement;
} else

do {

if(theModListHead->Next == NULL) {

theModListHead->Next = psElement;
break;
}

}while((theModListHead=theModListHead->Next) != NULL);

return status;
}
} else {
;
}
} except ( EXCEPTION_EXECUTE_HANDLER ) {
status = GetExceptionCode();
DbgPrint(“\nSpyWrite Exception Code: 0x%x\n”, status);
}

------------------------XXXXXXXXXXX---------------

reguards,
anurag