ReactOS 0.4.15-dev-7961-gdcf9eb0
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}
VOID * FsGetDeviceSpecific(ULONG FileId)
Definition: fs.c:418
FORCEINLINE VOID FrLdrTempFree(PVOID Allocation, ULONG Tag)
Definition: mm.h:197
#define TAG_EXT_FILE
Definition: ext2.c:68
_Must_inspect_result_ _In_opt_ PFLT_INSTANCE _Out_ PHANDLE FileHandle
Definition: fltkernel.h:1231
@ ESUCCESS
Definition: arc.h:32

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}
FORCEINLINE PVOID FrLdrTempAlloc(_In_ SIZE_T Size, _In_ ULONG Tag)
Definition: mm.h:188
BOOLEAN Ext2CopyIndirectBlockPointers(PEXT2_VOLUME_INFO Volume, ULONG *BlockList, ULONG *CurrentBlockInList, ULONG BlockCount, ULONG IndirectBlock)
Definition: ext2.c:1090
BOOLEAN Ext2ReadBlock(PEXT2_VOLUME_INFO Volume, ULONG BlockNumber, PVOID Buffer)
Definition: ext2.c:828
#define TAG_EXT_BUFFER
Definition: ext2.c:69
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
UNICODE_STRING Volume
Definition: fltkernel.h:1172
#define TRACE(s)
Definition: solgame.cpp:4
uint32_t ULONG
Definition: typedefs.h:59

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}

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}
BOOLEAN Ext2CopyDoubleIndirectBlockPointers(PEXT2_VOLUME_INFO Volume, ULONG *BlockList, ULONG *CurrentBlockInList, ULONG BlockCount, ULONG DoubleIndirectBlock)
Definition: ext2.c:1122

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}
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
_In_ WDFREQUEST _In_ NTSTATUS _In_ ULONG_PTR Information
Definition: wdfrequest.h:1049

◆ 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}
#define EXT2_S_IFMT
Definition: ext2.h:218
#define EXT2_S_IFDIR
Definition: ext2.h:221
ULONG size
Definition: ext2.h:127
ULONG dir_acl
Definition: ext2.h:150
USHORT mode
Definition: ext2.h:125
uint64_t ULONGLONG
Definition: typedefs.h:67

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 //
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}
unsigned int UINT32
#define FAST_SYMLINK_MAX_NAME_SIZE
Definition: ext2.h:227
#define EXT2_S_IFREG
Definition: ext2.h:223
#define EXT2_ROOT_INO
Definition: ext2.h:177
#define EXT2_S_IFLNK
Definition: ext2.h:224
ULONG FsGetNumPathParts(PCSTR Path)
Definition: fs.c:330
VOID FileSystemError(PCSTR ErrorString)
Definition: fs.c:261
VOID FsGetFirstNameFromPath(PCHAR Buffer, PCSTR Path)
Definition: fs.c:358
BOOLEAN Ext2ReadDirectory(PEXT2_VOLUME_INFO Volume, ULONG Inode, PVOID *DirectoryBuffer, PEXT2_INODE InodePointer)
Definition: ext2.c:768
ULONGLONG Ext2GetInodeFileSize(PEXT2_INODE Inode)
Definition: ext2.c:1078
ULONG * Ext2ReadBlockPointerList(PEXT2_VOLUME_INFO Volume, PEXT2_INODE Inode)
Definition: ext2.c:1008
BOOLEAN Ext2ReadInode(PEXT2_VOLUME_INFO Volume, ULONG Inode, PEXT2_INODE InodeBuffer)
Definition: ext2.c:907
BOOLEAN Ext2SearchDirectoryBufferForFile(PVOID DirectoryBuffer, ULONG DirectorySize, PCHAR FileName, PEXT2_DIR_ENTRY DirectoryEntry)
Definition: ext2.c:303
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
ULONG * FileBlockList
Definition: ext2.h:235
PEXT2_VOLUME_INFO Volume
Definition: ext2.h:237
ULONGLONG FilePointer
Definition: ext2.h:234
ULONGLONG FileSize
Definition: ext2.h:233
EXT2_INODE Inode
Definition: ext2.h:236
ULONG inode
Definition: ext2.h:160
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
char CHAR
Definition: xmlstorage.h:175

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}
#define EXT2_MAGIC
Definition: ext2.h:43
ARC_STATUS ArcSeek(ULONG FileId, LARGE_INTEGER *Position, SEEKMODE SeekMode)
Definition: fs.c:245
ARC_STATUS ArcRead(ULONG FileId, VOID *Buffer, ULONG N, ULONG *Count)
Definition: fs.c:238
#define TAG_EXT_VOLUME
Definition: ext2.c:72
PEXT2_VOLUME_INFO Ext2Volumes[MAX_FDS]
Definition: ext2.c:65
BOOLEAN Ext2OpenVolume(PEXT2_VOLUME_INFO Volume)
Definition: ext2.c:74
const DEVVTBL Ext2FuncTable
Definition: ext2.c:1285
Status
Definition: gdiplustypes.h:25
int Count
Definition: noreturn.cpp:7
ULONG ARC_STATUS
Definition: arc.h:4
@ SeekAbsolute
Definition: arc.h:59
USHORT magic
Definition: ext2.h:86
static COORD Position
Definition: mouse.c:34

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 */
1237 return ESUCCESS;
1238}
PRTL_UNICODE_STRING_BUFFER Path
#define ENOENT
Definition: acclib.h:79
#define EACCES
Definition: acclib.h:85
ULONG FsGetDeviceId(ULONG FileId)
Definition: fs.c:425
VOID FsSetDeviceSpecific(ULONG FileId, VOID *Specific)
Definition: fs.c:411
PEXT2_FILE_INFO Ext2OpenFile(PEXT2_VOLUME_INFO Volume, PCSTR FileName)
Definition: ext2.c:103
@ OpenReadOnly
Definition: arc.h:65

