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)
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++)
1573 TRACE(
"Enter FatMount(%lu)\n", DeviceId);
1627 Volume->DeviceId = DeviceId;
1646 TRACE(
"FatMount(%lu) success\n", DeviceId);
PRTL_UNICODE_STRING_BUFFER Path
ACPI_SIZE strlen(const char *String)
int strncmp(const char *String1, const char *String2, ACPI_SIZE Count)
#define ReadBuffer(BaseIoAddress, Buffer, Count)
NTSTATUS FatMount(_In_ ULONG DeviceId, _In_ ULONG Unknown, _Out_ PBL_FILE_ENTRY *FileEntry)
ULONG PartitionSectorCount
#define DBG_DEFAULT_CHANNEL(ch)
struct FATX_DIRENTRY * PFATX_DIRENTRY
struct _FATX_BOOTSECTOR * PFATX_BOOTSECTOR
struct DIRENTRY * PDIRENTRY
struct LFN_DIRENTRY * PLFN_DIRENTRY
ARC_STATUS ArcGetFileInformation(ULONG FileId, FILEINFORMATION *Information)
ARC_STATUS ArcSeek(ULONG FileId, LARGE_INTEGER *Position, SEEKMODE SeekMode)
ULONG FsGetNumPathParts(PCSTR Path)
VOID FileSystemError(PCSTR ErrorString)
ULONG FsGetDeviceId(ULONG FileId)
VOID * FsGetDeviceSpecific(ULONG FileId)
ARC_STATUS ArcRead(ULONG FileId, VOID *Buffer, ULONG N, ULONG *Count)
VOID FsSetDeviceSpecific(ULONG FileId, VOID *Specific)
VOID FsGetFirstNameFromPath(PCHAR Buffer, PCSTR Path)
FORCEINLINE PVOID FrLdrTempAlloc(_In_ SIZE_T Size, _In_ ULONG Tag)
FORCEINLINE VOID FrLdrTempFree(PVOID Allocation, ULONG Tag)
static PUCHAR FatGetFatSector(PFAT_VOLUME_INFO Volume, UINT32 FatSectorNumber)
Reads 1-4 sectors from FAT using the cache.
static BOOLEAN FatReadAdjacentClusters(PFAT_VOLUME_INFO Volume, UINT32 StartClusterNumber, UINT32 MaxClusters, PVOID Buffer, PUINT32 ClustersRead, PUINT32 LastClusterNumber)
VOID FatSwapFatBootSector(PFAT_BOOTSECTOR Obj)
VOID FatSwapFat32BootSector(PFAT32_BOOTSECTOR Obj)
VOID FatSwapDirEntry(PDIRENTRY Obj)
static BOOLEAN FatGetFatEntry(PFAT_VOLUME_INFO Volume, UINT32 Cluster, PUINT32 ClusterPointer)
VOID FatSwapFatXBootSector(PFATX_BOOTSECTOR Obj)
ARC_STATUS FatLookupFile(PFAT_VOLUME_INFO Volume, PCSTR FileName, PFAT_FILE_INFO FatFileInfoPointer)
static BOOLEAN FatReadClusterChain(PFAT_VOLUME_INFO Volume, UINT32 StartClusterNumber, UINT32 NumberOfClusters, PVOID Buffer, PUINT32 LastClusterNumber)
ULONG FatDetermineFatType(PFAT_BOOTSECTOR FatBootSector, ULONGLONG PartitionSectorCount)
BOOLEAN FatSearchDirectoryBufferForFile(PFAT_VOLUME_INFO Volume, PVOID DirectoryBuffer, ULONG EntryCount, PCHAR FileName, PFAT_FILE_INFO FatFileInfoPointer)
struct _DIRECTORY_BUFFER DIRECTORY_BUFFER
static BOOLEAN FatReadFile(PFAT_FILE_INFO FatFileInfo, ULONG BytesToRead, ULONG *BytesRead, PVOID Buffer)
ARC_STATUS FatOpen(CHAR *Path, OPENMODE OpenMode, ULONG *FileId)
PVOID FatBufferDirectory(PFAT_VOLUME_INFO Volume, ULONG DirectoryStartCluster, ULONG *EntryCountPointer, BOOLEAN RootDirectory)
#define FAT_IS_END_CLUSTER(clnumber)
static ULONG FatCountClustersInChain(PFAT_VOLUME_INFO Volume, UINT32 StartCluster)
const DEVVTBL FatXFuncTable
static BOOLEAN FatXSearchDirectoryBufferForFile(PFAT_VOLUME_INFO Volume, PVOID DirectoryBuffer, ULONG DirectorySize, PCHAR FileName, PFAT_FILE_INFO FatFileInfoPointer)
VOID FatSwapLFNDirEntry(PLFN_DIRENTRY Obj)
struct _DIRECTORY_BUFFER * PDIRECTORY_BUFFER
ARC_STATUS FatSeek(ULONG FileId, LARGE_INTEGER *Position, SEEKMODE SeekMode)
BOOLEAN FatReadVolumeSectors(PFAT_VOLUME_INFO Volume, ULONG SectorNumber, ULONG SectorCount, PVOID Buffer)
BOOLEAN FatOpenVolume(PFAT_VOLUME_INFO Volume, PFAT_BOOTSECTOR BootSector, ULONGLONG PartitionSectorCount)
ARC_STATUS FatRead(ULONG FileId, VOID *Buffer, ULONG N, ULONG *Count)
PFAT_VOLUME_INFO FatVolumes[MAX_FDS]
VOID FatSwapFatXDirEntry(PFATX_DIRENTRY Obj)
#define FAT_MAX_CACHE_SIZE
const DEVVTBL FatFuncTable
ARC_STATUS FatGetFileInformation(ULONG FileId, FILEINFORMATION *Information)
struct _FAT_VOLUME_INFO FAT_VOLUME_INFO
void FatParseShortFileName(PCHAR Buffer, PDIRENTRY DirEntry)
LIST_ENTRY DirectoryBufferListHead
ARC_STATUS FatClose(ULONG FileId)
BOOLEAN FatReadPartialCluster(PFAT_VOLUME_INFO Volume, ULONG ClusterNumber, ULONG StartingOffset, ULONG Length, PVOID Buffer)
BOOL BackupBootSector(LPCTSTR lpszVolumeName)
#define SW(Object, Field)
#define SD(Object, Field)
_In_ PFCB _In_ LONGLONG StartingOffset
#define _strnicmp(_String1, _String2, _MaxCount)
#define InsertTailList(ListHead, Entry)
#define ROUND_UP(n, align)
_Must_inspect_result_ _In_opt_ PFLT_INSTANCE _Out_ PHANDLE FileHandle
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
#define RtlEqualMemory(a, b, c)
static unsigned char * fat
#define sprintf(buf, format,...)
static OUT PIO_STATUS_BLOCK OUT PVOID FileInformation
static PLARGE_INTEGER Time
_In_ ULONG _In_ ULONG _In_ ULONG Length
struct _FAT32_BOOTSECTOR * PFAT32_BOOTSECTOR
struct _FAT_BOOTSECTOR * PFAT_BOOTSECTOR
base of all file and directory entries
ULONG DirectoryStartCluster
ULONG RootDirStartCluster
ULONG ActiveFatSectorStart
ULONG RootDirStartCluster
struct _LIST_ENTRY * Flink
#define RtlCopyMemory(Destination, Source, Length)
#define RtlZeroMemory(Destination, Length)
#define CONTAINING_RECORD(address, type, field)
static int Link(const char **args)
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
_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
_In_ WDFREQUEST _In_ NTSTATUS _In_ ULONG_PTR Information
_In_ ULONG _In_ ULONG _In_ ULONG NumberOfHeads
_In_ ULONG _In_ ULONG SectorsPerTrack