ReactOS 0.4.16-dev-188-g678aa63
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 1195 of file ext2.c.

1196{
1199 return ESUCCESS;
1200}
PVOID FsGetDeviceSpecific(ULONG FileId)
Definition: fs.c:632
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 1125 of file ext2.c.

1126{
1127 ULONG* BlockBuffer;
1128 ULONG CurrentBlock;
1129 ULONG BlockPointersPerBlock;
1130
1131 TRACE("Ext2CopyDoubleIndirectBlockPointers() BlockCount = %d\n", BlockCount);
1132
1133 BlockPointersPerBlock = Volume->BlockSizeInBytes / sizeof(ULONG);
1134
1135 BlockBuffer = (ULONG*)FrLdrTempAlloc(Volume->BlockSizeInBytes, TAG_EXT_BUFFER);
1136 if (BlockBuffer == NULL)
1137 {
1138 return FALSE;
1139 }
1140
1141 if (!Ext2ReadBlock(Volume, DoubleIndirectBlock, BlockBuffer))
1142 {
1143 FrLdrTempFree(BlockBuffer, TAG_EXT_BUFFER);
1144 return FALSE;
1145 }
1146
1147 for (CurrentBlock=0; (*CurrentBlockInList)<BlockCount && CurrentBlock<BlockPointersPerBlock; CurrentBlock++)
1148 {
1149 if (!Ext2CopyIndirectBlockPointers(Volume, BlockList, CurrentBlockInList, BlockCount, BlockBuffer[CurrentBlock]))
1150 {
1151 FrLdrTempFree(BlockBuffer, TAG_EXT_BUFFER);
1152 return FALSE;
1153 }
1154 }
1155
1156 FrLdrTempFree(BlockBuffer, TAG_EXT_BUFFER);
1157 return TRUE;
1158}
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:1093
BOOLEAN Ext2ReadBlock(PEXT2_VOLUME_INFO Volume, ULONG BlockNumber, PVOID Buffer)
Definition: ext2.c:831
#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 1093 of file ext2.c.

1094{
1095 ULONG* BlockBuffer;
1096 ULONG CurrentBlock;
1097 ULONG BlockPointersPerBlock;
1098
1099 TRACE("Ext2CopyIndirectBlockPointers() BlockCount = %d\n", BlockCount);
1100
1101 BlockPointersPerBlock = Volume->BlockSizeInBytes / sizeof(ULONG);
1102
1103 BlockBuffer = FrLdrTempAlloc(Volume->BlockSizeInBytes, TAG_EXT_BUFFER);
1104 if (!BlockBuffer)
1105 {
1106 return FALSE;
1107 }
1108
1109 if (!Ext2ReadBlock(Volume, IndirectBlock, BlockBuffer))
1110 {
1111 return FALSE;
1112 }
1113
1114 for (CurrentBlock=0; (*CurrentBlockInList)<BlockCount && CurrentBlock<BlockPointersPerBlock; CurrentBlock++)
1115 {
1116 BlockList[(*CurrentBlockInList)] = BlockBuffer[CurrentBlock];
1117 (*CurrentBlockInList)++;
1118 }
1119
1120 FrLdrTempFree(BlockBuffer, TAG_EXT_BUFFER);
1121
1122 return TRUE;
1123}

Referenced by Ext2CopyDoubleIndirectBlockPointers(), and Ext2ReadBlockPointerList().

◆ Ext2CopyTripleIndirectBlockPointers()

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

Definition at line 1160 of file ext2.c.

