IoPageRead and IO_STATUS_BLOCK::Information
A Linux ext2/ext3 file system driver for Windows
Brought to you by:
matt_wu
Test:
NTSTATUS DriverEntry(
__in PDRIVER_OBJECT pDriverObject,
__in PUNICODE_STRING pusRegistryPath
)
{
HANDLE hFile;
UNICODE_STRING usFileName;
OBJECT_ATTRIBUTES ObjectAttributes;
IO_STATUS_BLOCK IoStatus;
FILE_STANDARD_INFORMATION FileInfo;
LARGE_INTEGER liFileOffset;
PFILE_OBJECT pFileObject;
PMDL pMdl;
void *pReadBuffer;
NTSTATUS Status;
static const ULONG nBufferLength = 0x10000;
UNREFERENCED_PARAMETER(pDriverObject);
UNREFERENCED_PARAMETER(pusRegistryPath);
RtlInitUnicodeString(&usFileName, L"\\??\\c:\\test.exe");
InitializeObjectAttributes(
&ObjectAttributes,
&usFileName,
OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE,
NULL,
NULL);
Status =
ZwOpenFile(
&hFile,
GENERIC_READ,
&ObjectAttributes,
&IoStatus,
FILE_SHARE_READ | FILE_SHARE_DELETE,
FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT);
if (!NT_SUCCESS(Status))
{
DbgPrint("ZwOpenFile(...)=0x%08x\n", Status);
return Status;
}
Status =
ZwQueryInformationFile(
hFile,
&IoStatus,
&FileInfo,
sizeof(FileInfo),
FileStandardInformation);
if (!NT_SUCCESS(Status))
{
DbgPrint("ZwQueryInformationFile(...)=0x%08x\n", Status);
ZwClose(hFile);
return Status;
}
DbgPrint("AllocationSize=0x%I64x\n", FileInfo.AllocationSize.QuadPart);
DbgPrint("EndOfFile=0x%I64x\n", FileInfo.EndOfFile.QuadPart);
Status =
ObReferenceObjectByHandle(
hFile,
GENERIC_READ,
IoFileObjectType,
KernelMode,
&pFileObject,
NULL);
if (!NT_SUCCESS(Status))
{
DbgPrint("ObReferenceObjectByHandle(...)=0x%08x\n", Status);
ZwClose(hFile);
return Status;
}
pReadBuffer = ExAllocatePoolWithTag(NonPagedPool, nBufferLength, 'tset');
if (!pReadBuffer)
{
DbgPrint("ExAllocatePoolWithTag(...)=NULL\n");
ObDereferenceObject(pFileObject);
ZwClose(hFile);
return Status;
}
pMdl = IoAllocateMdl(pReadBuffer, nBufferLength, FALSE, FALSE, NULL);
if (!pMdl)
{
DbgPrint("IoAllocateMdl(...)=NULL\n");
ExFreePool(pReadBuffer);
ObDereferenceObject(pFileObject);
ZwClose(hFile);
return Status;
}
MmBuildMdlForNonPagedPool(pMdl);
liFileOffset.QuadPart = 0;
for (; ; )
{
KEVENT Event;
KeInitializeEvent(&Event, NotificationEvent, FALSE);
Status = IoPageRead(pFileObject, pMdl, &liFileOffset, &Event, &IoStatus);
if (STATUS_SUCCESS != Status)
break;
DbgPrint("IoStatus.Information=0x%x\n", IoStatus.Information);
if (IoStatus.Information < nBufferLength)
break;
liFileOffset.QuadPart += nBufferLength;
}
IoFreeMdl(pMdl);
ExFreePool(pReadBuffer);
ObDereferenceObject(pFileObject);
ZwClose(hFile);
return STATUS_NOT_IMPLEMENTED;
}
Output for file on ntfs:
AllocationSize=0x65000
EndOfFile=0x64a00
IoStatus.Information=0x10000
IoStatus.Information=0x10000
IoStatus.Information=0x10000
IoStatus.Information=0x10000
IoStatus.Information=0x10000
IoStatus.Information=0x10000
IoStatus.Information=0x4a00
Output for file on ext3:
AllocationSize=0x64c00
EndOfFile=0x64a00
IoStatus.Information=0x10000
IoStatus.Information=0x10000
IoStatus.Information=0x10000
IoStatus.Information=0x10000
IoStatus.Information=0x10000
IoStatus.Information=0x10000
IoStatus.Information=0x4c00
0x10000+0x10000+0x10000+0x10000+0x10000+0x10000+0x4c00 != 0x64a00 (!= EndOfFile)
Ext2Fsd v. 0.53
kd> lm vm Ext2Fsd
start end module name
99d1a000 99dc0080 Ext2Fsd (deferred)
Image path: Ext2Fsd.sys
Image name: Ext2Fsd.sys
Timestamp: Tue Aug 26 07:45:21 2014 (53FC02D1)
CheckSum: 000AA014
ImageSize: 000A6080
Translations: 0000.04b0 0000.04e4 0409.04b0 0409.04e4
Fixed in 0.60. Prevoius versions of Ext2Fsd uses file allocation size for paging i/o. This way of file reading is rarely used.