ReactOS  0.4.14-dev-49-gfb4591c
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 1194 of file ext2.c.

1195 {
1198  return ESUCCESS;
1199 }
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:186

Referenced by Ext2DispatchRequest().

◆ Ext2CopyDoubleIndirectBlockPointers()

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

Definition at line 1124 of file ext2.c.

1125 {
1126  ULONG* BlockBuffer;
1127  ULONG CurrentBlock;
1128  ULONG BlockPointersPerBlock;
1129 
1130  TRACE("Ext2CopyDoubleIndirectBlockPointers() BlockCount = %d\n", BlockCount);
1131 
1132  BlockPointersPerBlock = Volume->BlockSizeInBytes / sizeof(ULONG);
1133 
1134  BlockBuffer = (ULONG*)FrLdrTempAlloc(Volume->BlockSizeInBytes, TAG_EXT_BUFFER);
1135  if (BlockBuffer == NULL)
1136  {
1137  return FALSE;
1138  }
1139 
1140  if (!Ext2ReadBlock(Volume, DoubleIndirectBlock, BlockBuffer))
1141  {
1142  FrLdrTempFree(BlockBuffer, TAG_EXT_BUFFER);
1143  return FALSE;
1144  }
1145 
1146  for (CurrentBlock=0; (*CurrentBlockInList)<BlockCount && CurrentBlock<BlockPointersPerBlock; CurrentBlock++)
1147  {
1148  if (!Ext2CopyIndirectBlockPointers(Volume, BlockList, CurrentBlockInList, BlockCount, BlockBuffer[CurrentBlock]))
1149  {
1150  FrLdrTempFree(BlockBuffer, TAG_EXT_BUFFER);
1151  return FALSE;
1152  }
1153  }
1154 
1155  FrLdrTempFree(BlockBuffer, TAG_EXT_BUFFER);
1156  return TRUE;
1157 }
#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:830
FORCEINLINE PVOID FrLdrTempAlloc(_In_ SIZE_T Size, _In_ ULONG Tag)
Definition: mm.h:177
smooth NULL
Definition: ftsmooth.c:416
#define TRACE(s)
Definition: solgame.cpp:4
unsigned int ULONG
Definition: retypes.h:1
BOOLEAN Ext2CopyIndirectBlockPointers(PEXT2_VOLUME_INFO Volume, ULONG *BlockList, ULONG *CurrentBlockInList, ULONG BlockCount, ULONG IndirectBlock)
Definition: ext2.c:1092
FORCEINLINE VOID FrLdrTempFree(PVOID Allocation, ULONG Tag)
Definition: mm.h:186

Referenced by Ext2CopyTripleIndirectBlockPointers(), and Ext2ReadBlockPointerList().

◆ Ext2CopyIndirectBlockPointers()

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

Definition at line 1092 of file ext2.c.

1093 {
1094  ULONG* BlockBuffer;
1095  ULONG CurrentBlock;
1096  ULONG BlockPointersPerBlock;
1097 
1098  TRACE("Ext2CopyIndirectBlockPointers() BlockCount = %d\n", BlockCount);
1099 
1100  BlockPointersPerBlock = Volume->BlockSizeInBytes / sizeof(ULONG);
1101 
1102  BlockBuffer = FrLdrTempAlloc(Volume->BlockSizeInBytes, TAG_EXT_BUFFER);
1103  if (!BlockBuffer)
1104  {
1105  return FALSE;
1106  }
1107 
1108  if (!Ext2ReadBlock(Volume, IndirectBlock, BlockBuffer))
1109  {
1110  return FALSE;
1111  }
1112 
1113  for (CurrentBlock=0; (*CurrentBlockInList)<BlockCount && CurrentBlock<BlockPointersPerBlock; CurrentBlock++)
1114  {
1115  BlockList[(*CurrentBlockInList)] = BlockBuffer[CurrentBlock];
1116  (*CurrentBlockInList)++;
1117  }
1118 
1119  FrLdrTempFree(BlockBuffer, TAG_EXT_BUFFER);
1120 
1121  return TRUE;
1122 }
#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:830
FORCEINLINE PVOID FrLdrTempAlloc(_In_ SIZE_T Size, _In_ ULONG Tag)
Definition: mm.h:177
#define TRACE(s)
Definition: solgame.cpp:4
unsigned int ULONG
Definition: retypes.h:1
FORCEINLINE VOID FrLdrTempFree(PVOID Allocation, ULONG Tag)
Definition: mm.h:186

Referenced by Ext2CopyDoubleIndirectBlockPointers(), and Ext2ReadBlockPointerList().

◆ Ext2CopyTripleIndirectBlockPointers()

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

Definition at line 1159 of file ext2.c.

