ReactOS  0.4.15-dev-2964-ge2a8585
ext2.c File Reference
#include <freeldr.h>
#include <debug.h>
Include dependency graph for ext2.c:

Go to the source code of this file.

Classes

struct  _EXT2_VOLUME_INFO
 

Macros

#define TAG_EXT_BLOCK_LIST   'LtxE'
 
#define TAG_EXT_FILE   'FtxE'
 
#define TAG_EXT_BUFFER   'BtxE'
 
#define TAG_EXT_SUPER_BLOCK   'StxE'
 
#define TAG_EXT_GROUP_DESC   'GtxE'
 
#define TAG_EXT_VOLUME   'VtxE'
 

Typedefs

typedef struct _EXT2_VOLUME_INFO EXT2_VOLUME_INFO
 

Functions

 DBG_DEFAULT_CHANNEL (FILESYSTEM)
 
BOOLEAN Ext2OpenVolume (PEXT2_VOLUME_INFO Volume)
 
PEXT2_FILE_INFO Ext2OpenFile (PEXT2_VOLUME_INFO Volume, PCSTR FileName)
 
BOOLEAN Ext2LookupFile (PEXT2_VOLUME_INFO Volume, PCSTR FileName, PEXT2_FILE_INFO Ext2FileInfo)
 
BOOLEAN Ext2SearchDirectoryBufferForFile (PVOID DirectoryBuffer, ULONG DirectorySize, PCHAR FileName, PEXT2_DIR_ENTRY DirectoryEntry)
 
BOOLEAN Ext2ReadVolumeSectors (PEXT2_VOLUME_INFO Volume, ULONGLONG SectorNumber, ULONG SectorCount, PVOID Buffer)
 
BOOLEAN Ext2ReadFileBig (PEXT2_FILE_INFO Ext2FileInfo, ULONGLONG BytesToRead, ULONGLONG *BytesRead, PVOID Buffer)
 
BOOLEAN Ext2ReadSuperBlock (PEXT2_VOLUME_INFO Volume)
 
BOOLEAN Ext2ReadGroupDescriptors (PEXT2_VOLUME_INFO Volume)
 
BOOLEAN Ext2ReadDirectory (PEXT2_VOLUME_INFO Volume, ULONG Inode, PVOID *DirectoryBuffer, PEXT2_INODE InodePointer)
 
BOOLEAN Ext2ReadBlock (PEXT2_VOLUME_INFO Volume, ULONG BlockNumber, PVOID Buffer)
 
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)
 
ULONGExt2ReadBlockPointerList (PEXT2_VOLUME_INFO Volume, PEXT2_INODE Inode)
 
ULONGLONG Ext2GetInodeFileSize (PEXT2_INODE Inode)
 
BOOLEAN Ext2CopyIndirectBlockPointers (PEXT2_VOLUME_INFO Volume, ULONG *BlockList, ULONG *CurrentBlockInList, ULONG BlockCount, ULONG IndirectBlock)
 
BOOLEAN Ext2CopyDoubleIndirectBlockPointers (PEXT2_VOLUME_INFO Volume, ULONG *BlockList, ULONG *CurrentBlockInList, ULONG BlockCount, ULONG DoubleIndirectBlock)
 
BOOLEAN Ext2CopyTripleIndirectBlockPointers (PEXT2_VOLUME_INFO Volume, ULONG *BlockList, ULONG *CurrentBlockInList, ULONG BlockCount, ULONG TripleIndirectBlock)
 
ULONG Ext2GetInodeGroupNumber (PEXT2_VOLUME_INFO Volume, ULONG Inode)
 
ULONG Ext2GetInodeBlockNumber (PEXT2_VOLUME_INFO Volume, ULONG Inode)
 
ULONG Ext2GetInodeOffsetInBlock (PEXT2_VOLUME_INFO Volume, ULONG Inode)
 
ARC_STATUS Ext2Close (ULONG FileId)
 
ARC_STATUS Ext2GetFileInformation (ULONG FileId, FILEINFORMATION *Information)
 
ARC_STATUS Ext2Open (CHAR *Path, OPENMODE OpenMode, ULONG *FileId)
 
ARC_STATUS Ext2Read (ULONG FileId, VOID *Buffer, ULONG N, ULONG *Count)
 
ARC_STATUS Ext2Seek (ULONG FileId, LARGE_INTEGER *Position, SEEKMODE SeekMode)
 
const DEVVTBLExt2Mount (ULONG DeviceId)
 

Variables

PEXT2_VOLUME_INFO Ext2Volumes [MAX_FDS]
 
const DEVVTBL Ext2FuncTable
 

Macro Definition Documentation

◆ TAG_EXT_BLOCK_LIST

#define TAG_EXT_BLOCK_LIST   'LtxE'

Definition at line 67 of file ext2.c.

◆ TAG_EXT_BUFFER

#define TAG_EXT_BUFFER   'BtxE'

Definition at line 69 of file ext2.c.

◆ TAG_EXT_FILE

#define TAG_EXT_FILE   'FtxE'

Definition at line 68 of file ext2.c.

◆ TAG_EXT_GROUP_DESC

#define TAG_EXT_GROUP_DESC   'GtxE'

Definition at line 71 of file ext2.c.

◆ TAG_EXT_SUPER_BLOCK

#define TAG_EXT_SUPER_BLOCK   'StxE'

Definition at line 70 of file ext2.c.

◆ TAG_EXT_VOLUME

#define TAG_EXT_VOLUME   'VtxE'

Definition at line 72 of file ext2.c.

Typedef Documentation

◆ EXT2_VOLUME_INFO

Function Documentation

◆ DBG_DEFAULT_CHANNEL()

DBG_DEFAULT_CHANNEL ( FILESYSTEM  )

◆ Ext2Close()

ARC_STATUS Ext2Close ( ULONG  FileId)

Definition at line 1192 of file ext2.c.

1193 {
1196  return ESUCCESS;
1197 }
Definition: arc.h:32
VOID * FsGetDeviceSpecific(ULONG FileId)
Definition: fs.c:416
HANDLE FileHandle
Definition: stats.c:38
#define TAG_EXT_FILE
Definition: ext2.c:68
FORCEINLINE VOID FrLdrTempFree(PVOID Allocation, ULONG Tag)
Definition: mm.h:197

Referenced by Ext2DispatchRequest().

◆ Ext2CopyDoubleIndirectBlockPointers()

BOOLEAN Ext2CopyDoubleIndirectBlockPointers ( PEXT2_VOLUME_INFO  Volume,
ULONG BlockList,
ULONG CurrentBlockInList,
ULONG  BlockCount,
ULONG  DoubleIndirectBlock 
)

Definition at line 1122 of file ext2.c.

1123 {
1124  ULONG* BlockBuffer;
1125  ULONG CurrentBlock;
1126  ULONG BlockPointersPerBlock;
1127 
1128  TRACE("Ext2CopyDoubleIndirectBlockPointers() BlockCount = %d\n", BlockCount);
1129 
1130  BlockPointersPerBlock = Volume->BlockSizeInBytes / sizeof(ULONG);
1131 
1132  BlockBuffer = (ULONG*)FrLdrTempAlloc(Volume->BlockSizeInBytes, TAG_EXT_BUFFER);
1133  if (BlockBuffer == NULL)
1134  {
1135  return FALSE;
1136  }
1137 
1138  if (!Ext2ReadBlock(Volume, DoubleIndirectBlock, BlockBuffer))
1139  {
1140  FrLdrTempFree(BlockBuffer, TAG_EXT_BUFFER);
1141  return FALSE;
1142  }
1143 
1144  for (CurrentBlock=0; (*CurrentBlockInList)<BlockCount && CurrentBlock<BlockPointersPerBlock; CurrentBlock++)
1145  {
1146  if (!Ext2CopyIndirectBlockPointers(Volume, BlockList, CurrentBlockInList, BlockCount, BlockBuffer[CurrentBlock]))
1147  {
1148  FrLdrTempFree(BlockBuffer, TAG_EXT_BUFFER);
1149  return FALSE;
1150  }
1151  }
1152 
1153  FrLdrTempFree(BlockBuffer, TAG_EXT_BUFFER);
1154  return TRUE;
1155 }
#define TRUE
Definition: types.h:120
#define TAG_EXT_BUFFER
Definition: ext2.c:69
BOOLEAN Ext2ReadBlock(PEXT2_VOLUME_INFO Volume, ULONG BlockNumber, PVOID Buffer)
Definition: ext2.c:828
#define FALSE
Definition: types.h:117
FORCEINLINE PVOID FrLdrTempAlloc(_In_ SIZE_T Size, _In_ ULONG Tag)
Definition: mm.h:188
#define TRACE(s)
Definition: solgame.cpp:4
#define NULL
Definition: types.h:112
unsigned int ULONG
Definition: retypes.h:1
BOOLEAN Ext2CopyIndirectBlockPointers(PEXT2_VOLUME_INFO Volume, ULONG *BlockList, ULONG *CurrentBlockInList, ULONG BlockCount, ULONG IndirectBlock)
Definition: ext2.c:1090
FORCEINLINE VOID FrLdrTempFree(PVOID Allocation, ULONG Tag)
Definition: mm.h:197

Referenced by Ext2CopyTripleIndirectBlockPointers(), and Ext2ReadBlockPointerList().

◆ Ext2CopyIndirectBlockPointers()

BOOLEAN Ext2CopyIndirectBlockPointers ( PEXT2_VOLUME_INFO  Volume,
ULONG BlockList,
ULONG CurrentBlockInList,
ULONG  BlockCount,
ULONG  IndirectBlock 
)

Definition at line 1090 of file ext2.c.

1091 {
1092  ULONG* BlockBuffer;
1093  ULONG CurrentBlock;
1094  ULONG BlockPointersPerBlock;
1095 
1096  TRACE("Ext2CopyIndirectBlockPointers() BlockCount = %d\n", BlockCount);
1097 
1098  BlockPointersPerBlock = Volume->BlockSizeInBytes / sizeof(ULONG);
1099 
1100  BlockBuffer = FrLdrTempAlloc(Volume->BlockSizeInBytes, TAG_EXT_BUFFER);
1101  if (!BlockBuffer)
1102  {
1103  return FALSE;
1104  }
1105 
1106  if (!Ext2ReadBlock(Volume, IndirectBlock, BlockBuffer))
1107  {
1108  return FALSE;
1109  }
1110 
1111  for (CurrentBlock=0; (*CurrentBlockInList)<BlockCount && CurrentBlock<BlockPointersPerBlock; CurrentBlock++)
1112  {
1113  BlockList[(*CurrentBlockInList)] = BlockBuffer[CurrentBlock];
1114  (*CurrentBlockInList)++;
1115  }
1116 
1117  FrLdrTempFree(BlockBuffer, TAG_EXT_BUFFER);
1118 
1119  return TRUE;
1120 }
#define TRUE
Definition: types.h:120
#define TAG_EXT_BUFFER
Definition: ext2.c:69
BOOLEAN Ext2ReadBlock(PEXT2_VOLUME_INFO Volume, ULONG BlockNumber, PVOID Buffer)
Definition: ext2.c:828
#define FALSE
Definition: types.h:117
FORCEINLINE PVOID FrLdrTempAlloc(_In_ SIZE_T Size, _In_ ULONG Tag)
Definition: mm.h:188
#define TRACE(s)
Definition: solgame.cpp:4
unsigned int ULONG
Definition: retypes.h:1
FORCEINLINE VOID FrLdrTempFree(PVOID Allocation, ULONG Tag)
Definition: mm.h:197

