Hi all,
I have a mini filter that uses some code to read files from a preCreate callback. I am reading the file in blocks of 512 bytes, but the Information field at my IO_STATUS_BLOCK structure always is set to 1. I have checked the contents of the buffer where data is stored and the system is storing 512 bytes.
The code is like this:
NTSTATUS TestReadFile(IN CONST PFLT_INSTANCE Instance, IN CONST UNICODE_STRING& File, IN OUT PUCHAR Result)
{
IO_STATUS_BLOCK IoStatus;
PFILE_OBJECT FileObject = NULL;
HANDLE hFile = NULL;
NTSTATUS Status = GetFileObject(Instance, File, hFile, IoStatus, &FileObject);
if (!NT_SUCCESS(Status)) return Status;
PUCHAR ReadBuffer = (PUCHAR)FltAllocatePoolAlignedWithTag(Instance, NonPagedPool, 512, ‘TEST’);
if (!ReadBuffer) Status = STATUS_UNSUCCESSFUL;
KEVENT ReadCompletionEvent;
KeInitializeEvent(&ReadCompletionEvent, SynchronizationEvent, FALSE);
LARGE_INTEGER ByteOffset = { 0 };
while (Status == STATUS_SUCCESS)
{
Status = FltReadFile(Instance, FileObject, &ByteOffset, 512, ReadBuffer,
FLTFL_IO_OPERATION_NON_CACHED, NULL, (PFLT_COMPLETED_ASYNC_IO_CALLBACK)ReadCompletionRoutine,
&ReadCompletionEvent);
if (Status == STATUS_PENDING)
{
KeWaitForSingleObject(&ReadCompletionEvent, Executive, KernelMode, FALSE, NULL);
Status = IoStatus.Status;
}
if (Status == STATUS_SUCCESS)
{
ByteOffset.QuadPart += IoStatus.Information;
}
}
if (Status == STATUS_END_OF_FILE)
{
Status = STATUS_SUCCESS;
}
if (ReadBuffer) FltFreePoolAlignedWithTag(Instance, ReadBuffer, ‘TEST’);
if (FileObject) ObDereferenceObject(FileObject);
if (hFile) FltClose(hFile);
return Status;
}
VOID ReadCompletionRoutine(IN PFLT_CALLBACK_DATA CallbackData, IN PFLT_CONTEXT Context)
{
UNREFERENCED_PARAMETER(CallbackData);
if (Context) KeSetEvent((PKEVENT)Context, IO_NO_INCREMENT, FALSE);
}
NTSTATUS GetFileObject(IN CONST PFLT_INSTANCE Instance, IN CONST UNICODE_STRING& File,
IN OUT HANDLE& FileHandle, IN OUT IO_STATUS_BLOCK& IoStatus,
IN OUT PFILE_OBJECT* FileObjectResult)
{
if (!m_Flt) return STATUS_UNSUCCESSFUL;
if (!Instance) return STATUS_UNSUCCESSFUL;
if (!FileObjectResult) return STATUS_UNSUCCESSFUL;
OBJECT_ATTRIBUTES Attr;
InitializeObjectAttributes(&Attr, (PUNICODE_STRING)&File, OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, NULL, NULL);
NTSTATUS Status = FltCreateFile(m_Flt, Instance, &FileHandle, FILE_READ_DATA /*| SYNCHRONIZE*/, &Attr, &IoStatus,
NULL, FILE_ATTRIBUTE_NORMAL, FILE_SHARE_VALID_FLAGS, FILE_OPEN,
FILE_NON_DIRECTORY_FILE | FILE_SEQUENTIAL_ONLY , NULL, 0, 0);
if (NT_SUCCESS(Status))
{
PFILE_OBJECT Result = NULL;
Status = ObReferenceObjectByHandle(FileHandle, FILE_READ_DATA, *IoFileObjectType,
KernelMode, reinterpret_cast(&Result), NULL);
if (NT_SUCCESS(Status)) *FileObjectResult = Result;
}
return Status;
}
Thanks in advance.
Eugenio