1160 {
1161  ULONG* BlockBuffer;
1162  ULONG CurrentBlock;
1163  ULONG BlockPointersPerBlock;
1164 
1165  TRACE("Ext2CopyTripleIndirectBlockPointers() BlockCount = %d\n", BlockCount);
1166 
1167  BlockPointersPerBlock = Volume->BlockSizeInBytes / sizeof(ULONG);
1168 
1169  BlockBuffer = (ULONG*)FrLdrTempAlloc(Volume->BlockSizeInBytes, TAG_EXT_BUFFER);
1170  if (BlockBuffer == NULL)
1171  {
1172  return FALSE;
1173  }
1174 
1175  if (!Ext2ReadBlock(Volume, TripleIndirectBlock, BlockBuffer))
1176  {
1177  FrLdrTempFree(BlockBuffer, TAG_EXT_BUFFER);
1178  return FALSE;
1179  }
1180 
1181  for (CurrentBlock=0; (*CurrentBlockInList)<BlockCount && CurrentBlock<BlockPointersPerBlock; CurrentBlock++)
1182  {
1183  if (!Ext2CopyDoubleIndirectBlockPointers(Volume, BlockList, CurrentBlockInList, BlockCount, BlockBuffer[CurrentBlock]))
1184  {
1185  FrLdrTempFree(BlockBuffer, TAG_EXT_BUFFER);
1186  return FALSE;
1187  }
1188  }
1189 
1190  FrLdrTempFree(BlockBuffer, TAG_EXT_BUFFER);
1191  return TRUE;
1192 }
#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:830
FORCEINLINE PVOID FrLdrTempAlloc(_In_ SIZE_T Size, _In_ ULONG Tag)
Definition: mm.h:177
smooth NULL
Definition: ftsmooth.c:416
#define TRACE(s)
Definition: solgame.cpp:4
BOOLEAN Ext2CopyDoubleIndirectBlockPointers(PEXT2_VOLUME_INFO Volume, ULONG *BlockList, ULONG *CurrentBlockInList, ULONG BlockCount, ULONG DoubleIndirectBlock)
Definition: ext2.c:1124
unsigned int ULONG
Definition: retypes.h:1
FORCEINLINE VOID FrLdrTempFree(PVOID Allocation, ULONG Tag)
Definition: mm.h:186

Referenced by Ext2ReadBlockPointerList().

◆ Ext2GetFileInformation()

ARC_STATUS Ext2GetFileInformation ( ULONG  FileId,
FILEINFORMATION Information 
)

Definition at line 1201 of file ext2.c.

1202 {
1204 
1206  Information->EndingAddress.QuadPart = FileHandle->FileSize;
1207  Information->CurrentAddress.QuadPart = FileHandle->FilePointer;
1208 
1209  TRACE("Ext2GetFileInformation(%lu) -> FileSize = %llu, FilePointer = 0x%llx\n",
1210  FileId, Information->EndingAddress.QuadPart, Information->CurrentAddress.QuadPart);
1211 
1212  return ESUCCESS;
1213 }
Definition: arc.h:32
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:261
Iosb Information
Definition: create.c:4377

◆ Ext2GetInodeBlockNumber()

ULONG Ext2GetInodeBlockNumber ( PEXT2_VOLUME_INFO  Volume,
ULONG  Inode 
)

Definition at line 899 of file ext2.c.

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

Referenced by Ext2ReadInode().

◆ Ext2GetInodeFileSize()

ULONGLONG Ext2GetInodeFileSize ( PEXT2_INODE  Inode)

Definition at line 1080 of file ext2.c.

1081 {
1082  if ((Inode->mode & EXT2_S_IFMT) == EXT2_S_IFDIR)
1083  {
1084  return (ULONGLONG)(Inode->size);
1085  }
1086  else
1087  {
1088  return ((ULONGLONG)(Inode->size) | ((ULONGLONG)(Inode->dir_acl) << 32));
1089  }
1090 }
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:65
#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 894 of file ext2.c.

895 {
896  return ((Inode - 1) / Volume->SuperBlock->inodes_per_group);
897 }

Referenced by Ext2ReadInode().

◆ Ext2GetInodeOffsetInBlock()

ULONG Ext2GetInodeOffsetInBlock ( PEXT2_VOLUME_INFO  Volume,
ULONG  Inode 
)

Definition at line 904 of file ext2.c.

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

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:909
#define TRUE
Definition: types.h:120
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
ULONG * FileBlockList
Definition: ext2.h:235
VOID FsGetFirstNameFromPath(PCHAR Buffer, PCSTR Path)
Definition: fs.c:356
#define EXT2_S_IFLNK
Definition: ext2.h:224
BOOLEAN Ext2ReadDirectory(PEXT2_VOLUME_INFO Volume, ULONG Inode, PVOID *DirectoryBuffer, PEXT2_INODE InodePointer)
Definition: ext2.c:770
char CHAR
Definition: xmlstorage.h:175
ULONGLONG Ext2GetInodeFileSize(PEXT2_INODE Inode)
Definition: ext2.c:1080
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
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
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
smooth NULL
Definition: ftsmooth.c:416
#define EXT2_ROOT_INO
Definition: ext2.h:177
ULONG * Ext2ReadBlockPointerList(PEXT2_VOLUME_INFO Volume, PEXT2_INODE Inode)
Definition: ext2.c:1010
#define TRACE(s)
Definition: solgame.cpp:4
#define EXT2_S_IFMT
Definition: ext2.h:218
#define EXT2_S_IFREG
Definition: ext2.h:223
USHORT mode
Definition: ext2.h:125
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
FORCEINLINE VOID FrLdrTempFree(PVOID Allocation, ULONG Tag)
Definition: mm.h:186

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

