ReactOS 0.4.16-dev-965-gf669426
ext.c File Reference
#include <freeldr.h>
#include <debug.h>
Include dependency graph for ext.c:

Go to the source code of this file.

Classes

struct  _EXT_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 _EXT_VOLUME_INFO EXT_VOLUME_INFO
 

Functions

 DBG_DEFAULT_CHANNEL (FILESYSTEM)
 
BOOLEAN ExtOpenVolume (PEXT_VOLUME_INFO Volume)
 
PEXT_FILE_INFO ExtOpenFile (PEXT_VOLUME_INFO Volume, PCSTR FileName)
 
BOOLEAN ExtLookupFile (PEXT_VOLUME_INFO Volume, PCSTR FileName, PEXT_FILE_INFO ExtFileInfo)
 
BOOLEAN ExtSearchDirectoryBufferForFile (PVOID DirectoryBuffer, ULONG DirectorySize, PCHAR FileName, PEXT_DIR_ENTRY DirectoryEntry)
 
BOOLEAN ExtReadVolumeSectors (PEXT_VOLUME_INFO Volume, ULONGLONG SectorNumber, ULONG SectorCount, PVOID Buffer)
 
BOOLEAN ExtReadFileBig (PEXT_FILE_INFO ExtFileInfo, ULONGLONG BytesToRead, ULONGLONG *BytesRead, PVOID Buffer)
 
BOOLEAN ExtReadSuperBlock (PEXT_VOLUME_INFO Volume)
 
BOOLEAN ExtReadGroupDescriptors (PEXT_VOLUME_INFO Volume)
 
BOOLEAN ExtReadDirectory (PEXT_VOLUME_INFO Volume, ULONG Inode, PVOID *DirectoryBuffer, PEXT_INODE InodePointer)
 
BOOLEAN ExtReadBlock (PEXT_VOLUME_INFO Volume, ULONG BlockNumber, PVOID Buffer)
 
BOOLEAN ExtReadPartialBlock (PEXT_VOLUME_INFO Volume, ULONG BlockNumber, ULONG StartingOffset, ULONG Length, PVOID Buffer)
 
BOOLEAN ExtReadInode (PEXT_VOLUME_INFO Volume, ULONG Inode, PEXT_INODE InodeBuffer)
 
BOOLEAN ExtReadGroupDescriptor (PEXT_VOLUME_INFO Volume, ULONG Group, PEXT_GROUP_DESC GroupBuffer)
 
ULONGExtReadBlockPointerList (PEXT_VOLUME_INFO Volume, PEXT_INODE Inode)
 
ULONGLONG ExtGetInodeFileSize (PEXT_INODE Inode)
 
BOOLEAN ExtCopyBlockPointersByExtents (PEXT_VOLUME_INFO Volume, ULONG *BlockList, ULONG *CurrentBlockInList, ULONG BlockCount, PEXT4_EXTENT_HEADER ExtentHeader)
 
BOOLEAN ExtCopyIndirectBlockPointers (PEXT_VOLUME_INFO Volume, ULONG *BlockList, ULONG *CurrentBlockInList, ULONG BlockCount, ULONG IndirectBlock)
 
BOOLEAN ExtCopyDoubleIndirectBlockPointers (PEXT_VOLUME_INFO Volume, ULONG *BlockList, ULONG *CurrentBlockInList, ULONG BlockCount, ULONG DoubleIndirectBlock)
 
BOOLEAN ExtCopyTripleIndirectBlockPointers (PEXT_VOLUME_INFO Volume, ULONG *BlockList, ULONG *CurrentBlockInList, ULONG BlockCount, ULONG TripleIndirectBlock)
 
ULONG ExtGetInodeGroupNumber (PEXT_VOLUME_INFO Volume, ULONG Inode)
 
ULONG ExtGetInodeBlockNumber (PEXT_VOLUME_INFO Volume, ULONG Inode)
 
ULONG ExtGetInodeOffsetInBlock (PEXT_VOLUME_INFO Volume, ULONG Inode)
 
ARC_STATUS ExtClose (ULONG FileId)
 
ARC_STATUS ExtGetFileInformation (ULONG FileId, FILEINFORMATION *Information)
 
ARC_STATUS ExtOpen (CHAR *Path, OPENMODE OpenMode, ULONG *FileId)
 
ARC_STATUS ExtRead (ULONG FileId, VOID *Buffer, ULONG N, ULONG *Count)
 
ARC_STATUS ExtSeek (ULONG FileId, LARGE_INTEGER *Position, SEEKMODE SeekMode)
 
const DEVVTBLExtMount (ULONG DeviceId)
 

Variables

PEXT_VOLUME_INFO ExtVolumes [MAX_FDS]
 
const DEVVTBL ExtFuncTable
 

Macro Definition Documentation

◆ TAG_EXT_BLOCK_LIST

#define TAG_EXT_BLOCK_LIST   'LtxE'

Definition at line 71 of file ext.c.

◆ TAG_EXT_BUFFER

#define TAG_EXT_BUFFER   'BtxE'

Definition at line 73 of file ext.c.

◆ TAG_EXT_FILE

#define TAG_EXT_FILE   'FtxE'

Definition at line 72 of file ext.c.

◆ TAG_EXT_GROUP_DESC

#define TAG_EXT_GROUP_DESC   'GtxE'

Definition at line 75 of file ext.c.

◆ TAG_EXT_SUPER_BLOCK

#define TAG_EXT_SUPER_BLOCK   'StxE'

Definition at line 74 of file ext.c.

◆ TAG_EXT_VOLUME

#define TAG_EXT_VOLUME   'VtxE'

Definition at line 76 of file ext.c.

Typedef Documentation

◆ EXT_VOLUME_INFO

Function Documentation

◆ DBG_DEFAULT_CHANNEL()

DBG_DEFAULT_CHANNEL ( FILESYSTEM  )

◆ ExtClose()

ARC_STATUS ExtClose ( ULONG  FileId)

Definition at line 1277 of file ext.c.

1278{
1281 return ESUCCESS;
1282}
PVOID FsGetDeviceSpecific(ULONG FileId)
Definition: fs.c:632
VOID FrLdrTempFree(PVOID Allocation, ULONG Tag)
Definition: heap.c:553
#define TAG_EXT_FILE
Definition: ext.c:72
_Must_inspect_result_ _In_opt_ PFLT_INSTANCE _Out_ PHANDLE FileHandle
Definition: fltkernel.h:1231
@ ESUCCESS
Definition: arc.h:32

◆ ExtCopyBlockPointersByExtents()

BOOLEAN ExtCopyBlockPointersByExtents ( PEXT_VOLUME_INFO  Volume,
ULONG BlockList,
ULONG CurrentBlockInList,
ULONG  BlockCount,
PEXT4_EXTENT_HEADER  ExtentHeader 
)

Definition at line 1109 of file ext.c.

1110{
1111 TRACE("ExtCopyBlockPointersByExtents() BlockCount = 0x%p\n", BlockCount);
1112
1113 if (ExtentHeader->Magic != EXT4_EXTENT_HEADER_MAGIC ||
1114 ExtentHeader->Depth > EXT4_EXTENT_MAX_LEVEL)
1115 return FALSE;
1116
1117 ULONG Level = ExtentHeader->Depth;
1118 ULONG Entries = ExtentHeader->Entries;
1119
1120 TRACE("Level: %d\n", Level);
1121 TRACE("Entries: %d\n", Entries);
1122
1123 // If the level is 0, we have a direct extent block mapping
1124 if (!Level)
1125 {
1126 PEXT4_EXTENT Extent = (PVOID)&ExtentHeader[1];
1127
1128 while ((*CurrentBlockInList) < BlockCount && Entries--)
1129 {
1130 BOOLEAN SparseExtent = (Extent->Length > EXT4_EXTENT_MAX_LENGTH);
1131 ULONG Length = SparseExtent ? (Extent->Length - EXT4_EXTENT_MAX_LENGTH) : Extent->Length;
1132 ULONG CurrentBlock = SparseExtent ? 0 : Extent->Start;
1133
1134 // Copy the pointers to the block list
1135 while ((*CurrentBlockInList) < BlockCount && Length--)
1136 {
1137 BlockList[(*CurrentBlockInList)++] = CurrentBlock;
1138
1139 if (!SparseExtent)
1140 CurrentBlock++;
1141 }
1142
1143 Extent++;
1144 }
1145 }
1146 else
1147 {
1148 PEXT4_EXTENT_IDX Extent = (PVOID)&ExtentHeader[1];
1149
1150 PEXT4_EXTENT_HEADER BlockBuffer = FrLdrTempAlloc(Volume->BlockSizeInBytes, TAG_EXT_BUFFER);
1151 if (!BlockBuffer)
1152 {
1153 return FALSE;
1154 }
1155
1156 // Recursively copy the pointers to the block list
1157 while ((*CurrentBlockInList) < BlockCount && Entries--)
1158 {
1159 if (!(ExtReadBlock(Volume, Extent->Leaf, BlockBuffer) &&
1160 ExtCopyBlockPointersByExtents(Volume, BlockList, CurrentBlockInList, BlockCount, BlockBuffer)))
1161 {
1162 FrLdrTempFree(BlockBuffer, TAG_EXT_BUFFER);
1163 return FALSE;
1164 }
1165
1166 Extent++;
1167 }
1168
1169 FrLdrTempFree(BlockBuffer, TAG_EXT_BUFFER);
1170 }
1171
1172 return TRUE;
1173}
unsigned char BOOLEAN
#define EXT4_EXTENT_MAX_LEVEL
Definition: ext.h:206
#define EXT4_EXTENT_HEADER_MAGIC
Definition: ext.h:203
#define EXT4_EXTENT_MAX_LENGTH
Definition: ext.h:209
PVOID FrLdrTempAlloc(_In_ SIZE_T Size, _In_ ULONG Tag)
Definition: heap.c:545
BOOLEAN ExtCopyBlockPointersByExtents(PEXT_VOLUME_INFO Volume, ULONG *BlockList, ULONG *CurrentBlockInList, ULONG BlockCount, PEXT4_EXTENT_HEADER ExtentHeader)
Definition: ext.c:1109
BOOLEAN ExtReadBlock(PEXT_VOLUME_INFO Volume, ULONG BlockNumber, PVOID Buffer)
Definition: ext.c:844
#define TAG_EXT_BUFFER
Definition: ext.c:73
while(CdLookupNextInitialFileDirent(IrpContext, Fcb, FileContext))
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
UNICODE_STRING Volume
Definition: fltkernel.h:1172
static const ENTRY Entries[]
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
#define TRACE(s)
Definition: solgame.cpp:4
uint64 Length
Definition: DriveVolume.h:48
USHORT Magic
Definition: ext.h:118
USHORT Depth
Definition: ext.h:121
USHORT Entries
Definition: ext.h:119
void * PVOID
Definition: typedefs.h:50
uint32_t ULONG
Definition: typedefs.h:59
_IRQL_requires_same_ typedef _In_ ULONG _In_ UCHAR Level
Definition: wmitypes.h:56

