26 #define FAT_IS_END_CLUSTER(clnumber) \ 27 (((Volume->FatType == FAT12) && (clnumber >= 0xff8)) || \ 28 ((Volume->FatType == FAT16 || Volume->FatType == FATX16) && (clnumber >= 0xfff8)) || \ 29 ((Volume->FatType == FAT32 || Volume->FatType == FATX32) && (clnumber >= 0x0ffffff8))) 31 #define TAG_FAT_CHAIN 'CtaT' 32 #define TAG_FAT_FILE 'FtaF' 33 #define TAG_FAT_VOLUME 'VtaF' 34 #define TAG_FAT_BUFFER 'BtaF' 35 #define TAG_FAT_CACHE 'HtaF' 37 #define FAT_MAX_CACHE_SIZE (256 * 1024) // 256 KiB, note: it should fit maximum FAT12 FAT size (6144 bytes) 62 SW(
Obj, BytesPerSector);
63 SW(
Obj, ReservedSectors);
64 SW(
Obj, RootDirEntries);
65 SW(
Obj, TotalSectors);
66 SW(
Obj, SectorsPerFat);
69 SD(
Obj, HiddenSectors);
70 SD(
Obj, TotalSectorsBig);
71 SD(
Obj, VolumeSerialNumber);
72 SW(
Obj, BootSectorMagic);
77 SW(
Obj, BytesPerSector);
78 SW(
Obj, ReservedSectors);
79 SW(
Obj, RootDirEntries);
80 SW(
Obj, TotalSectors);
81 SW(
Obj, SectorsPerFat);
83 SD(
Obj, HiddenSectors);
84 SD(
Obj, TotalSectorsBig);
85 SD(
Obj, SectorsPerFatBig);
86 SW(
Obj, ExtendedFlags);
87 SW(
Obj, FileSystemVersion);
88 SD(
Obj, RootDirStartCluster);
91 SD(
Obj, VolumeSerialNumber);
92 SW(
Obj, BootSectorMagic);
97 SD(
Obj, VolumeSerialNumber);
98 SD(
Obj, SectorsPerCluster);
99 SW(
Obj, NumberOfFats);
106 SW(
Obj, LastAccessDate);
107 SW(
Obj, ClusterHigh);
117 SW(
Obj, StartCluster);
118 for(
i = 0;
i < 5;
i++)
120 for(
i = 0;
i < 6;
i++)
122 for(
i = 0;
i < 2;
i++)
128 SD(
Obj, StartCluster);
134 SW(
Obj, LastAccessTime);
135 SW(
Obj, LastAccessDate);
146 TRACE(
"FatOpenVolume() DeviceId = %d\n",
Volume->DeviceId);
159 TRACE(
"Dumping boot sector:\n");
169 TRACE(
"Unknown: 0x%x\n", FatXVolumeBootSector->
Unknown);
179 TRACE(
"JumpBoot: 0x%x 0x%x 0x%x\n", Fat32VolumeBootSector->
JumpBoot[0], Fat32VolumeBootSector->
JumpBoot[1], Fat32VolumeBootSector->
JumpBoot[2]);
180 TRACE(
"OemName: %c%c%c%c%c%c%c%c\n", Fat32VolumeBootSector->
OemName[0], Fat32VolumeBootSector->
OemName[1], Fat32VolumeBootSector->
OemName[2], Fat32VolumeBootSector->
OemName[3], Fat32VolumeBootSector->
OemName[4], Fat32VolumeBootSector->
OemName[5], Fat32VolumeBootSector->
OemName[6], Fat32VolumeBootSector->
OemName[7]);
197 TRACE(
"FsInfo: %d\n", Fat32VolumeBootSector->
FsInfo);
204 TRACE(
"VolumeLabel: %c%c%c%c%c%c%c%c%c%c%c\n", Fat32VolumeBootSector->
VolumeLabel[0], Fat32VolumeBootSector->
VolumeLabel[1], Fat32VolumeBootSector->
VolumeLabel[2], Fat32VolumeBootSector->
VolumeLabel[3], Fat32VolumeBootSector->
VolumeLabel[4], Fat32VolumeBootSector->
VolumeLabel[5], Fat32VolumeBootSector->
VolumeLabel[6], Fat32VolumeBootSector->
VolumeLabel[7], Fat32VolumeBootSector->
VolumeLabel[8], Fat32VolumeBootSector->
VolumeLabel[9], Fat32VolumeBootSector->
VolumeLabel[10]);
214 TRACE(
"OemName: %c%c%c%c%c%c%c%c\n", FatVolumeBootSector->
OemName[0], FatVolumeBootSector->
OemName[1], FatVolumeBootSector->
OemName[2], FatVolumeBootSector->
OemName[3], FatVolumeBootSector->
OemName[4], FatVolumeBootSector->
OemName[5], FatVolumeBootSector->
OemName[6], FatVolumeBootSector->
OemName[7]);
231 TRACE(
"VolumeLabel: %c%c%c%c%c%c%c%c%c%c%c\n", FatVolumeBootSector->
VolumeLabel[0], FatVolumeBootSector->
VolumeLabel[1], FatVolumeBootSector->
VolumeLabel[2], FatVolumeBootSector->
VolumeLabel[3], FatVolumeBootSector->
VolumeLabel[4], FatVolumeBootSector->
VolumeLabel[5], FatVolumeBootSector->
VolumeLabel[6], FatVolumeBootSector->
VolumeLabel[7], FatVolumeBootSector->
VolumeLabel[8], FatVolumeBootSector->
VolumeLabel[9], FatVolumeBootSector->
VolumeLabel[10]);
241 sprintf(ErrMsg,
"Invalid boot sector magic (expected 0xaa55 found 0x%x)",
254 FileSystemError(
"This file system has cluster sizes bigger than 64k.\nFreeLoader does not support this.");
265 Volume->BytesPerSector = 512;
267 Volume->FatSectorStart = (0x1000 /
Volume->BytesPerSector);
312 FileSystemError(
"FreeLoader is too old to work with this FAT32 filesystem.\nPlease update FreeLoader.");
318 TRACE(
"FAT cache is %d sectors, %d bytes\n",
Volume->FatCacheSize,
Volume->FatCacheSize *
Volume->BytesPerSector);
328 if (!
Volume->FatCacheIndex)
345 for (
i = 0;
i <
Volume->FatCacheSize;
i++)
355 ULONG RootDirSectors;
356 ULONG DataSectorCount;
359 ULONG CountOfClusters;
366 if (CountOfClusters < 65525)
390 if (CountOfClusters < 4085)
395 else if (CountOfClusters < 65525)
424 TRACE(
"FatBufferDirectory() DirectoryStartCluster = %d RootDirectory = %s\n", DirectoryStartCluster, (
RootDirectory ?
"TRUE" :
"FALSE"));
432 DirectoryStartCluster =
Volume->RootDirStartCluster;
447 TRACE(
"Found cached buffer\n");
449 return DirectoryBuffer->
Data;
458 *DirectorySize =
Volume->RootDirSectors *
Volume->BytesPerSector;
468 TRACE(
"Trying to allocate (DirectorySize) %d bytes.\n", *DirectorySize);
472 if (DirectoryBuffer ==
NULL)
503 return DirectoryBuffer->
Data;
510 CHAR LfnNameBuffer[265];
511 CHAR ShortNameBuffer[20];
518 EntryCount = DirectorySize /
sizeof(
DIRENTRY);
520 TRACE(
"FatSearchDirectoryBufferForFile() DirectoryBuffer = 0x%x EntryCount = %d FileName = %s\n", DirectoryBuffer, EntryCount,
FileName);
525 for (CurrentEntry=0; CurrentEntry<EntryCount; CurrentEntry++, DirectoryBuffer = ((
PDIRENTRY)DirectoryBuffer)+1)
529 OurDirEntry = *((
PDIRENTRY) DirectoryBuffer);
549 if (
DirEntry->FileName[0] ==
'\xE5')
580 if (LfnDirEntry->
Name0_4[0] != 0xFFFF)
584 if (LfnDirEntry->
Name0_4[1] != 0xFFFF)
588 if (LfnDirEntry->
Name0_4[2] != 0xFFFF)
592 if (LfnDirEntry->
Name0_4[3] != 0xFFFF)
596 if (LfnDirEntry->
Name0_4[4] != 0xFFFF)
600 if (LfnDirEntry->
Name5_10[0] != 0xFFFF)
604 if (LfnDirEntry->
Name5_10[1] != 0xFFFF)
608 if (LfnDirEntry->
Name5_10[2] != 0xFFFF)
612 if (LfnDirEntry->
Name5_10[3] != 0xFFFF)
616 if (LfnDirEntry->
Name5_10[4] != 0xFFFF)
620 if (LfnDirEntry->
Name5_10[5] != 0xFFFF)
682 TRACE(
"MSDOS Directory Entry:\n");
683 TRACE(
"FileName[11] = %c%c%c%c%c%c%c%c%c%c%c\n",
DirEntry->FileName[0],
DirEntry->FileName[1],
DirEntry->FileName[2],
DirEntry->FileName[3],
DirEntry->FileName[4],
DirEntry->FileName[5],
DirEntry->FileName[6],
DirEntry->FileName[7],
DirEntry->FileName[8],
DirEntry->FileName[9],
DirEntry->FileName[10]);
695 TRACE(
"StartCluster = 0x%x\n", StartCluster);
721 TRACE(
"FatXSearchDirectoryBufferForFile() DirectoryBuffer = 0x%x EntryCount = %d FileName = %s\n", DirectoryBuffer, EntryCount,
FileName);
725 for (CurrentEntry = 0; CurrentEntry < EntryCount; CurrentEntry++, DirectoryBuffer = ((
PFATX_DIRENTRY)DirectoryBuffer)+1)
749 TRACE(
"FATX Directory Entry:\n");
777 ULONG NumberOfPathParts;
779 PVOID DirectoryBuffer;
780 ULONG DirectoryStartCluster = 0;
796 for (
i=0;
i<NumberOfPathParts;
i++)
815 if (DirectoryBuffer ==
NULL)
842 if ((
i+1) < NumberOfPathParts)
915 UINT32 SectorNumAbsolute =
Volume->ActiveFatSectorStart + FatSectorNumber;
916 UINT32 CacheIndex = FatSectorNumber %
Volume->FatCacheSize;
918 ASSERT(FatSectorNumber < Volume->SectorsPerFat);
921 if (
Volume->FatCacheIndex[CacheIndex] != SectorNumAbsolute)
931 for (
i = 0;
i < SectorsToRead;
i++)
933 Volume->FatCacheIndex[CacheIndex +
i] = SectorNumAbsolute +
i;
936 TRACE(
"FAT cache miss: read sector 0x%x from disk\n", SectorNumAbsolute);
940 TRACE(
"FAT cache hit: sector 0x%x present\n", SectorNumAbsolute);
943 return &
Volume->FatCache[CacheIndex *
Volume->BytesPerSector];
953 UINT32 FatOffset, ThisFatSecNum, ThisFatEntOffset,
fat;
956 TRACE(
"FatGetFatEntry() Retrieving FAT entry for cluster %d.\n", Cluster);
962 FatOffset = Cluster + (Cluster / 2);
963 ThisFatSecNum = FatOffset /
Volume->BytesPerSector;
964 ThisFatEntOffset = (FatOffset %
Volume->BytesPerSector);
966 TRACE(
"FatOffset: %d\n", FatOffset);
967 TRACE(
"ThisFatSecNum: %d\n", ThisFatSecNum);
968 TRACE(
"ThisFatEntOffset: %d\n", ThisFatEntOffset);
984 if (Cluster & 0x0001)
994 FatOffset = (Cluster * 2);
995 ThisFatSecNum = FatOffset /
Volume->BytesPerSector;
996 ThisFatEntOffset = (FatOffset %
Volume->BytesPerSector);
1012 FatOffset = (Cluster * 4);
1013 ThisFatSecNum = FatOffset /
Volume->BytesPerSector;
1014 ThisFatEntOffset = (FatOffset %
Volume->BytesPerSector);
1029 ERR(
"Unknown FAT type %d\n",
Volume->FatType);
1033 TRACE(
"FAT entry is 0x%x.\n",
fat);
1035 *ClusterPointer =
fat;
1043 ULONG ClusterCount = 0;
1045 TRACE(
"FatCountClustersInChain() StartCluster = %d\n", StartCluster);
1071 TRACE(
"FatCountClustersInChain() ClusterCount = %d\n", ClusterCount);
1073 return ClusterCount;
1079 UINT32 StartClusterNumber,
1085 UINT32 NextClusterNumber;
1086 UINT32 ClustersToRead = 1;
1087 UINT32 PrevClusterNumber = StartClusterNumber;
1088 UINT32 ClusterStartSector = ((PrevClusterNumber - 2) *
Volume->SectorsPerCluster) +
Volume->DataSectorStart;
1091 *LastClusterNumber = 0;
1099 while (!
FAT_IS_END_CLUSTER(NextClusterNumber) && ClustersToRead < MaxClusters && (NextClusterNumber == PrevClusterNumber + 1))
1102 PrevClusterNumber = NextClusterNumber;
1114 *ClustersRead = ClustersToRead;
1115 *LastClusterNumber = NextClusterNumber;
1127 UINT32 ClustersRead, NextClusterNumber, ClustersLeft = NumberOfClusters;
1129 TRACE(
"FatReadClusterChain() StartClusterNumber = %d NumberOfClusters = %d Buffer = 0x%x\n", StartClusterNumber, NumberOfClusters,
Buffer);
1131 ASSERT(NumberOfClusters > 0);
1135 ClustersLeft -= ClustersRead;
1137 StartClusterNumber = NextClusterNumber;
1140 if (LastClusterNumber)
1142 *LastClusterNumber = NextClusterNumber;
1145 return (ClustersRead > 0);
1154 ULONG ClusterStartSector;
1161 ClusterStartSector = ((ClusterNumber - 2) *
Volume->SectorsPerCluster) +
Volume->DataSectorStart;
1199 UINT32 NextClusterNumber, BytesPerCluster;
1201 TRACE(
"FatReadFile() BytesToRead = %d Buffer = 0x%x\n", BytesToRead,
Buffer);
1254 BytesPerCluster =
Volume->SectorsPerCluster *
Volume->BytesPerSector;
1266 UINT32 LengthInCluster =
min(BytesToRead, BytesPerCluster - OffsetInCluster);
1268 ASSERT(LengthInCluster <= BytesPerCluster && LengthInCluster > 0);
1281 BytesToRead -= LengthInCluster;
1286 if ((LengthInCluster + OffsetInCluster) == BytesPerCluster)
1301 if (BytesToRead > 0)
1306 UINT32 NumberOfClusters = BytesToRead / BytesPerCluster;
1308 TRACE(
"Going to read: %u clusters\n", NumberOfClusters);
1310 if (NumberOfClusters > 0)
1312 UINT32 BytesReadHere = NumberOfClusters * BytesPerCluster;
1325 BytesToRead -= BytesReadHere;
1339 if (BytesToRead > 0)
1376 TRACE(
"FatReadVolumeSectors() Failed to seek\n");
1386 TRACE(
"FatReadVolumeSectors() Failed to read\n");
1411 TRACE(
"FatGetFileInformation(%lu) -> FileSize = %lu, FilePointer = 0x%lx\n",
1432 TRACE(
"FatOpen() FileName = %s\n",
Path);
1501 TRACE(
"FatSeek() NewPosition = %u, OldPointer = %u, SeekMode = %d\n", NewPosition.
LowPart,
FileHandle->FilePointer, SeekMode);
1507 TRACE(
"FatSeek() OldClusterIdx: %u, NewClusterIdx: %u\n", OldClusterIdx, NewClusterIdx);
1509 if (NewClusterIdx != OldClusterIdx)
1511 UINT32 CurrentClusterIdx, ClusterNumber;
1513 if (NewClusterIdx > OldClusterIdx)
1515 CurrentClusterIdx = OldClusterIdx;
1520 CurrentClusterIdx = 0;
1524 for (; CurrentClusterIdx < NewClusterIdx; CurrentClusterIdx++)
1563 TRACE(
"Enter FatMount(%lu)\n", DeviceId);
1617 Volume->DeviceId = DeviceId;
1636 TRACE(
"FatMount(%lu) success\n", DeviceId);
#define SD(Object, Field)
struct DIRENTRY * PDIRENTRY
PVOID FatBufferDirectory(PFAT_VOLUME_INFO Volume, ULONG DirectoryStartCluster, ULONG *EntryCountPointer, BOOLEAN RootDirectory)
VOID FatSwapFatXBootSector(PFATX_BOOTSECTOR Obj)
_In_ ULONG _In_ ULONG _In_ ULONG Length
#define FAT_MAX_CACHE_SIZE
#define ROUND_UP(n, align)
VOID FsGetFirstNameFromPath(PCHAR Buffer, PCSTR Path)
_In_ PFCB _In_ LONGLONG StartingOffset
VOID FatSwapDirEntry(PDIRENTRY Obj)
NTSTATUS FatMount(_In_ ULONG DeviceId, _In_ ULONG Unknown, _Out_ PBL_FILE_ENTRY *FileEntry)
ACPI_SIZE strlen(const char *String)
static BOOLEAN FatXSearchDirectoryBufferForFile(PFAT_VOLUME_INFO Volume, PVOID DirectoryBuffer, ULONG DirectorySize, PCHAR FileName, PFAT_FILE_INFO FatFileInfoPointer)
#define ReadBuffer(BaseIoAddress, Buffer, Count)
VOID FatSwapFatXDirEntry(PFATX_DIRENTRY Obj)
struct _FAT_VOLUME_INFO FAT_VOLUME_INFO
ULONG FsGetNumPathParts(PCSTR Path)
static OUT PIO_STATUS_BLOCK OUT PVOID FileInformation
IN PVOID IN PVOID IN USHORT IN USHORT Size
#define SW(Object, Field)
static BOOLEAN FatReadAdjacentClusters(PFAT_VOLUME_INFO Volume, UINT32 StartClusterNumber, UINT32 MaxClusters, PVOID Buffer, PUINT32 ClustersRead, PUINT32 LastClusterNumber)
_In_ ULONG _In_ ULONG _In_ ULONG NumberOfHeads
#define InsertTailList(ListHead, Entry)
struct FATX_DIRENTRY * PFATX_DIRENTRY
_In_ WDFREQUEST _In_ NTSTATUS _In_ ULONG_PTR Information
VOID * FsGetDeviceSpecific(ULONG FileId)
static BOOLEAN FatReadClusterChain(PFAT_VOLUME_INFO Volume, UINT32 StartClusterNumber, UINT32 NumberOfClusters, PVOID Buffer, PUINT32 LastClusterNumber)
static int Link(const char **args)
_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
static PUCHAR FatGetFatSector(PFAT_VOLUME_INFO Volume, UINT32 FatSectorNumber)
Reads 1-4 sectors from FAT using the cache.
static BOOLEAN FatGetFatEntry(PFAT_VOLUME_INFO Volume, UINT32 Cluster, PUINT32 ClusterPointer)
BOOL BackupBootSector(LPCTSTR lpszVolumeName)
DBG_DEFAULT_CHANNEL(FILESYSTEM)
#define sprintf(buf, format,...)
#define FAT_IS_END_CLUSTER(clnumber)
ULONG FatDetermineFatType(PFAT_BOOTSECTOR FatBootSector, ULONGLONG PartitionSectorCount)
_In_ ULONG _In_ ULONG SectorsPerTrack
struct LFN_DIRENTRY * PLFN_DIRENTRY
VOID FileSystemError(PCSTR ErrorString)
struct _DIRECTORY_BUFFER * PDIRECTORY_BUFFER
FORCEINLINE PVOID FrLdrTempAlloc(_In_ SIZE_T Size, _In_ ULONG Tag)
ARC_STATUS FatGetFileInformation(ULONG FileId, FILEINFORMATION *Information)
struct tagDIRENTRY DIRENTRY
struct _FAT32_BOOTSECTOR * PFAT32_BOOTSECTOR
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
ULONG DirectoryStartCluster
struct _LIST_ENTRY * Flink
VOID FatSwapFatBootSector(PFAT_BOOTSECTOR Obj)
static ULONG FatCountClustersInChain(PFAT_VOLUME_INFO Volume, UINT32 StartCluster)
NTSYSAPI ULONG NTAPI RtlEqualMemory(CONST VOID *Source1, CONST VOID *Source2, ULONG Length)
PFAT_VOLUME_INFO FatVolumes[MAX_FDS]
int strncmp(const char *String1, const char *String2, ACPI_SIZE Count)
VOID FsSetDeviceSpecific(ULONG FileId, VOID *Specific)
ARC_STATUS FatRead(ULONG FileId, VOID *Buffer, ULONG N, ULONG *Count)
#define _strnicmp(_String1, _String2, _MaxCount)
BOOLEAN FatReadVolumeSectors(PFAT_VOLUME_INFO Volume, ULONG SectorNumber, ULONG SectorCount, PVOID Buffer)
ARC_STATUS ArcRead(ULONG FileId, VOID *Buffer, ULONG N, ULONG *Count)
void FatParseShortFileName(PCHAR Buffer, PDIRENTRY DirEntry)
_Must_inspect_result_ _In_ PFLT_INSTANCE _Out_ PBOOLEAN IsDirectory
ARC_STATUS ArcSeek(ULONG FileId, LARGE_INTEGER *Position, SEEKMODE SeekMode)
const DEVVTBL FatFuncTable
ARC_STATUS FatOpen(CHAR *Path, OPENMODE OpenMode, ULONG *FileId)
BOOLEAN FatOpenVolume(PFAT_VOLUME_INFO Volume, PFAT_BOOTSECTOR BootSector, ULONGLONG PartitionSectorCount)
VOID FatSwapFat32BootSector(PFAT32_BOOTSECTOR Obj)
PRTL_UNICODE_STRING_BUFFER Path
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
struct _FAT_BOOTSECTOR * PFAT_BOOTSECTOR
ULONG PartitionSectorCount
ULONG RootDirStartCluster
ULONG ActiveFatSectorStart
BOOLEAN FatReadPartialCluster(PFAT_VOLUME_INFO Volume, ULONG ClusterNumber, ULONG StartingOffset, ULONG Length, PVOID Buffer)
VOID FatSwapLFNDirEntry(PLFN_DIRENTRY Obj)
ARC_STATUS FatSeek(ULONG FileId, LARGE_INTEGER *Position, SEEKMODE SeekMode)
ARC_STATUS FatLookupFile(PFAT_VOLUME_INFO Volume, PCSTR FileName, PFAT_FILE_INFO FatFileInfoPointer)
ARC_STATUS ArcGetFileInformation(ULONG FileId, FILEINFORMATION *Information)
ULONG FsGetDeviceId(ULONG FileId)
#define RtlZeroMemory(Destination, Length)
#define RtlCopyMemory(Destination, Source, Length)
struct _DIRECTORY_BUFFER DIRECTORY_BUFFER
ARC_STATUS FatClose(ULONG FileId)
struct _FATX_BOOTSECTOR * PFATX_BOOTSECTOR
BOOLEAN FatSearchDirectoryBufferForFile(PFAT_VOLUME_INFO Volume, PVOID DirectoryBuffer, ULONG EntryCount, PCHAR FileName, PFAT_FILE_INFO FatFileInfoPointer)
LIST_ENTRY DirectoryBufferListHead
static unsigned char * fat
static BOOLEAN FatReadFile(PFAT_FILE_INFO FatFileInfo, ULONG BytesToRead, ULONG *BytesRead, PVOID Buffer)
static PLARGE_INTEGER Time
base of all file and directory entries
ULONG RootDirStartCluster
FORCEINLINE VOID FrLdrTempFree(PVOID Allocation, ULONG Tag)