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;
536 BytesToRead -= BytesToRead;
558 TRACE(
"Ext2ReadVolumeSectors() Failed to seek\n");
566 TRACE(
"Ext2ReadVolumeSectors() Failed to read\n");
581 TRACE(
"Ext2ReadSuperBlock()\n");
585 if (SuperBlock !=
NULL)
593 if (SuperBlock ==
NULL)
596 if (SuperBlock ==
NULL)
602 Volume->SuperBlock = SuperBlock;
616 TRACE(
"Dumping super block:\n");
648 TRACE(
"unique_id = { 0x%x, 0x%x, 0x%x, 0x%x }\n",
669 FileSystemError(
"FreeLoader does not understand the revision of this EXT2/EXT3 filesystem.\nPlease update FreeLoader.");
683 FileSystemError(
"FreeLoader does not understand features of this EXT2/EXT3 filesystem.\nPlease update FreeLoader.");
694 TRACE(
"Ext2BlockSizeInBytes: %d\n",
Volume->BlockSizeInBytes);
695 TRACE(
"Ext2BlockSizeInSectors: %d\n",
Volume->BlockSizeInSectors);
707 TRACE(
"Ext2FragmentSizeInBytes: %d\n",
Volume->FragmentSizeInBytes);
708 TRACE(
"Ext2FragmentSizeInSectors: %d\n",
Volume->FragmentSizeInSectors);
711 if (
Volume->BlockSizeInBytes !=
Volume->FragmentSizeInBytes)
719 TRACE(
"Ext2InodesPerBlock: %d\n",
Volume->InodesPerBlock);
723 TRACE(
"Ext2GroupDescPerBlock: %d\n",
Volume->GroupDescPerBlock);
730 ULONG GroupDescBlockCount;
732 PUCHAR CurrentGroupDescBlock;
734 TRACE(
"Ext2ReadGroupDescriptors()\n");
753 CurrentGroupDescBlock = (
PUCHAR)
Volume->GroupDescriptors;
754 BlockNumber =
Volume->SuperBlock->first_data_block + 1;
756 while (GroupDescBlockCount--)
764 CurrentGroupDescBlock +=
Volume->BlockSizeInBytes;
774 TRACE(
"Ext2ReadDirectory() Inode = %d\n", Inode);
810 if (*DirectoryBuffer ==
NULL)
821 *DirectoryBuffer =
NULL;
832 CHAR ErrorString[80];
834 TRACE(
"Ext2ReadBlock() BlockNumber = %d Buffer = 0x%x\n", BlockNumber,
Buffer);
837 if (BlockNumber >
Volume->SuperBlock->total_blocks)
839 sprintf(ErrorString,
"Error reading block %d - block out of range.", (
int) BlockNumber);
845 if (BlockNumber == 0)
847 TRACE(
"Block is part of a sparse file. Zeroing input buffer.\n");
896 return ((Inode - 1) /
Volume->SuperBlock->inodes_per_group);
901 return (((Inode - 1) %
Volume->SuperBlock->inodes_per_group) /
Volume->InodesPerBlock);
906 return (((Inode - 1) %
Volume->SuperBlock->inodes_per_group) %
Volume->InodesPerBlock);
911 ULONG InodeGroupNumber;
912 ULONG InodeBlockNumber;
913 ULONG InodeOffsetInBlock;
914 CHAR ErrorString[80];
917 TRACE(
"Ext2ReadInode() Inode = %d\n", Inode);
920 if ((Inode < 1) || (Inode >
Volume->SuperBlock->total_inodes))
922 sprintf(ErrorString,
"Error reading inode %ld - inode out of range.", Inode);
931 TRACE(
"InodeGroupNumber = %d\n", InodeGroupNumber);
932 TRACE(
"InodeBlockNumber = %d\n", InodeBlockNumber);
933 TRACE(
"InodeOffsetInBlock = %d\n", InodeOffsetInBlock);
943 TRACE(
"InodeBlockNumber (after group desc correction) = %d\n", InodeBlockNumber);
955 TRACE(
"Dumping inode information:\n");
956 TRACE(
"mode = 0x%x\n", InodeBuffer->
mode);
957 TRACE(
"uid = %d\n", InodeBuffer->
uid);
963 TRACE(
"gid = %d\n", InodeBuffer->
gid);
967 TRACE(
"osd1 = 0x%x\n", InodeBuffer->
osd1);
968 TRACE(
"dir_blocks = { %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u }\n",
969 InodeBuffer->
blocks.dir_blocks[0], InodeBuffer->
blocks.dir_blocks[1], InodeBuffer->
blocks.dir_blocks[ 2], InodeBuffer->
blocks.dir_blocks[ 3],
970 InodeBuffer->
blocks.dir_blocks[4], InodeBuffer->
blocks.dir_blocks[5], InodeBuffer->
blocks.dir_blocks[ 6], InodeBuffer->
blocks.dir_blocks[ 7],
971 InodeBuffer->
blocks.dir_blocks[8], InodeBuffer->
blocks.dir_blocks[9], InodeBuffer->
blocks.dir_blocks[10], InodeBuffer->
blocks.dir_blocks[11]);
972 TRACE(
"indir_block = %u\n", InodeBuffer->
blocks.indir_block);
973 TRACE(
"double_indir_block = %u\n", InodeBuffer->
blocks.double_indir_block);
974 TRACE(
"tripple_indir_block = %u\n", InodeBuffer->
blocks.tripple_indir_block);
976 TRACE(
"acl = %d\n", InodeBuffer->
acl);
979 TRACE(
"osd2 = { %d, %d, %d }\n",
980 InodeBuffer->
osd2[0], InodeBuffer->
osd2[1], InodeBuffer->
osd2[2]);
987 TRACE(
"Ext2ReadGroupDescriptor()\n");
999 TRACE(
"Dumping group descriptor:\n");
1015 ULONG CurrentBlockInList;
1018 TRACE(
"Ext2ReadBlockPointerList()\n");
1032 if (BlockList ==
NULL)
1040 for (CurrentBlockInList = CurrentBlock = 0;
1042 CurrentBlock++, CurrentBlockInList++)
1044 BlockList[CurrentBlockInList] = Inode->
blocks.dir_blocks[CurrentBlock];
1048 if (CurrentBlockInList < BlockCount)
1058 if (CurrentBlockInList < BlockCount)
1068 if (CurrentBlockInList < BlockCount)
1096 ULONG BlockPointersPerBlock;
1098 TRACE(
"Ext2CopyIndirectBlockPointers() BlockCount = %d\n", BlockCount);
1100 BlockPointersPerBlock =
Volume->BlockSizeInBytes /
sizeof(
ULONG);
1113 for (CurrentBlock=0; (*CurrentBlockInList)<BlockCount && CurrentBlock<BlockPointersPerBlock; CurrentBlock++)
1115 BlockList[(*CurrentBlockInList)] = BlockBuffer[CurrentBlock];
1116 (*CurrentBlockInList)++;
1128 ULONG BlockPointersPerBlock;
1130 TRACE(
"Ext2CopyDoubleIndirectBlockPointers() BlockCount = %d\n", BlockCount);
1132 BlockPointersPerBlock =
Volume->BlockSizeInBytes /
sizeof(
ULONG);
1135 if (BlockBuffer ==
NULL)
1146 for (CurrentBlock=0; (*CurrentBlockInList)<BlockCount && CurrentBlock<BlockPointersPerBlock; CurrentBlock++)
1163 ULONG BlockPointersPerBlock;
1165 TRACE(
"Ext2CopyTripleIndirectBlockPointers() BlockCount = %d\n", BlockCount);
1167 BlockPointersPerBlock =
Volume->BlockSizeInBytes /
sizeof(
ULONG);
1170 if (BlockBuffer ==
NULL)
1181 for (CurrentBlock=0; (*CurrentBlockInList)<BlockCount && CurrentBlock<BlockPointersPerBlock; CurrentBlock++)
1209 TRACE(
"Ext2GetFileInformation(%lu) -> FileSize = %llu, FilePointer = 0x%llx\n",
1229 TRACE(
"Ext2Open() FileName = %s\n",
Path);
1305 TRACE(
"Enter Ext2Mount(%lu)\n", DeviceId);
1335 Volume->DeviceId = DeviceId;
1348 TRACE(
"Ext2Mount(%lu) success\n", DeviceId);
BOOLEAN Ext2ReadInode(PEXT2_VOLUME_INFO Volume, ULONG Inode, PEXT2_INODE InodeBuffer)
BOOLEAN Ext2ReadSuperBlock(PEXT2_VOLUME_INFO Volume)
_In_ ULONG _In_ ULONG _In_ ULONG Length
#define ROUND_UP(n, align)
VOID FsGetFirstNameFromPath(PCHAR Buffer, PCSTR Path)
BOOLEAN Ext2ReadFileBig(PEXT2_FILE_INFO Ext2FileInfo, ULONGLONG BytesToRead, ULONGLONG *BytesRead, PVOID Buffer)
_In_ PFCB _In_ LONGLONG StartingOffset
BOOLEAN Ext2LookupFile(PEXT2_VOLUME_INFO Volume, PCSTR FileName, PEXT2_FILE_INFO Ext2FileInfo)
char * strcat(char *DstString, const char *SrcString)
ACPI_SIZE strlen(const char *String)
IN BOOLEAN OUT PSTR Buffer
struct ext2_sblock * PEXT2_SUPER_BLOCK
#define EXT3_FEATURE_INCOMPAT_SUPP
BOOLEAN Ext2ReadDirectory(PEXT2_VOLUME_INFO Volume, ULONG Inode, PVOID *DirectoryBuffer, PEXT2_INODE InodePointer)
ULONGLONG Ext2GetInodeFileSize(PEXT2_INODE Inode)
BOOLEAN Ext2ReadGroupDescriptor(PEXT2_VOLUME_INFO Volume, ULONG Group, PEXT2_GROUP_DESC GroupBuffer)
struct ext2_block_group * PEXT2_GROUP_DESC
ULONG FsGetNumPathParts(PCSTR Path)
ULONG Ext2GetInodeOffsetInBlock(PEXT2_VOLUME_INFO Volume, ULONG Inode)
#define FAST_SYMLINK_MAX_NAME_SIZE
_In_ WDFREQUEST _In_ NTSTATUS _In_ ULONG_PTR Information
VOID * FsGetDeviceSpecific(ULONG FileId)
BOOLEAN Ext2ReadBlock(PEXT2_VOLUME_INFO Volume, ULONG BlockNumber, PVOID Buffer)
ULONG feature_compatibility
_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
PEXT2_GROUP_DESC GroupDescriptors
struct _EXT2_VOLUME_INFO EXT2_VOLUME_INFO
#define sprintf(buf, format,...)
BOOLEAN CacheReadDiskSectors(UCHAR DiskNumber, ULONGLONG StartSector, ULONG SectorCount, PVOID Buffer)
VOID FileSystemError(PCSTR ErrorString)
ARC_STATUS Ext2GetFileInformation(ULONG FileId, FILEINFORMATION *Information)
BOOLEAN Ext2SearchDirectoryBufferForFile(PVOID DirectoryBuffer, ULONG DirectorySize, PCHAR FileName, PEXT2_DIR_ENTRY DirectoryEntry)
FORCEINLINE PVOID FrLdrTempAlloc(_In_ SIZE_T Size, _In_ ULONG Tag)
PEXT2_FILE_INFO Ext2OpenFile(PEXT2_VOLUME_INFO Volume, PCSTR FileName)
struct ext2_inode::@161::datablocks blocks
DBG_DEFAULT_CHANNEL(FILESYSTEM)
ULONG * Ext2ReadBlockPointerList(PEXT2_VOLUME_INFO Volume, PEXT2_INODE Inode)
#define EXT2_INODE_SIZE(sb)
#define TAG_EXT_BLOCK_LIST
_In_ WDFCOLLECTION _In_ ULONG Index
struct ext2_dirent * PEXT2_DIR_ENTRY
ARC_STATUS Ext2Close(ULONG FileId)
VOID FsSetDeviceSpecific(ULONG FileId, VOID *Specific)
#define DPRINT_FILESYSTEM
BOOLEAN Ext2CopyTripleIndirectBlockPointers(PEXT2_VOLUME_INFO Volume, ULONG *BlockList, ULONG *CurrentBlockInList, ULONG BlockCount, ULONG TripleIndirectBlock)
#define _strnicmp(_String1, _String2, _MaxCount)
BOOLEAN CacheInitializeDrive(UCHAR DriveNumber)
ARC_STATUS ArcRead(ULONG FileId, VOID *Buffer, ULONG N, ULONG *Count)
#define EXT2_DESC_PER_BLOCK(s)
ARC_STATUS ArcSeek(ULONG FileId, LARGE_INTEGER *Position, SEEKMODE SeekMode)
_Must_inspect_result_ _Out_ PLARGE_INTEGER FileSize
ARC_STATUS Ext2Open(CHAR *Path, OPENMODE OpenMode, ULONG *FileId)
BOOLEAN Ext2CopyDoubleIndirectBlockPointers(PEXT2_VOLUME_INFO Volume, ULONG *BlockList, ULONG *CurrentBlockInList, ULONG BlockCount, ULONG DoubleIndirectBlock)
ULONG Ext2GetInodeBlockNumber(PEXT2_VOLUME_INFO Volume, ULONG Inode)
BOOLEAN Ext2ReadVolumeSectors(PEXT2_VOLUME_INFO Volume, ULONGLONG SectorNumber, ULONG SectorCount, PVOID Buffer)
ARC_STATUS Ext2Seek(ULONG FileId, LARGE_INTEGER *Position, SEEKMODE SeekMode)
ULONG FragmentSizeInBytes
ULONG FragmentSizeInSectors
PRTL_UNICODE_STRING_BUFFER Path
ARC_STATUS Ext2Read(ULONG FileId, VOID *Buffer, ULONG N, ULONG *Count)
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
const DEVVTBL * Ext2Mount(ULONG DeviceId)
#define DbgDumpBuffer(mask, buf, len)
#define TAG_EXT_SUPER_BLOCK
BOOLEAN Ext2ReadPartialBlock(PEXT2_VOLUME_INFO Volume, ULONG BlockNumber, ULONG StartingOffset, ULONG Length, PVOID Buffer)
#define EXT2_DYNAMIC_REVISION
ULONG Ext2GetInodeGroupNumber(PEXT2_VOLUME_INFO Volume, ULONG Inode)
char * strcpy(char *DstString, const char *SrcString)
ULONG FsGetDeviceId(ULONG FileId)
PEXT2_VOLUME_INFO Ext2Volumes[MAX_FDS]
#define RtlZeroMemory(Destination, Length)
#define RtlCopyMemory(Destination, Source, Length)
const DEVVTBL Ext2FuncTable
BOOLEAN Ext2CopyIndirectBlockPointers(PEXT2_VOLUME_INFO Volume, ULONG *BlockList, ULONG *CurrentBlockInList, ULONG BlockCount, ULONG IndirectBlock)
PEXT2_SUPER_BLOCK SuperBlock
ULONG fragments_per_group
USHORT block_group_number
BOOLEAN Ext2ReadGroupDescriptors(PEXT2_VOLUME_INFO Volume)
USHORT minor_revision_level
BOOLEAN Ext2OpenVolume(PEXT2_VOLUME_INFO Volume)
#define TAG_EXT_GROUP_DESC
FORCEINLINE VOID FrLdrTempFree(PVOID Allocation, ULONG Tag)