Referenced by ExtCopyBlockPointersByExtents(), and ExtReadBlockPointerList().

◆ ExtCopyDoubleIndirectBlockPointers()

BOOLEAN ExtCopyDoubleIndirectBlockPointers ( PEXT_VOLUME_INFO  Volume,
ULONG BlockList,
ULONG CurrentBlockInList,
ULONG  BlockCount,
ULONG  DoubleIndirectBlock 
)

Definition at line 1207 of file ext.c.

1208{
1209 ULONG* BlockBuffer;
1210 ULONG CurrentBlock;
1211 ULONG BlockPointersPerBlock;
1212
1213 TRACE("ExtCopyDoubleIndirectBlockPointers() BlockCount = %d\n", BlockCount);
1214
1215 BlockPointersPerBlock = Volume->BlockSizeInBytes / sizeof(ULONG);
1216
1217 BlockBuffer = (ULONG*)FrLdrTempAlloc(Volume->BlockSizeInBytes, TAG_EXT_BUFFER);
1218 if (BlockBuffer == NULL)
1219 {
1220 return FALSE;
1221 }
1222
1223 if (!ExtReadBlock(Volume, DoubleIndirectBlock, BlockBuffer))
1224 {
1225 FrLdrTempFree(BlockBuffer, TAG_EXT_BUFFER);
1226 return FALSE;
1227 }
1228
1229 for (CurrentBlock=0; (*CurrentBlockInList)<BlockCount && CurrentBlock<BlockPointersPerBlock; CurrentBlock++)
1230 {
1231 if (!ExtCopyIndirectBlockPointers(Volume, BlockList, CurrentBlockInList, BlockCount, BlockBuffer[CurrentBlock]))
1232 {
1233 FrLdrTempFree(BlockBuffer, TAG_EXT_BUFFER);
1234 return FALSE;
1235 }
1236 }
1237
1238 FrLdrTempFree(BlockBuffer, TAG_EXT_BUFFER);
1239 return TRUE;
1240}
BOOLEAN ExtCopyIndirectBlockPointers(PEXT_VOLUME_INFO Volume, ULONG *BlockList, ULONG *CurrentBlockInList, ULONG BlockCount, ULONG IndirectBlock)
Definition: ext.c:1175
#define NULL
Definition: types.h:112

Referenced by ExtCopyTripleIndirectBlockPointers(), and ExtReadBlockPointerList().

◆ ExtCopyIndirectBlockPointers()

BOOLEAN ExtCopyIndirectBlockPointers ( PEXT_VOLUME_INFO  Volume,
ULONG BlockList,
ULONG CurrentBlockInList,
ULONG  BlockCount,
ULONG  IndirectBlock 
)

Definition at line 1175 of file ext.c.

1176{
1177 ULONG* BlockBuffer;
1178 ULONG CurrentBlock;
1179 ULONG BlockPointersPerBlock;
1180
1181 TRACE("ExtCopyIndirectBlockPointers() BlockCount = %d\n", BlockCount);
1182
1183 BlockPointersPerBlock = Volume->BlockSizeInBytes / sizeof(ULONG);
1184
1185 BlockBuffer = FrLdrTempAlloc(Volume->BlockSizeInBytes, TAG_EXT_BUFFER);
1186 if (!BlockBuffer)
1187 {
1188 return FALSE;
1189 }
1190
1191 if (!ExtReadBlock(Volume, IndirectBlock, BlockBuffer))
1192 {
1193 return FALSE;
1194 }
1195
1196 for (CurrentBlock=0; (*CurrentBlockInList)<BlockCount && CurrentBlock<BlockPointersPerBlock; CurrentBlock++)
1197 {
1198 BlockList[(*CurrentBlockInList)] = BlockBuffer[CurrentBlock];
1199 (*CurrentBlockInList)++;
1200 }
1201
1202 FrLdrTempFree(BlockBuffer, TAG_EXT_BUFFER);
1203
1204 return TRUE;
1205}

Referenced by ExtCopyDoubleIndirectBlockPointers(), and ExtReadBlockPointerList().

◆ ExtCopyTripleIndirectBlockPointers()

BOOLEAN ExtCopyTripleIndirectBlockPointers ( PEXT_VOLUME_INFO  Volume,
ULONG BlockList,
ULONG CurrentBlockInList,
ULONG  BlockCount,
ULONG  TripleIndirectBlock 
)

Definition at line 1242 of file ext.c.

1243{
1244 ULONG* BlockBuffer;
1245 ULONG CurrentBlock;
1246 ULONG BlockPointersPerBlock;
1247
1248 TRACE("ExtCopyTripleIndirectBlockPointers() BlockCount = %d\n", BlockCount);
1249
1250 BlockPointersPerBlock = Volume->BlockSizeInBytes / sizeof(ULONG);
1251
1252 BlockBuffer = (ULONG*)FrLdrTempAlloc(Volume->BlockSizeInBytes, TAG_EXT_BUFFER);
1253 if (BlockBuffer == NULL)
1254 {
1255 return FALSE;
1256 }
1257
1258 if (!ExtReadBlock(Volume, TripleIndirectBlock, BlockBuffer))
1259 {
1260 FrLdrTempFree(BlockBuffer, TAG_EXT_BUFFER);
1261 return FALSE;
1262 }
1263
1264 for (CurrentBlock=0; (*CurrentBlockInList)<BlockCount && CurrentBlock<BlockPointersPerBlock; CurrentBlock++)
1265 {
1266 if (!ExtCopyDoubleIndirectBlockPointers(Volume, BlockList, CurrentBlockInList, BlockCount, BlockBuffer[CurrentBlock]))
1267 {
1268 FrLdrTempFree(BlockBuffer, TAG_EXT_BUFFER);
1269 return FALSE;
1270 }
1271 }
1272
1273 FrLdrTempFree(BlockBuffer, TAG_EXT_BUFFER);
1274 return TRUE;
1275}
BOOLEAN ExtCopyDoubleIndirectBlockPointers(PEXT_VOLUME_INFO Volume, ULONG *BlockList, ULONG *CurrentBlockInList, ULONG BlockCount, ULONG DoubleIndirectBlock)
Definition: ext.c:1207

Referenced by ExtReadBlockPointerList().

◆ ExtGetFileInformation()

ARC_STATUS ExtGetFileInformation ( ULONG  FileId,
FILEINFORMATION Information 
)

Definition at line 1284 of file ext.c.

1285{
1287
1289 Information->EndingAddress.QuadPart = FileHandle->FileSize;
1290 Information->CurrentAddress.QuadPart = FileHandle->FilePointer;
1291
1292 TRACE("ExtGetFileInformation(%lu) -> FileSize = %llu, FilePointer = 0x%llx\n",
1293 FileId, Information->EndingAddress.QuadPart, Information->CurrentAddress.QuadPart);
1294
1295 return ESUCCESS;
1296}
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
_In_ WDFREQUEST _In_ NTSTATUS _In_ ULONG_PTR Information
Definition: wdfrequest.h:1049

