worked on FAT stuff and tests
This commit is contained in:
@@ -6,12 +6,12 @@
|
||||
|
||||
namespace FAT32 {
|
||||
|
||||
static inline uint16_t getU8(const uint8_t* src) {return src[0];}
|
||||
static inline uint16_t getU16(const uint8_t* src) {return src[0]<<0 | src[1]<<8;}
|
||||
static inline uint32_t getU32(const uint8_t* src) {return src[0]<<0 | src[1]<<8 | src[2]<<16 | src[3]<<24;}
|
||||
static inline size_t min(size_t a, size_t b) {return (a<b) ? a : b;}
|
||||
|
||||
static inline uint16_t getU8(const uint8_t* src) {return src[0];}
|
||||
static inline uint16_t getU16(const uint8_t* src) {return src[0]<<0 | src[1]<<8;}
|
||||
static inline uint32_t getU32(const uint8_t* src) {return src[0]<<0 | src[1]<<8 | src[2]<<16 | src[3]<<24;}
|
||||
static inline size_t min(size_t a, size_t b) {return (a<b) ? a : b;}
|
||||
|
||||
/** describes a uint32_t Cluster Number and typical helper functions */
|
||||
struct ClusterNr {
|
||||
|
||||
uint32_t val;
|
||||
@@ -35,10 +35,10 @@ static inline size_t min(size_t a, size_t b) {return (a<b) ? a : b;}
|
||||
|
||||
};
|
||||
|
||||
const ClusterNr END_OF_CLUSTERS = 0xFFFFFFF;
|
||||
const ClusterNr END_OF_CLUSTERS = 0x0FFFFFF8;
|
||||
|
||||
|
||||
/** header within the first 512 bytes */
|
||||
/** FAT32: header within the first 512 bytes of the Filesystem */
|
||||
struct FSHeader { // https://www.easeus.com/resource/fat32-disk-structure.htm
|
||||
uint8_t dummy1[11];
|
||||
uint16_t bytesPerSector; // @0x0B;
|
||||
@@ -49,28 +49,12 @@ static inline size_t min(size_t a, size_t b) {return (a<b) ? a : b;}
|
||||
uint8_t mediaDescriptor; // @0x15;
|
||||
uint8_t dummy3[10];
|
||||
uint32_t sectorsInPartition; // @0x20;
|
||||
uint32_t sectorsPerFAT; // @0x24;
|
||||
uint32_t sectorsPerFAT; // @0x24; // home many sectors does each of the 2 FATs contain?
|
||||
uint8_t dummy4[4];
|
||||
uint32_t rootDirFirstCluster; // @0x2C
|
||||
} __attribute__((packed));
|
||||
|
||||
struct FSDesc {
|
||||
uint16_t bytesPerSector;
|
||||
uint8_t sectorsPerCluster;
|
||||
uint16_t numReservedSectors;
|
||||
uint8_t numberOfFATs;
|
||||
uint32_t sectorsPerFAT;
|
||||
ClusterNr rootDirFirstCluster;
|
||||
};
|
||||
|
||||
struct Precomputed {
|
||||
uint32_t bytesPerCluster;
|
||||
AbsPos startOfFAT; // absolute byte offset where the FAT begins
|
||||
AbsPos startOfFirstDataCluster; // absolute byte offset where the first cluster is
|
||||
AbsPos startOfFirstRootDirCluster; // absolute byte offset where the first root dir cluster is
|
||||
uint32_t dirEntriesPerSector; // number of directory entries that fit into a sector
|
||||
};
|
||||
|
||||
/** FAT32: attributes of a DirEntry */
|
||||
union Attributes {
|
||||
uint8_t raw;
|
||||
struct {
|
||||
@@ -85,10 +69,15 @@ static inline size_t min(size_t a, size_t b) {return (a<b) ? a : b;}
|
||||
} bits;
|
||||
} __attribute__((packed));
|
||||
|
||||
/** structure for a DirectoryEntry as defined in the FAT standard */
|
||||
/** FAT32: structure for a DirectoryEntry as defined in the FAT standard */
|
||||
struct DirEntry {
|
||||
unsigned char name[8];
|
||||
unsigned char ext[3];
|
||||
union {
|
||||
unsigned char name83[8+3];
|
||||
struct {
|
||||
unsigned char name[8];
|
||||
unsigned char ext[3];
|
||||
} __attribute__((packed));
|
||||
} __attribute__((packed));
|
||||
Attributes attr;
|
||||
uint8_t dummy1[8];
|
||||
uint16_t firstClusterHi;
|
||||
@@ -97,67 +86,29 @@ static inline size_t min(size_t a, size_t b) {return (a<b) ? a : b;}
|
||||
uint32_t size; // file size in bytes
|
||||
} __attribute__((packed));
|
||||
|
||||
/** combine a DirectoryEntry with its absolute location on disk */
|
||||
struct DirEntryAt {
|
||||
|
||||
AbsPos posOnDisk;
|
||||
DirEntry entry;
|
||||
bool valid;
|
||||
|
||||
/** ctor for an invalid entry */
|
||||
DirEntryAt() : valid(false) {}
|
||||
|
||||
/** ctor for a valid entry */
|
||||
DirEntryAt(AbsPos posOnDisk, DirEntry* entry) : posOnDisk(posOnDisk), entry(*entry), valid(true) {}
|
||||
|
||||
static DirEntryAt invalid() {return DirEntryAt();}
|
||||
|
||||
/** is this a valid entry? */
|
||||
bool isValid() const {return valid;}
|
||||
|
||||
uint32_t getSize() const {return entry.size;}
|
||||
void setSize(uint32_t size) {entry.size = size;}
|
||||
|
||||
bool isUnused() const {return entry.name[0] == 0xE5;}
|
||||
bool isDirectory() const {return entry.attr.bits.directory;}
|
||||
bool isEndOfDirectory() const {return entry.name[0] == 0x00;}
|
||||
bool isLongFileName() const {return (entry.attr.raw & 0b1111) == 0b1111;}
|
||||
|
||||
void setEndOfDirectory() {entry.name[0] = 0x00;}
|
||||
|
||||
ClusterNr getFirstCluster() const {return entry.firstClusterHi<<16 | entry.firstClusterLo<<0;}
|
||||
void setFirstCluster(ClusterNr nr) {entry.firstClusterHi = (uint16_t)(nr << 16); entry.firstClusterLo = (uint16_t)(nr << 0);}
|
||||
|
||||
std::string getName() const {
|
||||
char buf[16];
|
||||
uint8_t pos = 0;
|
||||
for (uint8_t i = 0; i < 8; ++i) {if (entry.name[i] != ' ') {buf[pos++] = entry.name[i];}}
|
||||
buf[pos++] = '.';
|
||||
for (uint8_t i = 0; i < 3; ++i) {if ( entry.ext[i] != ' ') {buf[pos++] = entry.ext[i];}}
|
||||
buf[pos] = 0;
|
||||
return std::string(buf);
|
||||
}
|
||||
|
||||
void setName(const std::string& str) {
|
||||
|
||||
// "zero" fill name and extension
|
||||
memset(entry.name, ' ', 8);
|
||||
memset(entry.ext, ' ', 3);
|
||||
|
||||
auto pos = str.find('.');
|
||||
for (size_t i = 0; i < min(pos, str.length()); ++i) {
|
||||
if (i >= 8) {break;}
|
||||
entry.name[i] = str[i];
|
||||
}
|
||||
for (size_t i = 0; i < min(pos, str.length()); ++i) {
|
||||
if (i >= 3) {break;}
|
||||
entry.ext[i] = str[i+pos+1];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/** only the important parts of above header (to save space) */
|
||||
struct FSDesc {
|
||||
uint16_t bytesPerSector;
|
||||
uint8_t sectorsPerCluster;
|
||||
uint16_t numReservedSectors;
|
||||
uint8_t numberOfFATs;
|
||||
uint32_t sectorsPerFAT;
|
||||
ClusterNr rootDirFirstCluster;
|
||||
};
|
||||
|
||||
/** additional pre-computed values, to reduce calculations */
|
||||
struct Precomputed {
|
||||
uint32_t bytesPerCluster;
|
||||
AbsPos startOfFAT1; // absolute byte offset where the FAT1 begins
|
||||
AbsPos startOfFAT2; // absolute byte offset where the FAT2 begins
|
||||
AbsPos startOfFirstDataCluster; // absolute byte offset where the first cluster is
|
||||
AbsPos startOfFirstRootDirCluster; // absolute byte offset where the first root dir cluster is
|
||||
uint32_t entriesPerFAT; // number of entries (cluster pointers) within each FAT
|
||||
uint32_t dirEntriesPerSector; // number of directory entries that fit into a sector
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user