Referenced by Ext2CopyDoubleIndirectBlockPointers(), and Ext2ReadBlockPointerList().

◆ Ext2CopyTripleIndirectBlockPointers()

BOOLEAN Ext2CopyTripleIndirectBlockPointers ( PEXT2_VOLUME_INFO  Volume,
ULONG BlockList,
ULONG CurrentBlockInList,
ULONG  BlockCount,
ULONG  TripleIndirectBlock 
)

Definition at line 1157 of file ext2.c.

1158 {
1159  ULONG* BlockBuffer;
1160  ULONG CurrentBlock;
1161  ULONG BlockPointersPerBlock;
1162 
1163  TRACE("Ext2CopyTripleIndirectBlockPointers() BlockCount = %d\n", BlockCount);
1164 
1165  BlockPointersPerBlock = Volume->BlockSizeInBytes / sizeof(ULONG);
1166 
1167  BlockBuffer = (ULONG*)FrLdrTempAlloc(Volume->BlockSizeInBytes, TAG_EXT_BUFFER);
1168  if (BlockBuffer == NULL)
1169  {
1170  return FALSE;
1171  }
1172 
1173  if (!Ext2ReadBlock(Volume, TripleIndirectBlock, BlockBuffer))
1174  {
1175  FrLdrTempFree(BlockBuffer, TAG_EXT_BUFFER);
1176  return FALSE;
1177  }
1178 
1179  for (CurrentBlock=0; (*CurrentBlockInList)<BlockCount && CurrentBlock<BlockPointersPerBlock; CurrentBlock++)
1180  {
1181  if (!Ext2CopyDoubleIndirectBlockPointers(Volume, BlockList, CurrentBlockInList, BlockCount, BlockBuffer[CurrentBlock]))
1182  {
1183  FrLdrTempFree(BlockBuffer, TAG_EXT_BUFFER);
1184  return FALSE;
1185  }
1186  }
1187 
1188  FrLdrTempFree(BlockBuffer, TAG_EXT_BUFFER);
1189  return TRUE;
1190 }
#define TRUE
Definition: types.h:120
#define TAG_EXT_BUFFER
Definition: ext2.c:69
BOOLEAN Ext2ReadBlock(PEXT2_VOLUME_INFO Volume, ULONG BlockNumber, PVOID Buffer)
Definition: ext2.c:828
#define FALSE
Definition: types.h:117
FORCEINLINE PVOID FrLdrTempAlloc(_In_ SIZE_T Size, _In_ ULONG Tag)
Definition: mm.h:188
#define TRACE(s)
Definition: solgame.cpp:4
BOOLEAN Ext2CopyDoubleIndirectBlockPointers(PEXT2_VOLUME_INFO Volume, ULONG *BlockList, ULONG *CurrentBlockInList, ULONG BlockCount, ULONG DoubleIndirectBlock)
Definition: ext2.c:1122
#define NULL
Definition: types.h:112
unsigned int ULONG
Definition: retypes.h:1
FORCEINLINE VOID FrLdrTempFree(PVOID Allocation, ULONG Tag)
Definition: mm.h:197

Referenced by Ext2ReadBlockPointerList().

◆ Ext2GetFileInformation()

ARC_STATUS Ext2GetFileInformation ( ULONG  FileId,
FILEINFORMATION Information 
)

Definition at line 1199 of file ext2.c.

1200 {
1202 
1204  Information->EndingAddress.QuadPart = FileHandle->FileSize;
1205  Information->CurrentAddress.QuadPart = FileHandle->FilePointer;
1206 
1207  TRACE("Ext2GetFileInformation(%lu) -> FileSize = %llu, FilePointer = 0x%llx\n",
1208  FileId, Information->EndingAddress.QuadPart, Information->CurrentAddress.QuadPart);
1209 
1210  return ESUCCESS;
1211 }
Definition: arc.h:32
_In_ WDFREQUEST _In_ NTSTATUS _In_ ULONG_PTR Information
Definition: wdfrequest.h:1044
VOID * FsGetDeviceSpecific(ULONG FileId)
Definition: fs.c:416
HANDLE FileHandle
Definition: stats.c:38
#define TRACE(s)
Definition: solgame.cpp:4
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262

◆ Ext2GetInodeBlockNumber()

ULONG Ext2GetInodeBlockNumber ( PEXT2_VOLUME_INFO  Volume,
ULONG  Inode 
)

Definition at line 897 of file ext2.c.

898 {
899  return (((Inode - 1) % Volume->SuperBlock->inodes_per_group) / Volume->InodesPerBlock);
900 }

Referenced by Ext2ReadInode().

◆ Ext2GetInodeFileSize()

ULONGLONG Ext2GetInodeFileSize ( PEXT2_INODE  Inode)

Definition at line 1078 of file ext2.c.

1079 {
1080  if ((Inode->mode & EXT2_S_IFMT) == EXT2_S_IFDIR)
1081  {
1082  return (ULONGLONG)(Inode->size);
1083  }
1084  else
1085  {
1086  return ((ULONGLONG)(Inode->size) | ((ULONGLONG)(Inode->dir_acl) << 32));
1087  }
1088 }
ULONG dir_acl
Definition: ext2.h:150
ULONG size
Definition: ext2.h:127
#define EXT2_S_IFDIR
Definition: ext2.h:221
uint64_t ULONGLONG
Definition: typedefs.h:67
#define EXT2_S_IFMT
Definition: ext2.h:218
USHORT mode
Definition: ext2.h:125

Referenced by Ext2LookupFile(), Ext2ReadBlockPointerList(), and Ext2ReadDirectory().

◆ Ext2GetInodeGroupNumber()

ULONG Ext2GetInodeGroupNumber ( PEXT2_VOLUME_INFO  Volume,
ULONG  Inode 
)

Definition at line 892 of file ext2.c.

893 {
894  return ((Inode - 1) / Volume->SuperBlock->inodes_per_group);
895 }

Referenced by Ext2ReadInode().

◆ Ext2GetInodeOffsetInBlock()

ULONG Ext2GetInodeOffsetInBlock ( PEXT2_VOLUME_INFO  Volume,
ULONG  Inode 
)

Definition at line 902 of file ext2.c.

903 {
904  return (((Inode - 1) % Volume->SuperBlock->inodes_per_group) % Volume->InodesPerBlock);
905 }

Referenced by Ext2ReadInode().

◆ Ext2LookupFile()

BOOLEAN Ext2LookupFile ( PEXT2_VOLUME_INFO  Volume,
PCSTR  FileName,
PEXT2_FILE_INFO  Ext2FileInfo 
)

Definition at line 205 of file ext2.c.

206 {
207  UINT32 i;
208  ULONG NumberOfPathParts;
209  CHAR PathPart[261];
210  PVOID DirectoryBuffer;
211  ULONG DirectoryInode = EXT2_ROOT_INO;
212  EXT2_INODE InodeData;
213  EXT2_DIR_ENTRY DirectoryEntry;
214 
215  TRACE("Ext2LookupFile() FileName = %s\n", FileName);
216 
217  RtlZeroMemory(Ext2FileInfo, sizeof(EXT2_FILE_INFO));
218 
219  //
220  // Figure out how many sub-directories we are nested in
221  //
222  NumberOfPathParts = FsGetNumPathParts(FileName);
223 
224  //
225  // Loop once for each part
226  //
227  for (i=0; i<NumberOfPathParts; i++)
228  {
229  //
230  // Get first path part
231  //
232  FsGetFirstNameFromPath(PathPart, FileName);
233 
234  //
235  // Advance to the next part of the path
236  //
237  for (; (*FileName != '\\') && (*FileName != '/') && (*FileName != '\0'); FileName++)
238  {
239  }
240  FileName++;
241 
242  //
243  // Buffer the directory contents
244  //
245  if (!Ext2ReadDirectory(Volume, DirectoryInode, &DirectoryBuffer, &InodeData))
246  {
247  return FALSE;
248  }
249 
250  //
251  // Search for file name in directory
252  //
253  if (!Ext2SearchDirectoryBufferForFile(DirectoryBuffer, (ULONG)Ext2GetInodeFileSize(&InodeData), PathPart, &DirectoryEntry))
254  {
255  FrLdrTempFree(DirectoryBuffer, TAG_EXT_BUFFER);
256  return FALSE;
257  }
258 
259  FrLdrTempFree(DirectoryBuffer, TAG_EXT_BUFFER);
260 
261  DirectoryInode = DirectoryEntry.inode;
262  }
263 
264  if (!Ext2ReadInode(Volume, DirectoryInode, &InodeData))
265  {
266  return FALSE;
267  }
268 
269  if (((InodeData.mode & EXT2_S_IFMT) != EXT2_S_IFREG) &&
270  ((InodeData.mode & EXT2_S_IFMT) != EXT2_S_IFLNK))
271  {
272  FileSystemError("Inode is not a regular file or symbolic link.");
273  return FALSE;
274  }
275 
276  // Set the associated volume
277  Ext2FileInfo->Volume = Volume;
278 
279  // If it's a regular file or a regular symbolic link
280  // then get the block pointer list otherwise it must
281  // be a fast symbolic link which doesn't have a block list
282  if (((InodeData.mode & EXT2_S_IFMT) == EXT2_S_IFREG) ||
283  ((InodeData.mode & EXT2_S_IFMT) == EXT2_S_IFLNK && InodeData.size > FAST_SYMLINK_MAX_NAME_SIZE))
284  {
285  Ext2FileInfo->FileBlockList = Ext2ReadBlockPointerList(Volume, &InodeData);
286  if (Ext2FileInfo->FileBlockList == NULL)
287  {
288  return FALSE;
289  }
290  }
291  else
292  {
293  Ext2FileInfo->FileBlockList = NULL;
294  }
295 
296  Ext2FileInfo->FilePointer = 0;
297  Ext2FileInfo->FileSize = Ext2GetInodeFileSize(&InodeData);
298  RtlCopyMemory(&Ext2FileInfo->Inode, &InodeData, sizeof(EXT2_INODE));
299 
300  return TRUE;
301 }
ULONGLONG FilePointer
Definition: ext2.h:234
BOOLEAN Ext2ReadInode(PEXT2_VOLUME_INFO Volume, ULONG Inode, PEXT2_INODE InodeBuffer)
Definition: ext2.c:907
ULONG * FileBlockList
Definition: ext2.h:235
VOID FsGetFirstNameFromPath(PCHAR Buffer, PCSTR Path)
Definition: fs.c:356
#define EXT2_S_IFLNK
Definition: ext2.h:224
#define TRUE
Definition: types.h:120
BOOLEAN Ext2ReadDirectory(PEXT2_VOLUME_INFO Volume, ULONG Inode, PVOID *DirectoryBuffer, PEXT2_INODE InodePointer)
Definition: ext2.c:768
char CHAR
Definition: xmlstorage.h:175
ULONGLONG Ext2GetInodeFileSize(PEXT2_INODE Inode)
Definition: ext2.c:1078
EXT2_INODE Inode
Definition: ext2.h:236
ULONG FsGetNumPathParts(PCSTR Path)
Definition: fs.c:328
#define TAG_EXT_BUFFER
Definition: ext2.c:69
ULONG inode
Definition: ext2.h:160
#define FAST_SYMLINK_MAX_NAME_SIZE
Definition: ext2.h:227
PEXT2_VOLUME_INFO Volume
Definition: ext2.h:237
ULONG size
Definition: ext2.h:127
#define FALSE
Definition: types.h:117
unsigned int UINT32
VOID FileSystemError(PCSTR ErrorString)
Definition: fs.c:259
ULONGLONG FileSize
Definition: ext2.h:233
BOOLEAN Ext2SearchDirectoryBufferForFile(PVOID DirectoryBuffer, ULONG DirectorySize, PCHAR FileName, PEXT2_DIR_ENTRY DirectoryEntry)
Definition: ext2.c:303
#define EXT2_ROOT_INO
Definition: ext2.h:177
ULONG * Ext2ReadBlockPointerList(PEXT2_VOLUME_INFO Volume, PEXT2_INODE Inode)
Definition: ext2.c:1008
#define TRACE(s)
Definition: solgame.cpp:4
#define EXT2_S_IFMT
Definition: ext2.h:218
#define EXT2_S_IFREG
Definition: ext2.h:223
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
Definition: glfuncs.h:248
#define NULL
Definition: types.h:112
USHORT mode
Definition: ext2.h:125
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
FORCEINLINE VOID FrLdrTempFree(PVOID Allocation, ULONG Tag)
Definition: mm.h:197