◆ ExtGetInodeBlockNumber()

ULONG ExtGetInodeBlockNumber ( PEXT_VOLUME_INFO  Volume,
ULONG  Inode 
)

Definition at line 901 of file ext.c.

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

Referenced by ExtReadInode().

◆ ExtGetInodeFileSize()

ULONGLONG ExtGetInodeFileSize ( PEXT_INODE  Inode)

Definition at line 1097 of file ext.c.

1098{
1099 if ((Inode->Mode & EXT_S_IFMT) == EXT_S_IFDIR)
1100 {
1101 return (ULONGLONG)(Inode->Size);
1102 }
1103 else
1104 {
1105 return ((ULONGLONG)(Inode->Size) | ((ULONGLONG)(Inode->DirACL) << 32));
1106 }
1107}
#define EXT_S_IFMT
Definition: ext.h:231
#define EXT_S_IFDIR
Definition: ext.h:234
ULONG DirACL
Definition: ext.h:169
USHORT Mode
Definition: ext.h:143
ULONG Size
Definition: ext.h:145
uint64_t ULONGLONG
Definition: typedefs.h:67

Referenced by ExtLookupFile(), ExtReadBlockPointerList(), and ExtReadDirectory().

◆ ExtGetInodeGroupNumber()

ULONG ExtGetInodeGroupNumber ( PEXT_VOLUME_INFO  Volume,
ULONG  Inode 
)

Definition at line 896 of file ext.c.

897{
898 return ((Inode - 1) / Volume->SuperBlock->InodesPerGroup);
899}

Referenced by ExtReadInode().

◆ ExtGetInodeOffsetInBlock()

ULONG ExtGetInodeOffsetInBlock ( PEXT_VOLUME_INFO  Volume,
ULONG  Inode 
)

Definition at line 906 of file ext.c.

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

Referenced by ExtReadInode().

◆ ExtLookupFile()

BOOLEAN ExtLookupFile ( PEXT_VOLUME_INFO  Volume,
PCSTR  FileName,
PEXT_FILE_INFO  ExtFileInfo 
)

Definition at line 209 of file ext.c.

210{
211 UINT32 i;
212 ULONG NumberOfPathParts;
213 CHAR PathPart[261];
214 PVOID DirectoryBuffer;
215 ULONG DirectoryInode = EXT_ROOT_INODE;
216 EXT_INODE InodeData;
217 EXT_DIR_ENTRY DirectoryEntry;
218
219 TRACE("ExtLookupFile() FileName = \"%s\"\n", FileName);
220
221 RtlZeroMemory(ExtFileInfo, sizeof(EXT_FILE_INFO));
222
223 /* Skip leading path separator, if any */
224 if (*FileName == '\\' || *FileName == '/')
225 ++FileName;
226 //
227 // Figure out how many sub-directories we are nested in
228 //
229 NumberOfPathParts = FsGetNumPathParts(FileName);
230
231 //
232 // Loop once for each part
233 //
234 for (i=0; i<NumberOfPathParts; i++)
235 {
236 //
237 // Get first path part
238 //
240
241 //
242 // Advance to the next part of the path
243 //
244 for (; (*FileName != '\\') && (*FileName != '/') && (*FileName != '\0'); FileName++)
245 {
246 }
247 FileName++;
248
249 //
250 // Buffer the directory contents
251 //
252 if (!ExtReadDirectory(Volume, DirectoryInode, &DirectoryBuffer, &InodeData))
253 {
254 return FALSE;
255 }
256
257 //
258 // Search for file name in directory
259 //
260 if (!ExtSearchDirectoryBufferForFile(DirectoryBuffer, (ULONG)ExtGetInodeFileSize(&InodeData), PathPart, &DirectoryEntry))
261 {
262 FrLdrTempFree(DirectoryBuffer, TAG_EXT_BUFFER);
263 return FALSE;
264 }
265
266 FrLdrTempFree(DirectoryBuffer, TAG_EXT_BUFFER);
267
268 DirectoryInode = DirectoryEntry.Inode;
269 }
270
271 if (!ExtReadInode(Volume, DirectoryInode, &InodeData))
272 {
273 return FALSE;
274 }
275
276 if (((InodeData.Mode & EXT_S_IFMT) != EXT_S_IFREG) &&
277 ((InodeData.Mode & EXT_S_IFMT) != EXT_S_IFLNK))
278 {
279 FileSystemError("Inode is not a regular file or symbolic link.");
280 return FALSE;
281 }
282
283 // Set the associated volume
284 ExtFileInfo->Volume = Volume;
285
286 // If it's a regular file or a regular symbolic link
287 // then get the block pointer list otherwise it must
288 // be a fast symbolic link which doesn't have a block list
289 if (((InodeData.Mode & EXT_S_IFMT) == EXT_S_IFREG) ||
290 ((InodeData.Mode & EXT_S_IFMT) == EXT_S_IFLNK && InodeData.Size > FAST_SYMLINK_MAX_NAME_SIZE))
291 {
292 ExtFileInfo->FileBlockList = ExtReadBlockPointerList(Volume, &InodeData);
293 if (ExtFileInfo->FileBlockList == NULL)
294 {
295 return FALSE;
296 }
297 }
298 else
299 {
300 ExtFileInfo->FileBlockList = NULL;
301 }
302
303 ExtFileInfo->FilePointer = 0;
304 ExtFileInfo->FileSize = ExtGetInodeFileSize(&InodeData);
305 RtlCopyMemory(&ExtFileInfo->Inode, &InodeData, sizeof(EXT_INODE));
306
307 return TRUE;
308}
unsigned int UINT32
#define FAST_SYMLINK_MAX_NAME_SIZE
Definition: ext.h:240
#define EXT_S_IFREG
Definition: ext.h:236
#define EXT_S_IFLNK
Definition: ext.h:237
#define EXT_ROOT_INODE
Definition: ext.h:186
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
ULONGLONG ExtGetInodeFileSize(PEXT_INODE Inode)
Definition: ext.c:1097
BOOLEAN ExtReadDirectory(PEXT_VOLUME_INFO Volume, ULONG Inode, PVOID *DirectoryBuffer, PEXT_INODE InodePointer)
Definition: ext.c:784
BOOLEAN ExtSearchDirectoryBufferForFile(PVOID DirectoryBuffer, ULONG DirectorySize, PCHAR FileName, PEXT_DIR_ENTRY DirectoryEntry)
Definition: ext.c:310
BOOLEAN ExtReadInode(PEXT_VOLUME_INFO Volume, ULONG Inode, PEXT_INODE InodeBuffer)
Definition: ext.c:911
ULONG * ExtReadBlockPointerList(PEXT_VOLUME_INFO Volume, PEXT_INODE Inode)
Definition: ext.c:1012
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
EXT_INODE Inode
Definition: ext.h:249
PEXT_VOLUME_INFO Volume
Definition: ext.h:250
PULONG FileBlockList
Definition: ext.h:248
ULONGLONG FilePointer
Definition: ext.h:247
ULONGLONG FileSize
Definition: ext.h:246
ULONG Inode
Definition: ext.h:176
Definition: ext.h:142
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
char CHAR
Definition: xmlstorage.h:175

Referenced by ExtOpenFile().

◆ ExtMount()

const DEVVTBL * ExtMount ( ULONG  DeviceId)

Definition at line 1380 of file ext.c.

1381{
1383 EXT_SUPER_BLOCK SuperBlock;
1385 ULONG Count;
1387
1388 TRACE("Enter ExtMount(%lu)\n", DeviceId);
1389
1390 /* Allocate data for volume information */
1392 if (!Volume)
1393 return NULL;
1395
1396 /* Read the SuperBlock */
1397 Position.QuadPart = 2 * 512;
1398 Status = ArcSeek(DeviceId, &Position, SeekAbsolute);
1399 if (Status != ESUCCESS)
1400 {
1402 return NULL;
1403 }
1404 Status = ArcRead(DeviceId, &SuperBlock, sizeof(SuperBlock), &Count);
1405 if (Status != ESUCCESS || Count != sizeof(SuperBlock))
1406 {
1408 return NULL;
1409 }
1410
1411 /* Check if SuperBlock is valid. If yes, return Ext function table. */
1412 if (SuperBlock.Magic != EXT_SUPERBLOCK_MAGIC)
1413 {
1415 return NULL;
1416 }
1417
1418 Volume->DeviceId = DeviceId;
1419
1420 /* Really open the volume */
1421 if (!ExtOpenVolume(Volume))
1422 {
1424 return NULL;
1425 }
1426
1427 /* Remember EXT volume information */
1428 ExtVolumes[DeviceId] = Volume;
1429
1430 /* Return success */
1431 TRACE("ExtMount(%lu) success\n", DeviceId);
1432 return &ExtFuncTable;
1433}
#define EXT_SUPERBLOCK_MAGIC
Definition: ext.h:45
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: ext.c:76
const DEVVTBL ExtFuncTable
Definition: ext.c:1370
BOOLEAN ExtOpenVolume(PEXT_VOLUME_INFO Volume)
Definition: ext.c:78
PEXT_VOLUME_INFO ExtVolumes[MAX_FDS]
Definition: ext.c:69
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: ext.h:70
static COORD Position
Definition: mouse.c:34