◆ Ext2Mount()

const DEVVTBL* Ext2Mount ( ULONG  DeviceId)

Definition at line 1297 of file ext2.c.

1298 {
1300  EXT2_SUPER_BLOCK SuperBlock;
1302  ULONG Count;
1304 
1305  TRACE("Enter Ext2Mount(%lu)\n", DeviceId);
1306 
1307  /* Allocate data for volume information */
1309  if (!Volume)
1310  return NULL;
1312 
1313  /* Read the SuperBlock */
1314  Position.QuadPart = 2 * 512;
1315  Status = ArcSeek(DeviceId, &Position, SeekAbsolute);
1316  if (Status != ESUCCESS)
1317  {
1319  return NULL;
1320  }
1321  Status = ArcRead(DeviceId, &SuperBlock, sizeof(SuperBlock), &Count);
1322  if (Status != ESUCCESS || Count != sizeof(SuperBlock))
1323  {
1325  return NULL;
1326  }
1327 
1328  /* Check if SuperBlock is valid. If yes, return Ext2 function table. */
1329  if (SuperBlock.magic != EXT2_MAGIC)
1330  {
1332  return NULL;
1333  }
1334 
1335  Volume->DeviceId = DeviceId;
1336 
1337  /* Really open the volume */
1338  if (!Ext2OpenVolume(Volume))
1339  {
1341  return NULL;
1342  }
1343 
1344  /* Remember EXT2 volume information */
1345  Ext2Volumes[DeviceId] = Volume;
1346 
1347  /* Return success */
1348  TRACE("Ext2Mount(%lu) success\n", DeviceId);
1349  return &Ext2FuncTable;
1350 }
Definition: arc.h:32
static COORD Position
Definition: mouse.c:34
_Inout_ __drv_aliasesMem PSLIST_ENTRY _Inout_ PSLIST_ENTRY _In_ ULONG Count
Definition: exfuncs.h:1015
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:177
smooth NULL
Definition: ftsmooth.c:416
USHORT magic
Definition: ext2.h:86
#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
Status
Definition: gdiplustypes.h:24
#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:261
const DEVVTBL Ext2FuncTable
Definition: ext2.c:1287
BOOLEAN Ext2OpenVolume(PEXT2_VOLUME_INFO Volume)
Definition: ext2.c:74
FORCEINLINE VOID FrLdrTempFree(PVOID Allocation, ULONG Tag)
Definition: mm.h:186

Referenced by ArcOpen().

◆ Ext2Open()

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

Definition at line 1215 of file ext2.c.

1216 {
1219  ULONG DeviceId;
1220 
1221  /* Check parameters */
1222  if (OpenMode != OpenReadOnly)
1223  return EACCES;
1224 
1225  /* Get underlying device */
1226  DeviceId = FsGetDeviceId(*FileId);
1227  Volume = Ext2Volumes[DeviceId];
1228 
1229  TRACE("Ext2Open() FileName = %s\n", Path);
1230 
1231  /* Call the internal open method */
1232  // Status = Ext2OpenFile(Volume, Path, &FileHandle);
1234  if (!FileHandle)
1235  return ENOENT;
1236 
1237  /* Success, remember the handle */
1238  FsSetDeviceSpecific(*FileId, FileHandle);
1239  return ESUCCESS;
1240 }
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 }
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
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:63
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:177
smooth NULL
Definition: ftsmooth.c:416
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
#define EXT2_S_IFMT
Definition: ext2.h:218
static const UCHAR Index[8]
Definition: usbohci.c:18
#define EXT2_NAME_LEN
Definition: ext2.h:156
#define TAG_EXT_FILE
Definition: ext2.c:68
USHORT mode
Definition: ext2.h:125
char * strcpy(char *DstString, const char *SrcString)
Definition: utclib.c:388
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
FORCEINLINE VOID FrLdrTempFree(PVOID Allocation, ULONG Tag)
Definition: mm.h:186

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:574
#define TRUE
Definition: types.h:120
#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:728

Referenced by Ext2Mount().

◆ Ext2Read()

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

Definition at line 1242 of file ext2.c.