◆ 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}
char * strcat(char *DstString, const char *SrcString)
Definition: utclib.c:568
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
char * strcpy(char *DstString, const char *SrcString)
Definition: utclib.c:388
#define EXT2_NAME_LEN
Definition: ext2.h:156
#define TAG_EXT_BLOCK_LIST
Definition: ext2.c:67
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
uint32_t ULONG_PTR
Definition: typedefs.h:65
_In_ WDFCOLLECTION _In_ ULONG Index

Referenced by Ext2Open(), and Ext2OpenFile().

◆ 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 CacheInitializeDrive(UCHAR DriveNumber)
Definition: cache.c:37
#define SECTOR_SIZE
Definition: fs.h:22
BOOLEAN Ext2ReadSuperBlock(PEXT2_VOLUME_INFO Volume)
Definition: ext2.c:572
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;
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}
#define N
Definition: crc32.c:57
unsigned char BOOLEAN
#define EIO
Definition: acclib.h:81
Definition: bufpool.h:45
@ Success
Definition: eventcreate.c:712

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}
BOOLEAN Ext2ReadVolumeSectors(PEXT2_VOLUME_INFO Volume, ULONGLONG SectorNumber, ULONG SectorCount, PVOID Buffer)
Definition: ext2.c:541
#define sprintf(buf, format,...)
Definition: sprintf.c:55

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;
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 {
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 {
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 {
1071 return NULL;
1072 }
1073 }
1074
1075 return BlockList;
1076}
#define INDIRECT_BLOCKS
Definition: ext2.h:45
BOOLEAN Ext2CopyTripleIndirectBlockPointers(PEXT2_VOLUME_INFO Volume, ULONG *BlockList, ULONG *CurrentBlockInList, ULONG BlockCount, ULONG TripleIndirectBlock)
Definition: ext2.c:1157
#define ROUND_UP(n, align)
Definition: eventvwr.h:34
_Must_inspect_result_ _Out_ PLARGE_INTEGER FileSize
Definition: fsrtlfuncs.h:108
struct ext2_inode::@173::datablocks blocks

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 {
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;
821 return FALSE;
822 }
823
825 return TRUE;
826}
struct ext2_dirent * PEXT2_DIR_ENTRY
Definition: ext2.h:174
#define ASSERT(a)
Definition: mode.c:44

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}
BOOLEAN Ext2ReadPartialBlock(PEXT2_VOLUME_INFO Volume, ULONG BlockNumber, ULONG StartingOffset, ULONG Length, PVOID Buffer)
Definition: ext2.c:859
char symlink[60]
Definition: ext2.h:146
void * PVOID
Definition: typedefs.h:50
_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:870

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}
_In_opt_ PSID Group
Definition: rtlfuncs.h:1646
ULONG inode_table_id
Definition: ext2.h:114
USHORT free_inodes
Definition: ext2.h:116
USHORT used_dirs
Definition: ext2.h:117
ULONG inode_id
Definition: ext2.h:113
USHORT free_blocks
Definition: ext2.h:115
ULONG block_id
Definition: ext2.h:112

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}
struct ext2_block_group * PEXT2_GROUP_DESC
Definition: ext2.h:173
#define TAG_EXT_GROUP_DESC
Definition: ext2.c:71
while(CdLookupNextInitialFileDirent(IrpContext, Fcb, FileContext))
unsigned char * PUCHAR
Definition: typedefs.h:53

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}
#define EXT2_INODE_SIZE(sb)
Definition: ext2.h:192
ULONG Ext2GetInodeGroupNumber(PEXT2_VOLUME_INFO Volume, ULONG Inode)
Definition: ext2.c:892
ULONG Ext2GetInodeOffsetInBlock(PEXT2_VOLUME_INFO Volume, ULONG Inode)
Definition: ext2.c:902
ULONG Ext2GetInodeBlockNumber(PEXT2_VOLUME_INFO Volume, ULONG Inode)
Definition: ext2.c:897
BOOLEAN Ext2ReadGroupDescriptor(PEXT2_VOLUME_INFO Volume, ULONG Group, PEXT2_GROUP_DESC GroupBuffer)
Definition: ext2.c:983
ULONG osd2[3]
Definition: ext2.h:152
ULONG ctime
Definition: ext2.h:129
USHORT nlinks
Definition: ext2.h:133
ULONG version
Definition: ext2.h:148
ULONG acl
Definition: ext2.h:149
ULONG mtime
Definition: ext2.h:130
ULONG flags
Definition: ext2.h:135
USHORT gid
Definition: ext2.h:132
ULONG blockcnt
Definition: ext2.h:134
ULONG osd1
Definition: ext2.h:136
ULONG fragment_addr
Definition: ext2.h:151
USHORT uid
Definition: ext2.h:126
ULONG atime
Definition: ext2.h:128
ULONG dtime
Definition: ext2.h:131

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
874
875 FrLdrTempFree(TempBuffer, TAG_EXT_BUFFER);
876
877 return TRUE;
878}
_In_ PFCB _In_ LONGLONG StartingOffset
Definition: cdprocs.h:291
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102

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 {
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}
#define EXT2_DESC_PER_BLOCK(s)
Definition: ext2.h:196
struct ext2_sblock * PEXT2_SUPER_BLOCK
Definition: ext2.h:171
#define EXT3_FEATURE_INCOMPAT_SUPP
Definition: ext2.h:180
#define EXT2_DYNAMIC_REVISION
Definition: ext2.h:53
#define TAG_EXT_SUPER_BLOCK
Definition: ext2.c:70
ULONG revision_level
Definition: ext2.h:93
USHORT max_mnt_count
Definition: ext2.h:85
ULONG feature_ro_compat
Definition: ext2.h:101
char last_mounted_on[64]
Definition: ext2.h:104
ULONG compression_info
Definition: ext2.h:105
ULONG feature_compatibility
Definition: ext2.h:99
ULONG free_blocks
Definition: ext2.h:74
ULONG reserved_blocks
Definition: ext2.h:73
USHORT block_group_number
Definition: ext2.h:98
ULONG mtime
Definition: ext2.h:82
ULONG utime
Definition: ext2.h:83
USHORT error_handling
Definition: ext2.h:88
ULONG first_inode
Definition: ext2.h:96
ULONG log2_block_size
Definition: ext2.h:77
USHORT fs_state
Definition: ext2.h:87
char volume_name[16]
Definition: ext2.h:103
ULONG total_inodes
Definition: ext2.h:71
USHORT inode_size
Definition: ext2.h:97
LONG log2_fragment_size
Definition: ext2.h:78
ULONG free_inodes
Definition: ext2.h:75
ULONG inodes_per_group
Definition: ext2.h:81
USHORT gid_reserved
Definition: ext2.h:95
USHORT minor_revision_level
Definition: ext2.h:89
ULONG total_blocks
Definition: ext2.h:72
USHORT uid_reserved
Definition: ext2.h:94
ULONG fragments_per_group
Definition: ext2.h:80
ULONG checkinterval
Definition: ext2.h:91
ULONG unique_id[4]
Definition: ext2.h:102
ULONG feature_incompat
Definition: ext2.h:100
ULONG blocks_per_group
Definition: ext2.h:79
USHORT mnt_count
Definition: ext2.h:84
ULONG lastcheck
Definition: ext2.h:90
ULONG creator_os
Definition: ext2.h:92
ULONG first_data_block
Definition: ext2.h:76

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}
BOOLEAN CacheReadDiskSectors(UCHAR DiskNumber, ULONGLONG StartSector, ULONG SectorCount, PVOID Buffer)
Definition: cache.c:113
ULONG SectorCount
Definition: part_xbox.c:31

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}
#define DbgDumpBuffer(mask, buf, len)
Definition: debug.h:119
#define DPRINT_FILESYSTEM
Definition: debug.h:26
#define _strnicmp(_String1, _String2, _MaxCount)
Definition: compat.h:23
UCHAR namelen
Definition: ext2.h:162
UCHAR filetype
Definition: ext2.h:163
CHAR name[EXT2_NAME_LEN]
Definition: ext2.h:164
USHORT direntlen
Definition: ext2.h:161

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}
#define EINVAL
Definition: acclib.h:90
@ SeekRelative
Definition: arc.h:60
LONGLONG QuadPart
Definition: typedefs.h:114

Variable Documentation

◆ Ext2FuncTable

const DEVVTBL Ext2FuncTable
Initial value:
=
{
L"ext2fs",
}
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 Ext2Close(ULONG FileId)
Definition: ext2.c:1192
ARC_STATUS Ext2Read(ULONG FileId, VOID *Buffer, ULONG N, ULONG *Count)
Definition: ext2.c:1240
ARC_STATUS Ext2GetFileInformation(ULONG FileId, FILEINFORMATION *Information)
Definition: ext2.c:1199
#define L(x)
Definition: ntvdm.h:50

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().