rewrite comments into one, unified style

This commit is contained in:
maksw committed 2026-06-15 10:17:48 +02:00
1 parent 6260de0085
commit 467a58c9c6
163 files changed
+3560 -2556

No files matched your search

+73 -63
View File
@@ -1,9 +1,8 @@
// fat32.c - FAT32 filesystem core, directory, cache, and I/O implementation.
// FAT32 filesystem driver. This file owns filesystem operations and FAT-backed file access.
#include "fat32.h"
// ---------------------------------------------------------------------------
// On-disk structures
// ---------------------------------------------------------------------------
// On-disk structures.
#pragma pack(push, 1)
typedef struct {
@@ -110,9 +109,7 @@ typedef struct {
// FAT32_VOL forward declaration (needed by cache helpers).
typedef struct FAT32_VOL_S FAT32_VOL;
// ---------------------------------------------------------------------------
// FAT sector cache (fixes #1 and #5)
// ---------------------------------------------------------------------------
// 32 direct-mapped slots, indexed by (lba % FAT_CACHE_SLOTS).
// Write-back: WriteFatEntry modifies the in-cache bytes and marks the slot
// dirty. FlushFatCache() propagates dirty slots to every FAT copy at once,
@@ -164,12 +161,14 @@ static KSTATUS FatCacheRead(FAT32_VOL *v, uint64_t lba, uint8_t **out) {
return STATUS_SUCCESS;
}
// Implements the fat Cache Mark Dirty operation.
static void FatCacheMarkDirty(FAT32_VOL *v, uint64_t lba) {
uint32_t slot = (uint32_t)(lba % FAT_CACHE_SLOTS);
if (gFatCache[slot].valid && gFatCache[slot].vol == v && gFatCache[slot].lba == lba)
gFatCache[slot].dirty = true;
}
// Implements the fat Cache Invalidate operation.
static void FatCacheInvalidate(void) {
for (int i = 0; i < FAT_CACHE_SLOTS; i++) {
gFatCache[i].vol = (FAT32_VOL*)0;
@@ -182,9 +181,7 @@ static void FatCacheInvalidate(void) {
// Defined after FAT32_VOL is fully declared (below).
static void FlushFatCache(FAT32_VOL *v);
// ---------------------------------------------------------------------------
// Driver state
// ---------------------------------------------------------------------------
// Driver state.
struct FAT32_VOL_S {
uint8_t DriveIndex; // physical disk DEVICE_OBJECT index
uint64_t PartitionLba; // absolute LBA of the mounted volume
@@ -208,9 +205,7 @@ typedef struct {
uint32_t DirentOffset;
} FAT32_FILE;
// ---------------------------------------------------------------------------
// Raw sector I/O (bypasses FAT cache; used for file data and cache eviction)
// ---------------------------------------------------------------------------
// Raw sector I/O (bypasses FAT cache; used for file data and cache eviction).
static KSTATUS ReadSectorsRaw(FAT32_VOL *v, uint64_t lba,
uint32_t count, void *buf) {
if (!v) return STATUS_INVALID_PARAMETER;
@@ -225,15 +220,15 @@ static KSTATUS WriteSectorsRaw(FAT32_VOL *v, uint64_t lba,
// Convenience aliases for file-data I/O.
static KSTATUS ReadSectors (FAT32_VOL *v, uint64_t lba, uint32_t n, void *b) { return ReadSectorsRaw (v, lba, n, b); }
// Updates sectors.
static KSTATUS WriteSectors(FAT32_VOL *v, uint64_t lba, uint32_t n, const void *b) { return WriteSectorsRaw(v, lba, n, b); }
// Implements the cluster To Lba operation.
static uint64_t ClusterToLba(FAT32_VOL *v, uint32_t cluster) {
return v->DataStart + (uint64_t)(cluster - 2) * v->SectorsPerCluster;
}
// ---------------------------------------------------------------------------
// FlushFatCache — needs full FAT32_VOL definition
// ---------------------------------------------------------------------------
// FlushFatCache — needs full FAT32_VOL definition.
static void FlushFatCache(FAT32_VOL *v) {
uint64_t fat0Start = (uint64_t)v->PartitionLba + v->ReservedSectors;
@@ -253,9 +248,7 @@ static void FlushFatCache(FAT32_VOL *v) {
}
}
// ---------------------------------------------------------------------------
// FAT read / write (through cache)
// ---------------------------------------------------------------------------
// FAT read / write (through cache).
static uint32_t FatEntry(FAT32_VOL *v, uint32_t cluster) {
uint32_t fatOffset = cluster * 4;
@@ -268,6 +261,7 @@ static uint32_t FatEntry(FAT32_VOL *v, uint32_t cluster) {
return *(uint32_t *)(sec + offInSec) & 0x0FFFFFFF;
}
// Updates fat Entry.
static KSTATUS WriteFatEntry(FAT32_VOL *v, uint32_t cluster, uint32_t value) {
uint32_t fatOffset = cluster * 4;
uint64_t sector = (uint64_t)v->PartitionLba + v->ReservedSectors
@@ -285,9 +279,7 @@ static KSTATUS WriteFatEntry(FAT32_VOL *v, uint32_t cluster, uint32_t value) {
return STATUS_SUCCESS;
}
// ---------------------------------------------------------------------------
// Cluster allocation (fix #3: next-free hint + two-phase wrap-around scan)
// ---------------------------------------------------------------------------
// Cluster allocation (fix #3: next-free hint + two-phase wrap-around scan).
static uint32_t AllocCluster(FAT32_VOL *v) {
if (v->TotalClusters == 0) return 0;
@@ -317,6 +309,7 @@ static uint32_t AllocCluster(FAT32_VOL *v) {
return 0;
}
// Appends cluster.
static uint32_t AppendCluster(FAT32_VOL *v, uint32_t lastCluster) {
uint32_t newCluster = AllocCluster(v);
if (!newCluster) return 0;
@@ -324,6 +317,7 @@ static uint32_t AppendCluster(FAT32_VOL *v, uint32_t lastCluster) {
return newCluster;
}
// Returns chain End.
static uint32_t GetChainEnd(FAT32_VOL *v, uint32_t start, uint32_t *outCount) {
uint32_t cluster = start, prev = start, count = 0;
while (cluster >= 2 && cluster < FAT32_EOC) {
@@ -334,6 +328,7 @@ static uint32_t GetChainEnd(FAT32_VOL *v, uint32_t start, uint32_t *outCount) {
return prev;
}
// Releases cluster Chain.
static void FreeClusterChain(FAT32_VOL *v, uint32_t start) {
uint32_t cluster = start;
while (cluster >= 2 && cluster < FAT32_EOC) {
@@ -344,9 +339,7 @@ static void FreeClusterChain(FAT32_VOL *v, uint32_t start) {
}
}
// ---------------------------------------------------------------------------
// FAT timestamp and DIRENT metadata helpers
// ---------------------------------------------------------------------------
// FAT timestamp and DIRENT metadata helpers.
typedef struct FAT32_ENCODED_TIME {
uint16_t Date;
@@ -367,10 +360,12 @@ typedef struct FAT32_DIRENT_UPDATE {
#define FAT32_DIRENT_UPDATE_WRITE_TIME 0x00000008u
#define FAT32_DIRENT_UPDATE_ACCESS_DATE 0x00000010u
// Implements the fat Is Leap Year operation.
static int FatIsLeapYear(uint32_t year) {
return ((year % 4u) == 0u && (year % 100u) != 0u) || ((year % 400u) == 0u);
}
// Implements the fat Days In Month operation.
static uint32_t FatDaysInMonth(uint32_t year, uint32_t month) {
static const uint8_t days[12] = { 31,28,31,30,31,30,31,31,30,31,30,31 };
if (month < 1u || month > 12u) return 31u;
@@ -389,11 +384,13 @@ static uint64_t FatCalendarToEpochSeconds(uint32_t year, uint32_t month, uint32_
return (((days * 24u) + hour) * 60u + minute) * 60u + second;
}
// Implements the fat Day Of Week operation.
static uint8_t FatDayOfWeek(uint32_t year, uint32_t month, uint32_t day) {
uint64_t epoch = FatCalendarToEpochSeconds(year, month, day, 0, 0, 0);
return (uint8_t)(((epoch / 86400u) + 4u) % 7u);
}
// Implements the fat Encode Date operation.
static uint16_t FatEncodeDate(const SYS_SYSTEM_TIME* t) {
uint32_t year = t && t->Year ? t->Year : 1980u;
uint32_t month = t && t->Month ? t->Month : 1u;
@@ -408,6 +405,7 @@ static uint16_t FatEncodeDate(const SYS_SYSTEM_TIME* t) {
return (uint16_t)(((year - 1980u) << 9) | (month << 5) | day);
}
// Implements the fat Encode Time operation.
static uint16_t FatEncodeTime(const SYS_SYSTEM_TIME* t) {
uint32_t hour = t ? t->Hour : 0u;
uint32_t minute = t ? t->Minute : 0u;
@@ -418,6 +416,7 @@ static uint16_t FatEncodeTime(const SYS_SYSTEM_TIME* t) {
return (uint16_t)((hour << 11) | (minute << 5) | (second / 2u));
}
// Implements the fat Encode Create Time Tenth operation.
static uint8_t FatEncodeCreateTimeTenth(const SYS_SYSTEM_TIME* t) {
uint32_t second = t ? t->Second : 0u;
uint32_t ms = t ? t->Millisecond : 0u;
@@ -428,6 +427,7 @@ static uint8_t FatEncodeCreateTimeTenth(const SYS_SYSTEM_TIME* t) {
return (uint8_t)v;
}
// Implements the fat Query Encoded Time operation.
static void FatQueryEncodedTime(FAT32_ENCODED_TIME* out) {
SYS_SYSTEM_TIME now;
memset(&now, 0, sizeof(now));
@@ -472,6 +472,7 @@ static void FatDecodeDateTime(uint16_t date, uint16_t time, uint8_t createTenth,
out->EpochSeconds = FatCalendarToEpochSeconds(year, month, day, hour, minute, second);
}
// Implements the fat Decode Access Date operation.
static void FatDecodeAccessDate(uint16_t date, SYS_SYSTEM_TIME* out) {
FatDecodeDateTime(date, 0, 0, out);
}
@@ -527,9 +528,7 @@ static KSTATUS DirentUpdateFirstCluster(FAT32_VOL *v, uint64_t lba,
return DirentUpdateMetadata(v, lba, offset, &u);
}
// ---------------------------------------------------------------------------
// 8.3 name matching / assembly
// ---------------------------------------------------------------------------
// 8.3 name matching / assembly.
static int MatchRaw83(const char dirName[8], const char dirExt[3],
const char wantName[8], const char wantExt[3]) {
@@ -541,6 +540,7 @@ static char FatUpperChar(char c);
static int FatIsLowerChar(char c);
static int FatIsValidShortChar(char c);
// Implements the make83 Name V operation.
static void Make83NameV(SYS_STRING_VIEW src, char name8[8], char ext3[3]) {
memset(name8, ' ', 8);
memset(ext3, ' ', 3);
@@ -571,19 +571,20 @@ static void Make83NameV(SYS_STRING_VIEW src, char name8[8], char ext3[3]) {
}
}
// ---------------------------------------------------------------------------
// LFN assembly / matching
// ---------------------------------------------------------------------------
// LFN assembly / matching.
#define MAX_LFN 256
// Implements the fat Upper Char operation.
static char FatUpperChar(char c) {
return (c >= 'a' && c <= 'z') ? (char)(c - 32) : c;
}
// Implements the fat Is Lower Char operation.
static int FatIsLowerChar(char c) {
return c >= 'a' && c <= 'z';
}
// Implements the fat Is Valid Short Char operation.
static int FatIsValidShortChar(char c) {
c = FatUpperChar(c);
if (c >= 'A' && c <= 'Z') return 1;
@@ -621,12 +622,14 @@ static int FatNameIsStructurallyShort83V(SYS_STRING_VIEW name) {
return baseLen >= 1 && baseLen <= 8 && extLen <= 3;
}
// Implements the fat Component Has Lower V operation.
static int FatComponentHasLowerV(SYS_STRING_VIEW name, size_t start, size_t end) {
for (size_t i = start; i < end; i++)
if (FatIsLowerChar(name.Data[i])) return 1;
return 0;
}
// Implements the fat Component Has Upper V operation.
static int FatComponentHasUpperV(SYS_STRING_VIEW name, size_t start, size_t end) {
for (size_t i = start; i < end; i++)
if (name.Data[i] >= 'A' && name.Data[i] <= 'Z') return 1;
@@ -667,6 +670,7 @@ static int FatNameNeedsLfnForCreateV(SYS_STRING_VIEW name) {
return 0;
}
// Implements the fat Short Name Case Flags V operation.
static uint8_t FatShortNameCaseFlagsV(SYS_STRING_VIEW name) {
if (!FatNameIsStructurallyShort83V(name)) return 0;
size_t baseEnd, extStart, extEnd;
@@ -682,6 +686,7 @@ static uint8_t FatShortNameCaseFlagsV(SYS_STRING_VIEW name) {
return flags;
}
// Implements the lfn Checksum operation.
static uint8_t LfnChecksum(const char name8[8], const char ext3[3]) {
uint8_t sum = 0;
for (int i = 0; i < 11; i++) {
@@ -691,6 +696,7 @@ static uint8_t LfnChecksum(const char name8[8], const char ext3[3]) {
return sum;
}
// Implements the lfn Set Char operation.
static void LfnSetChar(LFN_ENTRY *e, int idx, uint16_t value) {
if (idx < 5) e->Name1[idx] = value;
else if (idx < 11) e->Name2[idx - 5] = value;
@@ -719,6 +725,7 @@ static void BuildLfnEntry(LFN_ENTRY *e, const char *name, size_t nameLen,
}
}
// Creates legacy Broken Dot83.
static void MakeLegacyBrokenDot83(const char *src, char name8[8], char ext3[3]) {
// This exactly models the pre-fix bug for ".doomrc": empty name + "DOO".
memset(name8, ' ', 8);
@@ -758,12 +765,14 @@ static int ShortNameExistsRaw(FAT32_VOL *v, uint32_t dirCluster,
return 0;
}
// Implements the fat Alias Append Char operation.
static void FatAliasAppendChar(char *dst, int *len, int maxLen, char c) {
c = FatUpperChar(c);
if (!FatIsValidShortChar(c)) return;
if (*len < maxLen) dst[(*len)++] = c;
}
// Builds alias Stem Ext V.
static void BuildAliasStemExtV(SYS_STRING_VIEW src, char stem[9], char ext3[3]) {
memset(stem, 0, 9);
memset(ext3, ' ', 3);
@@ -838,6 +847,7 @@ static int MakeUniqueShortAliasV(FAT32_VOL *v, uint32_t dirCluster,
return 0;
}
// Creates legacy Broken Dot83 V.
static void MakeLegacyBrokenDot83V(SYS_STRING_VIEW src, char name8[8], char ext3[3]) {
// This exactly models the pre-fix bug for ".doomrc": empty name + "DOO".
memset(name8, ' ', 8);
@@ -894,6 +904,7 @@ static KSTATUS DeleteLegacyBrokenDotAliasV(FAT32_VOL *v, uint32_t dirCluster,
return STATUS_SUCCESS;
}
// Implements the lfn Append operation.
static void LfnAppend(char *lfn, const LFN_ENTRY *e) {
int seq = (e->Order & 0x3F) - 1;
if (seq < 0 || seq >= (MAX_LFN / 13)) return;
@@ -910,13 +921,12 @@ static void LfnAppend(char *lfn, const LFN_ENTRY *e) {
}
// ---------------------------------------------------------------------------
// Directory search and view-native path traversal
// ---------------------------------------------------------------------------
// Directory search and view-native path traversal.
static int Fat32IsPathSep(char c) {
return c == '\\' || c == '/';
}
// Implements the name View Is Valid operation.
static int Fat32NameViewIsValid(SYS_STRING_VIEW name) {
if (!SysSvIsValid(name)) return 0;
if (name.Length == 0 || name.Length >= MAX_LFN) return 0;
@@ -927,6 +937,7 @@ static int Fat32NameViewIsValid(SYS_STRING_VIEW name) {
return 1;
}
// Implements the lfn Match V operation.
static int LfnMatchV(const char *lfn, SYS_STRING_VIEW want) {
if (!lfn || !SysSvIsValid(want)) return 0;
size_t i = 0;
@@ -1104,9 +1115,7 @@ static KSTATUS SplitPathV(SYS_STRING_VIEW path, SYS_STRING_VIEW* parent,
return STATUS_SUCCESS;
}
// ---------------------------------------------------------------------------
// Find a free DIRENT slot
// ---------------------------------------------------------------------------
// Find a free DIRENT slot.
static int FindFreeDirent(FAT32_VOL *v, uint32_t dirCluster,
uint64_t *outLba, uint32_t *outOffset) {
uint8_t *clusterBuf = (uint8_t *)MmAllocatePool(v->BytesPerCluster);
@@ -1197,9 +1206,7 @@ static int FindFreeDirentRun(FAT32_VOL *v, uint32_t dirCluster, uint32_t needed,
return 0;
}
// ---------------------------------------------------------------------------
// Open / Close
// ---------------------------------------------------------------------------
// Open / Close.
KSTATUS Fat32Open(IO_FILESYSTEM *fs, SYS_STRING_VIEW path, void **fileCtx) {
if (!fs || !fileCtx || !SysSvIsValid(path) || path.Length == 0)
return STATUS_INVALID_PARAMETER;
@@ -1217,6 +1224,7 @@ KSTATUS Fat32Open(IO_FILESYSTEM *fs, SYS_STRING_VIEW path, void **fileCtx) {
return STATUS_SUCCESS;
}
// Releases the requested object.
void Fat32Close(IO_FILESYSTEM *fs, void *fileCtx) {
(void)fs;
FAT32_FILE *f = (FAT32_FILE *)fileCtx;
@@ -1224,14 +1232,12 @@ void Fat32Close(IO_FILESYSTEM *fs, void *fileCtx) {
MmFreePool(fileCtx);
}
// ---------------------------------------------------------------------------
// Read (fix #4: contiguous-run coalescing)
// ---------------------------------------------------------------------------
// We peek ahead in the FAT chain: if cluster N+1 == cluster N physically,
// extend the current run instead of issuing a new ReadSectors call.
// Run length is capped at MAX_RUN_SECTORS to stay within the AHCI bounce
// buffer (128 sectors = 64 KB).
//
// FatEntry() calls in the peek loop are nearly free because they hit the
// FAT sector cache (fix #1).
@@ -1326,9 +1332,7 @@ KSTATUS Fat32Read(IO_FILESYSTEM *fs, void *fileCtx,
return STATUS_SUCCESS;
}
// ---------------------------------------------------------------------------
// Write (fix #4: contiguous-run coalescing)
// ---------------------------------------------------------------------------
// Same strategy as read. Whole-cluster-aligned runs skip the read-modify-
// write; partial head/tail clusters still require it.
@@ -1442,11 +1446,10 @@ KSTATUS Fat32Write(IO_FILESYSTEM *fs, void *fileCtx,
return (written == size) ? STATUS_SUCCESS : STATUS_DEVICE_ERROR;
}
// ---------------------------------------------------------------------------
// Create
// ---------------------------------------------------------------------------
// Create.
KSTATUS Fat32Truncate(IO_FILESYSTEM *fs, void *fileCtx, uint64_t newSize);
// Creates the requested object.
KSTATUS Fat32Create(IO_FILESYSTEM *fs, SYS_STRING_VIEW path, void **fileCtx) {
if (!fs || !fileCtx || !SysSvIsValid(path) || path.Length == 0)
return STATUS_INVALID_PARAMETER;
@@ -1559,9 +1562,7 @@ KSTATUS Fat32Create(IO_FILESYSTEM *fs, SYS_STRING_VIEW path, void **fileCtx) {
return STATUS_SUCCESS;
}
// ---------------------------------------------------------------------------
// Truncate
// ---------------------------------------------------------------------------
// Truncate.
KSTATUS Fat32Truncate(IO_FILESYSTEM *fs, void *fileCtx, uint64_t newSize) {
(void)fs;
FAT32_FILE *f = (FAT32_FILE *)fileCtx;
@@ -1625,9 +1626,7 @@ update_size:
return s; }
}
// ---------------------------------------------------------------------------
// Delete
// ---------------------------------------------------------------------------
// Delete.
KSTATUS Fat32Delete(IO_FILESYSTEM *fs, SYS_STRING_VIEW path) {
if (!fs || !SysSvIsValid(path) || path.Length == 0)
return STATUS_INVALID_PARAMETER;
@@ -1650,13 +1649,12 @@ KSTATUS Fat32Delete(IO_FILESYSTEM *fs, SYS_STRING_VIEW path) {
return STATUS_SUCCESS;
}
// Returns size.
uint64_t Fat32GetSize(IO_FILESYSTEM *fs, void *fileCtx) {
(void)fs; return ((FAT32_FILE *)fileCtx)->FileSize;
}
// ---------------------------------------------------------------------------
// Directory enumeration (fix #2: cluster buffer cached in context)
// ---------------------------------------------------------------------------
// Previously: allocate + ReadSectors + return 1 entry + free, every call.
// Now: buffer lives in FAT32_DIR_CTX; ReadSectors fires only on cluster
// boundaries.
@@ -1672,6 +1670,7 @@ typedef struct {
uint8_t *ClusterBuf; // allocated once in OpenDir, freed in CloseDir
} FAT32_DIR_CTX;
// Opens dir.
KSTATUS Fat32OpenDir(IO_FILESYSTEM *fs, SYS_STRING_VIEW dirPath, void **dirCtx) {
if (!fs || !dirCtx || !SysSvIsValid(dirPath))
return STATUS_INVALID_PARAMETER;
@@ -1703,6 +1702,7 @@ KSTATUS Fat32OpenDir(IO_FILESYSTEM *fs, SYS_STRING_VIEW dirPath, void **dirCtx)
return STATUS_SUCCESS;
}
// Returns dir.
KSTATUS Fat32ReadDir(IO_FILESYSTEM *fs, void *dirCtx, KDIR_ENTRY *out) {
(void)fs;
FAT32_DIR_CTX *ctx = (FAT32_DIR_CTX *)dirCtx;
@@ -1764,6 +1764,7 @@ KSTATUS Fat32ReadDir(IO_FILESYSTEM *fs, void *dirCtx, KDIR_ENTRY *out) {
return STATUS_NO_MORE_FILES;
}
// Releases dir.
void Fat32CloseDir(IO_FILESYSTEM *fs, void *dirCtx) {
(void)fs;
FAT32_DIR_CTX *ctx = (FAT32_DIR_CTX *)dirCtx;
@@ -1771,9 +1772,7 @@ void Fat32CloseDir(IO_FILESYSTEM *fs, void *dirCtx) {
MmFreePool(ctx);
}
// ---------------------------------------------------------------------------
// Volume scan (MBR + GPT + superfloppy)
// ---------------------------------------------------------------------------
// Volume scan (MBR + GPT + superfloppy).
static const EFI_GUID GUID_EFI_SYSTEM = { 0xC12A7328, 0xF81F, 0x11D2, {0xBA,0x4B,0x00,0xA0,0xC9,0x3E,0xC9,0x3B} };
static const EFI_GUID GUID_MS_BASIC_DATA = { 0xEBD0A0A2, 0xB9E5, 0x4433, {0x87,0xC0,0x68,0xB6,0xB7,0x26,0x99,0xC7} };
static const EFI_GUID GUID_LINUX_BASIC_DATA = { 0x0FC63DAF, 0x8483, 0x4772, {0x8E,0x79,0x3D,0x69,0xD8,0x47,0x7D,0xE4} };
@@ -1785,6 +1784,7 @@ typedef struct FAT32_PARTITION_CANDIDATE {
uint64_t SectorCount;
} FAT32_PARTITION_CANDIDATE;
// Returns le32.
static uint32_t ReadLe32(const void* p) {
const uint8_t* b = (const uint8_t*)p;
return (uint32_t)b[0]
@@ -1793,6 +1793,7 @@ static uint32_t ReadLe32(const void* p) {
| ((uint32_t)b[3] << 24);
}
// Checks whether fat32 Vbr.
static int IsFat32Vbr(FAT32_VOL *v, uint64_t lba) {
uint8_t sector[512];
if (!KSUCCESS(ReadSectors(v, lba, 1, sector))) return 0;
@@ -1946,9 +1947,7 @@ static uint32_t Fat32EnumerateDiskVolumes(uint8_t diskIndex,
return count;
}
// ---------------------------------------------------------------------------
// Native async read/write
// ---------------------------------------------------------------------------
// Metadata work (FAT traversal/allocation and partial-cluster read-modify
// preparation) still runs synchronously in the caller/completion context, but
// file data transfers are submitted as disk IRPs and completion is chained from
@@ -1990,6 +1989,7 @@ static volatile int gFat32AsyncInitState;
static void Fat32AsyncReadSubmitNext(FAT32_ASYNC_RW* ctx);
static void Fat32AsyncWriteSubmitNext(FAT32_ASYNC_RW* ctx);
// Implements the async Worker operation.
static void Fat32AsyncWorker(void* arg) {
(void)arg;
@@ -2013,6 +2013,7 @@ static void Fat32AsyncWorker(void* arg) {
}
}
// Implements the ensure Async Worker Started operation.
static KSTATUS Fat32EnsureAsyncWorkerStarted(void) {
uintptr_t flags = KeAcquireSpinlock(&gFat32AsyncLock);
if (gFat32AsyncInitState == 2) {
@@ -2044,6 +2045,7 @@ static KSTATUS Fat32EnsureAsyncWorkerStarted(void) {
return s;
}
// Implements the async Queue Continuation operation.
static void Fat32AsyncQueueContinuation(FAT32_ASYNC_RW* ctx) {
if (!ctx) return;
@@ -2053,6 +2055,7 @@ static void Fat32AsyncQueueContinuation(FAT32_ASYNC_RW* ctx) {
KeSignalSemaphore(gFat32AsyncSemaphore);
}
// Implements the async Finish operation.
static void Fat32AsyncFinish(FAT32_ASYNC_RW* ctx, KSTATUS status, size_t information) {
if (!ctx) return;
if (ctx->CurrentDevice) {
@@ -2066,6 +2069,7 @@ static void Fat32AsyncFinish(FAT32_ASYNC_RW* ctx, KSTATUS status, size_t informa
if (complete) complete(completeContext, status, information);
}
// Implements the async Read Irp Complete operation.
static void Fat32AsyncReadIrpComplete(IRP* irp, void* completeCtx) {
FAT32_ASYNC_RW* ctx = (FAT32_ASYNC_RW*)completeCtx;
if (!ctx) return;
@@ -2089,6 +2093,7 @@ static void Fat32AsyncReadIrpComplete(IRP* irp, void* completeCtx) {
Fat32AsyncQueueContinuation(ctx);
}
// Implements the async Read Submit Next operation.
static void Fat32AsyncReadSubmitNext(FAT32_ASYNC_RW* ctx) {
if (ctx->Remaining == 0) {
Fat32AsyncFinish(ctx, STATUS_SUCCESS, ctx->Done);
@@ -2206,6 +2211,7 @@ KSTATUS Fat32ReadAsync(IO_FILESYSTEM *fs, void *fileCtx,
return STATUS_PENDING;
}
// Implements the async Write Irp Complete operation.
static void Fat32AsyncWriteIrpComplete(IRP* irp, void* completeCtx) {
FAT32_ASYNC_RW* ctx = (FAT32_ASYNC_RW*)completeCtx;
if (!ctx) return;
@@ -2228,6 +2234,7 @@ static void Fat32AsyncWriteIrpComplete(IRP* irp, void* completeCtx) {
Fat32AsyncQueueContinuation(ctx);
}
// Implements the async Write Submit Next operation.
static void Fat32AsyncWriteSubmitNext(FAT32_ASYNC_RW* ctx) {
if (ctx->Remaining == 0) {
uint64_t newEnd = ctx->Offset + ctx->Done;
@@ -2396,9 +2403,7 @@ KSTATUS Fat32WriteAsync(IO_FILESYSTEM *fs, void *fileCtx,
return STATUS_PENDING;
}
// ---------------------------------------------------------------------------
// DriverEntry
// ---------------------------------------------------------------------------
// DriverEntry.
#define FAT32_MAX_VOLUMES 8
static FAT32_VOL gVols[FAT32_MAX_VOLUMES];
@@ -2408,6 +2413,7 @@ static bool gVolumeMounted[FAT32_MAX_VOLUMES];
static uint32_t gMountedCount;
static bool gDiskScanned[FAT32_MAX_VOLUMES];
// Returns free Volume Index.
static int Fat32FindFreeVolumeIndex(void) {
for (uint8_t i = 0; i < FAT32_MAX_VOLUMES; i++) {
if (!gVolumeMounted[i] && !IoFilesystemPresent(i))
@@ -2416,6 +2422,7 @@ static int Fat32FindFreeVolumeIndex(void) {
return -1;
}
// Implements the try Mount Disk operation.
static uint32_t Fat32TryMountDisk(uint8_t disk) {
if (disk >= FAT32_MAX_VOLUMES)
return 0;
@@ -2513,6 +2520,7 @@ static uint32_t Fat32TryMountDisk(uint8_t disk) {
return mountedHere;
}
// Implements the disk Arrival operation.
static void Fat32DiskArrival(uint8_t driveIndex, DEVICE_OBJECT* device, void* context) {
(void)device;
(void)context;
@@ -2526,6 +2534,7 @@ static void Fat32DiskArrival(uint8_t driveIndex, DEVICE_OBJECT* device, void* co
}
}
// Implements the unmount Disk operation.
static void Fat32UnmountDisk(uint8_t diskIndex, IO_DEVICE_CHANGE change) {
uint32_t removed = 0;
@@ -2580,6 +2589,7 @@ static void Fat32DiskChange(uint8_t driveIndex,
}
}
// Implements the driver Entry operation.
KSTATUS DriverEntry(const HAL_API *hal) {
DbgPrint("FAT32: Init\n");
if (!hal) return STATUS_INVALID_PARAMETER;