67#define TAG_EXT_BLOCK_LIST 'LtxE'
68#define TAG_EXT_FILE 'FtxE'
69#define TAG_EXT_BUFFER 'BtxE'
70#define TAG_EXT_SUPER_BLOCK 'StxE'
71#define TAG_EXT_GROUP_DESC 'GtxE'
72#define TAG_EXT_VOLUME 'VtxE'
76 TRACE(
"Ext2OpenVolume() DeviceId = %d\n",
Volume->DeviceId);
125 TRACE(
"File is a symbolic link\n");
138 TRACE(
"Symbolic link path = %s\n", SymLinkPath);
141 if (SymLinkPath[0] ==
'/' || SymLinkPath[0] ==
'\\')
146 strcpy(FullPath, &SymLinkPath[1]);
158 if (FullPath[
Index] ==
'/' || FullPath[
Index] ==
'\\')
163 FullPath[
Index] =
'\0';
167 strcat(FullPath, SymLinkPath);
170 TRACE(
"Full file path = %s\n", FullPath);
208 ULONG NumberOfPathParts;
210 PVOID DirectoryBuffer;
227 for (
i=0;
i<NumberOfPathParts;
i++)
261 DirectoryInode = DirectoryEntry.
inode;
308 TRACE(
"Ext2SearchDirectoryBufferForFile() DirectoryBuffer = 0x%x DirectorySize = %d FileName = %s\n", DirectoryBuffer, DirectorySize,
FileName);
310 for (CurrentOffset=0; CurrentOffset<DirectorySize; )
314 if (CurrentDirectoryEntry->
direntlen == 0)
319 if ((CurrentDirectoryEntry->
direntlen + CurrentOffset) > DirectorySize)
321 FileSystemError(
"Directory entry extends past end of directory file.");
325 TRACE(
"Dumping directory entry at offset %d:\n", CurrentOffset);
333 TRACE(
"EXT2 Directory Entry:\n");
339 for (CurrentOffset=0; CurrentOffset<DirectoryEntry->
namelen; CurrentOffset++)
341 TRACE(
"%c", DirectoryEntry->
name[CurrentOffset]);
348 CurrentOffset += CurrentDirectoryEntry->
direntlen;
363 ULONG BlockNumberIndex;
366 ULONG NumberOfBlocks;
368 TRACE(
"Ext2ReadFileBig() BytesToRead = %d Buffer = 0x%x\n", (
ULONG)BytesToRead,
Buffer);
383 FileSystemError(
"Block pointer list is NULL and file is not a fast symbolic link.");
411 TRACE(
"Reading fast symbolic link data\n");
465 LengthInBlock = (
ULONG)((BytesToRead > (
Volume->BlockSizeInBytes - OffsetInBlock)) ? (
Volume->BlockSizeInBytes - OffsetInBlock) : BytesToRead);
478 BytesToRead -= LengthInBlock;
491 NumberOfBlocks = (
ULONG)(BytesToRead /
Volume->BlockSizeInBytes);
493 while (NumberOfBlocks > 0)
509 BytesToRead -=
Volume->BlockSizeInBytes;
556 TRACE(
"Ext2ReadVolumeSectors() Failed to seek\n");
564 TRACE(
"Ext2ReadVolumeSectors() Failed to read\n");
579 TRACE(
"Ext2ReadSuperBlock()\n");
583 if (SuperBlock !=
NULL)
591 if (SuperBlock ==
NULL)
594 if (SuperBlock ==
NULL)
600 Volume->SuperBlock = SuperBlock;
614 TRACE(
"Dumping super block:\n");
646 TRACE(
"unique_id = { 0x%x, 0x%x, 0x%x, 0x%x }\n",
667 FileSystemError(
"FreeLoader does not understand the revision of this EXT2/EXT3 filesystem.\nPlease update FreeLoader.");
681 FileSystemError(
"FreeLoader does not understand features of this EXT2/EXT3 filesystem.\nPlease update FreeLoader.");
692 TRACE(
"Ext2BlockSizeInBytes: %d\n",
Volume->BlockSizeInBytes);
693 TRACE(
"Ext2BlockSizeInSectors: %d\n",
Volume->BlockSizeInSectors);
705 TRACE(
"Ext2FragmentSizeInBytes: %d\n",
Volume->FragmentSizeInBytes);
706 TRACE(
"Ext2FragmentSizeInSectors: %d\n",
Volume->FragmentSizeInSectors);
709 if (
Volume->BlockSizeInBytes !=
Volume->FragmentSizeInBytes)
717 TRACE(
"Ext2InodesPerBlock: %d\n",
Volume->InodesPerBlock);
721 TRACE(
"Ext2GroupDescPerBlock: %d\n",
Volume->GroupDescPerBlock);
728 ULONG GroupDescBlockCount;
730 PUCHAR CurrentGroupDescBlock;
732 TRACE(
"Ext2ReadGroupDescriptors()\n");
751 CurrentGroupDescBlock = (
PUCHAR)
Volume->GroupDescriptors;
752 BlockNumber =
Volume->SuperBlock->first_data_block + 1;
754 while (GroupDescBlockCount--)
762 CurrentGroupDescBlock +=
Volume->BlockSizeInBytes;
772 TRACE(
"Ext2ReadDirectory() Inode = %d\n", Inode);
808 if (*DirectoryBuffer ==
NULL)
819 *DirectoryBuffer =
NULL;
830 CHAR ErrorString[80];
832 TRACE(
"Ext2ReadBlock() BlockNumber = %d Buffer = 0x%x\n", BlockNumber,
Buffer);
835 if (BlockNumber >
Volume->SuperBlock->total_blocks)
837 sprintf(ErrorString,
"Error reading block %d - block out of range.", (
int) BlockNumber);
843 if (BlockNumber == 0)
845 TRACE(
"Block is part of a sparse file. Zeroing input buffer.\n");
894 return ((Inode - 1) /
Volume->SuperBlock->inodes_per_group);
899 return (((Inode - 1) %
Volume->SuperBlock->inodes_per_group) /
Volume->InodesPerBlock);
904 return (((Inode - 1) %
Volume->SuperBlock->inodes_per_group) %
Volume->InodesPerBlock);
909 ULONG InodeGroupNumber;
910 ULONG InodeBlockNumber;
911 ULONG InodeOffsetInBlock;
912 CHAR ErrorString[80];
915 TRACE(
"Ext2ReadInode() Inode = %d\n", Inode);
918 if ((Inode < 1) || (Inode >
Volume->SuperBlock->total_inodes))
920 sprintf(ErrorString,
"Error reading inode %ld - inode out of range.", Inode);
929 TRACE(
"InodeGroupNumber = %d\n", InodeGroupNumber);
930 TRACE(
"InodeBlockNumber = %d\n", InodeBlockNumber);
931 TRACE(
"InodeOffsetInBlock = %d\n", InodeOffsetInBlock);
941 TRACE(
"InodeBlockNumber (after group desc correction) = %d\n", InodeBlockNumber);
953 TRACE(
"Dumping inode information:\n");
954 TRACE(
"mode = 0x%x\n", InodeBuffer->
mode);
955 TRACE(
"uid = %d\n", InodeBuffer->
uid);
961 TRACE(
"gid = %d\n", InodeBuffer->
gid);
965 TRACE(
"osd1 = 0x%x\n", InodeBuffer->
osd1);
966 TRACE(
"dir_blocks = { %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u }\n",
967 InodeBuffer->
blocks.dir_blocks[0], InodeBuffer->
blocks.dir_blocks[1], InodeBuffer->
blocks.dir_blocks[ 2], InodeBuffer->
blocks.dir_blocks[ 3],
968 InodeBuffer->
blocks.dir_blocks[4], InodeBuffer->
blocks.dir_blocks[5], InodeBuffer->
blocks.dir_blocks[ 6], InodeBuffer->
blocks.dir_blocks[ 7],
969 InodeBuffer->
blocks.dir_blocks[8], InodeBuffer->
blocks.dir_blocks[9], InodeBuffer->
blocks.dir_blocks[10], InodeBuffer->
blocks.dir_blocks[11]);
970 TRACE(
"indir_block = %u\n", InodeBuffer->
blocks.indir_block);
971 TRACE(
"double_indir_block = %u\n", InodeBuffer->
blocks.double_indir_block);
972 TRACE(
"tripple_indir_block = %u\n", InodeBuffer->
blocks.tripple_indir_block);
974 TRACE(
"acl = %d\n", InodeBuffer->
acl);
977 TRACE(
"osd2 = { %d, %d, %d }\n",
978 InodeBuffer->
osd2[0], InodeBuffer->
osd2[1], InodeBuffer->
osd2[2]);
985 TRACE(
"Ext2ReadGroupDescriptor()\n");
997 TRACE(
"Dumping group descriptor:\n");
1013 ULONG CurrentBlockInList;
1016 TRACE(
"Ext2ReadBlockPointerList()\n");
1030 if (BlockList ==
NULL)
1038 for (CurrentBlockInList = CurrentBlock = 0;
1040 CurrentBlock++, CurrentBlockInList++)
1042 BlockList[CurrentBlockInList] = Inode->
blocks.dir_blocks[CurrentBlock];
1046 if (CurrentBlockInList < BlockCount)
1056 if (CurrentBlockInList < BlockCount)
1066 if (CurrentBlockInList < BlockCount)
1094 ULONG BlockPointersPerBlock;
1096 TRACE(
"Ext2CopyIndirectBlockPointers() BlockCount = %d\n", BlockCount);
1098 BlockPointersPerBlock =
Volume->BlockSizeInBytes /
sizeof(
ULONG);
1111 for (CurrentBlock=0; (*CurrentBlockInList)<BlockCount && CurrentBlock<BlockPointersPerBlock; CurrentBlock++)
1113 BlockList[(*CurrentBlockInList)] = BlockBuffer[CurrentBlock];
1114 (*CurrentBlockInList)++;
1126 ULONG BlockPointersPerBlock;
1128 TRACE(
"Ext2CopyDoubleIndirectBlockPointers() BlockCount = %d\n", BlockCount);
1130 BlockPointersPerBlock =
Volume->BlockSizeInBytes /
sizeof(
ULONG);
1133 if (BlockBuffer ==
NULL)
1144 for (CurrentBlock=0; (*CurrentBlockInList)<BlockCount && CurrentBlock<BlockPointersPerBlock; CurrentBlock++)
1161 ULONG BlockPointersPerBlock;
1163 TRACE(
"Ext2CopyTripleIndirectBlockPointers() BlockCount = %d\n", BlockCount);
1165 BlockPointersPerBlock =
Volume->BlockSizeInBytes /
sizeof(
ULONG);
1168 if (BlockBuffer ==
NULL)
1179 for (CurrentBlock=0; (*CurrentBlockInList)<BlockCount && CurrentBlock<BlockPointersPerBlock; CurrentBlock++)
1207 TRACE(
"Ext2GetFileInformation(%lu) -> FileSize = %llu, FilePointer = 0x%llx\n",
1227 TRACE(
"Ext2Open() FileName = %s\n",
Path);
1303 TRACE(
"Enter Ext2Mount(%lu)\n", DeviceId);
1333 Volume->DeviceId = DeviceId;
1346 TRACE(
"Ext2Mount(%lu) success\n", DeviceId);
PRTL_UNICODE_STRING_BUFFER Path
char * strcat(char *DstString, const char *SrcString)
ACPI_SIZE strlen(const char *String)
char * strcpy(char *DstString, const char *SrcString)
BOOLEAN CacheReadDiskSectors(UCHAR DiskNumber, ULONGLONG StartSector, ULONG SectorCount, PVOID Buffer)
BOOLEAN CacheInitializeDrive(UCHAR DriveNumber)
#define DbgDumpBuffer(mask, buf, len)
#define DPRINT_FILESYSTEM
#define DBG_DEFAULT_CHANNEL(ch)
#define FAST_SYMLINK_MAX_NAME_SIZE
#define EXT2_INODE_SIZE(sb)
#define EXT2_DESC_PER_BLOCK(s)
struct ext2_dirent * PEXT2_DIR_ENTRY
struct ext2_block_group * PEXT2_GROUP_DESC
struct ext2_sblock * PEXT2_SUPER_BLOCK
#define EXT3_FEATURE_INCOMPAT_SUPP
#define EXT2_DYNAMIC_REVISION
ARC_STATUS ArcSeek(ULONG FileId, LARGE_INTEGER *Position, SEEKMODE SeekMode)
ULONG FsGetNumPathParts(PCSTR Path)
VOID FileSystemError(PCSTR ErrorString)
ULONG FsGetDeviceId(ULONG FileId)
VOID * FsGetDeviceSpecific(ULONG FileId)
ARC_STATUS ArcRead(ULONG FileId, VOID *Buffer, ULONG N, ULONG *Count)
VOID FsSetDeviceSpecific(ULONG FileId, VOID *Specific)
VOID FsGetFirstNameFromPath(PCHAR Buffer, PCSTR Path)
FORCEINLINE PVOID FrLdrTempAlloc(_In_ SIZE_T Size, _In_ ULONG Tag)
FORCEINLINE VOID FrLdrTempFree(PVOID Allocation, ULONG Tag)
BOOLEAN Ext2ReadSuperBlock(PEXT2_VOLUME_INFO Volume)
BOOLEAN Ext2ReadDirectory(PEXT2_VOLUME_INFO Volume, ULONG Inode, PVOID *DirectoryBuffer, PEXT2_INODE InodePointer)
BOOLEAN Ext2CopyDoubleIndirectBlockPointers(PEXT2_VOLUME_INFO Volume, ULONG *BlockList, ULONG *CurrentBlockInList, ULONG BlockCount, ULONG DoubleIndirectBlock)
ULONGLONG Ext2GetInodeFileSize(PEXT2_INODE Inode)
BOOLEAN Ext2ReadVolumeSectors(PEXT2_VOLUME_INFO Volume, ULONGLONG SectorNumber, ULONG SectorCount, PVOID Buffer)
PEXT2_VOLUME_INFO Ext2Volumes[MAX_FDS]
BOOLEAN Ext2OpenVolume(PEXT2_VOLUME_INFO Volume)
#define TAG_EXT_BLOCK_LIST
struct _EXT2_VOLUME_INFO EXT2_VOLUME_INFO
ARC_STATUS Ext2Open(CHAR *Path, OPENMODE OpenMode, ULONG *FileId)
ARC_STATUS Ext2Seek(ULONG FileId, LARGE_INTEGER *Position, SEEKMODE SeekMode)
ULONG Ext2GetInodeGroupNumber(PEXT2_VOLUME_INFO Volume, ULONG Inode)
ULONG * Ext2ReadBlockPointerList(PEXT2_VOLUME_INFO Volume, PEXT2_INODE Inode)
BOOLEAN Ext2CopyIndirectBlockPointers(PEXT2_VOLUME_INFO Volume, ULONG *BlockList, ULONG *CurrentBlockInList, ULONG BlockCount, ULONG IndirectBlock)
ARC_STATUS Ext2Close(ULONG FileId)
BOOLEAN Ext2ReadFileBig(PEXT2_FILE_INFO Ext2FileInfo, ULONGLONG BytesToRead, ULONGLONG *BytesRead, PVOID Buffer)
BOOLEAN Ext2ReadBlock(PEXT2_VOLUME_INFO Volume, ULONG BlockNumber, PVOID Buffer)
ARC_STATUS Ext2Read(ULONG FileId, VOID *Buffer, ULONG N, ULONG *Count)
ULONG Ext2GetInodeOffsetInBlock(PEXT2_VOLUME_INFO Volume, ULONG Inode)
ULONG Ext2GetInodeBlockNumber(PEXT2_VOLUME_INFO Volume, ULONG Inode)
BOOLEAN Ext2ReadGroupDescriptors(PEXT2_VOLUME_INFO Volume)
const DEVVTBL Ext2FuncTable
ARC_STATUS Ext2GetFileInformation(ULONG FileId, FILEINFORMATION *Information)
BOOLEAN Ext2ReadPartialBlock(PEXT2_VOLUME_INFO Volume, ULONG BlockNumber, ULONG StartingOffset, ULONG Length, PVOID Buffer)
BOOLEAN Ext2ReadInode(PEXT2_VOLUME_INFO Volume, ULONG Inode, PEXT2_INODE InodeBuffer)
BOOLEAN Ext2ReadGroupDescriptor(PEXT2_VOLUME_INFO Volume, ULONG Group, PEXT2_GROUP_DESC GroupBuffer)
PEXT2_FILE_INFO Ext2OpenFile(PEXT2_VOLUME_INFO Volume, PCSTR FileName)
BOOLEAN Ext2CopyTripleIndirectBlockPointers(PEXT2_VOLUME_INFO Volume, ULONG *BlockList, ULONG *CurrentBlockInList, ULONG BlockCount, ULONG TripleIndirectBlock)
BOOLEAN Ext2SearchDirectoryBufferForFile(PVOID DirectoryBuffer, ULONG DirectorySize, PCHAR FileName, PEXT2_DIR_ENTRY DirectoryEntry)
BOOLEAN Ext2LookupFile(PEXT2_VOLUME_INFO Volume, PCSTR FileName, PEXT2_FILE_INFO Ext2FileInfo)
#define TAG_EXT_GROUP_DESC
#define TAG_EXT_SUPER_BLOCK
const DEVVTBL * Ext2Mount(ULONG DeviceId)
while(CdLookupNextInitialFileDirent(IrpContext, Fcb, FileContext))
_In_ PFCB _In_ LONGLONG StartingOffset
#define _strnicmp(_String1, _String2, _MaxCount)
#define ROUND_UP(n, align)
_Must_inspect_result_ _In_opt_ PFLT_INSTANCE _Out_ PHANDLE FileHandle
_Must_inspect_result_ _Out_ PLARGE_INTEGER FileSize
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
#define sprintf(buf, format,...)
_In_ ULONG _In_ ULONG _In_ ULONG Length
PEXT2_GROUP_DESC GroupDescriptors
PEXT2_SUPER_BLOCK SuperBlock
ULONG FragmentSizeInSectors
ULONG FragmentSizeInBytes
struct ext2_inode::@167::datablocks blocks
ULONG feature_compatibility
USHORT block_group_number
USHORT minor_revision_level
ULONG fragments_per_group
#define RtlCopyMemory(Destination, Source, Length)
#define RtlZeroMemory(Destination, Length)
_In_ WDFCOLLECTION _In_ ULONG Index
_Must_inspect_result_ _In_ WDFIOTARGET _In_opt_ WDFREQUEST _In_opt_ PWDF_MEMORY_DESCRIPTOR _In_opt_ PLONGLONG _In_opt_ PWDF_REQUEST_SEND_OPTIONS _Out_opt_ PULONG_PTR BytesRead
_In_ WDFREQUEST _In_ NTSTATUS _In_ ULONG_PTR Information