◆ ExtOpen()

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

Definition at line 1298 of file ext.c.

1299{
1302 ULONG DeviceId;
1303
1304 /* Check parameters */
1305 if (OpenMode != OpenReadOnly)
1306 return EACCES;
1307
1308 /* Get underlying device */
1309 DeviceId = FsGetDeviceId(*FileId);
1310 Volume = ExtVolumes[DeviceId];
1311
1312 TRACE("ExtOpen() FileName = \"%s\"\n", Path);
1313
1314 /* Call the internal open method */
1315 // Status = ExtOpenFile(Volume, Path, &FileHandle);
1317 if (!FileHandle)
1318 return ENOENT;
1319
1320 /* Success, remember the handle */
1322 return ESUCCESS;
1323}
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
PEXT_FILE_INFO ExtOpenFile(PEXT_VOLUME_INFO Volume, PCSTR FileName)
Definition: ext.c:107
@ OpenReadOnly
Definition: arc.h:65

◆ ExtOpenFile()

PEXT_FILE_INFO ExtOpenFile ( PEXT_VOLUME_INFO  Volume,
PCSTR  FileName 
)

Definition at line 107 of file ext.c.

108{
109 EXT_FILE_INFO TempExtFileInfo;
114
115 TRACE("ExtOpenFile() FileName = \"%s\"\n", FileName);
116
117 RtlZeroMemory(SymLinkPath, sizeof(SymLinkPath));
118
119 // Lookup the file in the file system
120 if (!ExtLookupFile(Volume, FileName, &TempExtFileInfo))
121 {
122 return NULL;
123 }
124
125 // If we got a symbolic link then fix up the path
126 // and re-call this function
127 if ((TempExtFileInfo.Inode.Mode & EXT_S_IFMT) == EXT_S_IFLNK)
128 {
129 TRACE("File is a symbolic link\n");
130
131 // Now read in the symbolic link path
132 if (!ExtReadFileBig(&TempExtFileInfo, TempExtFileInfo.FileSize, NULL, SymLinkPath))
133 {
134 if (TempExtFileInfo.FileBlockList != NULL)
135 {
137 }
138
139 return NULL;
140 }
141
142 TRACE("Symbolic link path = \"%s\"\n", SymLinkPath);
143
144 // Get the full path
145 if (SymLinkPath[0] == '/' || SymLinkPath[0] == '\\')
146 {
147 // Symbolic link is an absolute path
148 // So copy it to FullPath, but skip over
149 // the '/' character at the beginning
150 strcpy(FullPath, &SymLinkPath[1]);
151 }
152 else
153 {
154 // Symbolic link is a relative path
155 // Copy the first part of the path
156 strcpy(FullPath, FileName);
157
158 // Remove the last part of the path
159 for (Index=strlen(FullPath); Index>0; )
160 {
161 Index--;
162 if (FullPath[Index] == '/' || FullPath[Index] == '\\')
163 {
164 break;
165 }
166 }
167 FullPath[Index] = '\0';
168
169 // Concatenate the symbolic link
170 strcat(FullPath, Index == 0 ? "" : "/");
171 strcat(FullPath, SymLinkPath);
172 }
173
174 TRACE("Full file path = \"%s\"\n", FullPath);
175
176 if (TempExtFileInfo.FileBlockList != NULL)
177 {
179 }
180
181 return ExtOpenFile(Volume, FullPath);
182 }
183 else
184 {
186 if (FileHandle == NULL)
187 {
188 if (TempExtFileInfo.FileBlockList != NULL)
189 {
191 }
192
193 return NULL;
194 }
195
196 RtlCopyMemory(FileHandle, &TempExtFileInfo, sizeof(EXT_FILE_INFO));
197
198 return FileHandle;
199 }
200}
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
#define EXT_DIR_ENTRY_MAX_NAME_LENGTH
Definition: ext.h:50
#define TAG_EXT_BLOCK_LIST
Definition: ext.c:71
BOOLEAN ExtReadFileBig(PEXT_FILE_INFO ExtFileInfo, ULONGLONG BytesToRead, ULONGLONG *BytesRead, PVOID Buffer)
Definition: ext.c:365
BOOLEAN ExtLookupFile(PEXT_VOLUME_INFO Volume, PCSTR FileName, PEXT_FILE_INFO ExtFileInfo)
Definition: ext.c:209
strcat
Definition: string.h:92
strcpy
Definition: string.h:131
uint32_t ULONG_PTR
Definition: typedefs.h:65
_In_ WDFCOLLECTION _In_ ULONG Index

Referenced by ExtOpen(), and ExtOpenFile().

◆ ExtOpenVolume()

BOOLEAN ExtOpenVolume ( PEXT_VOLUME_INFO  Volume)

Definition at line 78 of file ext.c.

79{
80 TRACE("ExtOpenVolume() DeviceId = %d\n", Volume->DeviceId);
81
82#if 0
83 /* Initialize the disk cache for this drive */
84 if (!CacheInitializeDrive(DriveNumber))
85 {
86 return FALSE;
87 }
88#endif
89 Volume->BytesPerSector = SECTOR_SIZE;
90
91 /* Read in the super block */
93 return FALSE;
94
95 /* Read in the group descriptors */
97 return FALSE;
98
99 return TRUE;
100}
BOOLEAN CacheInitializeDrive(UCHAR DriveNumber)
Definition: cache.c:37
#define SECTOR_SIZE
Definition: fs.h:22
BOOLEAN ExtReadSuperBlock(PEXT_VOLUME_INFO Volume)
Definition: ext.c:578
BOOLEAN ExtReadGroupDescriptors(PEXT_VOLUME_INFO Volume)
Definition: ext.c:742

Referenced by ExtMount().

◆ ExtRead()

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

Definition at line 1325 of file ext.c.

1326{
1328 ULONGLONG BytesReadBig;
1330
1331 //
1332 // Read data
1333 //
1334 Success = ExtReadFileBig(FileHandle, N, &BytesReadBig, Buffer);
1335 *Count = (ULONG)BytesReadBig;
1336
1337 //
1338 // Check for success
1339 //
1340 if (Success)
1341 return ESUCCESS;
1342 else
1343 return EIO;
1344}
#define N
Definition: crc32.c:57
#define EIO
Definition: acclib.h:81
Definition: bufpool.h:45
@ Success
Definition: eventcreate.c:712

◆ ExtReadBlock()

BOOLEAN ExtReadBlock ( PEXT_VOLUME_INFO  Volume,
ULONG  BlockNumber,
PVOID  Buffer 
)

Definition at line 844 of file ext.c.

845{
846 CHAR ErrorString[80];
847
848 TRACE("ExtReadBlock() BlockNumber = %d Buffer = 0x%x\n", BlockNumber, Buffer);
849
850 // Make sure its a valid block
851 if (BlockNumber > Volume->SuperBlock->BlocksCountLo)
852 {
853 sprintf(ErrorString, "Error reading block %d - block out of range.", (int) BlockNumber);
854 FileSystemError(ErrorString);
855 return FALSE;
856 }
857
858 // Check to see if this is a sparse block
859 if (BlockNumber == 0)
860 {
861 TRACE("Block is part of a sparse file. Zeroing input buffer.\n");
862
863 RtlZeroMemory(Buffer, Volume->BlockSizeInBytes);
864
865 return TRUE;
866 }
867
868 return ExtReadVolumeSectors(Volume, (ULONGLONG)BlockNumber * Volume->BlockSizeInSectors, Volume->BlockSizeInSectors, Buffer);
869}
BOOLEAN ExtReadVolumeSectors(PEXT_VOLUME_INFO Volume, ULONGLONG SectorNumber, ULONG SectorCount, PVOID Buffer)
Definition: ext.c:547
#define sprintf(buf, format,...)
Definition: sprintf.c:55

Referenced by ExtCopyBlockPointersByExtents(), ExtCopyDoubleIndirectBlockPointers(), ExtCopyIndirectBlockPointers(), ExtCopyTripleIndirectBlockPointers(), ExtReadFileBig(), ExtReadGroupDescriptor(), ExtReadGroupDescriptors(), and ExtReadPartialBlock().

◆ ExtReadBlockPointerList()

ULONG * ExtReadBlockPointerList ( PEXT_VOLUME_INFO  Volume,
PEXT_INODE  Inode 
)

Definition at line 1012 of file ext.c.