1161{
1162 ULONG* BlockBuffer;
1163 ULONG CurrentBlock;
1164 ULONG BlockPointersPerBlock;
1165
1166 TRACE("Ext2CopyTripleIndirectBlockPointers() BlockCount = %d\n", BlockCount);
1167
1168 BlockPointersPerBlock = Volume->BlockSizeInBytes / sizeof(ULONG);
1169
1170 BlockBuffer = (ULONG*)FrLdrTempAlloc(Volume->BlockSizeInBytes, TAG_EXT_BUFFER);
1171 if (BlockBuffer == NULL)
1172 {
1173 return FALSE;
1174 }
1175
1176 if (!Ext2ReadBlock(Volume, TripleIndirectBlock, BlockBuffer))
1177 {
1178 FrLdrTempFree(BlockBuffer, TAG_EXT_BUFFER);
1179 return FALSE;
1180 }
1181
1182 for (CurrentBlock=0; (*CurrentBlockInList)<BlockCount && CurrentBlock<BlockPointersPerBlock; CurrentBlock++)
1183 {
1184 if (!Ext2CopyDoubleIndirectBlockPointers(Volume, BlockList, CurrentBlockInList, BlockCount, BlockBuffer[CurrentBlock]))
1185 {
1186 FrLdrTempFree(BlockBuffer, TAG_EXT_BUFFER);
1187 return FALSE;
1188 }
1189 }
1190
1191 FrLdrTempFree(BlockBuffer, TAG_EXT_BUFFER);
1192 return TRUE;
1193}
BOOLEAN Ext2CopyDoubleIndirectBlockPointers(PEXT2_VOLUME_INFO Volume, ULONG *BlockList, ULONG *CurrentBlockInList, ULONG BlockCount, ULONG DoubleIndirectBlock)
Definition: ext2.c:1125

Referenced by Ext2ReadBlockPointerList().

◆ Ext2GetFileInformation()

ARC_STATUS Ext2GetFileInformation ( ULONG  FileId,
FILEINFORMATION Information 
)

Definition at line 1202 of file ext2.c.

1203{
1205
1207 Information->EndingAddress.QuadPart = FileHandle->FileSize;
1208 Information->CurrentAddress.QuadPart = FileHandle->FilePointer;
1209
1210 TRACE("Ext2GetFileInformation(%lu) -> FileSize = %llu, FilePointer = 0x%llx\n",
1211 FileId, Information->EndingAddress.QuadPart, Information->CurrentAddress.QuadPart);
1212
1213 return ESUCCESS;
1214}
#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 900 of file ext2.c.

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

Referenced by Ext2ReadInode().

◆ Ext2GetInodeFileSize()

ULONGLONG Ext2GetInodeFileSize ( PEXT2_INODE  Inode)

Definition at line 1081 of file ext2.c.

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

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

Referenced by Ext2ReadInode().

◆ Ext2GetInodeOffsetInBlock()

ULONG Ext2GetInodeOffsetInBlock ( PEXT2_VOLUME_INFO  Volume,
ULONG  Inode 
)