Referenced by Ext2OpenFile(), Ext2ProcessEntry(), Ext2SetLinkInfo(), and Ext2SetRenameInfo().

◆ Ext2Mount()

const DEVVTBL* Ext2Mount ( ULONG  DeviceId)

Definition at line 1295 of file ext2.c.

1296 {
1298  EXT2_SUPER_BLOCK SuperBlock;
1300  ULONG Count;
1302 
1303  TRACE("Enter Ext2Mount(%lu)\n", DeviceId);
1304 
1305  /* Allocate data for volume information */
1307  if (!Volume)
1308  return NULL;
1310 
1311  /* Read the SuperBlock */
1312  Position.QuadPart = 2 * 512;
1313  Status = ArcSeek(DeviceId, &Position, SeekAbsolute);
1314  if (Status != ESUCCESS)
1315  {
1317  return NULL;
1318  }
1319  Status = ArcRead(DeviceId, &SuperBlock, sizeof(SuperBlock), &Count);
1320  if (Status != ESUCCESS || Count != sizeof(SuperBlock))
1321  {
1323  return NULL;
1324  }
1325 
1326  /* Check if SuperBlock is valid. If yes, return Ext2 function table. */
1327  if (SuperBlock.magic != EXT2_MAGIC)
1328  {
1330  return NULL;
1331  }
1332 
1333  Volume->DeviceId = DeviceId;
1334 
1335  /* Really open the volume */
1336  if (!Ext2OpenVolume(Volume))
1337  {
1339  return NULL;
1340  }
1341 
1342  /* Remember EXT2 volume information */
1343  Ext2Volumes[DeviceId] = Volume;
1344 
1345  /* Return success */
1346  TRACE("Ext2Mount(%lu) success\n", DeviceId);
1347  return &Ext2FuncTable;
1348 }
Definition: arc.h:32
static COORD Position
Definition: mouse.c:34
ULONG ARC_STATUS
Definition: arc.h:4
#define EXT2_MAGIC
Definition: ext2.h:43
FORCEINLINE PVOID FrLdrTempAlloc(_In_ SIZE_T Size, _In_ ULONG Tag)
Definition: mm.h:188
USHORT magic
Definition: ext2.h:86
Status
Definition: gdiplustypes.h:24
int Count
Definition: noreturn.cpp:7
#define TRACE(s)
Definition: solgame.cpp:4
ARC_STATUS ArcRead(ULONG FileId, VOID *Buffer, ULONG N, ULONG *Count)
Definition: fs.c:236
ARC_STATUS ArcSeek(ULONG FileId, LARGE_INTEGER *Position, SEEKMODE SeekMode)
Definition: fs.c:243
#define NULL
Definition: types.h:112
#define TAG_EXT_VOLUME
Definition: ext2.c:72
PEXT2_VOLUME_INFO Ext2Volumes[MAX_FDS]
Definition: ext2.c:65
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
const DEVVTBL Ext2FuncTable
Definition: ext2.c:1285
BOOLEAN Ext2OpenVolume(PEXT2_VOLUME_INFO Volume)
Definition: ext2.c:74
FORCEINLINE VOID FrLdrTempFree(PVOID Allocation, ULONG Tag)
Definition: mm.h:197

Referenced by ArcOpen().

◆ Ext2Open()

ARC_STATUS Ext2Open ( CHAR Path,
OPENMODE  OpenMode,
ULONG FileId 
)

Definition at line 1213 of file ext2.c.

1214 {
1217  ULONG DeviceId;
1218 
1219  /* Check parameters */
1220  if (OpenMode != OpenReadOnly)
1221  return EACCES;
1222 
1223  /* Get underlying device */
1224  DeviceId = FsGetDeviceId(*FileId);
1225  Volume = Ext2Volumes[DeviceId];
1226 
1227  TRACE("Ext2Open() FileName = %s\n", Path);
1228 
1229  /* Call the internal open method */
1230  // Status = Ext2OpenFile(Volume, Path, &FileHandle);
1232  if (!FileHandle)
1233  return ENOENT;
1234 
1235  /* Success, remember the handle */
1236  FsSetDeviceSpecific(*FileId, FileHandle);
1237  return ESUCCESS;
1238 }
Definition: arc.h:32
HANDLE FileHandle
Definition: stats.c:38
PEXT2_FILE_INFO Ext2OpenFile(PEXT2_VOLUME_INFO Volume, PCSTR FileName)
Definition: ext2.c:103
#define TRACE(s)
Definition: solgame.cpp:4
VOID FsSetDeviceSpecific(ULONG FileId, VOID *Specific)
Definition: fs.c:409
Definition: arc.h:34
PRTL_UNICODE_STRING_BUFFER Path
Definition: arc.h:46
ULONG FsGetDeviceId(ULONG FileId)
Definition: fs.c:423
PEXT2_VOLUME_INFO Ext2Volumes[MAX_FDS]
Definition: ext2.c:65
unsigned int ULONG
Definition: retypes.h:1

◆ Ext2OpenFile()

PEXT2_FILE_INFO Ext2OpenFile ( PEXT2_VOLUME_INFO  Volume,
PCSTR  FileName 
)

Definition at line 103 of file ext2.c.

104 {
105  EXT2_FILE_INFO TempExt2FileInfo;
107  CHAR SymLinkPath[EXT2_NAME_LEN];
108  CHAR FullPath[EXT2_NAME_LEN * 2];
110 
111  TRACE("Ext2OpenFile() FileName = %s\n", FileName);
112 
113  RtlZeroMemory(SymLinkPath, sizeof(SymLinkPath));
114 
115  // Lookup the file in the file system
116  if (!Ext2LookupFile(Volume, FileName, &TempExt2FileInfo))
117  {
118  return NULL;
119  }
120 
121  // If we got a symbolic link then fix up the path
122  // and re-call this function
123  if ((TempExt2FileInfo.Inode.mode & EXT2_S_IFMT) == EXT2_S_IFLNK)
124  {
125  TRACE("File is a symbolic link\n");
126 
127  // Now read in the symbolic link path
128  if (!Ext2ReadFileBig(&TempExt2FileInfo, TempExt2FileInfo.FileSize, NULL, SymLinkPath))
129  {
130  if (TempExt2FileInfo.FileBlockList != NULL)
131  {
133  }
134 
135  return NULL;
136  }
137 
138  TRACE("Symbolic link path = %s\n", SymLinkPath);
139 
140  // Get the full path
141  if (SymLinkPath[0] == '/' || SymLinkPath[0] == '\\')
142  {
143  // Symbolic link is an absolute path
144  // So copy it to FullPath, but skip over
145  // the '/' char at the beginning
146  strcpy(FullPath, &SymLinkPath[1]);
147  }
148  else
149  {
150  // Symbolic link is a relative path
151  // Copy the first part of the path
152  strcpy(FullPath, FileName);
153 
154  // Remove the last part of the path
155  for (Index=strlen(FullPath); Index>0; )
156  {
157  Index--;
158  if (FullPath[Index] == '/' || FullPath[Index] == '\\')
159  {
160  break;
161  }
162  }
163  FullPath[Index] = '\0';
164 
165  // Concatenate the symbolic link
166  strcat(FullPath, Index == 0 ? "" : "/");
167  strcat(FullPath, SymLinkPath);
168  }
169 
170  TRACE("Full file path = %s\n", FullPath);
171 
172  if (TempExt2FileInfo.FileBlockList != NULL)
173  {
175  }
176 
177  return Ext2OpenFile(Volume, FullPath);
178  }
179  else
180  {
182  if (FileHandle == NULL)
183  {
184  if (TempExt2FileInfo.FileBlockList != NULL)
185  {
187  }
188 
189  return NULL;
190  }
191 
192  RtlCopyMemory(FileHandle, &TempExt2FileInfo, sizeof(EXT2_FILE_INFO));
193 
194  return FileHandle;
195  }
196 }
ULONG * FileBlockList
Definition: ext2.h:235
BOOLEAN Ext2ReadFileBig(PEXT2_FILE_INFO Ext2FileInfo, ULONGLONG BytesToRead, ULONGLONG *BytesRead, PVOID Buffer)
Definition: ext2.c:359
BOOLEAN Ext2LookupFile(PEXT2_VOLUME_INFO Volume, PCSTR FileName, PEXT2_FILE_INFO Ext2FileInfo)
Definition: ext2.c:205
char * strcat(char *DstString, const char *SrcString)
Definition: utclib.c:568
#define EXT2_S_IFLNK
Definition: ext2.h:224
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
char CHAR
Definition: xmlstorage.h:175
EXT2_INODE Inode
Definition: ext2.h:236
uint32_t ULONG_PTR
Definition: typedefs.h:65
HANDLE FileHandle
Definition: stats.c:38
ULONGLONG FileSize
Definition: ext2.h:233
FORCEINLINE PVOID FrLdrTempAlloc(_In_ SIZE_T Size, _In_ ULONG Tag)
Definition: mm.h:188
PEXT2_FILE_INFO Ext2OpenFile(PEXT2_VOLUME_INFO Volume, PCSTR FileName)
Definition: ext2.c:103
#define TRACE(s)
Definition: solgame.cpp:4
#define TAG_EXT_BLOCK_LIST
Definition: ext2.c:67
_In_ WDFCOLLECTION _In_ ULONG Index
#define EXT2_S_IFMT
Definition: ext2.h:218
#define EXT2_NAME_LEN
Definition: ext2.h:156
#define TAG_EXT_FILE
Definition: ext2.c:68
#define NULL
Definition: types.h:112
USHORT mode
Definition: ext2.h:125
char * strcpy(char *DstString, const char *SrcString)
Definition: utclib.c:388
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
FORCEINLINE VOID FrLdrTempFree(PVOID Allocation, ULONG Tag)
Definition: mm.h:197

Referenced by Ext2Open().

◆ Ext2OpenVolume()

BOOLEAN Ext2OpenVolume ( PEXT2_VOLUME_INFO  Volume)

Definition at line 74 of file ext2.c.

