154 lines
6.1 KiB
C
154 lines
6.1 KiB
C
// FAT private implementation model shared by the driver's translation units.
|
|
|
|
#pragma once
|
|
|
|
#include <stdbool.h>
|
|
#include "fat.h"
|
|
#include "fat_disk.h"
|
|
|
|
#define FAT_PATH_CACHE_SLOTS 64u
|
|
#define FAT_PATH_CACHE_MAX 512u
|
|
#define FAT_CHAIN_CACHE_SLOTS 16u
|
|
#define FAT_WRITE_RUN_MAX_SECTORS 128u
|
|
#define FAT_READ_RUN_MAX_SECTORS 512u
|
|
#define FAT_MAX_LFN 256
|
|
|
|
#ifndef FAT_DEBUG
|
|
#define FAT_DEBUG 0
|
|
#endif
|
|
|
|
#define FatDebugPrint(...) do { if (FAT_DEBUG) DbgPrint(__VA_ARGS__); } while (0)
|
|
|
|
typedef struct FAT_PATH_CACHE_ENTRY {
|
|
bool Valid;
|
|
uint64_t Generation;
|
|
uint32_t Hash;
|
|
size_t PathLength;
|
|
char Path[FAT_PATH_CACHE_MAX];
|
|
uint32_t Cluster;
|
|
uint32_t Size;
|
|
uint8_t Attr;
|
|
uint64_t DirentLba;
|
|
uint32_t DirentOffset;
|
|
} FAT_PATH_CACHE_ENTRY;
|
|
|
|
typedef struct FAT_CHAIN_CACHE_ENTRY {
|
|
bool Valid;
|
|
uint32_t LogicalStart;
|
|
uint32_t PhysicalStart;
|
|
uint32_t Length;
|
|
uint32_t NextCluster;
|
|
} FAT_CHAIN_CACHE_ENTRY;
|
|
|
|
struct FAT_VOL_S {
|
|
FAT_VARIANT Variant;
|
|
uint8_t DriveIndex;
|
|
uint64_t PartitionLba;
|
|
uint64_t PartitionSize;
|
|
uint32_t BytesPerSector;
|
|
uint32_t SectorsPerCluster;
|
|
uint32_t BytesPerCluster;
|
|
uint32_t ReservedSectors;
|
|
uint32_t NumFats;
|
|
uint32_t FatSize;
|
|
uint32_t RootCluster;
|
|
uint32_t RootEntryCount;
|
|
uint32_t RootDirSectors;
|
|
uint64_t RootDirStart;
|
|
uint64_t DataStart;
|
|
uint32_t TotalClusters;
|
|
uint32_t NextFreeHint;
|
|
SPINLOCK PathCacheLock;
|
|
uint64_t PathCacheGeneration;
|
|
IO_FILESYSTEM_STATS Stats;
|
|
FAT_PATH_CACHE_ENTRY PathCache[FAT_PATH_CACHE_SLOTS];
|
|
IO_VOLUME* Volume;
|
|
LIST_ENTRY MountLink;
|
|
};
|
|
|
|
typedef struct FAT_FILE {
|
|
uint32_t StartCluster;
|
|
uint32_t FileSize;
|
|
FAT_VOL* Vol;
|
|
uint64_t DirentLba;
|
|
uint32_t DirentOffset;
|
|
SPINLOCK ChainCacheLock;
|
|
uint32_t ChainCacheClock;
|
|
FAT_CHAIN_CACHE_ENTRY ChainCache[FAT_CHAIN_CACHE_SLOTS];
|
|
} FAT_FILE;
|
|
|
|
typedef struct FAT_ENCODED_TIME {
|
|
uint16_t Date;
|
|
uint16_t Time;
|
|
uint8_t CreateTimeTenth;
|
|
} FAT_ENCODED_TIME;
|
|
|
|
typedef struct FAT_DIRENT_UPDATE {
|
|
uint32_t Flags;
|
|
uint32_t Size;
|
|
uint32_t FirstCluster;
|
|
FAT_ENCODED_TIME Timestamp;
|
|
} FAT_DIRENT_UPDATE;
|
|
|
|
#define FAT_DIRENT_UPDATE_SIZE 0x00000001u
|
|
#define FAT_DIRENT_UPDATE_FIRST_CLUSTER 0x00000002u
|
|
#define FAT_DIRENT_UPDATE_CREATE_TIME 0x00000004u
|
|
#define FAT_DIRENT_UPDATE_WRITE_TIME 0x00000008u
|
|
#define FAT_DIRENT_UPDATE_ACCESS_DATE 0x00000010u
|
|
|
|
KSTATUS FatReadSectors(FAT_VOL* volume, uint64_t lba, uint32_t count, void* buffer);
|
|
KSTATUS FatWriteSectors(FAT_VOL* volume, uint64_t lba, uint32_t count, const void* buffer);
|
|
const char* FatVariantName(FAT_VARIANT variant);
|
|
uint32_t FatEocMark(FAT_VOL* volume);
|
|
bool FatIsDataCluster(FAT_VOL* volume, uint32_t cluster);
|
|
uint32_t FatDirentFirstCluster(FAT_VOL* volume, const DIRENT* dirent);
|
|
void FatSetDirentFirstCluster(FAT_VOL* volume, DIRENT* dirent, uint32_t cluster);
|
|
bool FatIsFixedRoot(FAT_VOL* volume, uint32_t dirCluster);
|
|
bool FatDirectoryFirstSegment(FAT_VOL* volume, uint32_t dirCluster,
|
|
uint32_t* cursorOut, uint64_t* lbaOut, uint32_t* sectorsOut);
|
|
bool FatDirectoryNextSegment(FAT_VOL* volume, uint32_t dirCluster,
|
|
uint32_t* cursorInOut, uint64_t* lbaOut, uint32_t* sectorsOut);
|
|
uint64_t FatClusterToLba(FAT_VOL* volume, uint32_t cluster);
|
|
uint32_t FatEntry(FAT_VOL* volume, uint32_t cluster);
|
|
KSTATUS FatWriteEntry(FAT_VOL* volume, uint32_t cluster, uint32_t value);
|
|
void FatFlushCache(FAT_VOL* volume);
|
|
uint32_t FatAllocClusterEx(FAT_VOL* volume, bool zeroCluster);
|
|
uint32_t FatAllocCluster(FAT_VOL* volume);
|
|
uint32_t FatAppendClusterEx(FAT_VOL* volume, uint32_t lastCluster, bool zeroCluster);
|
|
uint32_t FatAppendCluster(FAT_VOL* volume, uint32_t lastCluster);
|
|
uint32_t FatGetChainEnd(FAT_VOL* volume, uint32_t start, uint32_t* countOut);
|
|
void FatFreeClusterChain(FAT_VOL* volume, uint32_t start);
|
|
void FatQueryEncodedTime(FAT_ENCODED_TIME* out);
|
|
void FatDecodeDateTime(uint16_t date, uint16_t time, uint8_t createTenth, SYS_SYSTEM_TIME* out);
|
|
void FatDecodeAccessDate(uint16_t date, SYS_SYSTEM_TIME* out);
|
|
KSTATUS FatDirentUpdateMetadata(FAT_VOL* volume, uint64_t lba, uint32_t offset,
|
|
const FAT_DIRENT_UPDATE* update);
|
|
KSTATUS FatDirentUpdateSize(FAT_VOL* volume, uint64_t lba, uint32_t offset, uint32_t size);
|
|
KSTATUS FatDirentUpdateFirstCluster(FAT_VOL* volume, uint64_t lba, uint32_t offset, uint32_t cluster);
|
|
void FatLfnAppend(char* lfn, const LFN_ENTRY* entry);
|
|
void FatPathCacheInvalidate(FAT_VOL* volume);
|
|
void FatStatsAddReadRun(FAT_VOL* volume, uint32_t sectors, uint32_t merges);
|
|
void FatFileInitChainCache(FAT_FILE* file);
|
|
void FatFileInvalidateChainCache(FAT_FILE* file);
|
|
uint32_t FatResolveFileCluster(FAT_FILE* file, uint32_t logicalIndex);
|
|
bool FatBuildReadRun(FAT_FILE* file, uint32_t logicalIndex,
|
|
uint32_t startCluster, uint32_t maxSectors,
|
|
uint32_t* runSectorsOut, uint32_t* nextClusterOut);
|
|
KSTATUS FatLookupPathV(FAT_VOL* volume, SYS_STRING_VIEW path,
|
|
uint32_t* clusterOut, uint32_t* sizeOut, uint8_t* attrOut,
|
|
uint64_t* direntLbaOut, uint32_t* direntOffsetOut);
|
|
KSTATUS FatTraverseV(FAT_VOL* volume, SYS_STRING_VIEW path,
|
|
uint32_t* clusterOut, uint32_t* sizeOut);
|
|
KSTATUS FatResolveParentForMutation(FAT_VOL* volume, SYS_STRING_VIEW path,
|
|
uint32_t* parentClusterOut, SYS_STRING_VIEW* nameOut);
|
|
KSTATUS FatCreateDirent(FAT_VOL* volume, SYS_STRING_VIEW path,
|
|
uint8_t attr, uint32_t firstCluster, uint32_t size,
|
|
uint64_t* direntLbaOut, uint32_t* direntOffsetOut);
|
|
KSTATUS FatInitializeDirectoryCluster(FAT_VOL* volume, uint32_t dirCluster,
|
|
uint32_t parentCluster);
|
|
KSTATUS FatDirectoryIsEmpty(FAT_VOL* volume, uint32_t dirCluster, bool* emptyOut);
|
|
KSTATUS FatDeleteDirentRunV(FAT_VOL* volume, uint32_t parentCluster,
|
|
SYS_STRING_VIEW name);
|
|
void FatCacheInvalidate(void);
|
|
void FatCacheInvalidateVolume(FAT_VOL* volume);
|