1243 {
1245  ULONGLONG BytesReadBig;
1246  BOOLEAN Success;
1247 
1248  //
1249  // Read data
1250  //
1251  Success = Ext2ReadFileBig(FileHandle, N, &BytesReadBig, Buffer);
1252  *Count = (ULONG)BytesReadBig;
1253 
1254  //
1255  // Check for success
1256  //
1257  if (Success)
1258  return ESUCCESS;
1259  else
1260  return EIO;
1261 }
BOOLEAN Ext2ReadFileBig(PEXT2_FILE_INFO Ext2FileInfo, ULONGLONG BytesToRead, ULONGLONG *BytesRead, PVOID Buffer)
Definition: ext2.c:359
Definition: arc.h:32
_Inout_ __drv_aliasesMem PSLIST_ENTRY _Inout_ PSLIST_ENTRY _In_ ULONG Count
Definition: exfuncs.h:1015
VOID * FsGetDeviceSpecific(ULONG FileId)
Definition: fs.c:416
HANDLE FileHandle
Definition: stats.c:38
unsigned char BOOLEAN
Definition: bufpool.h:45
uint64_t ULONGLONG
Definition: typedefs.h:65
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 830 of file ext2.c.

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

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

◆ Ext2ReadBlockPointerList()

ULONG * Ext2ReadBlockPointerList ( PEXT2_VOLUME_INFO  Volume,
PEXT2_INODE  Inode 
)

Definition at line 1010 of file ext2.c.

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

Referenced by Ext2LookupFile(), and Ext2ReadDirectory().

◆ Ext2ReadDirectory()

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

Definition at line 770 of file ext2.c.

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

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, BytesToRead, FilePointer, & Buffer
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  BytesToRead -= BytesToRead;
537  Buffer = (PVOID)((ULONG_PTR)Buffer + (ULONG_PTR)BytesToRead);
538  }
539 
540  return TRUE;
541 }
ULONGLONG FilePointer
Definition: ext2.h:234
#define TRUE
Definition: types.h:120
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
ULONG * FileBlockList
Definition: ext2.h:235
#define EXT2_S_IFLNK
Definition: ext2.h:224
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:830
uint32_t ULONG_PTR
Definition: typedefs.h:63
PEXT2_VOLUME_INFO Volume
Definition: ext2.h:237
VOID FileSystemError(PCSTR ErrorString)
Definition: fs.c:259
ULONGLONG FileSize
Definition: ext2.h:233
smooth NULL
Definition: ftsmooth.c:416
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:861
USHORT mode
Definition: ext2.h:125
unsigned int ULONG
Definition: retypes.h:1
#define ULONG_PTR
Definition: config.h:101
IN BOOLEAN OUT PSTR Buffer
Definition: progress.h:34
_Must_inspect_result_ _In_ PFILE_OBJECT _In_opt_ PLARGE_INTEGER _In_ ULONG _In_ FLT_IO_OPERATION_FLAGS _Out_opt_ PULONG BytesRead
Definition: fltkernel.h:1255

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

◆ Ext2ReadGroupDescriptor()

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

Definition at line 985 of file ext2.c.

986 {
987  TRACE("Ext2ReadGroupDescriptor()\n");
988 
989 #if 0
990  if (!Ext2ReadBlock(Volume, Ext2GetGroupDescBlockNumber(Volume, Group), (PVOID)FILESYSBUFFER))
991  {
992  return FALSE;
993  }
994  RtlCopyMemory(GroupBuffer, (PVOID)(FILESYSBUFFER + Ext2GetGroupDescOffsetInBlock(Volume, Group)), sizeof(EXT2_GROUP_DESC));
995 #endif
996 
997  RtlCopyMemory(GroupBuffer, &Volume->GroupDescriptors[Group], sizeof(EXT2_GROUP_DESC));
998 
999  TRACE("Dumping group descriptor:\n");
1000  TRACE("block_id = %d\n", GroupBuffer->block_id);
1001  TRACE("inode_id = %d\n", GroupBuffer->inode_id);
1002  TRACE("inode_table_id = %d\n", GroupBuffer->inode_table_id);
1003  TRACE("free_blocks = %d\n", GroupBuffer->free_blocks);
1004  TRACE("free_inodes = %d\n", GroupBuffer->free_inodes);
1005  TRACE("used_dirs = %d\n", GroupBuffer->used_dirs);
1006 
1007  return TRUE;
1008 }
#define TRUE
Definition: types.h:120
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
ULONG block_id
Definition: ext2.h:112
ULONG inode_id
Definition: ext2.h:113
USHORT free_inodes
Definition: ext2.h:116
_In_opt_ PSID Group
Definition: rtlfuncs.h:1606
BOOLEAN Ext2ReadBlock(PEXT2_VOLUME_INFO Volume, ULONG BlockNumber, PVOID Buffer)
Definition: ext2.c:830
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

Referenced by Ext2ReadInode().

◆ Ext2ReadGroupDescriptors()

BOOLEAN Ext2ReadGroupDescriptors ( PEXT2_VOLUME_INFO  Volume)

Definition at line 728 of file ext2.c.

