Hi all.
I’m trying to add a header to all *.txt files during the pre create callback for file is a certain directory.
The code looks like this:
addHeaderIfNeeded(PCFLT_RELATED_OBJECTS FltObjects,
PFLT_FILE_NAME_INFORMATION nameInfo){
IO_STATUS_BLOCK IoStatusBlock;
PVOID handleFileObject;
NTSTATUS status;
HANDLE fileHandle;
OBJECT_ATTRIBUTES InitializedAttributes;
PVOID buffer;
ULONG BytesRead, BytesWritten;
LARGE_INTEGER offset;
PVOID pFileBuffer;
offset.QuadPart = 0;
InitializeObjectAttributes(
&InitializedAttributes, &nameInfo->Name,
OBJ_KERNEL_HANDLE |
//OBJ_EXCLUSIVE |
0,
NULL,
NULL );
status = FltCreateFile(
FltObjects->Filter,
FltObjects->Instance,
&fileHandle,
//////////////////////////////////////////////////////////////////////////
//GENERIC_WRITE | GENERIC_READ,
FILE_READ_ACCESS | FILE_WRITE_ACCESS |
0,
&InitializedAttributes,
&IoStatusBlock,
NULL,
FILE_ATTRIBUTE_NORMAL,
0,
FILE_OPEN_IF,
FILE_NON_DIRECTORY_FILE,
NULL,
0,
0
);
if (!NT_SUCCESS(status)) {
DbgPrint(
FUNCTION" : failed create file %wZ, status = %08x\n",
&nameInfo->Name,
status
);
return;
}
status = ObReferenceObjectByHandle(
fileHandle,
0,
NULL,
KernelMode,
&handleFileObject,
NULL);
if(!NT_SUCCESS(status))
{
DbgPrint(
FUNCTION"ObReferenceObjectByHandle: FAILED - %08x\n", status);
goto CloseFile;
}
pFileBuffer = ExAllocatePoolWithTag(NonPagedPool,
65536,
‘test’);
if (NULL == pFileBuffer)
{
DbgPrint(
FUNCTION"ExAllocatePoolWithTag: failed allocating pFileBuffer\n");
goto DereferenceFileObject;
//return;
}
////////////////////////////////write and read////////////////////////////
status = FltReadFile(
FltObjects->Instance,
handleFileObject,
&offset,
MagicHeader.Length,
pFileBuffer,
FLTFL_IO_OPERATION_DO_NOT_UPDATE_BYTE_OFFSET |
FLTFL_IO_OPERATION_NON_CACHED |
0,
&BytesRead ,
NULL,
NULL
);
if (BytesRead >= MagicHeader.Length)
{
UNICODE_STRING readString;
RtlInitUnicodeString(&readString,
(PCWSTR)pFileBuffer);
if (!RtlCompareUnicodeString(&readString, &MagicHeader, FALSE))
{
DbgPrint(
FUNCTION"found existing headerin %wZ\n",
&nameInfo->Name);
goto FreepFileBuffer;
return;
}
}
//we need to add the header now
//RtlInitUnicodeString(&magic, L"this is a magic header");
buffer = FltAllocatePoolAlignedWithTag(
FltObjects->Instance,
NonPagedPoolCacheAligned,
MagicHeader.Length,
‘test’
);
if (NULL == buffer)
{
DbgPrint(
FUNCTION"failed to allocate bytes for header\n");
goto FreepFileBuffer;
}
status = FltReadFile(
FltObjects->Instance,
handleFileObject,
&offset,
65536,
pFileBuffer,
FLTFL_IO_OPERATION_DO_NOT_UPDATE_BYTE_OFFSET |
FLTFL_IO_OPERATION_NON_CACHED |
0,
&BytesRead ,
NULL,
NULL
);
RtlCopyMemory(buffer, MagicHeader.Buffer, MagicHeader.Length);
status = FltWriteFile(
FltObjects->Instance,
handleFileObject,
0,
MagicHeader.Length,
buffer,
FLTFL_IO_OPERATION_DO_NOT_UPDATE_BYTE_OFFSET |
FLTFL_IO_OPERATION_NON_CACHED |
0,
//0,
&BytesWritten,
NULL,
NULL
);
offset.QuadPart += BytesWritten;
if (BytesRead > 0)
{
status = FltWriteFile(
FltObjects->Instance,
handleFileObject,
&offset,
BytesRead,
pFileBuffer,
FLTFL_IO_OPERATION_DO_NOT_UPDATE_BYTE_OFFSET |
FLTFL_IO_OPERATION_NON_CACHED |
0,
//0,
&BytesWritten,
NULL,
NULL
);
}
FltFreePoolAlignedWithTag(
FltObjects->Instance,
buffer,
‘test’
);
FreepFileBuffer:
ExFreePoolWithTag(
pFileBuffer,
‘test’
);
DereferenceFileObject:
ObDereferenceObject(handleFileObject);
CloseFile:
FltClose(fileHandle);
//////////////////////////////////////////////////////////////////////////////////
I try to create a new text file in the directory mentioned above and:
Whenever I try to set the object attributes to OBJ_EXCLUSIVE (so my process will be the only one to open the file) i get 0xc000000d (invalid parameter) from FltCreateFile().
otherwise, all reads/writes succeed but my pre create method is then called again and again for the files
New text document.txt,
New text document (2).txt,
New text document(3).txt,
and so on until
New text document(999).txt.
I noticed that the same symptom doesn’t happen when i comment out the code reading/writing the header…
What’s wrong with what I’m doing?
Ariel.