clean up and standardize types across the codebase, unify atomic operations, improve UTF-8 handling throughout the system, remove obsolete input and named queue interfaces, redesign process preparation and creation, tighten IPC and service boundaries, improve error handling and reliability, minor documentation cleanup, fix doom surfaces, fix panic in ini parsing.
This commit is contained in:
1 parent
899225f551
commit
c0ad63c27f
226 files changed
+6562
-4147
No files matched your search
@@ -1,18 +1,19 @@
|
||||
// FAT name handling, path traversal, and directory mutation.
|
||||
|
||||
#include <stdbool.h>
|
||||
#include "fat_internal.h"
|
||||
|
||||
// 8.3 name matching / assembly.
|
||||
|
||||
static int MatchRaw83(const char dirName[8], const char dirExt[3],
|
||||
static bool MatchRaw83(const char dirName[8], const char dirExt[3],
|
||||
const char wantName[8], const char wantExt[3]) {
|
||||
return memcmp(dirName, wantName, 8) == 0 &&
|
||||
memcmp(dirExt, wantExt, 3) == 0;
|
||||
}
|
||||
|
||||
static char FatUpperChar(char c);
|
||||
static int FatIsLowerChar(char c);
|
||||
static int FatIsValidShortChar(char c);
|
||||
static bool FatIsLowerChar(char c);
|
||||
static bool FatIsValidShortChar(char c);
|
||||
|
||||
// Implements the make83 Name V operation.
|
||||
static void Make83NameV(SYS_STRING_VIEW src, char name8[8], char ext3[3]) {
|
||||
@@ -53,40 +54,40 @@ static char FatUpperChar(char c) {
|
||||
}
|
||||
|
||||
// Implements the fat Is Lower Char operation.
|
||||
static int FatIsLowerChar(char c) {
|
||||
static bool FatIsLowerChar(char c) {
|
||||
return c >= 'a' && c <= 'z';
|
||||
}
|
||||
|
||||
// Implements the fat Is Valid Short Char operation.
|
||||
static int FatIsValidShortChar(char c) {
|
||||
static bool FatIsValidShortChar(char c) {
|
||||
c = FatUpperChar(c);
|
||||
if (c >= 'A' && c <= 'Z') return 1;
|
||||
if (c >= '0' && c <= '9') return 1;
|
||||
if (c >= 'A' && c <= 'Z') return true;
|
||||
if (c >= '0' && c <= '9') return true;
|
||||
switch (c) {
|
||||
case '$': case '%': case '\'': case '-': case '_': case '@':
|
||||
case '~': case '`': case '!': case '(': case ')': case '{':
|
||||
case '}': case '^': case '#': case '&':
|
||||
return 1;
|
||||
return true;
|
||||
default:
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// True when the user spelling can refer to a normal FAT 8.3 entry. This is
|
||||
// intentionally structural and case-insensitive: "doom1.wad" must still open
|
||||
// an existing short entry named DOOM1.WAD. Leading-dot names are not 8.3.
|
||||
static int FatNameIsStructurallyShort83V(SYS_STRING_VIEW name) {
|
||||
if (!SysSvIsValid(name) || name.Length == 0) return 0;
|
||||
if (name.Data[0] == '.') return 0;
|
||||
static bool FatNameIsStructurallyShort83V(SYS_STRING_VIEW name) {
|
||||
if (!SysSvIsValid(name) || name.Length == 0) return false;
|
||||
if (name.Data[0] == '.') return false;
|
||||
|
||||
size_t dot = (size_t)-1;
|
||||
for (size_t i = 0; i < name.Length; i++) {
|
||||
char c = name.Data[i];
|
||||
if (c == '.') {
|
||||
if (dot != (size_t)-1) return 0;
|
||||
if (dot != (size_t)-1) return false;
|
||||
dot = i;
|
||||
} else if (!FatIsValidShortChar(c)) {
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -96,17 +97,17 @@ static int FatNameIsStructurallyShort83V(SYS_STRING_VIEW name) {
|
||||
}
|
||||
|
||||
// Implements the fat Component Has Lower V operation.
|
||||
static int FatComponentHasLowerV(SYS_STRING_VIEW name, size_t start, size_t end) {
|
||||
static bool 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;
|
||||
if (FatIsLowerChar(name.Data[i])) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Implements the fat Component Has Upper V operation.
|
||||
static int FatComponentHasUpperV(SYS_STRING_VIEW name, size_t start, size_t end) {
|
||||
static bool 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;
|
||||
return 0;
|
||||
if (name.Data[i] >= 'A' && name.Data[i] <= 'Z') return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
static void FatSplitShortNameV(SYS_STRING_VIEW name, size_t* baseEnd,
|
||||
@@ -128,19 +129,19 @@ static void FatSplitShortNameV(SYS_STRING_VIEW name, size_t* baseEnd,
|
||||
// Creation uses LFN only when the spelling cannot be represented by a short
|
||||
// entry, or when mixed-case 8.3 spelling would be lost. Plain lowercase
|
||||
// 8.3 names are represented with FAT's NT case bits, not VFAT LFN entries.
|
||||
static int FatNameNeedsLfnForCreateV(SYS_STRING_VIEW name) {
|
||||
if (!FatNameIsStructurallyShort83V(name)) return 1;
|
||||
static bool FatNameNeedsLfnForCreateV(SYS_STRING_VIEW name) {
|
||||
if (!FatNameIsStructurallyShort83V(name)) return true;
|
||||
|
||||
size_t baseEnd, extStart, extEnd;
|
||||
FatSplitShortNameV(name, &baseEnd, &extStart, &extEnd);
|
||||
|
||||
int baseLower = FatComponentHasLowerV(name, 0, baseEnd);
|
||||
int baseUpper = FatComponentHasUpperV(name, 0, baseEnd);
|
||||
int extLower = FatComponentHasLowerV(name, extStart, extEnd);
|
||||
int extUpper = FatComponentHasUpperV(name, extStart, extEnd);
|
||||
bool baseLower = FatComponentHasLowerV(name, 0, baseEnd);
|
||||
bool baseUpper = FatComponentHasUpperV(name, 0, baseEnd);
|
||||
bool extLower = FatComponentHasLowerV(name, extStart, extEnd);
|
||||
bool extUpper = FatComponentHasUpperV(name, extStart, extEnd);
|
||||
|
||||
if ((baseLower && baseUpper) || (extLower && extUpper)) return 1;
|
||||
return 0;
|
||||
if ((baseLower && baseUpper) || (extLower && extUpper)) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Implements the fat Short Name Case Flags V operation.
|
||||
@@ -211,15 +212,15 @@ static void MakeLegacyBrokenDot83(const char* src, char name8[8], char ext3[3])
|
||||
ext3[ei++] = FatUpperChar(*p);
|
||||
}
|
||||
|
||||
static int ShortNameExistsRaw(FAT_VOL* v, uint32_t dirCluster,
|
||||
static bool ShortNameExistsRaw(FAT_VOL* v, uint32_t dirCluster,
|
||||
const char name8[8], const char ext3[3]) {
|
||||
uint8_t* clusterBuf = (uint8_t*)MmAllocatePool(v->BytesPerCluster);
|
||||
if (!clusterBuf) return 1; // fail closed; caller should pick another alias
|
||||
if (!clusterBuf) return true; // fail closed; caller should pick another alias
|
||||
|
||||
uint32_t cursor; uint64_t lba; uint32_t sectors;
|
||||
if (!FatDirectoryFirstSegment(v, dirCluster, &cursor, &lba, §ors)) {
|
||||
MmFreePool(clusterBuf);
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
do {
|
||||
@@ -228,17 +229,17 @@ static int ShortNameExistsRaw(FAT_VOL* v, uint32_t dirCluster,
|
||||
uint32_t entries = (sectors * v->BytesPerSector) / sizeof(DIRENT);
|
||||
DIRENT* dir = (DIRENT*)clusterBuf;
|
||||
for (uint32_t i = 0; i < entries; i++) {
|
||||
if (dir[i].Name[0] == 0x00) { MmFreePool(clusterBuf); return 0; }
|
||||
if (dir[i].Name[0] == 0x00) { MmFreePool(clusterBuf); return false; }
|
||||
if ((uint8_t)dir[i].Name[0] == 0xE5 || dir[i].Attr == ATTR_LFN) continue;
|
||||
if (MatchRaw83(dir[i].Name, dir[i].Ext, name8, ext3)) {
|
||||
MmFreePool(clusterBuf);
|
||||
return 1;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} while (FatDirectoryNextSegment(v, dirCluster, &cursor, &lba, §ors));
|
||||
|
||||
MmFreePool(clusterBuf);
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Implements the fat Alias Append Char operation.
|
||||
@@ -310,7 +311,7 @@ static void MakeAliasAttempt(const char stem[9], const char extIn[3],
|
||||
memcpy(name8 + keep, suffix, suffixLen);
|
||||
}
|
||||
|
||||
static int MakeUniqueShortAliasV(FAT_VOL* v, uint32_t dirCluster,
|
||||
static bool MakeUniqueShortAliasV(FAT_VOL* v, uint32_t dirCluster,
|
||||
SYS_STRING_VIEW longName,
|
||||
char name8[8], char ext3[3]) {
|
||||
char stem[9], extCandidate[3];
|
||||
@@ -318,9 +319,9 @@ static int MakeUniqueShortAliasV(FAT_VOL* v, uint32_t dirCluster,
|
||||
|
||||
for (uint32_t attempt = 1; attempt < 1000000; attempt++) {
|
||||
MakeAliasAttempt(stem, extCandidate, attempt, name8, ext3);
|
||||
if (!ShortNameExistsRaw(v, dirCluster, name8, ext3)) return 1;
|
||||
if (!ShortNameExistsRaw(v, dirCluster, name8, ext3)) return true;
|
||||
}
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Creates legacy Broken Dot83 V.
|
||||
@@ -400,44 +401,44 @@ void FatLfnAppend(char* lfn, const LFN_ENTRY* e) {
|
||||
}
|
||||
|
||||
// Directory search and view-native path traversal.
|
||||
static int FatIsPathSep(char c) {
|
||||
static bool FatIsPathSep(char c) {
|
||||
return c == '\\' || c == '/';
|
||||
}
|
||||
|
||||
// Tests whether a non-empty FAT path view points at plausible kernel-owned storage.
|
||||
static int FatStringViewDataIsPlausible(SYS_STRING_VIEW view) {
|
||||
if (!SysSvIsValid(view)) return 0;
|
||||
if (view.Length == 0) return 1;
|
||||
static bool FatStringViewDataIsPlausible(SYS_STRING_VIEW view) {
|
||||
if (!SysSvIsValid(view)) return false;
|
||||
if (view.Length == 0) return true;
|
||||
uintptr_t data = (uintptr_t)view.Data;
|
||||
return data >= 0x10000u;
|
||||
}
|
||||
|
||||
// Implements the name View Is Valid operation.
|
||||
static int FatNameViewIsValid(SYS_STRING_VIEW name) {
|
||||
if (!FatStringViewDataIsPlausible(name)) return 0;
|
||||
if (name.Length == 0 || name.Length >= FAT_MAX_LFN) return 0;
|
||||
static bool FatNameViewIsValid(SYS_STRING_VIEW name) {
|
||||
if (!FatStringViewDataIsPlausible(name)) return false;
|
||||
if (name.Length == 0 || name.Length >= FAT_MAX_LFN) return false;
|
||||
for (size_t i = 0; i < name.Length; i++) {
|
||||
char c = name.Data[i];
|
||||
if (c == '\0' || FatIsPathSep(c)) return 0;
|
||||
if (c == '\0' || FatIsPathSep(c)) return false;
|
||||
}
|
||||
return 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Implements the lfn Match V operation.
|
||||
static int LfnMatchV(const char* lfn, SYS_STRING_VIEW want) {
|
||||
if (!lfn || !SysSvIsValid(want)) return 0;
|
||||
static bool LfnMatchV(const char* lfn, SYS_STRING_VIEW want) {
|
||||
if (!lfn || !SysSvIsValid(want)) return false;
|
||||
size_t i = 0;
|
||||
while (lfn[i] && i < want.Length) {
|
||||
char a = lfn[i], b = want.Data[i];
|
||||
if (a >= 'A' && a <= 'Z') a += 32;
|
||||
if (b >= 'A' && b <= 'Z') b += 32;
|
||||
if (a != b) return 0;
|
||||
if (a != b) return false;
|
||||
i++;
|
||||
}
|
||||
return lfn[i] == '\0' && i == want.Length;
|
||||
}
|
||||
|
||||
static int MatchName83V(const char* dirName, const char* dirExt,
|
||||
static bool MatchName83V(const char* dirName, const char* dirExt,
|
||||
SYS_STRING_VIEW want) {
|
||||
char buf[13];
|
||||
int n = 0;
|
||||
@@ -449,14 +450,14 @@ static int MatchName83V(const char* dirName, const char* dirExt,
|
||||
buf[n++] = (char)(dirExt[i] >= 'A' && dirExt[i] <= 'Z' ? dirExt[i]+32 : dirExt[i]);
|
||||
}
|
||||
|
||||
if ((size_t)n != want.Length) return 0;
|
||||
if ((size_t)n != want.Length) return false;
|
||||
for (int i = 0; i < n; i++) {
|
||||
char a = buf[i], b = want.Data[i];
|
||||
if (a >= 'A' && a <= 'Z') a += 32;
|
||||
if (b >= 'A' && b <= 'Z') b += 32;
|
||||
if (a != b) return 0;
|
||||
if (a != b) return false;
|
||||
}
|
||||
return 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Returns the path cache canonical byte used for hashes and comparisons.
|
||||
@@ -719,21 +720,21 @@ bool FatBuildReadRun(FAT_FILE* f, uint32_t logicalIndex,
|
||||
return true;
|
||||
}
|
||||
|
||||
static int SearchDirV(FAT_VOL* v, uint32_t dirCluster, SYS_STRING_VIEW name,
|
||||
static bool SearchDirV(FAT_VOL* v, uint32_t dirCluster, SYS_STRING_VIEW name,
|
||||
uint32_t* outCluster, uint32_t* outSize, uint8_t* outAttr,
|
||||
uint64_t* outDirentLba, uint32_t* outDirentOffset) {
|
||||
if (!FatNameViewIsValid(name)) return 0;
|
||||
if (!FatNameViewIsValid(name)) return false;
|
||||
|
||||
uint8_t* clusterBuf = (uint8_t*)MmAllocatePool(v->BytesPerCluster);
|
||||
if (!clusterBuf) return 0;
|
||||
if (!clusterBuf) return false;
|
||||
|
||||
char lfn[FAT_MAX_LFN]; int hasLfn = 0; memset(lfn, 0, sizeof(lfn));
|
||||
char lfn[FAT_MAX_LFN]; bool hasLfn = false; memset(lfn, 0, sizeof(lfn));
|
||||
char wantName83[8], wantExt83[3];
|
||||
int allowShortMatch = FatNameIsStructurallyShort83V(name);
|
||||
bool allowShortMatch = FatNameIsStructurallyShort83V(name);
|
||||
Make83NameV(name, wantName83, wantExt83);
|
||||
uint64_t clustersRead = 0;
|
||||
uint64_t entriesScanned = 0;
|
||||
int found = 0;
|
||||
bool found = false;
|
||||
|
||||
uint32_t cursor; uint64_t lba; uint32_t sectors;
|
||||
if (!FatDirectoryFirstSegment(v, dirCluster, &cursor, &lba, §ors))
|
||||
@@ -749,16 +750,16 @@ static int SearchDirV(FAT_VOL* v, uint32_t dirCluster, SYS_STRING_VIEW name,
|
||||
for (uint32_t i = 0; i < entries; i++) {
|
||||
entriesScanned++;
|
||||
if (dir[i].Name[0] == 0x00) goto done;
|
||||
if ((uint8_t)dir[i].Name[0] == 0xE5) { hasLfn = 0; memset(lfn, 0, sizeof(lfn)); continue; }
|
||||
if (dir[i].Attr == ATTR_LFN) { FatLfnAppend(lfn, (LFN_ENTRY*)&dir[i]); hasLfn = 1; continue; }
|
||||
if ((uint8_t)dir[i].Name[0] == 0xE5) { hasLfn = false; memset(lfn, 0, sizeof(lfn)); continue; }
|
||||
if (dir[i].Attr == ATTR_LFN) { FatLfnAppend(lfn, (LFN_ENTRY*)&dir[i]); hasLfn = true; continue; }
|
||||
|
||||
int match = 0;
|
||||
bool match = false;
|
||||
if (hasLfn && lfn[0]) match = LfnMatchV(lfn, name);
|
||||
if (!match && allowShortMatch)
|
||||
match = MatchName83V(dir[i].Name, dir[i].Ext, name);
|
||||
if (!match && allowShortMatch)
|
||||
match = MatchRaw83(dir[i].Name, dir[i].Ext, wantName83, wantExt83);
|
||||
hasLfn = 0; memset(lfn, 0, sizeof(lfn));
|
||||
hasLfn = false; memset(lfn, 0, sizeof(lfn));
|
||||
|
||||
if (match) {
|
||||
*outCluster = FatDirentFirstCluster(v, &dir[i]);
|
||||
@@ -769,7 +770,7 @@ static int SearchDirV(FAT_VOL* v, uint32_t dirCluster, SYS_STRING_VIEW name,
|
||||
if (outDirentLba) *outDirentLba = lba + eb / v->BytesPerSector;
|
||||
if (outDirentOffset) *outDirentOffset = (uint32_t)(eb % v->BytesPerSector);
|
||||
}
|
||||
found = 1;
|
||||
found = true;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
@@ -781,22 +782,22 @@ done:
|
||||
return found;
|
||||
}
|
||||
|
||||
static int FatPathNextComponent(SYS_STRING_VIEW path, size_t* cursor,
|
||||
static bool FatPathNextComponent(SYS_STRING_VIEW path, size_t* cursor,
|
||||
SYS_STRING_VIEW* component) {
|
||||
if (!cursor || !component || !SysSvIsValid(path)) return 0;
|
||||
if (!cursor || !component || !SysSvIsValid(path)) return false;
|
||||
size_t pos = *cursor;
|
||||
while (pos < path.Length && FatIsPathSep(path.Data[pos])) pos++;
|
||||
if (pos >= path.Length) {
|
||||
*cursor = pos;
|
||||
*component = SYS_SV_NULL;
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t start = pos;
|
||||
while (pos < path.Length && !FatIsPathSep(path.Data[pos])) pos++;
|
||||
*cursor = pos;
|
||||
*component = SysSvFromParts(path.Data + start, pos - start);
|
||||
return 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
KSTATUS FatLookupPathV(FAT_VOL* v, SYS_STRING_VIEW path,
|
||||
@@ -884,20 +885,20 @@ static KSTATUS SplitPathV(SYS_STRING_VIEW path, SYS_STRING_VIEW* parent,
|
||||
}
|
||||
|
||||
// Find a free DIRENT slot.
|
||||
static int FindFreeDirent(FAT_VOL* v, uint32_t dirCluster,
|
||||
static bool FindFreeDirent(FAT_VOL* v, uint32_t dirCluster,
|
||||
uint64_t* outLba, uint32_t* outOffset) {
|
||||
uint8_t* clusterBuf = (uint8_t*)MmAllocatePool(v->BytesPerCluster);
|
||||
if (!clusterBuf) return 0;
|
||||
if (!clusterBuf) return false;
|
||||
|
||||
uint32_t cursor; uint64_t lba; uint32_t sectors;
|
||||
if (!FatDirectoryFirstSegment(v, dirCluster, &cursor, &lba, §ors)) {
|
||||
MmFreePool(clusterBuf);
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
do {
|
||||
if (!KSUCCESS(FatReadSectors(v, lba, sectors, clusterBuf))) {
|
||||
MmFreePool(clusterBuf); return 0;
|
||||
MmFreePool(clusterBuf); return false;
|
||||
}
|
||||
uint32_t entries = (sectors * v->BytesPerSector) / sizeof(DIRENT);
|
||||
DIRENT* dir = (DIRENT*)clusterBuf;
|
||||
@@ -907,46 +908,46 @@ static int FindFreeDirent(FAT_VOL* v, uint32_t dirCluster,
|
||||
uint64_t eb = (uint64_t)i * sizeof(DIRENT);
|
||||
*outLba = lba + eb / v->BytesPerSector;
|
||||
*outOffset = (uint32_t)(eb % v->BytesPerSector);
|
||||
MmFreePool(clusterBuf); return 1;
|
||||
MmFreePool(clusterBuf); return true;
|
||||
}
|
||||
}
|
||||
} while (FatDirectoryNextSegment(v, dirCluster, &cursor, &lba, §ors));
|
||||
|
||||
if (FatIsFixedRoot(v, dirCluster)) {
|
||||
MmFreePool(clusterBuf);
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32_t newCluster = FatAppendCluster(v, cursor);
|
||||
if (newCluster) {
|
||||
*outLba = FatClusterToLba(v, newCluster); *outOffset = 0;
|
||||
MmFreePool(clusterBuf); return 1;
|
||||
MmFreePool(clusterBuf); return true;
|
||||
}
|
||||
MmFreePool(clusterBuf);
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Find a contiguous run of free directory entries.
|
||||
// VFAT LFN creation requires N long-name entries to immediately precede the
|
||||
// final short entry, so the run must live inside one readable/writeable segment.
|
||||
static int FindFreeDirentRun(FAT_VOL* v, uint32_t dirCluster, uint32_t needed,
|
||||
static bool FindFreeDirentRun(FAT_VOL* v, uint32_t dirCluster, uint32_t needed,
|
||||
uint64_t* outLba, uint32_t* outFirstIndex,
|
||||
uint32_t* outSectors) {
|
||||
if (!needed) return 0;
|
||||
if (!needed) return false;
|
||||
|
||||
uint8_t* clusterBuf = (uint8_t*)MmAllocatePool(v->BytesPerCluster);
|
||||
if (!clusterBuf) return 0;
|
||||
if (!clusterBuf) return false;
|
||||
|
||||
uint32_t cursor; uint64_t lba; uint32_t sectors;
|
||||
if (!FatDirectoryFirstSegment(v, dirCluster, &cursor, &lba, §ors)) {
|
||||
MmFreePool(clusterBuf);
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
do {
|
||||
if (!KSUCCESS(FatReadSectors(v, lba, sectors, clusterBuf))) {
|
||||
MmFreePool(clusterBuf);
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32_t entries = (sectors * v->BytesPerSector) / sizeof(DIRENT);
|
||||
@@ -963,7 +964,7 @@ static int FindFreeDirentRun(FAT_VOL* v, uint32_t dirCluster, uint32_t needed,
|
||||
*outFirstIndex = runStart;
|
||||
*outSectors = sectors;
|
||||
MmFreePool(clusterBuf);
|
||||
return 1;
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
runLen = 0;
|
||||
@@ -973,7 +974,7 @@ static int FindFreeDirentRun(FAT_VOL* v, uint32_t dirCluster, uint32_t needed,
|
||||
|
||||
if (FatIsFixedRoot(v, dirCluster)) {
|
||||
MmFreePool(clusterBuf);
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32_t newCluster = FatAppendCluster(v, cursor);
|
||||
@@ -982,11 +983,11 @@ static int FindFreeDirentRun(FAT_VOL* v, uint32_t dirCluster, uint32_t needed,
|
||||
*outFirstIndex = 0;
|
||||
*outSectors = v->SectorsPerCluster;
|
||||
MmFreePool(clusterBuf);
|
||||
return 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
MmFreePool(clusterBuf);
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Finds the parent directory and final component for a create or delete path.
|
||||
@@ -1039,7 +1040,7 @@ KSTATUS FatCreateDirent(FAT_VOL* v, SYS_STRING_VIEW path,
|
||||
}
|
||||
}
|
||||
|
||||
int useLfn = FatNameNeedsLfnForCreateV(filenameView);
|
||||
bool useLfn = FatNameNeedsLfnForCreateV(filenameView);
|
||||
char shortName[8], shortExt[3];
|
||||
if (useLfn) {
|
||||
s = DeleteLegacyBrokenDotAliasV(v, parentCluster, filenameView);
|
||||
@@ -1152,17 +1153,17 @@ KSTATUS FatInitializeDirectoryCluster(FAT_VOL* v, uint32_t dirCluster,
|
||||
}
|
||||
|
||||
// Tests whether a FAT directory entry is one of the synthetic dot entries.
|
||||
static int FatIsDotEntry(const DIRENT* d) {
|
||||
if (!d || !(d->Attr & ATTR_DIRECTORY)) return 0;
|
||||
if (d->Name[0] != '.') return 0;
|
||||
static bool FatIsDotEntry(const DIRENT* d) {
|
||||
if (!d || !(d->Attr & ATTR_DIRECTORY)) return false;
|
||||
if (d->Name[0] != '.') return false;
|
||||
if (d->Name[1] == ' ')
|
||||
return 1;
|
||||
return true;
|
||||
return d->Name[1] == '.' && d->Name[2] == ' ';
|
||||
}
|
||||
|
||||
// Tests whether a directory contains any real child entries.
|
||||
KSTATUS FatDirectoryIsEmpty(FAT_VOL* v, uint32_t dirCluster,
|
||||
int* emptyOut) {
|
||||
bool* emptyOut) {
|
||||
if (!v || !emptyOut)
|
||||
return NTLSTATUS_INVALID_PARAMETER;
|
||||
|
||||
@@ -1209,12 +1210,12 @@ KSTATUS FatDeleteDirentRunV(FAT_VOL* v, uint32_t parentCluster,
|
||||
if (!clusterBuf) return NTLSTATUS_NO_MEMORY;
|
||||
|
||||
char lfn[FAT_MAX_LFN];
|
||||
int hasLfn = 0;
|
||||
bool hasLfn = false;
|
||||
uint32_t lfnStart = 0;
|
||||
memset(lfn, 0, sizeof(lfn));
|
||||
|
||||
char wantName83[8], wantExt83[3];
|
||||
int allowShortMatch = FatNameIsStructurallyShort83V(name);
|
||||
bool allowShortMatch = FatNameIsStructurallyShort83V(name);
|
||||
Make83NameV(name, wantName83, wantExt83);
|
||||
|
||||
uint32_t cursor; uint64_t lba; uint32_t sectors;
|
||||
@@ -1229,20 +1230,20 @@ KSTATUS FatDeleteDirentRunV(FAT_VOL* v, uint32_t parentCluster,
|
||||
|
||||
uint32_t entries = (sectors * v->BytesPerSector) / sizeof(DIRENT);
|
||||
DIRENT* dir = (DIRENT*)clusterBuf;
|
||||
hasLfn = 0;
|
||||
hasLfn = false;
|
||||
memset(lfn, 0, sizeof(lfn));
|
||||
for (uint32_t i = 0; i < entries; i++) {
|
||||
uint8_t first = (uint8_t)dir[i].Name[0];
|
||||
if (first == 0x00) { MmFreePool(clusterBuf); return NTLSTATUS_NOT_FOUND; }
|
||||
if (first == 0xE5) { hasLfn = 0; memset(lfn, 0, sizeof(lfn)); continue; }
|
||||
if (first == 0xE5) { hasLfn = false; memset(lfn, 0, sizeof(lfn)); continue; }
|
||||
if (dir[i].Attr == ATTR_LFN) {
|
||||
if (!hasLfn) lfnStart = i;
|
||||
FatLfnAppend(lfn, (LFN_ENTRY*)&dir[i]);
|
||||
hasLfn = 1;
|
||||
hasLfn = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
int match = 0;
|
||||
bool match = false;
|
||||
if (hasLfn && lfn[0]) match = LfnMatchV(lfn, name);
|
||||
if (!match && allowShortMatch)
|
||||
match = MatchName83V(dir[i].Name, dir[i].Ext, name);
|
||||
@@ -1259,7 +1260,7 @@ KSTATUS FatDeleteDirentRunV(FAT_VOL* v, uint32_t parentCluster,
|
||||
return s;
|
||||
}
|
||||
|
||||
hasLfn = 0;
|
||||
hasLfn = false;
|
||||
memset(lfn, 0, sizeof(lfn));
|
||||
}
|
||||
} while (FatDirectoryNextSegment(v, parentCluster, &cursor, &lba, §ors));
|
||||
|
||||
Reference in new issue
Block a user