75 {
76  TRACE("Ext2OpenVolume() DeviceId = %d\n", Volume->DeviceId);
77 
78 #if 0
79  /* Initialize the disk cache for this drive */
80  if (!CacheInitializeDrive(DriveNumber))
81  {
82  return FALSE;
83  }
84 #endif
85  Volume->BytesPerSector = SECTOR_SIZE;
86 
87  /* Read in the super block */
89  return FALSE;
90 
91  /* Read in the group descriptors */
93  return FALSE;
94 
95  return TRUE;
96 }
BOOLEAN Ext2ReadSuperBlock(PEXT2_VOLUME_INFO Volume)
Definition: ext2.c:572
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define TRACE(s)
Definition: solgame.cpp:4
BOOLEAN CacheInitializeDrive(UCHAR DriveNumber)
Definition: cache.c:37
#define SECTOR_SIZE
Definition: fs.h:22
BOOLEAN Ext2ReadGroupDescriptors(PEXT2_VOLUME_INFO Volume)
Definition: ext2.c:726

Referenced by Ext2Mount().

◆ Ext2Read()

ARC_STATUS Ext2Read ( ULONG  FileId,
VOID Buffer,
ULONG  N,
ULONG Count 
)

Definition at line 1240 of file ext2.c.

1241 {
1243  ULONGLONG BytesReadBig;
1244  BOOLEAN Success;
1245 
1246  //
1247  // Read data
1248  //
1249  Success = Ext2ReadFileBig(FileHandle, N, &BytesReadBig, Buffer);
1250  *Count = (ULONG)BytesReadBig;
1251 
1252  //
1253  // Check for success
1254  //
1255  if (Success)
1256  return ESUCCESS;
1257  else
1258  return EIO;
1259 }
BOOLEAN Ext2ReadFileBig(PEXT2_FILE_INFO Ext2FileInfo, ULONGLONG BytesToRead, ULONGLONG *BytesRead, PVOID Buffer)
Definition: ext2.c:359
Definition: arc.h:32
VOID * FsGetDeviceSpecific(ULONG FileId)
Definition: fs.c:416
HANDLE FileHandle
Definition: stats.c:38
unsigned char BOOLEAN
Definition: bufpool.h:45
int Count
Definition: noreturn.cpp:7
uint64_t ULONGLONG
Definition: typedefs.h:67
Definition: arc.h:40
unsigned int ULONG
Definition: retypes.h:1

Referenced by Ext2DispatchRequest().

◆ Ext2ReadBlock()

BOOLEAN Ext2ReadBlock ( PEXT2_VOLUME_INFO  Volume,
ULONG  BlockNumber,
PVOID  Buffer 
)

Definition at line 828 of file ext2.c.

829 {
830  CHAR ErrorString[80];
831 
832  TRACE("Ext2ReadBlock() BlockNumber = %d Buffer = 0x%x\n", BlockNumber, Buffer);
833 
834  // Make sure its a valid block
835  if (BlockNumber > Volume->SuperBlock->total_blocks)
836  {
837  sprintf(ErrorString, "Error reading block %d - block out of range.", (int) BlockNumber);
838  FileSystemError(ErrorString);
839  return FALSE;
840  }
841 
842  // Check to see if this is a sparse block
843  if (BlockNumber == 0)
844  {
845  TRACE("Block is part of a sparse file. Zeroing input buffer.\n");
846 
847  RtlZeroMemory(Buffer, Volume->BlockSizeInBytes);
848 
849  return TRUE;
850  }
851 
852  return Ext2ReadVolumeSectors(Volume, (ULONGLONG)BlockNumber * Volume->BlockSizeInSectors, Volume->BlockSizeInSectors, Buffer);
853 }
#define TRUE
Definition: types.h:120
char CHAR
Definition: xmlstorage.h:175
#define sprintf(buf, format,...)
Definition: sprintf.c:55
#define FALSE
Definition: types.h:117
VOID FileSystemError(PCSTR ErrorString)
Definition: fs.c:259
Definition: bufpool.h:45
#define TRACE(s)
Definition: solgame.cpp:4
uint64_t ULONGLONG
Definition: typedefs.h:67
BOOLEAN Ext2ReadVolumeSectors(PEXT2_VOLUME_INFO Volume, ULONGLONG SectorNumber, ULONG SectorCount, PVOID Buffer)
Definition: ext2.c:541
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262

Referenced by Ext2CopyDoubleIndirectBlockPointers(), Ext2CopyIndirectBlockPointers(), Ext2CopyTripleIndirectBlockPointers(), Ext2ReadFileBig(), Ext2ReadGroupDescriptor(), Ext2ReadGroupDescriptors(), and Ext2ReadPartialBlock().

◆ Ext2ReadBlockPointerList()

ULONG * Ext2ReadBlockPointerList ( PEXT2_VOLUME_INFO  Volume,
PEXT2_INODE  Inode 
)

Definition at line 1008 of file ext2.c.

1009 {
1011  ULONG BlockCount;
1012  ULONG* BlockList;
1013  ULONG CurrentBlockInList;
1014  ULONG CurrentBlock;
1015 
1016  TRACE("Ext2ReadBlockPointerList()\n");
1017 
1018  // Get the number of blocks this file occupies
1019  // I would just use Inode->i_blocks but it
1020  // doesn't seem to be the number of blocks
1021  // the file size corresponds to, but instead
1022  // it is much bigger.
1023  //BlockCount = Inode->i_blocks;
1024  FileSize = Ext2GetInodeFileSize(Inode);
1025  FileSize = ROUND_UP(FileSize, Volume->BlockSizeInBytes);
1026  BlockCount = (ULONG)(FileSize / Volume->BlockSizeInBytes);
1027 
1028  // Allocate the memory for the block list
1029  BlockList = FrLdrTempAlloc(BlockCount * sizeof(ULONG), TAG_EXT_BLOCK_LIST);
1030  if (BlockList == NULL)
1031  {
1032  return NULL;
1033  }
1034 
1035  RtlZeroMemory(BlockList, BlockCount * sizeof(ULONG));
1036 
1037  // Copy the direct block pointers
1038  for (CurrentBlockInList = CurrentBlock = 0;
1039  CurrentBlockInList < BlockCount && CurrentBlock < INDIRECT_BLOCKS;
1040  CurrentBlock++, CurrentBlockInList++)
1041  {
1042  BlockList[CurrentBlockInList] = Inode->blocks.dir_blocks[CurrentBlock];
1043  }
1044 
1045  // Copy the indirect block pointers
1046  if (CurrentBlockInList < BlockCount)
1047  {
1048  if (!Ext2CopyIndirectBlockPointers(Volume, BlockList, &CurrentBlockInList, BlockCount, Inode->blocks.indir_block))
1049  {
1050  FrLdrTempFree(BlockList, TAG_EXT_BLOCK_LIST);
1051  return NULL;
1052  }
1053  }
1054 
1055  // Copy the double indirect block pointers
1056  if (CurrentBlockInList < BlockCount)
1057  {
1058  if (!Ext2CopyDoubleIndirectBlockPointers(Volume, BlockList, &CurrentBlockInList, BlockCount, Inode->blocks.double_indir_block))
1059  {
1060  FrLdrTempFree(BlockList, TAG_EXT_BLOCK_LIST);
1061  return NULL;
1062  }
1063  }
1064 
1065  // Copy the triple indirect block pointers
1066  if (CurrentBlockInList < BlockCount)
1067  {
1068  if (!Ext2CopyTripleIndirectBlockPointers(Volume, BlockList, &CurrentBlockInList, BlockCount, Inode->blocks.tripple_indir_block))
1069  {
1070  FrLdrTempFree(BlockList, TAG_EXT_BLOCK_LIST);
1071  return NULL;
1072  }
1073  }
1074 
1075  return BlockList;
1076 }
#define ROUND_UP(n, align)
Definition: eventvwr.h:31
ULONGLONG Ext2GetInodeFileSize(PEXT2_INODE Inode)
Definition: ext2.c:1078
#define INDIRECT_BLOCKS
Definition: ext2.h:45
FORCEINLINE PVOID FrLdrTempAlloc(_In_ SIZE_T Size, _In_ ULONG Tag)
Definition: mm.h:188
#define TRACE(s)
Definition: solgame.cpp:4
#define TAG_EXT_BLOCK_LIST
Definition: ext2.c:67
uint64_t ULONGLONG
Definition: typedefs.h:67
BOOLEAN Ext2CopyTripleIndirectBlockPointers(PEXT2_VOLUME_INFO Volume, ULONG *BlockList, ULONG *CurrentBlockInList, ULONG BlockCount, ULONG TripleIndirectBlock)
Definition: ext2.c:1157
_Must_inspect_result_ _Out_ PLARGE_INTEGER FileSize
Definition: fsrtlfuncs.h:108
BOOLEAN Ext2CopyDoubleIndirectBlockPointers(PEXT2_VOLUME_INFO Volume, ULONG *BlockList, ULONG *CurrentBlockInList, ULONG BlockCount, ULONG DoubleIndirectBlock)
Definition: ext2.c:1122
struct ext2_inode::@163::datablocks blocks
#define NULL
Definition: types.h:112
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
BOOLEAN Ext2CopyIndirectBlockPointers(PEXT2_VOLUME_INFO Volume, ULONG *BlockList, ULONG *CurrentBlockInList, ULONG BlockCount, ULONG IndirectBlock)
Definition: ext2.c:1090
FORCEINLINE VOID FrLdrTempFree(PVOID Allocation, ULONG Tag)
Definition: mm.h:197

Referenced by Ext2LookupFile(), and Ext2ReadDirectory().

◆ Ext2ReadDirectory()

BOOLEAN Ext2ReadDirectory ( PEXT2_VOLUME_INFO  Volume,
ULONG  Inode,
PVOID DirectoryBuffer,
PEXT2_INODE  InodePointer 
)

Definition at line 768 of file ext2.c.