1013{
1015 ULONG BlockCount;
1016 ULONG* BlockList;
1017 ULONG CurrentBlockInList;
1018 ULONG CurrentBlock;
1019
1020 TRACE("ExtReadBlockPointerList()\n");
1021
1022 // Get the number of blocks this file occupies
1023 // I would just use Inode->i_blocks but it
1024 // doesn't seem to be the number of blocks
1025 // the file size corresponds to, but instead
1026 // it is much bigger.
1027 //BlockCount = Inode->i_blocks;
1029 FileSize = ROUND_UP(FileSize, Volume->BlockSizeInBytes);
1030 BlockCount = (ULONG)(FileSize / Volume->BlockSizeInBytes);
1031
1032 // Allocate the memory for the block list
1033 BlockList = FrLdrTempAlloc(BlockCount * sizeof(ULONG), TAG_EXT_BLOCK_LIST);
1034 if (BlockList == NULL)
1035 {
1036 return NULL;
1037 }
1038
1039 RtlZeroMemory(BlockList, BlockCount * sizeof(ULONG));
1040
1041 // If the file is stored in extents, copy the block pointers by reading the
1042 // extent entries.
1043 if (Inode->Flags & EXT4_INODE_FLAG_EXTENTS)
1044 {
1045 CurrentBlockInList = 0;
1046
1047 if (!ExtCopyBlockPointersByExtents(Volume, BlockList, &CurrentBlockInList, BlockCount, &Inode->ExtentHeader))
1048 {
1050 return NULL;
1051 }
1052
1053 return BlockList;
1054 }
1055
1056 // Copy the direct block pointers
1057 for (CurrentBlockInList = CurrentBlock = 0;
1058 CurrentBlockInList < BlockCount && CurrentBlock < sizeof(Inode->Blocks.DirectBlocks) / sizeof(*Inode->Blocks.DirectBlocks);
1059 CurrentBlock++, CurrentBlockInList++)
1060 {
1061 BlockList[CurrentBlockInList] = Inode->Blocks.DirectBlocks[CurrentBlock];
1062 }
1063
1064 // Copy the indirect block pointers
1065 if (CurrentBlockInList < BlockCount)
1066 {
1067 if (!ExtCopyIndirectBlockPointers(Volume, BlockList, &CurrentBlockInList, BlockCount, Inode->Blocks.IndirectBlock))
1068 {
1070 return NULL;
1071 }
1072 }
1073
1074 // Copy the double indirect block pointers
1075 if (CurrentBlockInList < BlockCount)
1076 {
1077 if (!ExtCopyDoubleIndirectBlockPointers(Volume, BlockList, &CurrentBlockInList, BlockCount, Inode->Blocks.DoubleIndirectBlock))
1078 {
1080 return NULL;
1081 }
1082 }
1083
1084 // Copy the triple indirect block pointers
1085 if (CurrentBlockInList < BlockCount)
1086 {
1087 if (!ExtCopyTripleIndirectBlockPointers(Volume, BlockList, &CurrentBlockInList, BlockCount, Inode->Blocks.TripleIndirectBlock))
1088 {
1090 return NULL;
1091 }
1092 }
1093
1094 return BlockList;
1095}
#define EXT4_INODE_FLAG_EXTENTS
Definition: ext.h:200
BOOLEAN ExtCopyTripleIndirectBlockPointers(PEXT_VOLUME_INFO Volume, ULONG *BlockList, ULONG *CurrentBlockInList, ULONG BlockCount, ULONG TripleIndirectBlock)
Definition: ext.c:1242
#define ROUND_UP(n, align)
Definition: eventvwr.h:34
_Must_inspect_result_ _Out_ PLARGE_INTEGER FileSize
Definition: fsrtlfuncs.h:108
EXT4_EXTENT_HEADER ExtentHeader
Definition: ext.h:165
ULONG Flags
Definition: ext.h:153
struct _ExtInode::@187::@189 Blocks

Referenced by ExtLookupFile(), and ExtReadDirectory().

◆ ExtReadDirectory()

BOOLEAN ExtReadDirectory ( PEXT_VOLUME_INFO  Volume,
ULONG  Inode,
PVOID DirectoryBuffer,
PEXT_INODE  InodePointer 
)

Definition at line 784 of file ext.c.

785{
786 EXT_FILE_INFO DirectoryFileInfo;
787
788 TRACE("ExtReadDirectory() Inode = %d\n", Inode);
789
790 // Read the directory inode
791 if (!ExtReadInode(Volume, Inode, InodePointer))
792 {
793 return FALSE;
794 }
795
796 // Make sure it is a directory inode
797 if ((InodePointer->Mode & EXT_S_IFMT) != EXT_S_IFDIR)
798 {
799 FileSystemError("Inode is not a directory.");
800 return FALSE;
801 }
802
803 // Fill in file info struct so we can call ExtReadFileBig()
804 RtlZeroMemory(&DirectoryFileInfo, sizeof(EXT_FILE_INFO));
805 DirectoryFileInfo.Volume = Volume;
806 DirectoryFileInfo.FileBlockList = ExtReadBlockPointerList(Volume, InodePointer);
807 DirectoryFileInfo.FilePointer = 0;
808 DirectoryFileInfo.FileSize = ExtGetInodeFileSize(InodePointer);
809
810 if (DirectoryFileInfo.FileBlockList == NULL)
811 {
812 return FALSE;
813 }
814
815 //
816 // Now allocate the memory to hold the group descriptors
817 //
818 ASSERT(DirectoryFileInfo.FileSize <= 0xFFFFFFFF);
819 *DirectoryBuffer = (PEXT_DIR_ENTRY)FrLdrTempAlloc((ULONG)DirectoryFileInfo.FileSize, TAG_EXT_BUFFER);
820
821 //
822 // Make sure we got the memory
823 //
824 if (*DirectoryBuffer == NULL)
825 {
827 FileSystemError("Out of memory.");
828 return FALSE;
829 }
830
831 // Now read the root directory data
832 if (!ExtReadFileBig(&DirectoryFileInfo, DirectoryFileInfo.FileSize, NULL, *DirectoryBuffer))
833 {
834 FrLdrTempFree(*DirectoryBuffer, TAG_EXT_BUFFER);
835 *DirectoryBuffer = NULL;
837 return FALSE;
838 }
839
841 return TRUE;
842}
struct _ExtDirEntry * PEXT_DIR_ENTRY
#define ASSERT(a)
Definition: mode.c:44

Referenced by ExtLookupFile().

◆ ExtReadFileBig()

BOOLEAN ExtReadFileBig ( PEXT_FILE_INFO  ExtFileInfo,
ULONGLONG  BytesToRead,
ULONGLONG BytesRead,
PVOID  Buffer 
)

Definition at line 365 of file ext.c.

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

◆ ExtReadGroupDescriptor()

BOOLEAN ExtReadGroupDescriptor ( PEXT_VOLUME_INFO  Volume,
ULONG  Group,
PEXT_GROUP_DESC  GroupBuffer 
)

Definition at line 987 of file ext.c.

988{
989 TRACE("ExtReadGroupDescriptor()\n");
990
991#if 0
992 if (!ExtReadBlock(Volume, ExtGetGroupDescBlockNumber(Volume, Group), (PVOID)FILESYSBUFFER))
993 {
994 return FALSE;
995 }
996 RtlCopyMemory(GroupBuffer, (PVOID)(FILESYSBUFFER + ExtGetGroupDescOffsetInBlock(Volume, Group)), sizeof(EXT_GROUP_DESC));
997#endif
998
999 RtlCopyMemory(GroupBuffer, &((PUCHAR)Volume->GroupDescriptors)[Volume->GroupDescSizeInBytes * Group], sizeof(EXT_GROUP_DESC));
1000
1001 TRACE("Dumping group descriptor:\n");
1002 TRACE("BlockBitmap = %d\n", GroupBuffer->BlockBitmap);
1003 TRACE("InodeBitmap = %d\n", GroupBuffer->InodeBitmap);
1004 TRACE("InodeTable = %d\n", GroupBuffer->InodeTable);
1005 TRACE("FreeBlocksCount = %d\n", GroupBuffer->FreeBlocksCount);
1006 TRACE("FreeInodesCount = %d\n", GroupBuffer->FreeInodesCount);
1007 TRACE("UsedDirsCount = %d\n", GroupBuffer->UsedDirsCount);
1008
1009 return TRUE;
1010}
_In_opt_ PSID Group
Definition: rtlfuncs.h:1670
USHORT FreeBlocksCount
Definition: ext.h:111
ULONG InodeBitmap
Definition: ext.h:109
ULONG InodeTable
Definition: ext.h:110
ULONG BlockBitmap
Definition: ext.h:108
USHORT FreeInodesCount
Definition: ext.h:112
USHORT UsedDirsCount
Definition: ext.h:113
unsigned char * PUCHAR
Definition: typedefs.h:53

Referenced by ExtReadInode().

◆ ExtReadGroupDescriptors()

BOOLEAN ExtReadGroupDescriptors ( PEXT_VOLUME_INFO  Volume)

Definition at line 742 of file ext.c.