729 {
730  ULONG GroupDescBlockCount;
731  ULONG BlockNumber;
732  PUCHAR CurrentGroupDescBlock;
733 
734  TRACE("Ext2ReadGroupDescriptors()\n");
735 
736  /* Free any memory previously allocated */
737  if (Volume->GroupDescriptors != NULL)
738  {
739  FrLdrTempFree(Volume->GroupDescriptors, TAG_EXT_GROUP_DESC);
740  Volume->GroupDescriptors = NULL;
741  }
742 
743  /* Now allocate the memory to hold the group descriptors */
744  GroupDescBlockCount = ROUND_UP(Volume->GroupCount, Volume->GroupDescPerBlock) / Volume->GroupDescPerBlock;
745  Volume->GroupDescriptors = (PEXT2_GROUP_DESC)FrLdrTempAlloc(GroupDescBlockCount * Volume->BlockSizeInBytes, TAG_EXT_GROUP_DESC);
746  if (Volume->GroupDescriptors == NULL)
747  {
748  FileSystemError("Out of memory.");
749  return FALSE;
750  }
751 
752  // Now read the group descriptors
753  CurrentGroupDescBlock = (PUCHAR)Volume->GroupDescriptors;
754  BlockNumber = Volume->SuperBlock->first_data_block + 1;
755 
756  while (GroupDescBlockCount--)
757  {
758  if (!Ext2ReadBlock(Volume, BlockNumber, CurrentGroupDescBlock))
759  {
760  return FALSE;
761  }
762 
763  BlockNumber++;
764  CurrentGroupDescBlock += Volume->BlockSizeInBytes;
765  }
766 
767  return TRUE;
768 }
#define TRUE
Definition: types.h:120
#define ROUND_UP(n, align)
Definition: eventvwr.h:31
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:830
while(1)
Definition: macro.lex.yy.c:740
VOID FileSystemError(PCSTR ErrorString)
Definition: fs.c:259
FORCEINLINE PVOID FrLdrTempAlloc(_In_ SIZE_T Size, _In_ ULONG Tag)
Definition: mm.h:177
smooth NULL
Definition: ftsmooth.c:416
#define TRACE(s)
Definition: solgame.cpp:4
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:186

Referenced by Ext2OpenVolume().

◆ Ext2ReadInode()

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

Definition at line 909 of file ext2.c.

910 {
911  ULONG InodeGroupNumber;
912  ULONG InodeBlockNumber;
913  ULONG InodeOffsetInBlock;
914  CHAR ErrorString[80];
915  EXT2_GROUP_DESC GroupDescriptor;
916 
917  TRACE("Ext2ReadInode() Inode = %d\n", Inode);
918 
919  // Make sure its a valid inode
920  if ((Inode < 1) || (Inode > Volume->SuperBlock->total_inodes))
921  {
922  sprintf(ErrorString, "Error reading inode %ld - inode out of range.", Inode);
923  FileSystemError(ErrorString);
924  return FALSE;
925  }
926 
927  // Get inode group & block number and offset in block
928  InodeGroupNumber = Ext2GetInodeGroupNumber(Volume, Inode);
929  InodeBlockNumber = Ext2GetInodeBlockNumber(Volume, Inode);
930  InodeOffsetInBlock = Ext2GetInodeOffsetInBlock(Volume, Inode);
931  TRACE("InodeGroupNumber = %d\n", InodeGroupNumber);
932  TRACE("InodeBlockNumber = %d\n", InodeBlockNumber);
933  TRACE("InodeOffsetInBlock = %d\n", InodeOffsetInBlock);
934 
935  // Read the group descriptor
936  if (!Ext2ReadGroupDescriptor(Volume, InodeGroupNumber, &GroupDescriptor))
937  {
938  return FALSE;
939  }
940 
941  // Add the start block of the inode table to the inode block number
942  InodeBlockNumber += GroupDescriptor.inode_table_id;
943  TRACE("InodeBlockNumber (after group desc correction) = %d\n", InodeBlockNumber);
944 
945  // Read the block
947  InodeBlockNumber,
948  (InodeOffsetInBlock * EXT2_INODE_SIZE(Volume->SuperBlock)),
949  sizeof(EXT2_INODE),
950  InodeBuffer))
951  {
952  return FALSE;
953  }
954 
955  TRACE("Dumping inode information:\n");
956  TRACE("mode = 0x%x\n", InodeBuffer->mode);
957  TRACE("uid = %d\n", InodeBuffer->uid);
958  TRACE("size = %d\n", InodeBuffer->size);
959  TRACE("atime = %d\n", InodeBuffer->atime);
960  TRACE("ctime = %d\n", InodeBuffer->ctime);
961  TRACE("mtime = %d\n", InodeBuffer->mtime);
962  TRACE("dtime = %d\n", InodeBuffer->dtime);
963  TRACE("gid = %d\n", InodeBuffer->gid);
964  TRACE("nlinks = %d\n", InodeBuffer->nlinks);
965  TRACE("blockcnt = %d\n", InodeBuffer->blockcnt);
966  TRACE("flags = 0x%x\n", InodeBuffer->flags);
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);
975  TRACE("version = %d\n", InodeBuffer->version);
976  TRACE("acl = %d\n", InodeBuffer->acl);
977  TRACE("dir_acl = %d\n", InodeBuffer->dir_acl);
978  TRACE("fragment_addr = %d\n", InodeBuffer->fragment_addr);
979  TRACE("osd2 = { %d, %d, %d }\n",
980  InodeBuffer->osd2[0], InodeBuffer->osd2[1], InodeBuffer->osd2[2]);
981 
982  return TRUE;
983 }
#define TRUE
Definition: types.h:120
ULONG mtime
Definition: ext2.h:130
ULONG atime
Definition: ext2.h:128
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:985
ULONG Ext2GetInodeOffsetInBlock(PEXT2_VOLUME_INFO Volume, ULONG Inode)
Definition: ext2.c:904
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
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:899
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:861
USHORT mode
Definition: ext2.h:125
ULONG osd1
Definition: ext2.h:136
ULONG Ext2GetInodeGroupNumber(PEXT2_VOLUME_INFO Volume, ULONG Inode)
Definition: ext2.c:894
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 861 of file ext2.c.

