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.