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;
230 for (
i=0;
i<NumberOfPathParts;
i++)
264 DirectoryInode = DirectoryEntry.
inode;
311 TRACE(
"Ext2SearchDirectoryBufferForFile() DirectoryBuffer = 0x%x DirectorySize = %d FileName = %s\n", DirectoryBuffer, DirectorySize,
FileName);
313 for (CurrentOffset=0; CurrentOffset<DirectorySize; )
317 if (CurrentDirectoryEntry->
direntlen == 0)
322 if ((CurrentDirectoryEntry->
direntlen + CurrentOffset) > DirectorySize)
324 FileSystemError(
"Directory entry extends past end of directory file.");
328 TRACE(
"Dumping directory entry at offset %d:\n", CurrentOffset);
336 TRACE(
"EXT2 Directory Entry:\n");
342 for (CurrentOffset=0; CurrentOffset<DirectoryEntry->
namelen; CurrentOffset++)
344 TRACE(
"%c", DirectoryEntry->
name[CurrentOffset]);
351 CurrentOffset += CurrentDirectoryEntry->
direntlen;
366 ULONG BlockNumberIndex;
369 ULONG NumberOfBlocks;
371 TRACE(
"Ext2ReadFileBig() BytesToRead = %d Buffer = 0x%x\n", (
ULONG)BytesToRead,
Buffer);
386 FileSystemError(
"Block pointer list is NULL and file is not a fast symbolic link.");
414 TRACE(
"Reading fast symbolic link data\n");
468 LengthInBlock = (
ULONG)((BytesToRead > (
Volume->BlockSizeInBytes - OffsetInBlock)) ? (
Volume->BlockSizeInBytes - OffsetInBlock) : BytesToRead);
481 BytesToRead -= LengthInBlock;
494 NumberOfBlocks = (
ULONG)(BytesToRead /
Volume->BlockSizeInBytes);
496 while (NumberOfBlocks > 0)
512 BytesToRead -=
Volume->BlockSizeInBytes;
559 TRACE(
"Ext2ReadVolumeSectors() Failed to seek\n");
567 TRACE(
"Ext2ReadVolumeSectors() Failed to read\n");
582 TRACE(
"Ext2ReadSuperBlock()\n");
586 if (SuperBlock !=
NULL)
594 if (SuperBlock ==
NULL)
597 if (SuperBlock ==
NULL)
603 Volume->SuperBlock = SuperBlock;
617 TRACE(
"Dumping super block:\n");
649 TRACE(
"unique_id = { 0x%x, 0x%x, 0x%x, 0x%x }\n",
670 FileSystemError(
"FreeLoader does not understand the revision of this EXT2/EXT3 filesystem.\nPlease update FreeLoader.");
684 FileSystemError(
"FreeLoader does not understand features of this EXT2/EXT3 filesystem.\nPlease update FreeLoader.");
695 TRACE(
"Ext2BlockSizeInBytes: %d\n",
Volume->BlockSizeInBytes);
696 TRACE(
"Ext2BlockSizeInSectors: %d\n",
Volume->BlockSizeInSectors);
708 TRACE(
"Ext2FragmentSizeInBytes: %d\n",
Volume->FragmentSizeInBytes);
709 TRACE(
"Ext2FragmentSizeInSectors: %d\n",
Volume->FragmentSizeInSectors);
712 if (
Volume->BlockSizeInBytes !=
Volume->FragmentSizeInBytes)
720 TRACE(
"Ext2InodesPerBlock: %d\n",
Volume->InodesPerBlock);
724 TRACE(
"Ext2GroupDescPerBlock: %d\n",
Volume->GroupDescPerBlock);
731 ULONG GroupDescBlockCount;
733 PUCHAR CurrentGroupDescBlock;
735 TRACE(
"Ext2ReadGroupDescriptors()\n");
754 CurrentGroupDescBlock = (
PUCHAR)
Volume->GroupDescriptors;
755 BlockNumber =
Volume->SuperBlock->first_data_block + 1;
757 while (GroupDescBlockCount--)
765 CurrentGroupDescBlock +=
Volume->BlockSizeInBytes;
775 TRACE(
"Ext2ReadDirectory() Inode = %d\n", Inode);
811 if (*DirectoryBuffer ==
NULL)
822 *DirectoryBuffer =
NULL;
833 CHAR ErrorString[80];
835 TRACE(
"Ext2ReadBlock() BlockNumber = %d Buffer = 0x%x\n", BlockNumber,
Buffer);
838 if (BlockNumber >
Volume->SuperBlock->total_blocks)
840 sprintf(ErrorString,
"Error reading block %d - block out of range.", (
int) BlockNumber);
846 if (BlockNumber == 0)
848 TRACE(
"Block is part of a sparse file. Zeroing input buffer.\n");
897 return ((Inode - 1) /
Volume->SuperBlock->inodes_per_group);
902 return (((Inode - 1) %
Volume->SuperBlock->inodes_per_group) /
Volume->InodesPerBlock);
907 return (((Inode - 1) %
Volume->SuperBlock->inodes_per_group) %
Volume->InodesPerBlock);
912 ULONG InodeGroupNumber;
913 ULONG InodeBlockNumber;
914 ULONG InodeOffsetInBlock;
915 CHAR ErrorString[80];
918 TRACE(
"Ext2ReadInode() Inode = %d\n", Inode);
921 if ((Inode < 1) || (Inode >
Volume->SuperBlock->total_inodes))
923 sprintf(ErrorString,
"Error reading inode %ld - inode out of range.", Inode);
932 TRACE(
"InodeGroupNumber = %d\n", InodeGroupNumber);
933 TRACE(
"InodeBlockNumber = %d\n", InodeBlockNumber);
934 TRACE(
"InodeOffsetInBlock = %d\n", InodeOffsetInBlock);
944 TRACE(
"InodeBlockNumber (after group desc correction) = %d\n", InodeBlockNumber);
956 TRACE(
"Dumping inode information:\n");
957 TRACE(
"mode = 0x%x\n", InodeBuffer->
mode);
958 TRACE(
"uid = %d\n", InodeBuffer->
uid);
964 TRACE(
"gid = %d\n", InodeBuffer->
gid);
968 TRACE(
"osd1 = 0x%x\n", InodeBuffer->
osd1);
969 TRACE(
"dir_blocks = { %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u }\n",
970 InodeBuffer->
blocks.dir_blocks[0], InodeBuffer->
blocks.dir_blocks[1], InodeBuffer->
blocks.dir_blocks[ 2], InodeBuffer->
blocks.dir_blocks[ 3],
971 InodeBuffer->
blocks.dir_blocks[4], InodeBuffer->
blocks.dir_blocks[5], InodeBuffer->
blocks.dir_blocks[ 6], InodeBuffer->
blocks.dir_blocks[ 7],
972 InodeBuffer->
blocks.dir_blocks[8], InodeBuffer->
blocks.dir_blocks[9], InodeBuffer->
blocks.dir_blocks[10], InodeBuffer->
blocks.dir_blocks[11]);
973 TRACE(
"indir_block = %u\n", InodeBuffer->
blocks.indir_block);
974 TRACE(
"double_indir_block = %u\n", InodeBuffer->
blocks.double_indir_block);
975 TRACE(
"tripple_indir_block = %u\n", InodeBuffer->
blocks.tripple_indir_block);
977 TRACE(
"acl = %d\n", InodeBuffer->
acl);
980 TRACE(
"osd2 = { %d, %d, %d }\n",
981 InodeBuffer->
osd2[0], InodeBuffer->
osd2[1], InodeBuffer->
osd2[2]);
988 TRACE(
"Ext2ReadGroupDescriptor()\n");
1000 TRACE(
"Dumping group descriptor:\n");
1016 ULONG CurrentBlockInList;
1019 TRACE(
"Ext2ReadBlockPointerList()\n");
1033 if (BlockList ==
NULL)
1041 for (CurrentBlockInList = CurrentBlock = 0;
1043 CurrentBlock++, CurrentBlockInList++)
1045 BlockList[CurrentBlockInList] = Inode->
blocks.dir_blocks[CurrentBlock];
1049 if (CurrentBlockInList < BlockCount)
1059 if (CurrentBlockInList < BlockCount)
1069 if (CurrentBlockInList < BlockCount)
1097 ULONG BlockPointersPerBlock;
1099 TRACE(
"Ext2CopyIndirectBlockPointers() BlockCount = %d\n", BlockCount);
1101 BlockPointersPerBlock =
Volume->BlockSizeInBytes /
sizeof(
ULONG);
1114 for (CurrentBlock=0; (*CurrentBlockInList)<BlockCount && CurrentBlock<BlockPointersPerBlock; CurrentBlock++)
1116 BlockList[(*CurrentBlockInList)] = BlockBuffer[CurrentBlock];
1117 (*CurrentBlockInList)++;
1129 ULONG BlockPointersPerBlock;
1131 TRACE(
"Ext2CopyDoubleIndirectBlockPointers() BlockCount = %d\n", BlockCount);
1133 BlockPointersPerBlock =
Volume->BlockSizeInBytes /
sizeof(
ULONG);
1136 if (BlockBuffer ==
NULL)
1147 for (CurrentBlock=0; (*CurrentBlockInList)<BlockCount && CurrentBlock<BlockPointersPerBlock; CurrentBlock++)
1164 ULONG BlockPointersPerBlock;
1166 TRACE(
"Ext2CopyTripleIndirectBlockPointers() BlockCount = %d\n", BlockCount);
1168 BlockPointersPerBlock =
Volume->BlockSizeInBytes /
sizeof(
ULONG);
1171 if (BlockBuffer ==
NULL)
1182 for (CurrentBlock=0; (*CurrentBlockInList)<BlockCount && CurrentBlock<BlockPointersPerBlock; CurrentBlock++)
1210 TRACE(
"Ext2GetFileInformation(%lu) -> FileSize = %llu, FilePointer = 0x%llx\n",
1230 TRACE(
"Ext2Open() FileName = %s\n",
Path);
1306 TRACE(
"Enter Ext2Mount(%lu)\n", DeviceId);
1336 Volume->DeviceId = DeviceId;
1349 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)
ARC_STATUS ArcSeek(ULONG FileId, LARGE_INTEGER *Position, SEEKMODE SeekMode)
PVOID FsGetDeviceSpecific(ULONG FileId)
ULONG FsGetNumPathParts(PCSTR Path)
VOID FsSetDeviceSpecific(ULONG FileId, PVOID Specific)
VOID FileSystemError(PCSTR ErrorString)
ULONG FsGetDeviceId(ULONG FileId)
ARC_STATUS ArcRead(ULONG FileId, VOID *Buffer, ULONG N, ULONG *Count)
VOID FsGetFirstNameFromPath(PCHAR Buffer, PCSTR Path)
FORCEINLINE PVOID FrLdrTempAlloc(_In_ SIZE_T Size, _In_ ULONG Tag)
FORCEINLINE VOID FrLdrTempFree(PVOID Allocation, ULONG Tag)
while(CdLookupNextInitialFileDirent(IrpContext, Fcb, FileContext))
_In_ PFCB _In_ LONGLONG StartingOffset
#define _strnicmp(_String1, _String2, _MaxCount)
#define ROUND_UP(n, align)
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)
#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
struct _FileName FileName
_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