862 {
863  PVOID TempBuffer;
864 
865  TRACE("Ext2ReadPartialBlock() BlockNumber = %d StartingOffset = %d Length = %d Buffer = 0x%x\n", BlockNumber, StartingOffset, Length, Buffer);
866 
867  TempBuffer = FrLdrTempAlloc(Volume->BlockSizeInBytes, TAG_EXT_BUFFER);
868 
869  if (!Ext2ReadBlock(Volume, BlockNumber, TempBuffer))
870  {
871  FrLdrTempFree(TempBuffer, TAG_EXT_BUFFER);
872  return FALSE;
873  }
874 
875  memcpy(Buffer, ((PUCHAR)TempBuffer + StartingOffset), Length);
876 
877  FrLdrTempFree(TempBuffer, TAG_EXT_BUFFER);
878 
879  return TRUE;
880 }
#define TRUE
Definition: types.h:120
_In_ PFCB _In_ LONGLONG StartingOffset
Definition: cdprocs.h:282
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:830
FORCEINLINE PVOID FrLdrTempAlloc(_In_ SIZE_T Size, _In_ ULONG Tag)
Definition: mm.h:177
Definition: bufpool.h:45
#define TRACE(s)
Definition: solgame.cpp:4
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
FORCEINLINE VOID FrLdrTempFree(PVOID Allocation, ULONG Tag)
Definition: mm.h:186

Referenced by Ext2ReadFileBig(), and Ext2ReadInode().

◆ Ext2ReadSuperBlock()

BOOLEAN Ext2ReadSuperBlock ( PEXT2_VOLUME_INFO  Volume)

Definition at line 574 of file ext2.c.

