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 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 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 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 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