Definition at line 905 of file ext2.c.

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

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 /* Skip leading path separator, if any */
220 if (*FileName == '\\' || *FileName == '/')
221 ++FileName;
222 //
223 // Figure out how many sub-directories we are nested in
224 //
225 NumberOfPathParts = FsGetNumPathParts(FileName);
226
227 //
228 // Loop once for each part
229 //
230 for (i=0; i<NumberOfPathParts; i++)
231 {
232 //
233 // Get first path part
234 //
236
237 //
238 // Advance to the next part of the path
239 //
240 for (; (*FileName != '\\') && (*FileName != '/') && (*FileName != '\0'); FileName++)
241 {
242 }
243 FileName++;
244
245 //
246 // Buffer the directory contents
247 //
248 if (!Ext2ReadDirectory(Volume, DirectoryInode, &DirectoryBuffer, &InodeData))
249 {
250 return FALSE;
251 }
252
253 //
254 // Search for file name in directory
255 //
256 if (!Ext2SearchDirectoryBufferForFile(DirectoryBuffer, (ULONG)Ext2GetInodeFileSize(&InodeData), PathPart, &DirectoryEntry))
257 {
258 FrLdrTempFree(DirectoryBuffer, TAG_EXT_BUFFER);
259 return FALSE;
260 }
261
262 FrLdrTempFree(DirectoryBuffer, TAG_EXT_BUFFER);
263
264 DirectoryInode = DirectoryEntry.inode;
265 }
266
267 if (!Ext2ReadInode(Volume, DirectoryInode, &InodeData))
268 {
269 return FALSE;
270 }
271
272 if (((InodeData.mode & EXT2_S_IFMT) != EXT2_S_IFREG) &&
273 ((InodeData.mode & EXT2_S_IFMT) != EXT2_S_IFLNK))
274 {
275 FileSystemError("Inode is not a regular file or symbolic link.");
276 return FALSE;
277 }
278
279 // Set the associated volume
280 Ext2FileInfo->Volume = Volume;
281
282 // If it's a regular file or a regular symbolic link
283 // then get the block pointer list otherwise it must
284 // be a fast symbolic link which doesn't have a block list
285 if (((InodeData.mode & EXT2_S_IFMT) == EXT2_S_IFREG) ||
286 ((InodeData.mode & EXT2_S_IFMT) == EXT2_S_IFLNK && InodeData.size > FAST_SYMLINK_MAX_NAME_SIZE))
287 {
288 Ext2FileInfo->FileBlockList = Ext2ReadBlockPointerList(Volume, &InodeData);
289 if (Ext2FileInfo->FileBlockList == NULL)
290 {
291 return FALSE;
292 }
293 }
294 else
295 {
296 Ext2FileInfo->FileBlockList = NULL;
297 }
298
299 Ext2FileInfo->FilePointer = 0;
300 Ext2FileInfo->FileSize = Ext2GetInodeFileSize(&InodeData);
301 RtlCopyMemory(&Ext2FileInfo->Inode, &InodeData, sizeof(EXT2_INODE));
302
303 return TRUE;
304}
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:540
VOID FileSystemError(PCSTR ErrorString)
Definition: fs.c:471
VOID FsGetFirstNameFromPath(PCHAR Buffer, PCSTR Path)
Definition: fs.c:568
BOOLEAN Ext2ReadDirectory(PEXT2_VOLUME_INFO Volume, ULONG Inode, PVOID *DirectoryBuffer, PEXT2_INODE InodePointer)
Definition: ext2.c:771
ULONGLONG Ext2GetInodeFileSize(PEXT2_INODE Inode)
Definition: ext2.c:1081
ULONG * Ext2ReadBlockPointerList(PEXT2_VOLUME_INFO Volume, PEXT2_INODE Inode)
Definition: ext2.c:1011
BOOLEAN Ext2ReadInode(PEXT2_VOLUME_INFO Volume, ULONG Inode, PEXT2_INODE InodeBuffer)
Definition: ext2.c:910
BOOLEAN Ext2SearchDirectoryBufferForFile(PVOID DirectoryBuffer, ULONG DirectorySize, PCHAR FileName, PEXT2_DIR_ENTRY DirectoryEntry)
Definition: ext2.c:306
struct _FileName FileName
Definition: fatprocs.h:897
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 1298 of file ext2.c.

1299{
1301 EXT2_SUPER_BLOCK SuperBlock;
1303 ULONG Count;
1305
1306 TRACE("Enter Ext2Mount(%lu)\n", DeviceId);
1307
1308 /* Allocate data for volume information */
1310 if (!Volume)
1311 return NULL;
1313
1314 /* Read the SuperBlock */
1315 Position.QuadPart = 2 * 512;
1316 Status = ArcSeek(DeviceId, &Position, SeekAbsolute);
1317 if (Status != ESUCCESS)
1318 {
1320 return NULL;
1321 }
1322 Status = ArcRead(DeviceId, &SuperBlock, sizeof(SuperBlock), &Count);
1323 if (Status != ESUCCESS || Count != sizeof(SuperBlock))
1324 {
1326 return NULL;
1327 }
1328
1329 /* Check if SuperBlock is valid. If yes, return Ext2 function table. */
1330 if (SuperBlock.magic != EXT2_MAGIC)
1331 {
1333 return NULL;
1334 }
1335
1336 Volume->DeviceId = DeviceId;
1337
1338 /* Really open the volume */
1339 if (!Ext2OpenVolume(Volume))
1340 {
1342 return NULL;
1343 }
1344
1345 /* Remember EXT2 volume information */
1346 Ext2Volumes[DeviceId] = Volume;
1347
1348 /* Return success */
1349 TRACE("Ext2Mount(%lu) success\n", DeviceId);
1350 return &Ext2FuncTable;
1351}
#define EXT2_MAGIC
Definition: ext2.h:43
ARC_STATUS ArcSeek(ULONG FileId, LARGE_INTEGER *Position, SEEKMODE SeekMode)
Definition: fs.c:455
ARC_STATUS ArcRead(ULONG FileId, VOID *Buffer, ULONG N, ULONG *Count)
Definition: fs.c:448
#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:1288
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