575 {
576  PEXT2_SUPER_BLOCK SuperBlock = Volume->SuperBlock;
578  ULONG Count;
580 
581  TRACE("Ext2ReadSuperBlock()\n");
582 
583 #if 0
584  /* Free any memory previously allocated */
585  if (SuperBlock != NULL)
586  {
587  FrLdrTempFree(SuperBlock, TAG_EXT_SUPER_BLOCK);
588  SuperBlock = NULL;
589  }
590 #endif
591 
592  /* Allocate the memory to hold the super block if needed */
593  if (SuperBlock == NULL)
594  {
596  if (SuperBlock == NULL)
597  {
598  FileSystemError("Out of memory.");
599  return FALSE;
600  }
601  }
602  Volume->SuperBlock = SuperBlock;
603 
604  /* Reset its contents */
605  RtlZeroMemory(SuperBlock, 1024);
606 
607  /* Read the SuperBlock */
608  Position.QuadPart = 2 * 512;
609  Status = ArcSeek(Volume->DeviceId, &Position, SeekAbsolute);
610  if (Status != ESUCCESS)
611  return FALSE;
612  Status = ArcRead(Volume->DeviceId, SuperBlock, 2 * 512, &Count);
613  if (Status != ESUCCESS || Count != 2 * 512)
614  return FALSE;
615 
616  TRACE("Dumping super block:\n");
617  TRACE("total_inodes: %d\n", SuperBlock->total_inodes);
618  TRACE("total_blocks: %d\n", SuperBlock->total_blocks);
619  TRACE("reserved_blocks: %d\n", SuperBlock->reserved_blocks);
620  TRACE("free_blocks: %d\n", SuperBlock->free_blocks);
621  TRACE("free_inodes: %d\n", SuperBlock->free_inodes);
622  TRACE("first_data_block: %d\n", SuperBlock->first_data_block);
623  TRACE("log2_block_size: %d\n", SuperBlock->log2_block_size);
624  TRACE("log2_fragment_size: %d\n", SuperBlock->log2_fragment_size);
625  TRACE("blocks_per_group: %d\n", SuperBlock->blocks_per_group);
626  TRACE("fragments_per_group: %d\n", SuperBlock->fragments_per_group);
627  TRACE("inodes_per_group: %d\n", SuperBlock->inodes_per_group);
628  TRACE("mtime: %d\n", SuperBlock->mtime);
629  TRACE("utime: %d\n", SuperBlock->utime);
630  TRACE("mnt_count: %d\n", SuperBlock->mnt_count);
631  TRACE("max_mnt_count: %d\n", SuperBlock->max_mnt_count);
632  TRACE("magic: 0x%x\n", SuperBlock->magic);
633  TRACE("fs_state: %d\n", SuperBlock->fs_state);
634  TRACE("error_handling: %d\n", SuperBlock->error_handling);
635  TRACE("minor_revision_level: %d\n", SuperBlock->minor_revision_level);
636  TRACE("lastcheck: %d\n", SuperBlock->lastcheck);
637  TRACE("checkinterval: %d\n", SuperBlock->checkinterval);
638  TRACE("creator_os: %d\n", SuperBlock->creator_os);
639  TRACE("revision_level: %d\n", SuperBlock->revision_level);
640  TRACE("uid_reserved: %d\n", SuperBlock->uid_reserved);
641  TRACE("gid_reserved: %d\n", SuperBlock->gid_reserved);
642  TRACE("first_inode: %d\n", SuperBlock->first_inode);
643  TRACE("inode_size: %d\n", SuperBlock->inode_size);
644  TRACE("block_group_number: %d\n", SuperBlock->block_group_number);
645  TRACE("feature_compatibility: 0x%x\n", SuperBlock->feature_compatibility);
646  TRACE("feature_incompat: 0x%x\n", SuperBlock->feature_incompat);
647  TRACE("feature_ro_compat: 0x%x\n", SuperBlock->feature_ro_compat);
648  TRACE("unique_id = { 0x%x, 0x%x, 0x%x, 0x%x }\n",
649  SuperBlock->unique_id[0], SuperBlock->unique_id[1],
650  SuperBlock->unique_id[2], SuperBlock->unique_id[3]);
651  TRACE("volume_name = '%.16s'\n", SuperBlock->volume_name);
652  TRACE("last_mounted_on = '%.64s'\n", SuperBlock->last_mounted_on);
653  TRACE("compression_info = 0x%x\n", SuperBlock->compression_info);
654 
655  //
656  // Check the super block magic
657  //
658  if (SuperBlock->magic != EXT2_MAGIC)
659  {
660  FileSystemError("Invalid super block magic (0xef53)");
661  return FALSE;
662  }
663 
664  //
665  // Check the revision level
666  //
667  if (SuperBlock->revision_level > EXT2_DYNAMIC_REVISION)
668  {
669  FileSystemError("FreeLoader does not understand the revision of this EXT2/EXT3 filesystem.\nPlease update FreeLoader.");
670  return FALSE;
671  }
672 
673  //
674  // Check the feature set
675  // Don't need to check the compatible or read-only compatible features
676  // because we only mount the filesystem as read-only
677  //
678  if ((SuperBlock->revision_level >= EXT2_DYNAMIC_REVISION) &&
679  (/*((SuperBlock->s_feature_compat & ~EXT3_FEATURE_COMPAT_SUPP) != 0) ||*/
680  /*((SuperBlock->s_feature_ro_compat & ~EXT3_FEATURE_RO_COMPAT_SUPP) != 0) ||*/
681  ((SuperBlock->feature_incompat & ~EXT3_FEATURE_INCOMPAT_SUPP) != 0)))
682  {
683  FileSystemError("FreeLoader does not understand features of this EXT2/EXT3 filesystem.\nPlease update FreeLoader.");
684  return FALSE;
685  }
686 
687  // Calculate the group count
688  Volume->GroupCount = (SuperBlock->total_blocks - SuperBlock->first_data_block + SuperBlock->blocks_per_group - 1) / SuperBlock->blocks_per_group;
689  TRACE("Ext2GroupCount: %d\n", Volume->GroupCount);
690 
691  // Calculate the block size
692  Volume->BlockSizeInBytes = 1024 << SuperBlock->log2_block_size;
693  Volume->BlockSizeInSectors = Volume->BlockSizeInBytes / Volume->BytesPerSector;
694  TRACE("Ext2BlockSizeInBytes: %d\n", Volume->BlockSizeInBytes);
695  TRACE("Ext2BlockSizeInSectors: %d\n", Volume->BlockSizeInSectors);
696 
697  // Calculate the fragment size
698  if (SuperBlock->log2_fragment_size >= 0)
699  {
700  Volume->FragmentSizeInBytes = 1024 << SuperBlock->log2_fragment_size;
701  }
702  else
703  {
704  Volume->FragmentSizeInBytes = 1024 >> -(SuperBlock->log2_fragment_size);
705  }
706  Volume->FragmentSizeInSectors = Volume->FragmentSizeInBytes / Volume->BytesPerSector;
707  TRACE("Ext2FragmentSizeInBytes: %d\n", Volume->FragmentSizeInBytes);
708  TRACE("Ext2FragmentSizeInSectors: %d\n", Volume->FragmentSizeInSectors);
709 
710  // Verify that the fragment size and the block size are equal
711  if (Volume->BlockSizeInBytes != Volume->FragmentSizeInBytes)
712  {
713  FileSystemError("The fragment size must be equal to the block size.");
714  return FALSE;
715  }
716 
717  // Calculate the number of inodes in one block
718  Volume->InodesPerBlock = Volume->BlockSizeInBytes / EXT2_INODE_SIZE(SuperBlock);
719  TRACE("Ext2InodesPerBlock: %d\n", Volume->InodesPerBlock);
720 
721  // Calculate the number of group descriptors in one block
722  Volume->GroupDescPerBlock = EXT2_DESC_PER_BLOCK(SuperBlock);
723  TRACE("Ext2GroupDescPerBlock: %d\n", Volume->GroupDescPerBlock);
724 
725  return TRUE;
726 }
ULONG feature_incompat
Definition: ext2.h:100
ULONG free_blocks
Definition: ext2.h:74
#define TRUE
Definition: types.h:120
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 EXT3_FEATURE_INCOMPAT_SUPP
Definition: ext2.h:180
static COORD Position
Definition: mouse.c:34
ULONG feature_ro_compat
Definition: ext2.h:101
_Inout_ __drv_aliasesMem PSLIST_ENTRY _Inout_ PSLIST_ENTRY _In_ ULONG Count
Definition: exfuncs.h:1015
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
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:177
ULONG utime
Definition: ext2.h:83
smooth NULL
Definition: ftsmooth.c:416
USHORT magic
Definition: ext2.h:86
ULONG log2_block_size
Definition: ext2.h:77
USHORT mnt_count
Definition: ext2.h:84
#define EXT2_INODE_SIZE(sb)
Definition: ext2.h:192
#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
Status
Definition: gdiplustypes.h:24
ULONG total_blocks
Definition: ext2.h:72
#define TAG_EXT_SUPER_BLOCK
Definition: ext2.c:70
#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:261
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:186

