71#define TAG_EXT_BLOCK_LIST 'LtxE'
72#define TAG_EXT_FILE 'FtxE'
73#define TAG_EXT_BUFFER 'BtxE'
74#define TAG_EXT_SUPER_BLOCK 'StxE'
75#define TAG_EXT_GROUP_DESC 'GtxE'
76#define TAG_EXT_VOLUME 'VtxE'
80 TRACE(
"ExtOpenVolume() DeviceId = %d\n",
Volume->DeviceId);
129 TRACE(
"File is a symbolic link\n");
142 TRACE(
"Symbolic link path = \"%s\"\n", SymLinkPath);
145 if (SymLinkPath[0] ==
'/' || SymLinkPath[0] ==
'\\')
150 strcpy(FullPath, &SymLinkPath[1]);
162 if (FullPath[
Index] ==
'/' || FullPath[
Index] ==
'\\')
167 FullPath[
Index] =
'\0';
171 strcat(FullPath, SymLinkPath);
174 TRACE(
"Full file path = \"%s\"\n", FullPath);
212 ULONG NumberOfPathParts;
214 PVOID DirectoryBuffer;
234 for (
i=0;
i<NumberOfPathParts;
i++)
268 DirectoryInode = DirectoryEntry.
Inode;
312 ULONG CurrentOffset = 0;
315 TRACE(
"ExtSearchDirectoryBufferForFile() DirectoryBuffer = 0x%x DirectorySize = %d FileName = \"%s\"\n", DirectoryBuffer, DirectorySize,
FileName);
317 while (CurrentOffset < DirectorySize)
321 if (!CurrentDirectoryEntry->
EntryLen)
324 if ((CurrentDirectoryEntry->
EntryLen + CurrentOffset) > DirectorySize)
326 FileSystemError(
"Directory entry extends past end of directory file.");
330 if (!CurrentDirectoryEntry->
Inode)
331 goto NextDirectoryEntry;
333 TRACE(
"EXT Directory Entry:\n");
334 TRACE(
"Inode = %d\n", CurrentDirectoryEntry->
Inode);
336 TRACE(
"NameLen = %d\n", CurrentDirectoryEntry->
NameLen);
339 for (
ULONG NameOffset = 0; NameOffset < CurrentDirectoryEntry->
NameLen; NameOffset++)
341 TRACE(
"%c", CurrentDirectoryEntry->
Name[NameOffset]);
354 CurrentOffset += CurrentDirectoryEntry->
EntryLen;
369 ULONG BlockNumberIndex;
372 ULONG NumberOfBlocks;
374 TRACE(
"ExtReadFileBig() BytesToRead = %d Buffer = 0x%x\n", (
ULONG)BytesToRead,
Buffer);
389 FileSystemError(
"Block pointer list is NULL and file is not a fast symbolic link.");
417 TRACE(
"Reading fast symbolic link data\n");
471 LengthInBlock = (
ULONG)((BytesToRead > (
Volume->BlockSizeInBytes - OffsetInBlock)) ? (
Volume->BlockSizeInBytes - OffsetInBlock) : BytesToRead);
484 BytesToRead -= LengthInBlock;
497 NumberOfBlocks = (
ULONG)(BytesToRead /
Volume->BlockSizeInBytes);
499 while (NumberOfBlocks > 0)
515 BytesToRead -=
Volume->BlockSizeInBytes;
562 TRACE(
"ExtReadVolumeSectors() Failed to seek\n");
570 TRACE(
"ExtReadVolumeSectors() Failed to read\n");
585 TRACE(
"ExtReadSuperBlock()\n");
589 if (SuperBlock !=
NULL)
597 if (SuperBlock ==
NULL)
600 if (SuperBlock ==
NULL)
606 Volume->SuperBlock = SuperBlock;
620 TRACE(
"Dumping super block:\n");
656 if (
i <
sizeof(SuperBlock->
UUID) - 1)
666 TRACE(
"JournalUUID: { ");
677 TRACE(
"HashSeed: { 0x%02x, 0x%02x, 0x%02x, 0x%02x }\n",
700 TRACE(
"ExtBlockSizeInBytes: %d\n",
Volume->BlockSizeInBytes);
701 TRACE(
"ExtBlockSizeInSectors: %d\n",
Volume->BlockSizeInSectors);
713 TRACE(
"ExtFragmentSizeInBytes: %d\n",
Volume->FragmentSizeInBytes);
714 TRACE(
"ExtFragmentSizeInSectors: %d\n",
Volume->FragmentSizeInSectors);
717 if (
Volume->BlockSizeInBytes !=
Volume->FragmentSizeInBytes)
725 TRACE(
"InodeSizeInBytes: %d\n",
Volume->InodeSizeInBytes);
729 TRACE(
"GroupDescSizeInBytes: %d\n",
Volume->GroupDescSizeInBytes);
733 TRACE(
"ExtInodesPerBlock: %d\n",
Volume->InodesPerBlock);
737 TRACE(
"ExtGroupDescPerBlock: %d\n",
Volume->GroupDescPerBlock);
744 ULONG GroupDescBlockCount;
746 PUCHAR CurrentGroupDescBlock;
748 TRACE(
"ExtReadGroupDescriptors()\n");
767 CurrentGroupDescBlock = (
PUCHAR)
Volume->GroupDescriptors;
768 BlockNumber =
Volume->SuperBlock->FirstDataBlock + 1;
770 while (GroupDescBlockCount--)
778 CurrentGroupDescBlock +=
Volume->BlockSizeInBytes;
788 TRACE(
"ExtReadDirectory() Inode = %d\n", Inode);
824 if (*DirectoryBuffer ==
NULL)
835 *DirectoryBuffer =
NULL;
846 CHAR ErrorString[80];
848 TRACE(
"ExtReadBlock() BlockNumber = %d Buffer = 0x%x\n", BlockNumber,
Buffer);
851 if (BlockNumber >
Volume->SuperBlock->BlocksCountLo)
853 sprintf(ErrorString,
"Error reading block %d - block out of range.", (
int) BlockNumber);
859 if (BlockNumber == 0)
861 TRACE(
"Block is part of a sparse file. Zeroing input buffer.\n");
898 return ((Inode - 1) /
Volume->SuperBlock->InodesPerGroup);
903 return (((Inode - 1) %
Volume->SuperBlock->InodesPerGroup) /
Volume->InodesPerBlock);
908 return (((Inode - 1) %
Volume->SuperBlock->InodesPerGroup) %
Volume->InodesPerBlock);
913 ULONG InodeGroupNumber;
914 ULONG InodeBlockNumber;
915 ULONG InodeOffsetInBlock;
916 CHAR ErrorString[80];
919 TRACE(
"ExtReadInode() Inode = %d\n", Inode);
922 if ((Inode < 1) || (Inode >
Volume->SuperBlock->InodesCount))
924 sprintf(ErrorString,
"Error reading inode %ld - inode out of range.", Inode);
933 TRACE(
"InodeGroupNumber = %d\n", InodeGroupNumber);
934 TRACE(
"InodeBlockNumber = %d\n", InodeBlockNumber);
935 TRACE(
"InodeOffsetInBlock = %d\n", InodeOffsetInBlock);
944 InodeBlockNumber += GroupDescriptor.
InodeTable;
945 TRACE(
"InodeBlockNumber (after group desc correction) = %d\n", InodeBlockNumber);
950 (InodeOffsetInBlock *
Volume->InodeSizeInBytes),
957 TRACE(
"Dumping inode information:\n");
958 TRACE(
"Mode = 0x%x\n", InodeBuffer->
Mode);
959 TRACE(
"UID = %d\n", InodeBuffer->
UID);
965 TRACE(
"GID = %d\n", InodeBuffer->
GID);
969 TRACE(
"OSD1 = 0x%x\n", InodeBuffer->
OSD1);
970 TRACE(
"DirectBlocks = { %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u }\n",
971 InodeBuffer->
Blocks.DirectBlocks[0], InodeBuffer->
Blocks.DirectBlocks[1], InodeBuffer->
Blocks.DirectBlocks[2], InodeBuffer->
Blocks.DirectBlocks[3],
972 InodeBuffer->
Blocks.DirectBlocks[4], InodeBuffer->
Blocks.DirectBlocks[5], InodeBuffer->
Blocks.DirectBlocks[6], InodeBuffer->
Blocks.DirectBlocks[7],
973 InodeBuffer->
Blocks.DirectBlocks[8], InodeBuffer->
Blocks.DirectBlocks[9], InodeBuffer->
Blocks.DirectBlocks[10], InodeBuffer->
Blocks.DirectBlocks[11]);
974 TRACE(
"IndirectBlock = %u\n", InodeBuffer->
Blocks.IndirectBlock);
975 TRACE(
"DoubleIndirectBlock = %u\n", InodeBuffer->
Blocks.DoubleIndirectBlock);
976 TRACE(
"TripleIndirectBlock = %u\n", InodeBuffer->
Blocks.TripleIndirectBlock);
981 TRACE(
"OSD2 = { %d, %d, %d }\n",
982 InodeBuffer->
OSD2[0], InodeBuffer->
OSD2[1], InodeBuffer->
OSD2[2]);
989 TRACE(
"ExtReadGroupDescriptor()\n");
1001 TRACE(
"Dumping group descriptor:\n");
1017 ULONG CurrentBlockInList;
1020 TRACE(
"ExtReadBlockPointerList()\n");
1034 if (BlockList ==
NULL)
1045 CurrentBlockInList = 0;
1057 for (CurrentBlockInList = CurrentBlock = 0;
1058 CurrentBlockInList < BlockCount && CurrentBlock <
sizeof(Inode->
Blocks.DirectBlocks) /
sizeof(*Inode->
Blocks.DirectBlocks);
1059 CurrentBlock++, CurrentBlockInList++)
1061 BlockList[CurrentBlockInList] = Inode->
Blocks.DirectBlocks[CurrentBlock];
1065 if (CurrentBlockInList < BlockCount)
1075 if (CurrentBlockInList < BlockCount)
1085 if (CurrentBlockInList < BlockCount)
1111 TRACE(
"ExtCopyBlockPointersByExtents() BlockCount = 0x%p\n", BlockCount);
1128 while ((*CurrentBlockInList) < BlockCount &&
Entries--)
1132 ULONG CurrentBlock = SparseExtent ? 0 :
Extent->Start;
1135 while ((*CurrentBlockInList) < BlockCount &&
Length--)
1137 BlockList[(*CurrentBlockInList)++] = CurrentBlock;
1157 while ((*CurrentBlockInList) < BlockCount &&
Entries--)
1179 ULONG BlockPointersPerBlock;
1181 TRACE(
"ExtCopyIndirectBlockPointers() BlockCount = %d\n", BlockCount);
1183 BlockPointersPerBlock =
Volume->BlockSizeInBytes /
sizeof(
ULONG);
1196 for (CurrentBlock=0; (*CurrentBlockInList)<BlockCount && CurrentBlock<BlockPointersPerBlock; CurrentBlock++)
1198 BlockList[(*CurrentBlockInList)] = BlockBuffer[CurrentBlock];
1199 (*CurrentBlockInList)++;
1211 ULONG BlockPointersPerBlock;
1213 TRACE(
"ExtCopyDoubleIndirectBlockPointers() BlockCount = %d\n", BlockCount);
1215 BlockPointersPerBlock =
Volume->BlockSizeInBytes /
sizeof(
ULONG);
1218 if (BlockBuffer ==
NULL)
1229 for (CurrentBlock=0; (*CurrentBlockInList)<BlockCount && CurrentBlock<BlockPointersPerBlock; CurrentBlock++)
1246 ULONG BlockPointersPerBlock;
1248 TRACE(
"ExtCopyTripleIndirectBlockPointers() BlockCount = %d\n", BlockCount);
1250 BlockPointersPerBlock =
Volume->BlockSizeInBytes /
sizeof(
ULONG);
1253 if (BlockBuffer ==
NULL)
1264 for (CurrentBlock=0; (*CurrentBlockInList)<BlockCount && CurrentBlock<BlockPointersPerBlock; CurrentBlock++)
1292 TRACE(
"ExtGetFileInformation(%lu) -> FileSize = %llu, FilePointer = 0x%llx\n",
1312 TRACE(
"ExtOpen() FileName = \"%s\"\n",
Path);
1388 TRACE(
"Enter ExtMount(%lu)\n", DeviceId);
1418 Volume->DeviceId = DeviceId;
1431 TRACE(
"ExtMount(%lu) success\n", DeviceId);
PRTL_UNICODE_STRING_BUFFER Path
ACPI_SIZE strlen(const char *String)
BOOLEAN CacheReadDiskSectors(UCHAR DiskNumber, ULONGLONG StartSector, ULONG SectorCount, PVOID Buffer)
BOOLEAN CacheInitializeDrive(UCHAR DriveNumber)
#define DBG_DEFAULT_CHANNEL(ch)
#define FAST_SYMLINK_MAX_NAME_SIZE
#define EXT4_EXTENT_MAX_LEVEL
#define EXT_GROUP_DESC_SIZE(sb)
struct _ExtSuperBlock * PEXT_SUPER_BLOCK
#define EXT4_EXTENT_HEADER_MAGIC
struct _ExtDirEntry * PEXT_DIR_ENTRY
#define EXT_DIR_ENTRY_MAX_NAME_LENGTH
#define EXT_INODE_SIZE(sb)
#define EXT_SUPERBLOCK_MAGIC
struct _ExtGroupDescriptor * PEXT_GROUP_DESC
#define EXT4_EXTENT_MAX_LENGTH
#define EXT4_INODE_FLAG_EXTENTS
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)
VOID FrLdrTempFree(PVOID Allocation, ULONG Tag)
PVOID FrLdrTempAlloc(_In_ SIZE_T Size, _In_ ULONG Tag)
BOOLEAN ExtCopyTripleIndirectBlockPointers(PEXT_VOLUME_INFO Volume, ULONG *BlockList, ULONG *CurrentBlockInList, ULONG BlockCount, ULONG TripleIndirectBlock)
PEXT_FILE_INFO ExtOpenFile(PEXT_VOLUME_INFO Volume, PCSTR FileName)
ULONG ExtGetInodeGroupNumber(PEXT_VOLUME_INFO Volume, ULONG Inode)
ARC_STATUS ExtGetFileInformation(ULONG FileId, FILEINFORMATION *Information)
#define TAG_EXT_BLOCK_LIST
BOOLEAN ExtCopyBlockPointersByExtents(PEXT_VOLUME_INFO Volume, ULONG *BlockList, ULONG *CurrentBlockInList, ULONG BlockCount, PEXT4_EXTENT_HEADER ExtentHeader)
BOOLEAN ExtReadGroupDescriptor(PEXT_VOLUME_INFO Volume, ULONG Group, PEXT_GROUP_DESC GroupBuffer)
BOOLEAN ExtCopyIndirectBlockPointers(PEXT_VOLUME_INFO Volume, ULONG *BlockList, ULONG *CurrentBlockInList, ULONG BlockCount, ULONG IndirectBlock)
BOOLEAN ExtReadFileBig(PEXT_FILE_INFO ExtFileInfo, ULONGLONG BytesToRead, ULONGLONG *BytesRead, PVOID Buffer)
const DEVVTBL ExtFuncTable
ULONGLONG ExtGetInodeFileSize(PEXT_INODE Inode)
BOOLEAN ExtReadVolumeSectors(PEXT_VOLUME_INFO Volume, ULONGLONG SectorNumber, ULONG SectorCount, PVOID Buffer)
ULONG ExtGetInodeBlockNumber(PEXT_VOLUME_INFO Volume, ULONG Inode)
BOOLEAN ExtReadDirectory(PEXT_VOLUME_INFO Volume, ULONG Inode, PVOID *DirectoryBuffer, PEXT_INODE InodePointer)
BOOLEAN ExtLookupFile(PEXT_VOLUME_INFO Volume, PCSTR FileName, PEXT_FILE_INFO ExtFileInfo)
BOOLEAN ExtReadBlock(PEXT_VOLUME_INFO Volume, ULONG BlockNumber, PVOID Buffer)
BOOLEAN ExtCopyDoubleIndirectBlockPointers(PEXT_VOLUME_INFO Volume, ULONG *BlockList, ULONG *CurrentBlockInList, ULONG BlockCount, ULONG DoubleIndirectBlock)
BOOLEAN ExtOpenVolume(PEXT_VOLUME_INFO Volume)
ARC_STATUS ExtSeek(ULONG FileId, LARGE_INTEGER *Position, SEEKMODE SeekMode)
PEXT_VOLUME_INFO ExtVolumes[MAX_FDS]
ULONG ExtGetInodeOffsetInBlock(PEXT_VOLUME_INFO Volume, ULONG Inode)
BOOLEAN ExtSearchDirectoryBufferForFile(PVOID DirectoryBuffer, ULONG DirectorySize, PCHAR FileName, PEXT_DIR_ENTRY DirectoryEntry)
BOOLEAN ExtReadInode(PEXT_VOLUME_INFO Volume, ULONG Inode, PEXT_INODE InodeBuffer)
BOOLEAN ExtReadPartialBlock(PEXT_VOLUME_INFO Volume, ULONG BlockNumber, ULONG StartingOffset, ULONG Length, PVOID Buffer)
const DEVVTBL * ExtMount(ULONG DeviceId)
ARC_STATUS ExtRead(ULONG FileId, VOID *Buffer, ULONG N, ULONG *Count)
ARC_STATUS ExtClose(ULONG FileId)
ARC_STATUS ExtOpen(CHAR *Path, OPENMODE OpenMode, ULONG *FileId)
BOOLEAN ExtReadSuperBlock(PEXT_VOLUME_INFO Volume)
#define TAG_EXT_GROUP_DESC
ULONG * ExtReadBlockPointerList(PEXT_VOLUME_INFO Volume, PEXT_INODE Inode)
struct _EXT_VOLUME_INFO EXT_VOLUME_INFO
BOOLEAN ExtReadGroupDescriptors(PEXT_VOLUME_INFO Volume)
#define TAG_EXT_SUPER_BLOCK
while(CdLookupNextInitialFileDirent(IrpContext, Fcb, FileContext))
_In_ PFCB _In_ LONGLONG StartingOffset
#define _strnicmp(_String1, _String2, _MaxCount)
#define ROUND_UP(n, align)
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
static const ENTRY Entries[]
#define sprintf(buf, format,...)
_In_ ULONG _In_ ULONG _In_ ULONG Length
ULONG FragmentSizeInSectors
ULONG GroupDescSizeInBytes
ULONG FragmentSizeInBytes
PEXT_GROUP_DESC GroupDescriptors
PEXT_SUPER_BLOCK SuperBlock
CHAR Name[EXT_DIR_ENTRY_MAX_NAME_LENGTH]
EXT4_EXTENT_HEADER ExtentHeader
struct _ExtInode::@188::@190 Blocks
ULONG AlgorithmUsageBitmap
USHORT MinorRevisionLevel
#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
_IRQL_requires_same_ typedef _In_ ULONG _In_ UCHAR Level