◆ Ext2Open()

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

Definition at line 1216 of file ext2.c.

1217{
1220 ULONG DeviceId;
1221
1222 /* Check parameters */
1223 if (OpenMode != OpenReadOnly)
1224 return EACCES;
1225
1226 /* Get underlying device */
1227 DeviceId = FsGetDeviceId(*FileId);
1228 Volume = Ext2Volumes[DeviceId];
1229
1230 TRACE("Ext2Open() FileName = %s\n", Path);
1231
1232 /* Call the internal open method */
1233 // Status = Ext2OpenFile(Volume, Path, &FileHandle);
1235 if (!FileHandle)
1236 return ENOENT;
1237
1238 /* Success, remember the handle */
1240 return ESUCCESS;
1241}
PRTL_UNICODE_STRING_BUFFER Path
#define ENOENT
Definition: acclib.h:79
#define EACCES
Definition: acclib.h:85
VOID FsSetDeviceSpecific(ULONG FileId, PVOID Specific)
Definition: fs.c:625
ULONG FsGetDeviceId(ULONG FileId)
Definition: fs.c:639
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:362
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:575
BOOLEAN Ext2ReadGroupDescriptors(PEXT2_VOLUME_INFO Volume)
Definition: ext2.c:729

Referenced by Ext2Mount().

◆ Ext2Read()

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

Definition at line 1243 of file ext2.c.

1244{
1246 ULONGLONG BytesReadBig;
1248
1249 //
1250 // Read data
1251 //
1252 Success = Ext2ReadFileBig(FileHandle, N, &BytesReadBig, Buffer);
1253 *Count = (ULONG)BytesReadBig;
1254
1255 //
1256 // Check for success
1257 //
1258 if (Success)
1259 return ESUCCESS;
1260 else
1261 return EIO;
1262}
#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 831 of file ext2.c.

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

1012{
1014 ULONG BlockCount;
1015 ULONG* BlockList;
1016 ULONG CurrentBlockInList;
1017 ULONG CurrentBlock;
1018
1019 TRACE("Ext2ReadBlockPointerList()\n");
1020
1021 // Get the number of blocks this file occupies
1022 // I would just use Inode->i_blocks but it
1023 // doesn't seem to be the number of blocks
1024 // the file size corresponds to, but instead
1025 // it is much bigger.
1026 //BlockCount = Inode->i_blocks;
1028 FileSize = ROUND_UP(FileSize, Volume->BlockSizeInBytes);
1029 BlockCount = (ULONG)(FileSize / Volume->BlockSizeInBytes);
1030
1031 // Allocate the memory for the block list
1032 BlockList = FrLdrTempAlloc(BlockCount * sizeof(ULONG), TAG_EXT_BLOCK_LIST);
1033 if (BlockList == NULL)
1034 {
1035 return NULL;
1036 }
1037
1038 RtlZeroMemory(BlockList, BlockCount * sizeof(ULONG));
1039
1040 // Copy the direct block pointers
1041 for (CurrentBlockInList = CurrentBlock = 0;
1042 CurrentBlockInList < BlockCount && CurrentBlock < INDIRECT_BLOCKS;
1043 CurrentBlock++, CurrentBlockInList++)
1044 {
1045 BlockList[CurrentBlockInList] = Inode->blocks.dir_blocks[CurrentBlock];
1046 }
1047
1048 // Copy the indirect block pointers
1049 if (CurrentBlockInList < BlockCount)
1050 {
1051 if (!Ext2CopyIndirectBlockPointers(Volume, BlockList, &CurrentBlockInList, BlockCount, Inode->blocks.indir_block))
1052 {
1054 return NULL;
1055 }
1056 }
1057
1058 // Copy the double indirect block pointers
1059 if (CurrentBlockInList < BlockCount)
1060 {
1061 if (!Ext2CopyDoubleIndirectBlockPointers(Volume, BlockList, &CurrentBlockInList, BlockCount, Inode->blocks.double_indir_block))
1062 {
1064 return NULL;
1065 }
1066 }
1067
1068 // Copy the triple indirect block pointers
1069 if (CurrentBlockInList < BlockCount)
1070 {
1071 if (!Ext2CopyTripleIndirectBlockPointers(Volume, BlockList, &CurrentBlockInList, BlockCount, Inode->blocks.tripple_indir_block))
1072 {
1074 return NULL;
1075 }
1076 }
1077
1078 return BlockList;
1079}
#define INDIRECT_BLOCKS
Definition: ext2.h:45
BOOLEAN Ext2CopyTripleIndirectBlockPointers(PEXT2_VOLUME_INFO Volume, ULONG *BlockList, ULONG *CurrentBlockInList, ULONG BlockCount, ULONG TripleIndirectBlock)
Definition: ext2.c:1160
#define ROUND_UP(n, align)
Definition: eventvwr.h:34
_Must_inspect_result_ _Out_ PLARGE_INTEGER FileSize
Definition: fsrtlfuncs.h:108
struct ext2_inode::@167::datablocks blocks