769 {
770  EXT2_FILE_INFO DirectoryFileInfo;
771 
772  TRACE("Ext2ReadDirectory() Inode = %d\n", Inode);
773 
774  // Read the directory inode
775  if (!Ext2ReadInode(Volume, Inode, InodePointer))
776  {
777  return FALSE;
778  }
779 
780  // Make sure it is a directory inode
781  if ((InodePointer->mode & EXT2_S_IFMT) != EXT2_S_IFDIR)
782  {
783  FileSystemError("Inode is not a directory.");
784  return FALSE;
785  }
786 
787  // Fill in file info struct so we can call Ext2ReadFileBig()
788  RtlZeroMemory(&DirectoryFileInfo, sizeof(EXT2_FILE_INFO));
789  DirectoryFileInfo.Volume = Volume;
790  DirectoryFileInfo.FileBlockList = Ext2ReadBlockPointerList(Volume, InodePointer);
791  DirectoryFileInfo.FilePointer = 0;
792  DirectoryFileInfo.FileSize = Ext2GetInodeFileSize(InodePointer);
793 
794  if (DirectoryFileInfo.FileBlockList == NULL)
795  {
796  return FALSE;
797  }
798 
799  //
800  // Now allocate the memory to hold the group descriptors
801  //
802  ASSERT(DirectoryFileInfo.FileSize <= 0xFFFFFFFF);
803  *DirectoryBuffer = (PEXT2_DIR_ENTRY)FrLdrTempAlloc((ULONG)DirectoryFileInfo.FileSize, TAG_EXT_BUFFER);
804 
805  //
806  // Make sure we got the memory
807  //
808  if (*DirectoryBuffer == NULL)
809  {
810  FrLdrTempFree(DirectoryFileInfo.FileBlockList, TAG_EXT_BLOCK_LIST);
811  FileSystemError("Out of memory.");
812  return FALSE;
813  }
814 
815  // Now read the root directory data
816  if (!Ext2ReadFileBig(&DirectoryFileInfo, DirectoryFileInfo.FileSize, NULL, *DirectoryBuffer))
817  {
818  FrLdrTempFree(*DirectoryBuffer, TAG_EXT_BUFFER);
819  *DirectoryBuffer = NULL;
820  FrLdrTempFree(DirectoryFileInfo.FileBlockList, TAG_EXT_BLOCK_LIST);
821  return FALSE;
822  }
823 
824  FrLdrTempFree(DirectoryFileInfo.FileBlockList, TAG_EXT_BLOCK_LIST);
825  return TRUE;
826 }
ULONGLONG FilePointer
Definition: ext2.h:234
BOOLEAN Ext2ReadInode(PEXT2_VOLUME_INFO Volume, ULONG Inode, PEXT2_INODE InodeBuffer)
Definition: ext2.c:907
ULONG * FileBlockList
Definition: ext2.h:235
BOOLEAN Ext2ReadFileBig(PEXT2_FILE_INFO Ext2FileInfo, ULONGLONG BytesToRead, ULONGLONG *BytesRead, PVOID Buffer)
Definition: ext2.c:359
#define TRUE
Definition: types.h:120
ULONGLONG Ext2GetInodeFileSize(PEXT2_INODE Inode)
Definition: ext2.c:1078
#define TAG_EXT_BUFFER
Definition: ext2.c:69
PEXT2_VOLUME_INFO Volume
Definition: ext2.h:237
#define FALSE
Definition: types.h:117
VOID FileSystemError(PCSTR ErrorString)
Definition: fs.c:259
ULONGLONG FileSize
Definition: ext2.h:233
FORCEINLINE PVOID FrLdrTempAlloc(_In_ SIZE_T Size, _In_ ULONG Tag)
Definition: mm.h:188
#define EXT2_S_IFDIR
Definition: ext2.h:221
ULONG * Ext2ReadBlockPointerList(PEXT2_VOLUME_INFO Volume, PEXT2_INODE Inode)
Definition: ext2.c:1008
#define TRACE(s)
Definition: solgame.cpp:4
#define ASSERT(a)
Definition: mode.c:44
#define TAG_EXT_BLOCK_LIST
Definition: ext2.c:67
#define EXT2_S_IFMT
Definition: ext2.h:218
struct ext2_dirent * PEXT2_DIR_ENTRY
Definition: ext2.h:174
#define NULL
Definition: types.h:112
USHORT mode
Definition: ext2.h:125
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
FORCEINLINE VOID FrLdrTempFree(PVOID Allocation, ULONG Tag)
Definition: mm.h:197

Referenced by Ext2LookupFile().

◆ Ext2ReadFileBig()

BOOLEAN Ext2ReadFileBig ( PEXT2_FILE_INFO  Ext2FileInfo,
ULONGLONG  BytesToRead,
ULONGLONG BytesRead,
PVOID  Buffer 
)

Definition at line 359 of file ext2.c.

360 {
361  PEXT2_VOLUME_INFO Volume = Ext2FileInfo->Volume;
362  ULONG BlockNumber;
363  ULONG BlockNumberIndex;
364  ULONG OffsetInBlock;
365  ULONG LengthInBlock;
366  ULONG NumberOfBlocks;
367 
368  TRACE("Ext2ReadFileBig() BytesToRead = %d Buffer = 0x%x\n", (ULONG)BytesToRead, Buffer);
369 
370  if (BytesRead != NULL)
371  {
372  *BytesRead = 0;
373  }
374 
375  // Make sure we have the block pointer list if we need it
376  if (Ext2FileInfo->FileBlockList == NULL)
377  {
378  // Block pointer list is NULL
379  // so this better be a fast symbolic link or else
380  if (((Ext2FileInfo->Inode.mode & EXT2_S_IFMT) != EXT2_S_IFLNK) ||
381  (Ext2FileInfo->FileSize > FAST_SYMLINK_MAX_NAME_SIZE))
382  {
383  FileSystemError("Block pointer list is NULL and file is not a fast symbolic link.");
384  return FALSE;
385  }
386  }
387 
388  //
389  // If the user is trying to read past the end of
390  // the file then return success with BytesRead == 0.
391  //
392  if (Ext2FileInfo->FilePointer >= Ext2FileInfo->FileSize)
393  {
394  return TRUE;
395  }
396 
397  //
398  // If the user is trying to read more than there is to read
399  // then adjust the amount to read.
400  //
401  if ((Ext2FileInfo->FilePointer + BytesToRead) > Ext2FileInfo->FileSize)
402  {
403  BytesToRead = (Ext2FileInfo->FileSize - Ext2FileInfo->FilePointer);
404  }
405 
406  // Check if this is a fast symbolic link
407  // if so then the read is easy
408  if (((Ext2FileInfo->Inode.mode & EXT2_S_IFMT) == EXT2_S_IFLNK) &&
409  (Ext2FileInfo->FileSize <= FAST_SYMLINK_MAX_NAME_SIZE))
410  {
411  TRACE("Reading fast symbolic link data\n");
412 
413  // Copy the data from the link
414  RtlCopyMemory(Buffer, (PVOID)((ULONG_PTR)Ext2FileInfo->FilePointer + Ext2FileInfo->Inode.symlink), (ULONG)BytesToRead);
415 
416  if (BytesRead != NULL)
417  {
418  *BytesRead = BytesToRead;
419  }
420  // Ext2FileInfo->FilePointer += BytesToRead;
421 
422  return TRUE;
423  }
424 
425  //
426  // Ok, now we have to perform at most 3 calculations
427  // I'll draw you a picture (using nifty ASCII art):
428  //
429  // CurrentFilePointer -+
430  // |
431  // +----------------+
432  // |
433  // +-----------+-----------+-----------+-----------+
434  // | Block 1 | Block 2 | Block 3 | Block 4 |
435  // +-----------+-----------+-----------+-----------+
436  // | |
437  // +---------------+--------------------+
438  // |
439  // BytesToRead -------+
440  //
441  // 1 - The first calculation (and read) will align
442  // the file pointer with the next block.
443  // boundary (if we are supposed to read that much)
444  // 2 - The next calculation (and read) will read
445  // in all the full blocks that the requested
446  // amount of data would cover (in this case
447  // blocks 2 & 3).
448  // 3 - The last calculation (and read) would read
449  // in the remainder of the data requested out of
450  // the last block.
451  //
452 
453  //
454  // Only do the first read if we
455  // aren't aligned on a block boundary
456  //
457  if (Ext2FileInfo->FilePointer % Volume->BlockSizeInBytes)
458  {
459  //
460  // Do the math for our first read
461  //
462  BlockNumberIndex = (ULONG)(Ext2FileInfo->FilePointer / Volume->BlockSizeInBytes);
463  BlockNumber = Ext2FileInfo->FileBlockList[BlockNumberIndex];
464  OffsetInBlock = (Ext2FileInfo->FilePointer % Volume->BlockSizeInBytes);
465  LengthInBlock = (ULONG)((BytesToRead > (Volume->BlockSizeInBytes - OffsetInBlock)) ? (Volume->BlockSizeInBytes - OffsetInBlock) : BytesToRead);
466 
467  //
468  // Now do the read and update BytesRead, BytesToRead, FilePointer, & Buffer
469  //
470  if (!Ext2ReadPartialBlock(Volume, BlockNumber, OffsetInBlock, LengthInBlock, Buffer))
471  {
472  return FALSE;
473  }
474  if (BytesRead != NULL)
475  {
476  *BytesRead += LengthInBlock;
477  }
478  BytesToRead -= LengthInBlock;
479  Ext2FileInfo->FilePointer += LengthInBlock;
480  Buffer = (PVOID)((ULONG_PTR)Buffer + LengthInBlock);
481  }
482 
483  //
484  // Do the math for our second read (if any data left)
485  //
486  if (BytesToRead > 0)
487  {
488  //
489  // Determine how many full clusters we need to read
490  //
491  NumberOfBlocks = (ULONG)(BytesToRead / Volume->BlockSizeInBytes);
492 
493  while (NumberOfBlocks > 0)
494  {
495  BlockNumberIndex = (ULONG)(Ext2FileInfo->FilePointer / Volume->BlockSizeInBytes);
496  BlockNumber = Ext2FileInfo->FileBlockList[BlockNumberIndex];
497 
498  //
499  // Now do the read and update BytesRead, BytesToRead, FilePointer, & Buffer
500  //
501  if (!Ext2ReadBlock(Volume, BlockNumber, Buffer))
502  {
503  return FALSE;
504  }
505  if (BytesRead != NULL)
506  {
507  *BytesRead += Volume->BlockSizeInBytes;
508  }
509  BytesToRead -= Volume->BlockSizeInBytes;
510  Ext2FileInfo->FilePointer += Volume->BlockSizeInBytes;
511  Buffer = (PVOID)((ULONG_PTR)Buffer + Volume->BlockSizeInBytes);
512  NumberOfBlocks--;
513  }
514  }
515 
516  //
517  // Do the math for our third read (if any data left)
518  //
519  if (BytesToRead > 0)
520  {
521  BlockNumberIndex = (ULONG)(Ext2FileInfo->FilePointer / Volume->BlockSizeInBytes);
522  BlockNumber = Ext2FileInfo->FileBlockList[BlockNumberIndex];
523 
524  //
525  // Now do the read and update BytesRead & FilePointer
526  //
527  if (!Ext2ReadPartialBlock(Volume, BlockNumber, 0, (ULONG)BytesToRead, Buffer))
528  {
529  return FALSE;
530  }
531  if (BytesRead != NULL)
532  {
533  *BytesRead += BytesToRead;
534  }
535  Ext2FileInfo->FilePointer += BytesToRead;
536  }
537 
538  return TRUE;
539 }
ULONGLONG FilePointer
Definition: ext2.h:234
ULONG * FileBlockList
Definition: ext2.h:235
#define EXT2_S_IFLNK
Definition: ext2.h:224
IN BOOLEAN OUT PSTR Buffer
Definition: progress.h:34
#define TRUE
Definition: types.h:120
EXT2_INODE Inode
Definition: ext2.h:236
#define FAST_SYMLINK_MAX_NAME_SIZE
Definition: ext2.h:227
BOOLEAN Ext2ReadBlock(PEXT2_VOLUME_INFO Volume, ULONG BlockNumber, PVOID Buffer)
Definition: ext2.c:828
_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
Definition: wdfiotarget.h:859
uint32_t ULONG_PTR
Definition: typedefs.h:65
PEXT2_VOLUME_INFO Volume
Definition: ext2.h:237
#define FALSE
Definition: types.h:117
VOID FileSystemError(PCSTR ErrorString)
Definition: fs.c:259
ULONGLONG FileSize
Definition: ext2.h:233
Definition: bufpool.h:45
void * PVOID
Definition: retypes.h:9
#define TRACE(s)
Definition: solgame.cpp:4
#define EXT2_S_IFMT
Definition: ext2.h:218
char symlink[60]
Definition: ext2.h:146
BOOLEAN Ext2ReadPartialBlock(PEXT2_VOLUME_INFO Volume, ULONG BlockNumber, ULONG StartingOffset, ULONG Length, PVOID Buffer)
Definition: ext2.c:859
#define NULL
Definition: types.h:112
USHORT mode
Definition: ext2.h:125
unsigned int ULONG
Definition: retypes.h:1
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263