743{
744 ULONG GroupDescBlockCount;
745 ULONG BlockNumber;
746 PUCHAR CurrentGroupDescBlock;
747
748 TRACE("ExtReadGroupDescriptors()\n");
749
750 /* Free any memory previously allocated */
751 if (Volume->GroupDescriptors != NULL)
752 {
753 FrLdrTempFree(Volume->GroupDescriptors, TAG_EXT_GROUP_DESC);
754 Volume->GroupDescriptors = NULL;
755 }
756
757 /* Now allocate the memory to hold the group descriptors */
758 GroupDescBlockCount = ROUND_UP(Volume->GroupCount, Volume->GroupDescPerBlock) / Volume->GroupDescPerBlock;
759 Volume->GroupDescriptors = (PEXT_GROUP_DESC)FrLdrTempAlloc(GroupDescBlockCount * Volume->BlockSizeInBytes, TAG_EXT_GROUP_DESC);
760 if (Volume->GroupDescriptors == NULL)
761 {
762 FileSystemError("Out of memory.");
763 return FALSE;
764 }
765
766 // Now read the group descriptors
767 CurrentGroupDescBlock = (PUCHAR)Volume->GroupDescriptors;
768 BlockNumber = Volume->SuperBlock->FirstDataBlock + 1;
769
770 while (GroupDescBlockCount--)
771 {
772 if (!ExtReadBlock(Volume, BlockNumber, CurrentGroupDescBlock))
773 {
774 return FALSE;
775 }
776
777 BlockNumber++;
778 CurrentGroupDescBlock += Volume->BlockSizeInBytes;
779 }
780
781 return TRUE;
782}
struct _ExtGroupDescriptor * PEXT_GROUP_DESC
#define TAG_EXT_GROUP_DESC
Definition: ext.c:75

Referenced by ExtOpenVolume().

◆ ExtReadInode()

BOOLEAN ExtReadInode ( PEXT_VOLUME_INFO  Volume,
ULONG  Inode,
PEXT_INODE  InodeBuffer 
)

Definition at line 911 of file ext.c.

912{
913 ULONG InodeGroupNumber;
914 ULONG InodeBlockNumber;
915 ULONG InodeOffsetInBlock;
916 CHAR ErrorString[80];
917 EXT_GROUP_DESC GroupDescriptor;
918
919 TRACE("ExtReadInode() Inode = %d\n", Inode);
920
921 // Make sure its a valid inode
922 if ((Inode < 1) || (Inode > Volume->SuperBlock->InodesCount))
923 {
924 sprintf(ErrorString, "Error reading inode %ld - inode out of range.", Inode);
925 FileSystemError(ErrorString);
926 return FALSE;
927 }
928
929 // Get inode group & block number and offset in block
930 InodeGroupNumber = ExtGetInodeGroupNumber(Volume, Inode);
931 InodeBlockNumber = ExtGetInodeBlockNumber(Volume, Inode);
932 InodeOffsetInBlock = ExtGetInodeOffsetInBlock(Volume, Inode);
933 TRACE("InodeGroupNumber = %d\n", InodeGroupNumber);
934 TRACE("InodeBlockNumber = %d\n", InodeBlockNumber);
935 TRACE("InodeOffsetInBlock = %d\n", InodeOffsetInBlock);
936
937 // Read the group descriptor
938 if (!ExtReadGroupDescriptor(Volume, InodeGroupNumber, &GroupDescriptor))
939 {
940 return FALSE;
941 }
942
943 // Add the start block of the inode table to the inode block number
944 InodeBlockNumber += GroupDescriptor.InodeTable;
945 TRACE("InodeBlockNumber (after group desc correction) = %d\n", InodeBlockNumber);
946
947 // Read the block
949 InodeBlockNumber,
950 (InodeOffsetInBlock * Volume->InodeSizeInBytes),
951 sizeof(EXT_INODE),
952 InodeBuffer))
953 {
954 return FALSE;
955 }
956
957 TRACE("Dumping inode information:\n");
958 TRACE("Mode = 0x%x\n", InodeBuffer->Mode);
959 TRACE("UID = %d\n", InodeBuffer->UID);
960 TRACE("Size = %d\n", InodeBuffer->Size);
961 TRACE("Atime = %d\n", InodeBuffer->Atime);
962 TRACE("Ctime = %d\n", InodeBuffer->Ctime);
963 TRACE("Mtime = %d\n", InodeBuffer->Mtime);
964 TRACE("Dtime = %d\n", InodeBuffer->Dtime);
965 TRACE("GID = %d\n", InodeBuffer->GID);
966 TRACE("LinksCount = %d\n", InodeBuffer->LinksCount);
967 TRACE("Blocks = %d\n", InodeBuffer->Blocks);
968 TRACE("Flags = 0x%x\n", InodeBuffer->Flags);
969 TRACE("OSD1 = 0x%x\n", InodeBuffer->OSD1);
970 TRACE("DirectBlocks = { %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u }\n",
971 InodeBuffer->Blocks.DirectBlocks[0], InodeBuffer->Blocks.DirectBlocks[1], InodeBuffer->Blocks.DirectBlocks[2], InodeBuffer->Blocks.DirectBlocks[3],
972 InodeBuffer->Blocks.DirectBlocks[4], InodeBuffer->Blocks.DirectBlocks[5], InodeBuffer->Blocks.DirectBlocks[6], InodeBuffer->Blocks.DirectBlocks[7],
973 InodeBuffer->Blocks.DirectBlocks[8], InodeBuffer->Blocks.DirectBlocks[9], InodeBuffer->Blocks.DirectBlocks[10], InodeBuffer->Blocks.DirectBlocks[11]);
974 TRACE("IndirectBlock = %u\n", InodeBuffer->Blocks.IndirectBlock);
975 TRACE("DoubleIndirectBlock = %u\n", InodeBuffer->Blocks.DoubleIndirectBlock);
976 TRACE("TripleIndirectBlock = %u\n", InodeBuffer->Blocks.TripleIndirectBlock);
977 TRACE("Generation = %d\n", InodeBuffer->Generation);
978 TRACE("FileACL = %d\n", InodeBuffer->FileACL);
979 TRACE("DirACL = %d\n", InodeBuffer->DirACL);
980 TRACE("FragAddress = %d\n", InodeBuffer->FragAddress);
981 TRACE("OSD2 = { %d, %d, %d }\n",
982 InodeBuffer->OSD2[0], InodeBuffer->OSD2[1], InodeBuffer->OSD2[2]);
983
984 return TRUE;
985}
ULONG ExtGetInodeGroupNumber(PEXT_VOLUME_INFO Volume, ULONG Inode)
Definition: ext.c:896
BOOLEAN ExtReadGroupDescriptor(PEXT_VOLUME_INFO Volume, ULONG Group, PEXT_GROUP_DESC GroupBuffer)
Definition: ext.c:987
ULONG ExtGetInodeBlockNumber(PEXT_VOLUME_INFO Volume, ULONG Inode)
Definition: ext.c:901
ULONG ExtGetInodeOffsetInBlock(PEXT_VOLUME_INFO Volume, ULONG Inode)
Definition: ext.c:906
ULONG Dtime
Definition: ext.h:149
USHORT LinksCount
Definition: ext.h:151
ULONG FragAddress
Definition: ext.h:170
USHORT GID
Definition: ext.h:150
ULONG Generation
Definition: ext.h:167
ULONG Ctime
Definition: ext.h:147
USHORT UID
Definition: ext.h:144
ULONG OSD1
Definition: ext.h:154
ULONG FileACL
Definition: ext.h:168
ULONG Mtime
Definition: ext.h:148
ULONG OSD2[3]
Definition: ext.h:171
ULONG Atime
Definition: ext.h:146

Referenced by ExtLookupFile(), and ExtReadDirectory().

◆ ExtReadPartialBlock()

BOOLEAN ExtReadPartialBlock ( PEXT_VOLUME_INFO  Volume,
ULONG  BlockNumber,
ULONG  StartingOffset,
ULONG  Length,
PVOID  Buffer 
)

Definition at line 875 of file ext.c.

876{
877 PVOID TempBuffer;
878
879 TRACE("ExtReadPartialBlock() BlockNumber = %d StartingOffset = %d Length = %d Buffer = 0x%x\n", BlockNumber, StartingOffset, Length, Buffer);
880
881 TempBuffer = FrLdrTempAlloc(Volume->BlockSizeInBytes, TAG_EXT_BUFFER);
882
883 if (!ExtReadBlock(Volume, BlockNumber, TempBuffer))
884 {
885 FrLdrTempFree(TempBuffer, TAG_EXT_BUFFER);
886 return FALSE;
887 }
888
890
891 FrLdrTempFree(TempBuffer, TAG_EXT_BUFFER);
892
893 return TRUE;
894}
_In_ PFCB _In_ LONGLONG StartingOffset
Definition: cdprocs.h:291

Referenced by ExtReadFileBig(), and ExtReadInode().

◆ ExtReadSuperBlock()

BOOLEAN ExtReadSuperBlock ( PEXT_VOLUME_INFO  Volume)

Definition at line 578 of file ext.c.