Referenced by Ext2LookupFile(), and Ext2ReadDirectory().

◆ Ext2ReadDirectory()

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

Definition at line 771 of file ext2.c.

772{
773 EXT2_FILE_INFO DirectoryFileInfo;
774
775 TRACE("Ext2ReadDirectory() Inode = %d\n", Inode);
776
777 // Read the directory inode
778 if (!Ext2ReadInode(Volume, Inode, InodePointer))
779 {
780 return FALSE;
781 }
782
783 // Make sure it is a directory inode
784 if ((InodePointer->mode & EXT2_S_IFMT) != EXT2_S_IFDIR)
785 {
786 FileSystemError("Inode is not a directory.");
787 return FALSE;
788 }
789
790 // Fill in file info struct so we can call Ext2ReadFileBig()
791 RtlZeroMemory(&DirectoryFileInfo, sizeof(EXT2_FILE_INFO));
792 DirectoryFileInfo.Volume = Volume;
793 DirectoryFileInfo.FileBlockList = Ext2ReadBlockPointerList(Volume, InodePointer);
794 DirectoryFileInfo.FilePointer = 0;
795 DirectoryFileInfo.FileSize = Ext2GetInodeFileSize(InodePointer);
796
797 if (DirectoryFileInfo.FileBlockList == NULL)
798 {
799 return FALSE;
800 }
801
802 //
803 // Now allocate the memory to hold the group descriptors
804 //
805 ASSERT(DirectoryFileInfo.FileSize <= 0xFFFFFFFF);
806 *DirectoryBuffer = (PEXT2_DIR_ENTRY)FrLdrTempAlloc((ULONG)DirectoryFileInfo.FileSize, TAG_EXT_BUFFER);
807
808 //
809 // Make sure we got the memory
810 //
811 if (*DirectoryBuffer == NULL)
812 {
814 FileSystemError("Out of memory.");
815 return FALSE;
816 }
817
818 // Now read the root directory data
819 if (!Ext2ReadFileBig(&DirectoryFileInfo, DirectoryFileInfo.FileSize, NULL, *DirectoryBuffer))
820 {
821 FrLdrTempFree(*DirectoryBuffer, TAG_EXT_BUFFER);
822 *DirectoryBuffer = NULL;
824 return FALSE;
825 }
826
828 return TRUE;
829}
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 362 of file ext2.c.

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

987{
988 TRACE("Ext2ReadGroupDescriptor()\n");
989
990#if 0
991 if (!Ext2ReadBlock(Volume, Ext2GetGroupDescBlockNumber(Volume, Group), (PVOID)FILESYSBUFFER))
992 {
993 return FALSE;
994 }
995 RtlCopyMemory(GroupBuffer, (PVOID)(FILESYSBUFFER + Ext2GetGroupDescOffsetInBlock(Volume, Group)), sizeof(EXT2_GROUP_DESC));
996#endif
997
998 RtlCopyMemory(GroupBuffer, &Volume->GroupDescriptors[Group], sizeof(EXT2_GROUP_DESC));
999
1000 TRACE("Dumping group descriptor:\n");
1001 TRACE("block_id = %d\n", GroupBuffer->block_id);
1002 TRACE("inode_id = %d\n", GroupBuffer->inode_id);
1003 TRACE("inode_table_id = %d\n", GroupBuffer->inode_table_id);
1004 TRACE("free_blocks = %d\n", GroupBuffer->free_blocks);
1005 TRACE("free_inodes = %d\n", GroupBuffer->free_inodes);
1006 TRACE("used_dirs = %d\n", GroupBuffer->used_dirs);
1007
1008 return TRUE;
1009}
_In_opt_ PSID Group
Definition: rtlfuncs.h:1658
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 729 of file ext2.c.