Referenced by Ext2OpenFile(), Ext2Read(), and Ext2ReadDirectory().

◆ Ext2ReadGroupDescriptor()

BOOLEAN Ext2ReadGroupDescriptor ( PEXT2_VOLUME_INFO  Volume,
ULONG  Group,
PEXT2_GROUP_DESC  GroupBuffer 
)

Definition at line 983 of file ext2.c.

984 {
985  TRACE("Ext2ReadGroupDescriptor()\n");
986 
987 #if 0
988  if (!Ext2ReadBlock(Volume, Ext2GetGroupDescBlockNumber(Volume, Group), (PVOID)FILESYSBUFFER))
989  {
990  return FALSE;
991  }
992  RtlCopyMemory(GroupBuffer, (PVOID)(FILESYSBUFFER + Ext2GetGroupDescOffsetInBlock(Volume, Group)), sizeof(EXT2_GROUP_DESC));
993 #endif
994 
995  RtlCopyMemory(GroupBuffer, &Volume->GroupDescriptors[Group], sizeof(EXT2_GROUP_DESC));
996 
997  TRACE("Dumping group descriptor:\n");
998  TRACE("block_id = %d\n", GroupBuffer->block_id);
999  TRACE("inode_id = %d\n", GroupBuffer->inode_id);
1000  TRACE("inode_table_id = %d\n", GroupBuffer->inode_table_id);
1001  TRACE("free_blocks = %d\n", GroupBuffer->free_blocks);
1002  TRACE("free_inodes = %d\n", GroupBuffer->free_inodes);
1003  TRACE("used_dirs = %d\n", GroupBuffer->used_dirs);
1004 
1005  return TRUE;
1006 }
ULONG block_id
Definition: ext2.h:112
ULONG inode_id
Definition: ext2.h:113
#define TRUE
Definition: types.h:120
USHORT free_inodes
Definition: ext2.h:116
_In_opt_ PSID Group
Definition: rtlfuncs.h:1605
BOOLEAN Ext2ReadBlock(PEXT2_VOLUME_INFO Volume, ULONG BlockNumber, PVOID Buffer)
Definition: ext2.c:828
#define FALSE
Definition: types.h:117
ULONG inode_table_id
Definition: ext2.h:114
#define TRACE(s)
Definition: solgame.cpp:4
USHORT free_blocks
Definition: ext2.h:115
USHORT used_dirs
Definition: ext2.h:117
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263

Referenced by Ext2ReadInode().

◆ Ext2ReadGroupDescriptors()

BOOLEAN Ext2ReadGroupDescriptors ( PEXT2_VOLUME_INFO  Volume)

Definition at line 726 of file ext2.c.

727 {
728  ULONG GroupDescBlockCount;
729  ULONG BlockNumber;
730  PUCHAR CurrentGroupDescBlock;
731 
732  TRACE("Ext2ReadGroupDescriptors()\n");
733 
734  /* Free any memory previously allocated */
735  if (Volume->GroupDescriptors != NULL)
736  {
737  FrLdrTempFree(Volume->GroupDescriptors, TAG_EXT_GROUP_DESC);
738  Volume->GroupDescriptors = NULL;
739  }
740 
741  /* Now allocate the memory to hold the group descriptors */
742  GroupDescBlockCount = ROUND_UP(Volume->GroupCount, Volume->GroupDescPerBlock) / Volume->GroupDescPerBlock;
743  Volume->GroupDescriptors = (PEXT2_GROUP_DESC)FrLdrTempAlloc(GroupDescBlockCount * Volume->BlockSizeInBytes, TAG_EXT_GROUP_DESC);
744  if (Volume->GroupDescriptors == NULL)
745  {
746  FileSystemError("Out of memory.");
747  return FALSE;
748  }
749 
750  // Now read the group descriptors
751  CurrentGroupDescBlock = (PUCHAR)Volume->GroupDescriptors;
752  BlockNumber = Volume->SuperBlock->first_data_block + 1;
753 
754  while (GroupDescBlockCount--)
755  {
756  if (!Ext2ReadBlock(Volume, BlockNumber, CurrentGroupDescBlock))
757  {
758  return FALSE;
759  }
760 
761  BlockNumber++;
762  CurrentGroupDescBlock += Volume->BlockSizeInBytes;
763  }
764 
765  return TRUE;
766 }
while(CdLookupNextInitialFileDirent(IrpContext, Fcb, FileContext))
#define ROUND_UP(n, align)
Definition: eventvwr.h:31
#define TRUE
Definition: types.h:120
unsigned char * PUCHAR
Definition: retypes.h:3
struct ext2_block_group * PEXT2_GROUP_DESC
Definition: ext2.h:173
BOOLEAN Ext2ReadBlock(PEXT2_VOLUME_INFO Volume, ULONG BlockNumber, PVOID Buffer)
Definition: ext2.c:828
#define FALSE
Definition: types.h:117
VOID FileSystemError(PCSTR ErrorString)
Definition: fs.c:259
FORCEINLINE PVOID FrLdrTempAlloc(_In_ SIZE_T Size, _In_ ULONG Tag)
Definition: mm.h:188
#define TRACE(s)
Definition: solgame.cpp:4
#define NULL
Definition: types.h:112
unsigned int ULONG
Definition: retypes.h:1
#define TAG_EXT_GROUP_DESC
Definition: ext2.c:71
FORCEINLINE VOID FrLdrTempFree(PVOID Allocation, ULONG Tag)
Definition: mm.h:197

Referenced by Ext2OpenVolume().

◆ Ext2ReadInode()

BOOLEAN Ext2ReadInode ( PEXT2_VOLUME_INFO  Volume,
ULONG  Inode,
PEXT2_INODE  InodeBuffer 
)

Definition at line 907 of file ext2.c.

908 {
909  ULONG InodeGroupNumber;
910  ULONG InodeBlockNumber;
911  ULONG InodeOffsetInBlock;
912  CHAR ErrorString[80];
913  EXT2_GROUP_DESC GroupDescriptor;
914 
915  TRACE("Ext2ReadInode() Inode = %d\n", Inode);
916 
917  // Make sure its a valid inode
918  if ((Inode < 1) || (Inode > Volume->SuperBlock->total_inodes))
919  {
920  sprintf(ErrorString, "Error reading inode %ld - inode out of range.", Inode);
921  FileSystemError(ErrorString);
922  return FALSE;
923  }
924 
925  // Get inode group & block number and offset in block
926  InodeGroupNumber = Ext2GetInodeGroupNumber(Volume, Inode);
927  InodeBlockNumber = Ext2GetInodeBlockNumber(Volume, Inode);
928  InodeOffsetInBlock = Ext2GetInodeOffsetInBlock(Volume, Inode);
929  TRACE("InodeGroupNumber = %d\n", InodeGroupNumber);
930  TRACE("InodeBlockNumber = %d\n", InodeBlockNumber);
931  TRACE("InodeOffsetInBlock = %d\n", InodeOffsetInBlock);
932 
933  // Read the group descriptor
934  if (!Ext2ReadGroupDescriptor(Volume, InodeGroupNumber, &GroupDescriptor))
935  {
936  return FALSE;
937  }
938 
939  // Add the start block of the inode table to the inode block number
940  InodeBlockNumber += GroupDescriptor.inode_table_id;
941  TRACE("InodeBlockNumber (after group desc correction) = %d\n", InodeBlockNumber);
942 
943  // Read the block
945  InodeBlockNumber,
946  (InodeOffsetInBlock * EXT2_INODE_SIZE(Volume->SuperBlock)),
947  sizeof(EXT2_INODE),
948  InodeBuffer))
949  {
950  return FALSE;
951  }
952 
953  TRACE("Dumping inode information:\n");
954  TRACE("mode = 0x%x\n", InodeBuffer->mode);
955  TRACE("uid = %d\n", InodeBuffer->uid);
956  TRACE("size = %d\n", InodeBuffer->size);
957  TRACE("atime = %d\n", InodeBuffer->atime);
958  TRACE("ctime = %d\n", InodeBuffer->ctime);
959  TRACE("mtime = %d\n", InodeBuffer->mtime);
960  TRACE("dtime = %d\n", InodeBuffer->dtime);
961  TRACE("gid = %d\n", InodeBuffer->gid);
962  TRACE("nlinks = %d\n", InodeBuffer->nlinks);
963  TRACE("blockcnt = %d\n", InodeBuffer->blockcnt);
964  TRACE("flags = 0x%x\n", InodeBuffer->flags);
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);
973  TRACE("version = %d\n", InodeBuffer->version);
974  TRACE("acl = %d\n", InodeBuffer->acl);
975  TRACE("dir_acl = %d\n", InodeBuffer->dir_acl);
976  TRACE("fragment_addr = %d\n", InodeBuffer->fragment_addr);
977  TRACE("osd2 = { %d, %d, %d }\n",
978  InodeBuffer->osd2[0], InodeBuffer->osd2[1], InodeBuffer->osd2[2]);
979 
980  return TRUE;
981 }
ULONG mtime
Definition: ext2.h:130
ULONG atime
Definition: ext2.h:128
#define TRUE
Definition: types.h:120
ULONG fragment_addr
Definition: ext2.h:151
ULONG dtime
Definition: ext2.h:131
char CHAR
Definition: xmlstorage.h:175
BOOLEAN Ext2ReadGroupDescriptor(PEXT2_VOLUME_INFO Volume, ULONG Group, PEXT2_GROUP_DESC GroupBuffer)
Definition: ext2.c:983
ULONG Ext2GetInodeOffsetInBlock(PEXT2_VOLUME_INFO Volume, ULONG Inode)
Definition: ext2.c:902
ULONG dir_acl
Definition: ext2.h:150
USHORT uid
Definition: ext2.h:126
ULONG acl
Definition: ext2.h:149
ULONG ctime
Definition: ext2.h:129
#define sprintf(buf, format,...)
Definition: sprintf.c:55
USHORT gid
Definition: ext2.h:132
ULONG size
Definition: ext2.h:127
#define FALSE
Definition: types.h:117
VOID FileSystemError(PCSTR ErrorString)
Definition: fs.c:259
ULONG version
Definition: ext2.h:148
ULONG flags
Definition: ext2.h:135
ULONG blockcnt
Definition: ext2.h:134
#define EXT2_INODE_SIZE(sb)
Definition: ext2.h:192
ULONG inode_table_id
Definition: ext2.h:114
#define TRACE(s)
Definition: solgame.cpp:4
ULONG osd2[3]
Definition: ext2.h:152
ULONG Ext2GetInodeBlockNumber(PEXT2_VOLUME_INFO Volume, ULONG Inode)
Definition: ext2.c:897
USHORT nlinks
Definition: ext2.h:133
struct ext2_inode::@163::datablocks blocks
BOOLEAN Ext2ReadPartialBlock(PEXT2_VOLUME_INFO Volume, ULONG BlockNumber, ULONG StartingOffset, ULONG Length, PVOID Buffer)
Definition: ext2.c:859
USHORT mode
Definition: ext2.h:125
ULONG osd1
Definition: ext2.h:136
ULONG Ext2GetInodeGroupNumber(PEXT2_VOLUME_INFO Volume, ULONG Inode)
Definition: ext2.c:892
unsigned int ULONG
Definition: retypes.h:1