579{
580 PEXT_SUPER_BLOCK SuperBlock = Volume->SuperBlock;
582 ULONG Count;
584
585 TRACE("ExtReadSuperBlock()\n");
586
587#if 0
588 /* Free any memory previously allocated */
589 if (SuperBlock != NULL)
590 {
592 SuperBlock = NULL;
593 }
594#endif
595
596 /* Allocate the memory to hold the super block if needed */
597 if (SuperBlock == NULL)
598 {
600 if (SuperBlock == NULL)
601 {
602 FileSystemError("Out of memory.");
603 return FALSE;
604 }
605 }
606 Volume->SuperBlock = SuperBlock;
607
608 /* Reset its contents */
609 RtlZeroMemory(SuperBlock, 1024);
610
611 /* Read the SuperBlock */
612 Position.QuadPart = 2 * 512;
613 Status = ArcSeek(Volume->DeviceId, &Position, SeekAbsolute);
614 if (Status != ESUCCESS)
615 return FALSE;
616 Status = ArcRead(Volume->DeviceId, SuperBlock, 2 * 512, &Count);
617 if (Status != ESUCCESS || Count != 2 * 512)
618 return FALSE;
619
620 TRACE("Dumping super block:\n");
621 TRACE("InodesCount: %d\n", SuperBlock->InodesCount);
622 TRACE("BlocksCountLo: %d\n", SuperBlock->BlocksCountLo);
623 TRACE("RBlocksCountLo: %d\n", SuperBlock->RBlocksCountLo);
624 TRACE("FreeBlocksCountLo: %d\n", SuperBlock->FreeBlocksCountLo);
625 TRACE("FreeInodesCount: %d\n", SuperBlock->FreeInodesCount);
626 TRACE("FirstDataBlock: %d\n", SuperBlock->FirstDataBlock);
627 TRACE("LogBlockSize: %d\n", SuperBlock->LogBlockSize);
628 TRACE("LogFragSize: %d\n", SuperBlock->LogFragSize);
629 TRACE("BlocksPerGroup: %d\n", SuperBlock->BlocksPerGroup);
630 TRACE("FragsPerGroup: %d\n", SuperBlock->FragsPerGroup);
631 TRACE("InodesPerGroup: %d\n", SuperBlock->InodesPerGroup);
632 TRACE("MTime: %d\n", SuperBlock->MTime);
633 TRACE("WTime: %d\n", SuperBlock->WTime);
634 TRACE("MntCount: %d\n", SuperBlock->MntCount);
635 TRACE("MaxMntCount: %d\n", SuperBlock->MaxMntCount);
636 TRACE("Magic: 0x%x\n", SuperBlock->Magic);
637 TRACE("State: 0x%x\n", SuperBlock->State);
638 TRACE("Errors: 0x%x\n", SuperBlock->Errors);
639 TRACE("MinorRevisionLevel: %d\n", SuperBlock->MinorRevisionLevel);
640 TRACE("LastCheck: %d\n", SuperBlock->LastCheck);
641 TRACE("CheckInterval: %d\n", SuperBlock->CheckInterval);
642 TRACE("CreatorOS: %d\n", SuperBlock->CreatorOS);
643 TRACE("RevisionLevel: %d\n", SuperBlock->RevisionLevel);
644 TRACE("DefResUID: %d\n", SuperBlock->DefResUID);
645 TRACE("DefResGID: %d\n", SuperBlock->DefResGID);
646 TRACE("FirstInode: %d\n", SuperBlock->FirstInode);
647 TRACE("InodeSize: %d\n", SuperBlock->InodeSize);
648 TRACE("BlockGroupNr: %d\n", SuperBlock->BlockGroupNr);
649 TRACE("FeatureCompat: 0x%x\n", SuperBlock->FeatureCompat);
650 TRACE("FeatureIncompat: 0x%x\n", SuperBlock->FeatureIncompat);
651 TRACE("FeatureROCompat: 0x%x\n", SuperBlock->FeatureROCompat);
652 TRACE("UUID: { ");
653 for (ULONG i = 0; i < sizeof(SuperBlock->UUID); i++)
654 {
655 TRACE("0x%02x", SuperBlock->UUID[i]);
656 if (i < sizeof(SuperBlock->UUID) - 1)
657 TRACE(", ");
658 }
659 TRACE(" }\n");
660 TRACE("VolumeName: \"%s\"\n", SuperBlock->VolumeName);
661 TRACE("LastMounted: \"%s\"\n", SuperBlock->LastMounted);
662 TRACE("AlgorithmUsageBitmap: 0x%x\n", SuperBlock->AlgorithmUsageBitmap);
663 TRACE("PreallocBlocks: %d\n", SuperBlock->PreallocBlocks);
664 TRACE("PreallocDirBlocks: %d\n", SuperBlock->PreallocDirBlocks);
665 TRACE("ReservedGdtBlocks: %d\n", SuperBlock->ReservedGdtBlocks);
666 TRACE("JournalUUID: { ");
667 for (ULONG i = 0; i < sizeof(SuperBlock->JournalUUID); i++)
668 {
669 TRACE("0x%02x", SuperBlock->JournalUUID[i]);
670 if (i < sizeof(SuperBlock->JournalUUID) - 1)
671 TRACE(", ");
672 }
673 TRACE(" }\n");
674 TRACE("JournalInum: %d\n", SuperBlock->JournalInum);
675 TRACE("JournalDev: %d\n", SuperBlock->JournalDev);
676 TRACE("LastOrphan: %d\n", SuperBlock->LastOrphan);
677 TRACE("HashSeed: { 0x%02x, 0x%02x, 0x%02x, 0x%02x }\n",
678 SuperBlock->HashSeed[0], SuperBlock->HashSeed[1],
679 SuperBlock->HashSeed[2], SuperBlock->HashSeed[3]);
680 TRACE("DefHashVersion: %d\n", SuperBlock->DefHashVersion);
681 TRACE("JournalBackupType: %d\n", SuperBlock->JournalBackupType);
682 TRACE("GroupDescSize: %d\n", SuperBlock->GroupDescSize);
683
684 //
685 // Check the super block magic
686 //
687 if (SuperBlock->Magic != EXT_SUPERBLOCK_MAGIC)
688 {
689 FileSystemError("Invalid super block magic (0xef53)");
690 return FALSE;
691 }
692
693 // Calculate the group count
694 Volume->GroupCount = (SuperBlock->BlocksCountLo - SuperBlock->FirstDataBlock + SuperBlock->BlocksPerGroup - 1) / SuperBlock->BlocksPerGroup;
695 TRACE("ExtGroupCount: %d\n", Volume->GroupCount);
696
697 // Calculate the block size
698 Volume->BlockSizeInBytes = 1024 << SuperBlock->LogBlockSize;
699 Volume->BlockSizeInSectors = Volume->BlockSizeInBytes / Volume->BytesPerSector;
700 TRACE("ExtBlockSizeInBytes: %d\n", Volume->BlockSizeInBytes);
701 TRACE("ExtBlockSizeInSectors: %d\n", Volume->BlockSizeInSectors);
702
703 // Calculate the fragment size
704 if (SuperBlock->LogFragSize >= 0)
705 {
706 Volume->FragmentSizeInBytes = 1024 << SuperBlock->LogFragSize;
707 }
708 else
709 {
710 Volume->FragmentSizeInBytes = 1024 >> -(SuperBlock->LogFragSize);
711 }
712 Volume->FragmentSizeInSectors = Volume->FragmentSizeInBytes / Volume->BytesPerSector;
713 TRACE("ExtFragmentSizeInBytes: %d\n", Volume->FragmentSizeInBytes);
714 TRACE("ExtFragmentSizeInSectors: %d\n", Volume->FragmentSizeInSectors);
715
716 // Verify that the fragment size and the block size are equal
717 if (Volume->BlockSizeInBytes != Volume->FragmentSizeInBytes)
718 {
719 FileSystemError("The fragment size must be equal to the block size.");
720 return FALSE;
721 }
722
723 // Set the volume inode size in bytes
724 Volume->InodeSizeInBytes = EXT_INODE_SIZE(SuperBlock);
725 TRACE("InodeSizeInBytes: %d\n", Volume->InodeSizeInBytes);
726
727 // Set the volume group descriptor size in bytes
728 Volume->GroupDescSizeInBytes = EXT_GROUP_DESC_SIZE(SuperBlock);
729 TRACE("GroupDescSizeInBytes: %d\n", Volume->GroupDescSizeInBytes);
730
731 // Calculate the number of inodes in one block
732 Volume->InodesPerBlock = Volume->BlockSizeInBytes / Volume->InodeSizeInBytes;
733 TRACE("ExtInodesPerBlock: %d\n", Volume->InodesPerBlock);
734
735 // Calculate the number of group descriptors in one block
736 Volume->GroupDescPerBlock = Volume->BlockSizeInBytes / Volume->GroupDescSizeInBytes;
737 TRACE("ExtGroupDescPerBlock: %d\n", Volume->GroupDescPerBlock);
738
739 return TRUE;
740}
#define EXT_GROUP_DESC_SIZE(sb)
Definition: ext.h:196
struct _ExtSuperBlock * PEXT_SUPER_BLOCK
#define EXT_INODE_SIZE(sb)
Definition: ext.h:192
#define TAG_EXT_SUPER_BLOCK
Definition: ext.c:74
USHORT GroupDescSize
Definition: ext.h:102
ULONG FreeInodesCount
Definition: ext.h:59
UCHAR PreallocDirBlocks
Definition: ext.h:93
ULONG FeatureCompat
Definition: ext.h:85
UCHAR UUID[16]
Definition: ext.h:88
ULONG HashSeed[4]
Definition: ext.h:99
ULONG FeatureIncompat
Definition: ext.h:86
UCHAR DefHashVersion
Definition: ext.h:100
ULONG InodesCount
Definition: ext.h:55
UCHAR JournalBackupType
Definition: ext.h:101
ULONG BlocksCountLo
Definition: ext.h:56
USHORT MaxMntCount
Definition: ext.h:69
USHORT DefResUID
Definition: ext.h:78
ULONG InodesPerGroup
Definition: ext.h:65
ULONG MTime
Definition: ext.h:66
ULONG CreatorOS
Definition: ext.h:76
ULONG LogBlockSize
Definition: ext.h:61
ULONG LastCheck
Definition: ext.h:74
ULONG RevisionLevel
Definition: ext.h:77
USHORT BlockGroupNr
Definition: ext.h:84
ULONG CheckInterval
Definition: ext.h:75
ULONG AlgorithmUsageBitmap
Definition: ext.h:91
LONG LogFragSize
Definition: ext.h:62
ULONG FragsPerGroup
Definition: ext.h:64
USHORT DefResGID
Definition: ext.h:79
CHAR VolumeName[16]
Definition: ext.h:89
ULONG BlocksPerGroup
Definition: ext.h:63
ULONG FirstInode
Definition: ext.h:82
ULONG WTime
Definition: ext.h:67
ULONG LastOrphan
Definition: ext.h:98
ULONG RBlocksCountLo
Definition: ext.h:57
ULONG FeatureROCompat
Definition: ext.h:87
USHORT MntCount
Definition: ext.h:68
USHORT InodeSize
Definition: ext.h:83
USHORT State
Definition: ext.h:71
UCHAR JournalUUID[16]
Definition: ext.h:95
CHAR LastMounted[64]
Definition: ext.h:90
USHORT Errors
Definition: ext.h:72
ULONG FreeBlocksCountLo
Definition: ext.h:58
USHORT ReservedGdtBlocks
Definition: ext.h:94
USHORT MinorRevisionLevel
Definition: ext.h:73
ULONG FirstDataBlock
Definition: ext.h:60
UCHAR PreallocBlocks
Definition: ext.h:92
ULONG JournalDev
Definition: ext.h:97
ULONG JournalInum
Definition: ext.h:96