Referenced by Ext2OpenVolume().

◆ Ext2ReadVolumeSectors()

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

Definition at line 543 of file ext2.c.

544 {
545 #if 0
546  return CacheReadDiskSectors(DriveNumber, SectorNumber + Ext2VolumeStartSector, SectorCount, Buffer);
547 #endif
548 
550  ULONG Count;
552 
553  /* Seek to right position */
554  Position.QuadPart = (ULONGLONG)SectorNumber * 512;
555  Status = ArcSeek(Volume->DeviceId, &Position, SeekAbsolute);
556  if (Status != ESUCCESS)
557  {
558  TRACE("Ext2ReadVolumeSectors() Failed to seek\n");
559  return FALSE;
560  }
561 
562  /* Read data */
563  Status = ArcRead(Volume->DeviceId, Buffer, SectorCount * 512, &Count);
564  if (Status != ESUCCESS || Count != SectorCount * 512)
565  {
566  TRACE("Ext2ReadVolumeSectors() Failed to read\n");
567  return FALSE;
568  }
569 
570  /* Return success */
571  return TRUE;
572 }
#define TRUE
Definition: types.h:120
Definition: arc.h:32
static COORD Position
Definition: mouse.c:34
_Inout_ __drv_aliasesMem PSLIST_ENTRY _Inout_ PSLIST_ENTRY _In_ ULONG Count
Definition: exfuncs.h:1015
ULONG ARC_STATUS
Definition: arc.h:4
BOOLEAN CacheReadDiskSectors(UCHAR DiskNumber, ULONGLONG StartSector, ULONG SectorCount, PVOID Buffer)
Definition: cache.c:113
Definition: bufpool.h:45
#define TRACE(s)
Definition: solgame.cpp:4
uint64_t ULONGLONG
Definition: typedefs.h:65
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:32
Status
Definition: gdiplustypes.h:24
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
#define TRUE
Definition: types.h:120
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
UCHAR namelen
Definition: ext2.h:162
ULONG inode
Definition: ext2.h:160
uint32_t ULONG_PTR
Definition: typedefs.h:63
VOID FileSystemError(PCSTR ErrorString)
Definition: fs.c:259
_Check_return_ _CRTIMP int __cdecl _strnicmp(_In_reads_or_z_(_MaxCount) const char *_Str1, _In_reads_or_z_(_MaxCount) const char *_Str2, _In_ size_t _MaxCount)
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 DbgDumpBuffer(mask, buf, len)
Definition: debug.h:118
CHAR name[EXT2_NAME_LEN]
Definition: ext2.h:164
unsigned int ULONG
Definition: retypes.h:1

Referenced by Ext2LookupFile().

◆ Ext2Seek()

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

Definition at line 1263 of file ext2.c.

1264 {
1266  LARGE_INTEGER NewPosition = *Position;
1267 
1268  switch (SeekMode)
1269  {
1270  case SeekAbsolute:
1271  break;
1272  case SeekRelative:
1273  NewPosition.QuadPart += FileHandle->FilePointer;
1274  break;
1275  default:
1276  ASSERT(FALSE);
1277  return EINVAL;
1278  }
1279 
1280  if (NewPosition.QuadPart >= FileHandle->FileSize)
1281  return EINVAL;
1282 
1283  FileHandle->FilePointer = NewPosition.QuadPart;
1284  return ESUCCESS;
1285 }
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
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
LONGLONG QuadPart
Definition: typedefs.h:112

Variable Documentation

◆ Ext2FuncTable

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

Definition at line 1287 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().