Referenced by Ext2LookupFile(), Ext2QueryDirectory(), Ext2ReadDirectory(), Ext2ReadSymlink(), and Ext2SetParentEntry().

◆ Ext2ReadPartialBlock()

BOOLEAN Ext2ReadPartialBlock ( PEXT2_VOLUME_INFO  Volume,
ULONG  BlockNumber,
ULONG  StartingOffset,
ULONG  Length,
PVOID  Buffer 
)

Definition at line 859 of file ext2.c.

860 {
861  PVOID TempBuffer;
862 
863  TRACE("Ext2ReadPartialBlock() BlockNumber = %d StartingOffset = %d Length = %d Buffer = 0x%x\n", BlockNumber, StartingOffset, Length, Buffer);
864 
865  TempBuffer = FrLdrTempAlloc(Volume->BlockSizeInBytes, TAG_EXT_BUFFER);
866 
867  if (!Ext2ReadBlock(Volume, BlockNumber, TempBuffer))
868  {
869  FrLdrTempFree(TempBuffer, TAG_EXT_BUFFER);
870  return FALSE;
871  }
872 
873  RtlCopyMemory(Buffer, ((PUCHAR)TempBuffer + StartingOffset), Length);
874 
875  FrLdrTempFree(TempBuffer, TAG_EXT_BUFFER);
876 
877  return TRUE;
878 }
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
_In_ PFCB _In_ LONGLONG StartingOffset
Definition: cdprocs.h:290
#define TRUE
Definition: types.h:120
unsigned char * PUCHAR
Definition: retypes.h:3
#define TAG_EXT_BUFFER
Definition: ext2.c:69
BOOLEAN Ext2ReadBlock(PEXT2_VOLUME_INFO Volume, ULONG BlockNumber, PVOID Buffer)
Definition: ext2.c:828
#define FALSE
Definition: types.h:117
FORCEINLINE PVOID FrLdrTempAlloc(_In_ SIZE_T Size, _In_ ULONG Tag)
Definition: mm.h:188
Definition: bufpool.h:45
#define TRACE(s)
Definition: solgame.cpp:4
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
FORCEINLINE VOID FrLdrTempFree(PVOID Allocation, ULONG Tag)
Definition: mm.h:197

Referenced by Ext2ReadFileBig(), and Ext2ReadInode().

◆ Ext2ReadSuperBlock()

BOOLEAN Ext2ReadSuperBlock ( PEXT2_VOLUME_INFO  Volume)

Definition at line 572 of file ext2.c.

573 {
574  PEXT2_SUPER_BLOCK SuperBlock = Volume->SuperBlock;
576  ULONG Count;
578 
579  TRACE("Ext2ReadSuperBlock()\n");
580 
581 #if 0
582  /* Free any memory previously allocated */
583  if (SuperBlock != NULL)
584  {
585  FrLdrTempFree(SuperBlock, TAG_EXT_SUPER_BLOCK);
586  SuperBlock = NULL;
587  }
588 #endif
589 
590  /* Allocate the memory to hold the super block if needed */
591  if (SuperBlock == NULL)
592  {
594  if (SuperBlock == NULL)
595  {
596  FileSystemError("Out of memory.");
597  return FALSE;
598  }
599  }
600  Volume->SuperBlock = SuperBlock;
601 
602  /* Reset its contents */
603  RtlZeroMemory(SuperBlock, 1024);
604 
605  /* Read the SuperBlock */
606  Position.QuadPart = 2 * 512;
607  Status = ArcSeek(Volume->DeviceId, &Position, SeekAbsolute);
608  if (Status != ESUCCESS)
609  return FALSE;
610  Status = ArcRead(Volume->DeviceId, SuperBlock, 2 * 512, &Count);
611  if (Status != ESUCCESS || Count != 2 * 512)
612  return FALSE;
613 
614  TRACE("Dumping super block:\n");
615  TRACE("total_inodes: %d\n", SuperBlock->total_inodes);
616  TRACE("total_blocks: %d\n", SuperBlock->total_blocks);
617  TRACE("reserved_blocks: %d\n", SuperBlock->reserved_blocks);
618  TRACE("free_blocks: %d\n", SuperBlock->free_blocks);
619  TRACE("free_inodes: %d\n", SuperBlock->free_inodes);
620  TRACE("first_data_block: %d\n", SuperBlock->first_data_block);
621  TRACE("log2_block_size: %d\n", SuperBlock->log2_block_size);
622  TRACE("log2_fragment_size: %d\n", SuperBlock->log2_fragment_size);
623  TRACE("blocks_per_group: %d\n", SuperBlock->blocks_per_group);
624  TRACE("fragments_per_group: %d\n", SuperBlock->fragments_per_group);
625  TRACE("inodes_per_group: %d\n", SuperBlock->inodes_per_group);
626  TRACE("mtime: %d\n", SuperBlock->mtime);
627  TRACE("utime: %d\n", SuperBlock->utime);
628  TRACE("mnt_count: %d\n", SuperBlock->mnt_count);
629  TRACE("max_mnt_count: %d\n", SuperBlock->max_mnt_count);
630  TRACE("magic: 0x%x\n", SuperBlock->magic);
631  TRACE("fs_state: %d\n", SuperBlock->fs_state);
632  TRACE("error_handling: %d\n", SuperBlock->error_handling);
633  TRACE("minor_revision_level: %d\n", SuperBlock->minor_revision_level);
634  TRACE("lastcheck: %d\n", SuperBlock->lastcheck);
635  TRACE("checkinterval: %d\n", SuperBlock->checkinterval);
636  TRACE("creator_os: %d\n", SuperBlock->creator_os);
637  TRACE("revision_level: %d\n", SuperBlock->revision_level);
638  TRACE("uid_reserved: %d\n", SuperBlock->uid_reserved);
639  TRACE("gid_reserved: %d\n", SuperBlock->gid_reserved);
640  TRACE("first_inode: %d\n", SuperBlock->first_inode);
641  TRACE("inode_size: %d\n", SuperBlock->inode_size);
642  TRACE("block_group_number: %d\n", SuperBlock->block_group_number);
643  TRACE("feature_compatibility: 0x%x\n", SuperBlock->feature_compatibility);
644  TRACE("feature_incompat: 0x%x\n", SuperBlock->feature_incompat);
645  TRACE("feature_ro_compat: 0x%x\n", SuperBlock->feature_ro_compat);
646  TRACE("unique_id = { 0x%x, 0x%x, 0x%x, 0x%x }\n",
647  SuperBlock->unique_id[0], SuperBlock->unique_id[1],
648  SuperBlock->unique_id[2], SuperBlock->unique_id[3]);
649  TRACE("volume_name = '%.16s'\n", SuperBlock->volume_name);
650  TRACE("last_mounted_on = '%.64s'\n", SuperBlock->last_mounted_on);
651  TRACE("compression_info = 0x%x\n", SuperBlock->compression_info);
652 
653  //
654  // Check the super block magic
655  //
656  if (SuperBlock->magic != EXT2_MAGIC)
657  {
658  FileSystemError("Invalid super block magic (0xef53)");
659  return FALSE;
660  }
661 
662  //
663  // Check the revision level
664  //
665  if (SuperBlock->revision_level > EXT2_DYNAMIC_REVISION)
666  {
667  FileSystemError("FreeLoader does not understand the revision of this EXT2/EXT3 filesystem.\nPlease update FreeLoader.");
668  return FALSE;
669  }
670 
671  //
672  // Check the feature set
673  // Don't need to check the compatible or read-only compatible features
674  // because we only mount the filesystem as read-only
675  //
676  if ((SuperBlock->revision_level >= EXT2_DYNAMIC_REVISION) &&
677  (/*((SuperBlock->s_feature_compat & ~EXT3_FEATURE_COMPAT_SUPP) != 0) ||*/
678  /*((SuperBlock->s_feature_ro_compat & ~EXT3_FEATURE_RO_COMPAT_SUPP) != 0) ||*/
679  ((SuperBlock->feature_incompat & ~EXT3_FEATURE_INCOMPAT_SUPP) != 0)))
680  {
681  FileSystemError("FreeLoader does not understand features of this EXT2/EXT3 filesystem.\nPlease update FreeLoader.");
682  return FALSE;
683  }
684 
685  // Calculate the group count
686  Volume->GroupCount = (SuperBlock->total_blocks - SuperBlock->first_data_block + SuperBlock->blocks_per_group - 1) / SuperBlock->blocks_per_group;
687  TRACE("Ext2GroupCount: %d\n", Volume->GroupCount);
688 
689  // Calculate the block size
690  Volume->BlockSizeInBytes = 1024 << SuperBlock->log2_block_size;
691  Volume->BlockSizeInSectors = Volume->BlockSizeInBytes / Volume->BytesPerSector;
692  TRACE("Ext2BlockSizeInBytes: %d\n", Volume->BlockSizeInBytes);
693  TRACE("Ext2BlockSizeInSectors: %d\n", Volume->BlockSizeInSectors);
694 
695  // Calculate the fragment size
696  if (SuperBlock->log2_fragment_size >= 0)
697  {
698  Volume->FragmentSizeInBytes = 1024 << SuperBlock->log2_fragment_size;
699  }
700  else
701  {
702  Volume->FragmentSizeInBytes = 1024 >> -(SuperBlock->log2_fragment_size);
703  }
704  Volume->FragmentSizeInSectors = Volume->FragmentSizeInBytes / Volume->BytesPerSector;
705  TRACE("Ext2FragmentSizeInBytes: %d\n", Volume->FragmentSizeInBytes);
706  TRACE("Ext2FragmentSizeInSectors: %d\n", Volume->FragmentSizeInSectors);
707 
708  // Verify that the fragment size and the block size are equal
709  if (Volume->BlockSizeInBytes != Volume->FragmentSizeInBytes)
710  {
711  FileSystemError("The fragment size must be equal to the block size.");
712  return FALSE;
713  }
714 
715  // Calculate the number of inodes in one block
716  Volume->InodesPerBlock = Volume->BlockSizeInBytes / EXT2_INODE_SIZE(SuperBlock);
717  TRACE("Ext2InodesPerBlock: %d\n", Volume->InodesPerBlock);
718 
719  // Calculate the number of group descriptors in one block
720  Volume->GroupDescPerBlock = EXT2_DESC_PER_BLOCK(SuperBlock);
721  TRACE("Ext2GroupDescPerBlock: %d\n", Volume->GroupDescPerBlock);
722 
723  return TRUE;
724 }
ULONG feature_incompat
Definition: ext2.h:100
ULONG free_blocks
Definition: ext2.h:74
USHORT uid_reserved
Definition: ext2.h:94
USHORT inode_size
Definition: ext2.h:97
ULONG first_inode
Definition: ext2.h:96
USHORT fs_state
Definition: ext2.h:87
ULONG checkinterval
Definition: ext2.h:91
Definition: arc.h:32
struct ext2_sblock * PEXT2_SUPER_BLOCK
Definition: ext2.h:171
#define TRUE
Definition: types.h:120
#define EXT3_FEATURE_INCOMPAT_SUPP
Definition: ext2.h:180
static COORD Position
Definition: mouse.c:34
ULONG feature_ro_compat
Definition: ext2.h:101
ULONG ARC_STATUS
Definition: arc.h:4
USHORT max_mnt_count
Definition: ext2.h:85
ULONG free_inodes
Definition: ext2.h:75
ULONG unique_id[4]
Definition: ext2.h:102
ULONG total_inodes
Definition: ext2.h:71
ULONG mtime
Definition: ext2.h:82
ULONG feature_compatibility
Definition: ext2.h:99
char volume_name[16]
Definition: ext2.h:103
#define EXT2_MAGIC
Definition: ext2.h:43
ULONG reserved_blocks
Definition: ext2.h:73
#define FALSE
Definition: types.h:117
VOID FileSystemError(PCSTR ErrorString)
Definition: fs.c:259
ULONG compression_info
Definition: ext2.h:105
FORCEINLINE PVOID FrLdrTempAlloc(_In_ SIZE_T Size, _In_ ULONG Tag)
Definition: mm.h:188
ULONG utime
Definition: ext2.h:83
USHORT magic
Definition: ext2.h:86
ULONG log2_block_size
Definition: ext2.h:77
USHORT mnt_count
Definition: ext2.h:84
Status
Definition: gdiplustypes.h:24
#define EXT2_INODE_SIZE(sb)
Definition: ext2.h:192
int Count
Definition: noreturn.cpp:7
#define TRACE(s)
Definition: solgame.cpp:4
ULONG revision_level
Definition: ext2.h:93
ULONG first_data_block
Definition: ext2.h:76
USHORT gid_reserved
Definition: ext2.h:95
ARC_STATUS ArcRead(ULONG FileId, VOID *Buffer, ULONG N, ULONG *Count)
Definition: fs.c:236
#define EXT2_DESC_PER_BLOCK(s)
Definition: ext2.h:196
ULONG blocks_per_group
Definition: ext2.h:79
ARC_STATUS ArcSeek(ULONG FileId, LARGE_INTEGER *Position, SEEKMODE SeekMode)
Definition: fs.c:243
char last_mounted_on[64]
Definition: ext2.h:104
ULONG total_blocks
Definition: ext2.h:72
#define TAG_EXT_SUPER_BLOCK
Definition: ext2.c:70
#define NULL
Definition: types.h:112
#define EXT2_DYNAMIC_REVISION
Definition: ext2.h:53
ULONG lastcheck
Definition: ext2.h:90
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
ULONG inodes_per_group
Definition: ext2.h:81
ULONG creator_os
Definition: ext2.h:92
LONG log2_fragment_size
Definition: ext2.h:78
ULONG fragments_per_group
Definition: ext2.h:80
USHORT block_group_number
Definition: ext2.h:98
USHORT error_handling
Definition: ext2.h:88
USHORT minor_revision_level
Definition: ext2.h:89
FORCEINLINE VOID FrLdrTempFree(PVOID Allocation, ULONG Tag)
Definition: mm.h:197