730{
731 ULONG GroupDescBlockCount;
732 ULONG BlockNumber;
733 PUCHAR CurrentGroupDescBlock;
734
735 TRACE("Ext2ReadGroupDescriptors()\n");
736
737 /* Free any memory previously allocated */
738 if (Volume->GroupDescriptors != NULL)
739 {
740 FrLdrTempFree(Volume->GroupDescriptors, TAG_EXT_GROUP_DESC);
741 Volume->GroupDescriptors = NULL;
742 }
743
744 /* Now allocate the memory to hold the group descriptors */
745 GroupDescBlockCount = ROUND_UP(Volume->GroupCount, Volume->GroupDescPerBlock) / Volume->GroupDescPerBlock;
746 Volume->GroupDescriptors = (PEXT2_GROUP_DESC)FrLdrTempAlloc(GroupDescBlockCount * Volume->BlockSizeInBytes, TAG_EXT_GROUP_DESC);
747 if (Volume->GroupDescriptors == NULL)
748 {
749 FileSystemError("Out of memory.");
750 return FALSE;
751 }
752
753 // Now read the group descriptors
754 CurrentGroupDescBlock = (PUCHAR)Volume->GroupDescriptors;
755 BlockNumber = Volume->SuperBlock->first_data_block + 1;
756
757 while (GroupDescBlockCount--)
758 {
759 if (!Ext2ReadBlock(Volume, BlockNumber, CurrentGroupDescBlock))
760 {
761 return FALSE;
762 }
763
764 BlockNumber++;
765 CurrentGroupDescBlock += Volume->BlockSizeInBytes;
766 }
767
768 return TRUE;
769}
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 910 of file ext2.c.