Referenced by ExtOpenVolume().

◆ ExtReadVolumeSectors()

BOOLEAN ExtReadVolumeSectors ( PEXT_VOLUME_INFO  Volume,
ULONGLONG  SectorNumber,
ULONG  SectorCount,
PVOID  Buffer 
)

Definition at line 547 of file ext.c.

548{
549#if 0
550 return CacheReadDiskSectors(DriveNumber, SectorNumber + ExtVolumeStartSector, SectorCount, Buffer);
551#endif
552
554 ULONG Count;
556
557 /* Seek to right position */
558 Position.QuadPart = (ULONGLONG)SectorNumber * 512;
559 Status = ArcSeek(Volume->DeviceId, &Position, SeekAbsolute);
560 if (Status != ESUCCESS)
561 {
562 TRACE("ExtReadVolumeSectors() Failed to seek\n");
563 return FALSE;
564 }
565
566 /* Read data */
567 Status = ArcRead(Volume->DeviceId, Buffer, SectorCount * 512, &Count);
568 if (Status != ESUCCESS || Count != SectorCount * 512)
569 {
570 TRACE("ExtReadVolumeSectors() Failed to read\n");
571 return FALSE;
572 }
573
574 /* Return success */
575 return TRUE;
576}
BOOLEAN CacheReadDiskSectors(UCHAR DiskNumber, ULONGLONG StartSector, ULONG SectorCount, PVOID Buffer)
Definition: cache.c:113
ULONG SectorCount
Definition: part_xbox.c:31

Referenced by ExtReadBlock().

◆ ExtSearchDirectoryBufferForFile()

BOOLEAN ExtSearchDirectoryBufferForFile ( PVOID  DirectoryBuffer,
ULONG  DirectorySize,
PCHAR  FileName,
PEXT_DIR_ENTRY  DirectoryEntry 
)

Definition at line 310 of file ext.c.

311{
312 ULONG CurrentOffset = 0;
313 PEXT_DIR_ENTRY CurrentDirectoryEntry;
314
315 TRACE("ExtSearchDirectoryBufferForFile() DirectoryBuffer = 0x%x DirectorySize = %d FileName = \"%s\"\n", DirectoryBuffer, DirectorySize, FileName);
316
317 while (CurrentOffset < DirectorySize)
318 {
319 CurrentDirectoryEntry = (PEXT_DIR_ENTRY)((ULONG_PTR)DirectoryBuffer + CurrentOffset);
320
321 if (!CurrentDirectoryEntry->EntryLen)
322 break;
323
324 if ((CurrentDirectoryEntry->EntryLen + CurrentOffset) > DirectorySize)
325 {
326 FileSystemError("Directory entry extends past end of directory file.");
327 return FALSE;
328 }
329
330 if (!CurrentDirectoryEntry->Inode)
331 goto NextDirectoryEntry;
332
333 TRACE("EXT Directory Entry:\n");
334 TRACE("Inode = %d\n", CurrentDirectoryEntry->Inode);
335 TRACE("EntryLen = %d\n", CurrentDirectoryEntry->EntryLen);
336 TRACE("NameLen = %d\n", CurrentDirectoryEntry->NameLen);
337 TRACE("FileType = %d\n", CurrentDirectoryEntry->FileType);
338 TRACE("Name = \"");
339 for (ULONG NameOffset = 0; NameOffset < CurrentDirectoryEntry->NameLen; NameOffset++)
340 {
341 TRACE("%c", CurrentDirectoryEntry->Name[NameOffset]);
342 }
343 TRACE("\"\n\n");
344
345 if (strlen(FileName) == CurrentDirectoryEntry->NameLen &&
346 !_strnicmp(FileName, CurrentDirectoryEntry->Name, CurrentDirectoryEntry->NameLen))
347 {
348 RtlCopyMemory(DirectoryEntry, CurrentDirectoryEntry, sizeof(EXT_DIR_ENTRY));
349
350 return TRUE;
351 }
352
353NextDirectoryEntry:
354 CurrentOffset += CurrentDirectoryEntry->EntryLen;
355 }
356
357 return FALSE;
358}
#define _strnicmp(_String1, _String2, _MaxCount)
Definition: compat.h:23
USHORT EntryLen
Definition: ext.h:177
UCHAR FileType
Definition: ext.h:179
CHAR Name[EXT_DIR_ENTRY_MAX_NAME_LENGTH]
Definition: ext.h:180
UCHAR NameLen
Definition: ext.h:178

Referenced by ExtLookupFile().

◆ ExtSeek()

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

Definition at line 1346 of file ext.c.

1347{
1349 LARGE_INTEGER NewPosition = *Position;
1350
1351 switch (SeekMode)
1352 {
1353 case SeekAbsolute:
1354 break;
1355 case SeekRelative:
1356 NewPosition.QuadPart += FileHandle->FilePointer;
1357 break;
1358 default:
1359 ASSERT(FALSE);
1360 return EINVAL;
1361 }
1362
1363 if (NewPosition.QuadPart >= FileHandle->FileSize)
1364 return EINVAL;
1365
1366 FileHandle->FilePointer = NewPosition.QuadPart;
1367 return ESUCCESS;
1368}
#define EINVAL
Definition: acclib.h:90
@ SeekRelative
Definition: arc.h:60
LONGLONG QuadPart
Definition: typedefs.h:114

Variable Documentation

◆ ExtFuncTable

const DEVVTBL ExtFuncTable
Initial value:
=
{
L"ext2fs",
}
ARC_STATUS ExtGetFileInformation(ULONG FileId, FILEINFORMATION *Information)
Definition: ext.c:1284
ARC_STATUS ExtSeek(ULONG FileId, LARGE_INTEGER *Position, SEEKMODE SeekMode)
Definition: ext.c:1346
ARC_STATUS ExtRead(ULONG FileId, VOID *Buffer, ULONG N, ULONG *Count)
Definition: ext.c:1325
ARC_STATUS ExtClose(ULONG FileId)
Definition: ext.c:1277
ARC_STATUS ExtOpen(CHAR *Path, OPENMODE OpenMode, ULONG *FileId)
Definition: ext.c:1298
#define L(x)
Definition: ntvdm.h:50

Definition at line 1370 of file ext.c.

Referenced by ExtMount().

◆ ExtVolumes

Definition at line 69 of file ext.c.

Referenced by ExtMount(), and ExtOpen().