Referenced by Ext2OpenVolume().

◆ Ext2ReadVolumeSectors()

BOOLEAN Ext2ReadVolumeSectors ( PEXT2_VOLUME_INFO  Volume,
ULONGLONG  SectorNumber,
ULONG  SectorCount,
PVOID  Buffer 
)

Definition at line 541 of file ext2.c.

542 {
543 #if 0
544  return CacheReadDiskSectors(DriveNumber, SectorNumber + Ext2VolumeStartSector, SectorCount, Buffer);
545 #endif
546 
548  ULONG Count;
550 
551  /* Seek to right position */
552  Position.QuadPart = (ULONGLONG)SectorNumber * 512;
553  Status = ArcSeek(Volume->DeviceId, &Position, SeekAbsolute);
554  if (Status != ESUCCESS)
555  {
556  TRACE("Ext2ReadVolumeSectors() Failed to seek\n");
557  return FALSE;
558  }
559 
560  /* Read data */
561  Status = ArcRead(Volume->DeviceId, Buffer, SectorCount * 512, &Count);
562  if (Status != ESUCCESS || Count != SectorCount * 512)
563  {
564  TRACE("Ext2ReadVolumeSectors() Failed to read\n");
565  return FALSE;
566  }
567 
568  /* Return success */
569  return TRUE;
570 }
Definition: arc.h:32
#define TRUE
Definition: types.h:120
static COORD Position
Definition: mouse.c:34
ULONG ARC_STATUS
Definition: arc.h:4
#define FALSE
Definition: types.h:117
BOOLEAN CacheReadDiskSectors(UCHAR DiskNumber, ULONGLONG StartSector, ULONG SectorCount, PVOID Buffer)
Definition: cache.c:113
Definition: bufpool.h:45
Status
Definition: gdiplustypes.h:24
int Count
Definition: noreturn.cpp:7
#define TRACE(s)
Definition: solgame.cpp:4
uint64_t ULONGLONG
Definition: typedefs.h:67
ARC_STATUS ArcRead(ULONG FileId, VOID *Buffer, ULONG N, ULONG *Count)
Definition: fs.c:236
ARC_STATUS ArcSeek(ULONG FileId, LARGE_INTEGER *Position, SEEKMODE SeekMode)
Definition: fs.c:243
ULONG SectorCount
Definition: part_xbox.c:31
unsigned int ULONG
Definition: retypes.h:1

Referenced by Ext2ReadBlock().

◆ Ext2SearchDirectoryBufferForFile()

BOOLEAN Ext2SearchDirectoryBufferForFile ( PVOID  DirectoryBuffer,
ULONG  DirectorySize,
PCHAR  FileName,
PEXT2_DIR_ENTRY  DirectoryEntry 
)

Definition at line 303 of file ext2.c.

304 {
305  ULONG CurrentOffset;
306  PEXT2_DIR_ENTRY CurrentDirectoryEntry;
307 
308  TRACE("Ext2SearchDirectoryBufferForFile() DirectoryBuffer = 0x%x DirectorySize = %d FileName = %s\n", DirectoryBuffer, DirectorySize, FileName);
309 
310  for (CurrentOffset=0; CurrentOffset<DirectorySize; )
311  {
312  CurrentDirectoryEntry = (PEXT2_DIR_ENTRY)((ULONG_PTR)DirectoryBuffer + CurrentOffset);
313 
314  if (CurrentDirectoryEntry->direntlen == 0)
315  {
316  break;
317  }
318 
319  if ((CurrentDirectoryEntry->direntlen + CurrentOffset) > DirectorySize)
320  {
321  FileSystemError("Directory entry extends past end of directory file.");
322  return FALSE;
323  }
324 
325  TRACE("Dumping directory entry at offset %d:\n", CurrentOffset);
326  DbgDumpBuffer(DPRINT_FILESYSTEM, CurrentDirectoryEntry, CurrentDirectoryEntry->direntlen);
327 
328  if ((_strnicmp(FileName, CurrentDirectoryEntry->name, CurrentDirectoryEntry->namelen) == 0) &&
329  (strlen(FileName) == CurrentDirectoryEntry->namelen))
330  {
331  RtlCopyMemory(DirectoryEntry, CurrentDirectoryEntry, sizeof(EXT2_DIR_ENTRY));
332 
333  TRACE("EXT2 Directory Entry:\n");
334  TRACE("inode = %d\n", DirectoryEntry->inode);
335  TRACE("direntlen = %d\n", DirectoryEntry->direntlen);
336  TRACE("namelen = %d\n", DirectoryEntry->namelen);
337  TRACE("filetype = %d\n", DirectoryEntry->filetype);
338  TRACE("name = ");
339  for (CurrentOffset=0; CurrentOffset<DirectoryEntry->namelen; CurrentOffset++)
340  {
341  TRACE("%c", DirectoryEntry->name[CurrentOffset]);
342  }
343  TRACE("\n");
344 
345  return TRUE;
346  }
347 
348  CurrentOffset += CurrentDirectoryEntry->direntlen;
349  }
350 
351  return FALSE;
352 }
UCHAR filetype
Definition: ext2.h:163
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
#define TRUE
Definition: types.h:120
UCHAR namelen
Definition: ext2.h:162
ULONG inode
Definition: ext2.h:160
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define FALSE
Definition: types.h:117
VOID FileSystemError(PCSTR ErrorString)
Definition: fs.c:259
USHORT direntlen
Definition: ext2.h:161
#define TRACE(s)
Definition: solgame.cpp:4
struct ext2_dirent * PEXT2_DIR_ENTRY
Definition: ext2.h:174
#define DPRINT_FILESYSTEM
Definition: debug.h:26
#define _strnicmp(_String1, _String2, _MaxCount)
Definition: compat.h:23
#define DbgDumpBuffer(mask, buf, len)
Definition: debug.h:119
CHAR name[EXT2_NAME_LEN]
Definition: ext2.h:164
unsigned int ULONG
Definition: retypes.h:1
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263

Referenced by Ext2LookupFile().

◆ Ext2Seek()

ARC_STATUS Ext2Seek ( ULONG  FileId,
LARGE_INTEGER Position,
SEEKMODE  SeekMode 
)

Definition at line 1261 of file ext2.c.

1262 {
1264  LARGE_INTEGER NewPosition = *Position;
1265 
1266  switch (SeekMode)
1267  {
1268  case SeekAbsolute:
1269  break;
1270  case SeekRelative:
1271  NewPosition.QuadPart += FileHandle->FilePointer;
1272  break;
1273  default:
1274  ASSERT(FALSE);
1275  return EINVAL;
1276  }
1277 
1278  if (NewPosition.QuadPart >= FileHandle->FileSize)
1279  return EINVAL;
1280 
1281  FileHandle->FilePointer = NewPosition.QuadPart;
1282  return ESUCCESS;
1283 }
Definition: arc.h:32
Definition: arc.h:39
static COORD Position
Definition: mouse.c:34
VOID * FsGetDeviceSpecific(ULONG FileId)
Definition: fs.c:416
HANDLE FileHandle
Definition: stats.c:38
#define FALSE
Definition: types.h:117
#define ASSERT(a)
Definition: mode.c:44
LONGLONG QuadPart
Definition: typedefs.h:114

Variable Documentation

◆ Ext2FuncTable

const DEVVTBL Ext2FuncTable
Initial value:
=
{
L"ext2fs",
}
ARC_STATUS Ext2GetFileInformation(ULONG FileId, FILEINFORMATION *Information)
Definition: ext2.c:1199
ARC_STATUS Ext2Close(ULONG FileId)
Definition: ext2.c:1192
static const WCHAR L[]
Definition: oid.c:1250
ARC_STATUS Ext2Open(CHAR *Path, OPENMODE OpenMode, ULONG *FileId)
Definition: ext2.c:1213
ARC_STATUS Ext2Seek(ULONG FileId, LARGE_INTEGER *Position, SEEKMODE SeekMode)
Definition: ext2.c:1261
ARC_STATUS Ext2Read(ULONG FileId, VOID *Buffer, ULONG N, ULONG *Count)
Definition: ext2.c:1240

Definition at line 1285 of file ext2.c.

Referenced by Ext2Mount().

◆ Ext2Volumes

PEXT2_VOLUME_INFO Ext2Volumes[MAX_FDS]

Definition at line 65 of file ext2.c.

Referenced by Ext2Mount(), and Ext2Open().