911{
912 ULONG InodeGroupNumber;
913 ULONG InodeBlockNumber;
914 ULONG InodeOffsetInBlock;
915 CHAR ErrorString[80];
916 EXT2_GROUP_DESC GroupDescriptor;
917
918 TRACE("Ext2ReadInode() Inode = %d\n", Inode);
919
920 // Make sure its a valid inode
921 if ((Inode < 1) || (Inode > Volume->SuperBlock->total_inodes))
922 {
923 sprintf(ErrorString, "Error reading inode %ld - inode out of range.", Inode);
924 FileSystemError(ErrorString);
925 return FALSE;
926 }
927
928 // Get inode group & block number and offset in block
929 InodeGroupNumber = Ext2GetInodeGroupNumber(Volume, Inode);
930 InodeBlockNumber = Ext2GetInodeBlockNumber(Volume, Inode);
931 InodeOffsetInBlock = Ext2GetInodeOffsetInBlock(Volume, Inode);
932 TRACE("InodeGroupNumber = %d\n", InodeGroupNumber);
933 TRACE("InodeBlockNumber = %d\n", InodeBlockNumber);
934 TRACE("InodeOffsetInBlock = %d\n", InodeOffsetInBlock);
935
936 // Read the group descriptor
937 if (!Ext2ReadGroupDescriptor(Volume, InodeGroupNumber, &GroupDescriptor))
938 {
939 return FALSE;
940 }
941
942 // Add the start block of the inode table to the inode block number
943 InodeBlockNumber += GroupDescriptor.inode_table_id;
944 TRACE("InodeBlockNumber (after group desc correction) = %d\n", InodeBlockNumber);
945
946 // Read the block
948 InodeBlockNumber,
949 (InodeOffsetInBlock * EXT2_INODE_SIZE(Volume->SuperBlock)),
950 sizeof(EXT2_INODE),
951 InodeBuffer))
952 {
953 return FALSE;
954 }
955
956 TRACE("Dumping inode information:\n");
957 TRACE("mode = 0x%x\n", InodeBuffer->mode);
958 TRACE("uid = %d\n", InodeBuffer->uid);
959 TRACE("size = %d\n", InodeBuffer->size);
960 TRACE("atime = %d\n", InodeBuffer->atime);
961 TRACE("ctime = %d\n", InodeBuffer->ctime);
962 TRACE("mtime = %d\n", InodeBuffer->mtime);
963 TRACE("dtime = %d\n", InodeBuffer->dtime);
964 TRACE("gid = %d\n", InodeBuffer->gid);
965 TRACE("nlinks = %d\n", InodeBuffer->nlinks);
966 TRACE("blockcnt = %d\n", InodeBuffer->blockcnt);
967 TRACE("flags = 0x%x\n", InodeBuffer->flags);
968 TRACE("osd1 = 0x%x\n", InodeBuffer->osd1);
969 TRACE("dir_blocks = { %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u }\n",
970 InodeBuffer->blocks.dir_blocks[0], InodeBuffer->blocks.dir_blocks[1], InodeBuffer->blocks.dir_blocks[ 2], InodeBuffer->blocks.dir_blocks[ 3],
971 InodeBuffer->blocks.dir_blocks[4], InodeBuffer->blocks.dir_blocks[5], InodeBuffer->blocks.dir_blocks[ 6], InodeBuffer->blocks.dir_blocks[ 7],
972 InodeBuffer->blocks.dir_blocks[8], InodeBuffer->blocks.dir_blocks[9], InodeBuffer->blocks.dir_blocks[10], InodeBuffer->blocks.dir_blocks[11]);
973 TRACE("indir_block = %u\n", InodeBuffer->blocks.indir_block);
974 TRACE("double_indir_block = %u\n", InodeBuffer->blocks.double_indir_block);
975 TRACE("tripple_indir_block = %u\n", InodeBuffer->blocks.tripple_indir_block);
976 TRACE("version = %d\n", InodeBuffer->version);
977 TRACE("acl = %d\n", InodeBuffer->acl);
978 TRACE("dir_acl = %d\n", InodeBuffer->dir_acl);
979 TRACE("fragment_addr = %d\n", InodeBuffer->fragment_addr);
980 TRACE("osd2 = { %d, %d, %d }\n",
981 InodeBuffer->osd2[0], InodeBuffer->osd2[1], InodeBuffer->osd2[2]);
982
983 return TRUE;
984}
#define EXT2_INODE_SIZE(sb)
Definition: ext2.h:192
ULONG Ext2GetInodeGroupNumber(PEXT2_VOLUME_INFO Volume, ULONG Inode)
Definition: ext2.c:895
ULONG Ext2GetInodeOffsetInBlock(PEXT2_VOLUME_INFO Volume, ULONG Inode)
Definition: ext2.c:905
ULONG Ext2GetInodeBlockNumber(PEXT2_VOLUME_INFO Volume, ULONG Inode)
Definition: ext2.c:900
BOOLEAN Ext2ReadGroupDescriptor(PEXT2_VOLUME_INFO Volume, ULONG Group, PEXT2_GROUP_DESC GroupBuffer)
Definition: ext2.c:986
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 862 of file ext2.c.

863{
864 PVOID TempBuffer;
865
866 TRACE("Ext2ReadPartialBlock() BlockNumber = %d StartingOffset = %d Length = %d Buffer = 0x%x\n", BlockNumber, StartingOffset, Length, Buffer);
867
868 TempBuffer = FrLdrTempAlloc(Volume->BlockSizeInBytes, TAG_EXT_BUFFER);
869
870 if (!Ext2ReadBlock(Volume, BlockNumber, TempBuffer))
871 {
872 FrLdrTempFree(TempBuffer, TAG_EXT_BUFFER);
873 return FALSE;
874 }
875
877
878 FrLdrTempFree(TempBuffer, TAG_EXT_BUFFER);
879
880 return TRUE;
881}
_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 575 of file ext2.c.

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

545{
546#if 0
547 return CacheReadDiskSectors(DriveNumber, SectorNumber + Ext2VolumeStartSector, SectorCount, Buffer);
548#endif
549
551 ULONG Count;
553
554 /* Seek to right position */
555 Position.QuadPart = (ULONGLONG)SectorNumber * 512;
556 Status = ArcSeek(Volume->DeviceId, &Position, SeekAbsolute);
557 if (Status != ESUCCESS)
558 {
559 TRACE("Ext2ReadVolumeSectors() Failed to seek\n");
560 return FALSE;
561 }
562
563 /* Read data */
564 Status = ArcRead(Volume->DeviceId, Buffer, SectorCount * 512, &Count);
565 if (Status != ESUCCESS || Count != SectorCount * 512)
566 {
567 TRACE("Ext2ReadVolumeSectors() Failed to read\n");
568 return FALSE;
569 }
570
571 /* Return success */
572 return TRUE;
573}
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 306 of file ext2.c.

307{
308 ULONG CurrentOffset;
309 PEXT2_DIR_ENTRY CurrentDirectoryEntry;
310
311 TRACE("Ext2SearchDirectoryBufferForFile() DirectoryBuffer = 0x%x DirectorySize = %d FileName = %s\n", DirectoryBuffer, DirectorySize, FileName);
312
313 for (CurrentOffset=0; CurrentOffset<DirectorySize; )
314 {
315 CurrentDirectoryEntry = (PEXT2_DIR_ENTRY)((ULONG_PTR)DirectoryBuffer + CurrentOffset);
316
317 if (CurrentDirectoryEntry->direntlen == 0)
318 {
319 break;
320 }
321
322 if ((CurrentDirectoryEntry->direntlen + CurrentOffset) > DirectorySize)
323 {
324 FileSystemError("Directory entry extends past end of directory file.");
325 return FALSE;
326 }
327
328 TRACE("Dumping directory entry at offset %d:\n", CurrentOffset);
329 DbgDumpBuffer(DPRINT_FILESYSTEM, CurrentDirectoryEntry, CurrentDirectoryEntry->direntlen);
330
331 if ((_strnicmp(FileName, CurrentDirectoryEntry->name, CurrentDirectoryEntry->namelen) == 0) &&
332 (strlen(FileName) == CurrentDirectoryEntry->namelen))
333 {
334 RtlCopyMemory(DirectoryEntry, CurrentDirectoryEntry, sizeof(EXT2_DIR_ENTRY));
335
336 TRACE("EXT2 Directory Entry:\n");
337 TRACE("inode = %d\n", DirectoryEntry->inode);
338 TRACE("direntlen = %d\n", DirectoryEntry->direntlen);
339 TRACE("namelen = %d\n", DirectoryEntry->namelen);
340 TRACE("filetype = %d\n", DirectoryEntry->filetype);
341 TRACE("name = ");
342 for (CurrentOffset=0; CurrentOffset<DirectoryEntry->namelen; CurrentOffset++)
343 {
344 TRACE("%c", DirectoryEntry->name[CurrentOffset]);
345 }
346 TRACE("\n");
347
348 return TRUE;
349 }
350
351 CurrentOffset += CurrentDirectoryEntry->direntlen;
352 }
353
354 return FALSE;
355}
#define DbgDumpBuffer(mask, buf, len)
Definition: debug.h:122
#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 1264 of file ext2.c.

1265{
1267 LARGE_INTEGER NewPosition = *Position;
1268
1269 switch (SeekMode)
1270 {
1271 case SeekAbsolute:
1272 break;
1273 case SeekRelative:
1274 NewPosition.QuadPart += FileHandle->FilePointer;
1275 break;
1276 default:
1277 ASSERT(FALSE);
1278 return EINVAL;
1279 }
1280
1281 if (NewPosition.QuadPart >= FileHandle->FileSize)
1282 return EINVAL;
1283
1284 FileHandle->FilePointer = NewPosition.QuadPart;
1285 return ESUCCESS;
1286}
#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:1216
ARC_STATUS Ext2Seek(ULONG FileId, LARGE_INTEGER *Position, SEEKMODE SeekMode)
Definition: ext2.c:1264
ARC_STATUS Ext2Close(ULONG FileId)
Definition: ext2.c:1195
ARC_STATUS Ext2Read(ULONG FileId, VOID *Buffer, ULONG N, ULONG *Count)
Definition: ext2.c:1243
ARC_STATUS Ext2GetFileInformation(ULONG FileId, FILEINFORMATION *Information)
Definition: ext2.c:1202
#define L(x)
Definition: ntvdm.h:50

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