mirror of
https://github.com/wiiu-env/libfat.git
synced 2024-11-22 01:49:17 +01:00
support > 512 bytes per sector in libfat (dimok)
This commit is contained in:
parent
566206a741
commit
d5f437723f
@ -46,7 +46,7 @@
|
||||
|
||||
#define CACHE_FREE UINT_MAX
|
||||
|
||||
CACHE* _FAT_cache_constructor (unsigned int numberOfPages, unsigned int sectorsPerPage, const DISC_INTERFACE* discInterface, sec_t endOfPartition) {
|
||||
CACHE* _FAT_cache_constructor (unsigned int numberOfPages, unsigned int sectorsPerPage, const DISC_INTERFACE* discInterface, sec_t endOfPartition, unsigned int bytesPerSector) {
|
||||
CACHE* cache;
|
||||
unsigned int i;
|
||||
CACHE_ENTRY* cacheEntries;
|
||||
@ -68,6 +68,7 @@ CACHE* _FAT_cache_constructor (unsigned int numberOfPages, unsigned int sectorsP
|
||||
cache->endOfPartition = endOfPartition;
|
||||
cache->numberOfPages = numberOfPages;
|
||||
cache->sectorsPerPage = sectorsPerPage;
|
||||
cache->bytesPerSector = bytesPerSector;
|
||||
|
||||
|
||||
cacheEntries = (CACHE_ENTRY*) _FAT_mem_allocate ( sizeof(CACHE_ENTRY) * numberOfPages);
|
||||
@ -81,7 +82,7 @@ CACHE* _FAT_cache_constructor (unsigned int numberOfPages, unsigned int sectorsP
|
||||
cacheEntries[i].count = 0;
|
||||
cacheEntries[i].last_access = 0;
|
||||
cacheEntries[i].dirty = false;
|
||||
cacheEntries[i].cache = (uint8_t*) _FAT_mem_align ( sectorsPerPage * BYTES_PER_READ );
|
||||
cacheEntries[i].cache = (uint8_t*) _FAT_mem_align ( sectorsPerPage * bytesPerSector );
|
||||
}
|
||||
|
||||
cache->cacheEntries = cacheEntries;
|
||||
@ -127,7 +128,7 @@ static CACHE_ENTRY* _FAT_cache_getPage(CACHE *cache,sec_t sector)
|
||||
cacheEntries[i].last_access = accessTime();
|
||||
return &(cacheEntries[i]);
|
||||
}
|
||||
|
||||
|
||||
if(foundFree==false && (cacheEntries[i].sector==CACHE_FREE || cacheEntries[i].last_access<oldAccess)) {
|
||||
if(cacheEntries[i].sector==CACHE_FREE) foundFree = true;
|
||||
oldUsed = i;
|
||||
@ -168,9 +169,9 @@ bool _FAT_cache_readSectors(CACHE *cache,sec_t sector,sec_t numSectors,void *buf
|
||||
secs_to_read = entry->count - sec;
|
||||
if(secs_to_read>numSectors) secs_to_read = numSectors;
|
||||
|
||||
memcpy(dest,entry->cache + (sec*BYTES_PER_READ),(secs_to_read*BYTES_PER_READ));
|
||||
memcpy(dest,entry->cache + (sec*cache->bytesPerSector),(secs_to_read*cache->bytesPerSector));
|
||||
|
||||
dest += (secs_to_read*BYTES_PER_READ);
|
||||
dest += (secs_to_read*cache->bytesPerSector);
|
||||
sector += secs_to_read;
|
||||
numSectors -= secs_to_read;
|
||||
}
|
||||
@ -181,18 +182,18 @@ bool _FAT_cache_readSectors(CACHE *cache,sec_t sector,sec_t numSectors,void *buf
|
||||
/*
|
||||
Reads some data from a cache page, determined by the sector number
|
||||
*/
|
||||
bool _FAT_cache_readPartialSector (CACHE* cache, void* buffer, sec_t sector, unsigned int offset, size_t size)
|
||||
bool _FAT_cache_readPartialSector (CACHE* cache, void* buffer, sec_t sector, unsigned int offset, size_t size)
|
||||
{
|
||||
sec_t sec;
|
||||
CACHE_ENTRY *entry;
|
||||
|
||||
if (offset + size > BYTES_PER_READ) return false;
|
||||
if (offset + size > cache->bytesPerSector) return false;
|
||||
|
||||
entry = _FAT_cache_getPage(cache,sector);
|
||||
if(entry==NULL) return false;
|
||||
|
||||
sec = sector - entry->sector;
|
||||
memcpy(buffer,entry->cache + ((sec*BYTES_PER_READ) + offset),size);
|
||||
memcpy(buffer,entry->cache + ((sec*cache->bytesPerSector) + offset),size);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -213,18 +214,18 @@ bool _FAT_cache_readLittleEndianValue (CACHE* cache, uint32_t *value, sec_t sect
|
||||
/*
|
||||
Writes some data to a cache page, making sure it is loaded into memory first.
|
||||
*/
|
||||
bool _FAT_cache_writePartialSector (CACHE* cache, const void* buffer, sec_t sector, unsigned int offset, size_t size)
|
||||
bool _FAT_cache_writePartialSector (CACHE* cache, const void* buffer, sec_t sector, unsigned int offset, size_t size)
|
||||
{
|
||||
sec_t sec;
|
||||
CACHE_ENTRY *entry;
|
||||
|
||||
if (offset + size > BYTES_PER_READ) return false;
|
||||
if (offset + size > cache->bytesPerSector) return false;
|
||||
|
||||
entry = _FAT_cache_getPage(cache,sector);
|
||||
if(entry==NULL) return false;
|
||||
|
||||
sec = sector - entry->sector;
|
||||
memcpy(entry->cache + ((sec*BYTES_PER_READ) + offset),buffer,size);
|
||||
memcpy(entry->cache + ((sec*cache->bytesPerSector) + offset),buffer,size);
|
||||
|
||||
entry->dirty = true;
|
||||
return true;
|
||||
@ -246,26 +247,26 @@ bool _FAT_cache_writeLittleEndianValue (CACHE* cache, const uint32_t value, sec_
|
||||
/*
|
||||
Writes some data to a cache page, zeroing out the page first
|
||||
*/
|
||||
bool _FAT_cache_eraseWritePartialSector (CACHE* cache, const void* buffer, sec_t sector, unsigned int offset, size_t size)
|
||||
bool _FAT_cache_eraseWritePartialSector (CACHE* cache, const void* buffer, sec_t sector, unsigned int offset, size_t size)
|
||||
{
|
||||
sec_t sec;
|
||||
CACHE_ENTRY *entry;
|
||||
|
||||
if (offset + size > BYTES_PER_READ) return false;
|
||||
if (offset + size > cache->bytesPerSector) return false;
|
||||
|
||||
entry = _FAT_cache_getPage(cache,sector);
|
||||
if(entry==NULL) return false;
|
||||
|
||||
sec = sector - entry->sector;
|
||||
memset(entry->cache + (sec*BYTES_PER_READ),0,BYTES_PER_READ);
|
||||
memcpy(entry->cache + ((sec*BYTES_PER_READ) + offset),buffer,size);
|
||||
memset(entry->cache + (sec*cache->bytesPerSector),0,cache->bytesPerSector);
|
||||
memcpy(entry->cache + ((sec*cache->bytesPerSector) + offset),buffer,size);
|
||||
|
||||
entry->dirty = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool _FAT_cache_writeSectors (CACHE* cache, sec_t sector, sec_t numSectors, const void* buffer)
|
||||
bool _FAT_cache_writeSectors (CACHE* cache, sec_t sector, sec_t numSectors, const void* buffer)
|
||||
{
|
||||
sec_t sec;
|
||||
sec_t secs_to_write;
|
||||
@ -281,9 +282,9 @@ bool _FAT_cache_writeSectors (CACHE* cache, sec_t sector, sec_t numSectors, cons
|
||||
secs_to_write = entry->count - sec;
|
||||
if(secs_to_write>numSectors) secs_to_write = numSectors;
|
||||
|
||||
memcpy(entry->cache + (sec*BYTES_PER_READ),src,(secs_to_write*BYTES_PER_READ));
|
||||
memcpy(entry->cache + (sec*cache->bytesPerSector),src,(secs_to_write*cache->bytesPerSector));
|
||||
|
||||
src += (secs_to_write*BYTES_PER_READ);
|
||||
src += (secs_to_write*cache->bytesPerSector);
|
||||
sector += secs_to_write;
|
||||
numSectors -= secs_to_write;
|
||||
|
||||
|
@ -39,9 +39,6 @@
|
||||
#include "common.h"
|
||||
#include "disc.h"
|
||||
|
||||
#define PAGE_SECTORS 64
|
||||
#define CACHE_PAGE_SIZE (BYTES_PER_READ * PAGE_SECTORS)
|
||||
|
||||
typedef struct {
|
||||
sec_t sector;
|
||||
unsigned int count;
|
||||
@ -55,6 +52,7 @@ typedef struct {
|
||||
sec_t endOfPartition;
|
||||
unsigned int numberOfPages;
|
||||
unsigned int sectorsPerPage;
|
||||
unsigned int bytesPerSector;
|
||||
CACHE_ENTRY* cacheEntries;
|
||||
} CACHE;
|
||||
|
||||
@ -100,14 +98,14 @@ bool _FAT_cache_readSectors (CACHE* cache, sec_t sector, sec_t numSectors, void*
|
||||
Read a full sector from the cache
|
||||
*/
|
||||
static inline bool _FAT_cache_readSector (CACHE* cache, void* buffer, sec_t sector) {
|
||||
return _FAT_cache_readPartialSector (cache, buffer, sector, 0, BYTES_PER_READ);
|
||||
return _FAT_cache_readPartialSector (cache, buffer, sector, 0, cache->bytesPerSector);
|
||||
}
|
||||
|
||||
/*
|
||||
Write a full sector to the cache
|
||||
*/
|
||||
static inline bool _FAT_cache_writeSector (CACHE* cache, const void* buffer, sec_t sector) {
|
||||
return _FAT_cache_writePartialSector (cache, buffer, sector, 0, BYTES_PER_READ);
|
||||
return _FAT_cache_writePartialSector (cache, buffer, sector, 0, cache->bytesPerSector);
|
||||
}
|
||||
|
||||
bool _FAT_cache_writeSectors (CACHE* cache, sec_t sector, sec_t numSectors, const void* buffer);
|
||||
@ -122,7 +120,7 @@ Clear out the contents of the cache without writing any dirty sectors first
|
||||
*/
|
||||
void _FAT_cache_invalidate (CACHE* cache);
|
||||
|
||||
CACHE* _FAT_cache_constructor (unsigned int numberOfPages, unsigned int sectorsPerPage, const DISC_INTERFACE* discInterface, sec_t endOfPartition);
|
||||
CACHE* _FAT_cache_constructor (unsigned int numberOfPages, unsigned int sectorsPerPage, const DISC_INTERFACE* discInterface, sec_t endOfPartition, unsigned int bytesPerSector);
|
||||
|
||||
void _FAT_cache_destructor (CACHE* cache);
|
||||
|
||||
|
@ -3,7 +3,7 @@
|
||||
Common definitions and included files for the FATlib
|
||||
|
||||
Copyright (c) 2006 Michael "Chishm" Chisholm
|
||||
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
@ -29,7 +29,6 @@
|
||||
#ifndef _COMMON_H
|
||||
#define _COMMON_H
|
||||
|
||||
#define BYTES_PER_READ 512
|
||||
#include <fat.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
@ -4,7 +4,7 @@
|
||||
a FAT partition
|
||||
|
||||
Copyright (c) 2006 Michael "Chishm" Chisholm
|
||||
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
@ -53,7 +53,7 @@ typedef unsigned short ucs2_t;
|
||||
// Long file name directory entry
|
||||
enum LFN_offset {
|
||||
LFN_offset_ordinal = 0x00, // Position within LFN
|
||||
LFN_offset_char0 = 0x01,
|
||||
LFN_offset_char0 = 0x01,
|
||||
LFN_offset_char1 = 0x03,
|
||||
LFN_offset_char2 = 0x05,
|
||||
LFN_offset_char3 = 0x07,
|
||||
@ -71,7 +71,7 @@ enum LFN_offset {
|
||||
LFN_offset_char11 = 0x1C,
|
||||
LFN_offset_char12 = 0x1E
|
||||
};
|
||||
static const int LFN_offset_table[13]={0x01,0x03,0x05,0x07,0x09,0x0E,0x10,0x12,0x14,0x16,0x18,0x1C,0x1E};
|
||||
static const int LFN_offset_table[13]={0x01,0x03,0x05,0x07,0x09,0x0E,0x10,0x12,0x14,0x16,0x18,0x1C,0x1E};
|
||||
|
||||
#define LFN_END 0x40
|
||||
#define LFN_DEL 0x80
|
||||
@ -79,7 +79,7 @@ static const int LFN_offset_table[13]={0x01,0x03,0x05,0x07,0x09,0x0E,0x10,0x12,0
|
||||
static const char ILLEGAL_ALIAS_CHARACTERS[] = "\\/:;*?\"<>|&+,=[] ";
|
||||
static const char ILLEGAL_LFN_CHARACTERS[] = "\\/:*?\"<>|";
|
||||
|
||||
/*
|
||||
/*
|
||||
Returns number of UCS-2 characters needed to encode an LFN
|
||||
Returns -1 if it is an invalid LFN
|
||||
*/
|
||||
@ -89,7 +89,7 @@ static int _FAT_directory_lfnLength (const char* name) {
|
||||
size_t nameLength;
|
||||
int ucsLength;
|
||||
const char* tempName = name;
|
||||
|
||||
|
||||
nameLength = strnlen(name, MAX_FILENAME_LENGTH);
|
||||
// Make sure the name is short enough to be valid
|
||||
if ( nameLength >= MAX_FILENAME_LENGTH) {
|
||||
@ -110,7 +110,7 @@ static int _FAT_directory_lfnLength (const char* name) {
|
||||
if (ucsLength < 0 || ucsLength >= MAX_LFN_LENGTH) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
// Otherwise it is valid
|
||||
return ucsLength;
|
||||
}
|
||||
@ -153,7 +153,7 @@ static size_t _FAT_directory_ucs2tombs (char* dst, const ucs2_t* src, size_t len
|
||||
int bytes;
|
||||
char buff[MB_CUR_MAX];
|
||||
int i;
|
||||
|
||||
|
||||
while (count < len - 1 && *src != '\0') {
|
||||
bytes = wcrtomb (buff, *src, &ps);
|
||||
if (bytes < 0) {
|
||||
@ -170,7 +170,7 @@ static size_t _FAT_directory_ucs2tombs (char* dst, const ucs2_t* src, size_t len
|
||||
}
|
||||
}
|
||||
*dst = L'\0';
|
||||
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
@ -183,11 +183,11 @@ static int _FAT_directory_mbsncasecmp (const char* s1, const char* s2, size_t le
|
||||
mbstate_t ps2 = {0};
|
||||
size_t b1 = 0;
|
||||
size_t b2 = 0;
|
||||
|
||||
|
||||
if (len1 == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
do {
|
||||
s1 += b1;
|
||||
s2 += b2;
|
||||
@ -198,7 +198,7 @@ static int _FAT_directory_mbsncasecmp (const char* s1, const char* s2, size_t le
|
||||
}
|
||||
len1 -= b1;
|
||||
} while (len1 > 0 && towlower(wc1) == towlower(wc2) && wc1 != 0);
|
||||
|
||||
|
||||
return towlower(wc1) - towlower(wc2);
|
||||
}
|
||||
|
||||
@ -217,7 +217,7 @@ static bool _FAT_directory_entryGetAlias (const u8* entryData, char* destName) {
|
||||
} else {
|
||||
destName[1] = '\0';
|
||||
}
|
||||
} else {
|
||||
} else {
|
||||
// Copy the filename from the dirEntry to the string
|
||||
for (i = 0; (i < 8) && (entryData[DIR_ENTRY_name + i] != ' '); i++) {
|
||||
destName[i] = entryData[DIR_ENTRY_name + i];
|
||||
@ -251,7 +251,7 @@ static bool _FAT_directory_incrementDirEntryPosition (PARTITION* partition, DIR_
|
||||
|
||||
// Increment offset, wrapping at the end of a sector
|
||||
++ position.offset;
|
||||
if (position.offset == BYTES_PER_READ / DIR_ENTRY_DATA_SIZE) {
|
||||
if (position.offset == partition->bytesPerSector / DIR_ENTRY_DATA_SIZE) {
|
||||
position.offset = 0;
|
||||
// Increment sector when wrapping
|
||||
++ position.sector;
|
||||
@ -269,7 +269,7 @@ static bool _FAT_directory_incrementDirEntryPosition (PARTITION* partition, DIR_
|
||||
} else {
|
||||
return false; // Got to the end of the directory, not extending it
|
||||
}
|
||||
}
|
||||
}
|
||||
position.cluster = tempCluster;
|
||||
} else if ((position.cluster == FAT16_ROOT_DIR_CLUSTER) && (position.sector == (partition->dataStart - partition->rootDirStart))) {
|
||||
return false; // Got to end of root directory, can't extend it
|
||||
@ -329,7 +329,7 @@ bool _FAT_directory_getNextEntry (PARTITION* partition, DIR_ENTRY* entry) {
|
||||
}
|
||||
lfn[lfnPos] = '\0'; // Set end of lfn to null character
|
||||
lfnChkSum = entryData[LFN_offset_checkSum];
|
||||
}
|
||||
}
|
||||
if (lfnChkSum != entryData[LFN_offset_checkSum]) {
|
||||
lfnExists = false;
|
||||
}
|
||||
@ -353,14 +353,14 @@ bool _FAT_directory_getNextEntry (PARTITION* partition, DIR_ENTRY* entry) {
|
||||
chkSum = 0;
|
||||
for (i=0; i < 11; i++) {
|
||||
// NOTE: The operation is an unsigned char rotate right
|
||||
chkSum = ((chkSum & 1) ? 0x80 : 0) + (chkSum >> 1) + entryData[i];
|
||||
chkSum = ((chkSum & 1) ? 0x80 : 0) + (chkSum >> 1) + entryData[i];
|
||||
}
|
||||
if (chkSum != lfnChkSum) {
|
||||
lfnExists = false;
|
||||
entry->filename[0] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (lfnExists) {
|
||||
if (_FAT_directory_ucs2tombs (entry->filename, lfn, MAX_FILENAME_LENGTH) == (size_t)-1) {
|
||||
// Failed to convert the file name to UTF-8. Maybe the wrong locale is set?
|
||||
@ -400,21 +400,21 @@ bool _FAT_directory_getRootEntry (PARTITION* partition, DIR_ENTRY* entry) {
|
||||
entry->dataStart.cluster = 0;
|
||||
entry->dataStart.sector = 0;
|
||||
entry->dataStart.offset = 0;
|
||||
|
||||
entry->dataEnd = entry->dataStart;
|
||||
|
||||
|
||||
entry->dataEnd = entry->dataStart;
|
||||
|
||||
memset (entry->filename, '\0', MAX_FILENAME_LENGTH);
|
||||
entry->filename[0] = '.';
|
||||
|
||||
|
||||
memset (entry->entryData, 0, DIR_ENTRY_DATA_SIZE);
|
||||
memset (entry->entryData, ' ', 11);
|
||||
entry->entryData[0] = '.';
|
||||
|
||||
|
||||
entry->entryData[DIR_ENTRY_attributes] = ATTRIB_DIR;
|
||||
|
||||
|
||||
u16_to_u8array (entry->entryData, DIR_ENTRY_cluster, partition->rootDirCluster);
|
||||
u16_to_u8array (entry->entryData, DIR_ENTRY_clusterHigh, partition->rootDirCluster >> 16);
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -438,7 +438,7 @@ bool _FAT_directory_getVolumeLabel (PARTITION* partition, char *label) {
|
||||
label[11]='\0';
|
||||
end = false;
|
||||
//this entry should be among the first 3 entries in the root directory table, if not, then system can have trouble displaying the right volume label
|
||||
while(!end) {
|
||||
while(!end) {
|
||||
if(!_FAT_cache_readPartialSector (partition->cache, entryData,
|
||||
_FAT_fat_clusterToSector(partition, entryEnd.cluster) + entryEnd.sector,
|
||||
entryEnd.offset * DIR_ENTRY_DATA_SIZE, DIR_ENTRY_DATA_SIZE))
|
||||
@ -446,15 +446,15 @@ bool _FAT_directory_getVolumeLabel (PARTITION* partition, char *label) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (entryData[DIR_ENTRY_attributes] == ATTRIB_VOL && entryData[0] != DIR_ENTRY_FREE) {
|
||||
if (entryData[DIR_ENTRY_attributes] == ATTRIB_VOL && entryData[0] != DIR_ENTRY_FREE) {
|
||||
for (i = 0; i < 11; i++) {
|
||||
label[i] = entryData[DIR_ENTRY_name + i];
|
||||
label[i] = entryData[DIR_ENTRY_name + i];
|
||||
}
|
||||
return true;
|
||||
} else if (entryData[0] == DIR_ENTRY_LAST) {
|
||||
end = true;
|
||||
}
|
||||
|
||||
|
||||
if (_FAT_directory_incrementDirEntryPosition (partition, &entryEnd, false) == false) {
|
||||
end = true;
|
||||
}
|
||||
@ -471,18 +471,18 @@ bool _FAT_directory_entryFromPosition (PARTITION* partition, DIR_ENTRY* entry) {
|
||||
int i;
|
||||
int lfnPos;
|
||||
uint8_t entryData[DIR_ENTRY_DATA_SIZE];
|
||||
|
||||
|
||||
memset (entry->filename, '\0', MAX_FILENAME_LENGTH);
|
||||
|
||||
// Create an empty directory entry to overwrite the old ones with
|
||||
for ( entryStillValid = true, finished = false;
|
||||
entryStillValid && !finished;
|
||||
for ( entryStillValid = true, finished = false;
|
||||
entryStillValid && !finished;
|
||||
entryStillValid = _FAT_directory_incrementDirEntryPosition (partition, &entryStart, false))
|
||||
{
|
||||
_FAT_cache_readPartialSector (partition->cache, entryData,
|
||||
_FAT_cache_readPartialSector (partition->cache, entryData,
|
||||
_FAT_fat_clusterToSector(partition, entryStart.cluster) + entryStart.sector,
|
||||
entryStart.offset * DIR_ENTRY_DATA_SIZE, DIR_ENTRY_DATA_SIZE);
|
||||
|
||||
|
||||
if ((entryStart.cluster == entryEnd.cluster)
|
||||
&& (entryStart.sector == entryEnd.sector)
|
||||
&& (entryStart.offset == entryEnd.offset)) {
|
||||
@ -504,7 +504,7 @@ bool _FAT_directory_entryFromPosition (PARTITION* partition, DIR_ENTRY* entry) {
|
||||
if (!entryStillValid) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
if ((entryStart.cluster == entryEnd.cluster)
|
||||
&& (entryStart.sector == entryEnd.sector)
|
||||
&& (entryStart.offset == entryEnd.offset)) {
|
||||
@ -518,7 +518,7 @@ bool _FAT_directory_entryFromPosition (PARTITION* partition, DIR_ENTRY* entry) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -534,7 +534,7 @@ bool _FAT_directory_entryFromPath (PARTITION* partition, DIR_ENTRY* entry, const
|
||||
bool found, notFound;
|
||||
|
||||
pathPosition = path;
|
||||
|
||||
|
||||
found = false;
|
||||
notFound = false;
|
||||
|
||||
@ -560,13 +560,13 @@ bool _FAT_directory_entryFromPath (PARTITION* partition, DIR_ENTRY* entry, const
|
||||
dirCluster = partition->cwdCluster;
|
||||
}
|
||||
|
||||
// If the path is only specifying a directory in the form "."
|
||||
// If the path is only specifying a directory in the form "."
|
||||
// and this is the root directory, return it
|
||||
if ((dirCluster == partition->rootDirCluster) && (strcmp(".", pathPosition) == 0)) {
|
||||
_FAT_directory_getRootEntry (partition, entry);
|
||||
found = true;
|
||||
}
|
||||
|
||||
|
||||
while (!found && !notFound) {
|
||||
// Get the name of the next required subdirectory within the path
|
||||
nextPathPosition = strchr (pathPosition, DIR_SEPARATOR);
|
||||
@ -633,7 +633,7 @@ bool _FAT_directory_entryFromPath (PARTITION* partition, DIR_ENTRY* entry, const
|
||||
|
||||
if (found && !notFound) {
|
||||
if (partition->filesysType == FS_FAT32 && (entry->entryData[DIR_ENTRY_attributes] & ATTRIB_DIR) &&
|
||||
_FAT_directory_entryGetCluster (partition, entry->entryData) == CLUSTER_ROOT)
|
||||
_FAT_directory_entryGetCluster (partition, entry->entryData) == CLUSTER_ROOT)
|
||||
{
|
||||
// On FAT32 it should specify an actual cluster for the root entry,
|
||||
// not cluster 0 as on FAT16
|
||||
@ -653,8 +653,8 @@ bool _FAT_directory_removeEntry (PARTITION* partition, DIR_ENTRY* entry) {
|
||||
uint8_t entryData[DIR_ENTRY_DATA_SIZE];
|
||||
|
||||
// Create an empty directory entry to overwrite the old ones with
|
||||
for ( entryStillValid = true, finished = false;
|
||||
entryStillValid && !finished;
|
||||
for ( entryStillValid = true, finished = false;
|
||||
entryStillValid && !finished;
|
||||
entryStillValid = _FAT_directory_incrementDirEntryPosition (partition, &entryStart, false))
|
||||
{
|
||||
_FAT_cache_readPartialSector (partition->cache, entryData, _FAT_fat_clusterToSector(partition, entryStart.cluster) + entryStart.sector, entryStart.offset * DIR_ENTRY_DATA_SIZE, DIR_ENTRY_DATA_SIZE);
|
||||
@ -689,10 +689,10 @@ static bool _FAT_directory_findEntryGap (PARTITION* partition, DIR_ENTRY* entry,
|
||||
entryStillValid = true;
|
||||
dirEntryRemain = size;
|
||||
endOfDirectory = false;
|
||||
|
||||
|
||||
while (entryStillValid && !endOfDirectory && (dirEntryRemain > 0)) {
|
||||
_FAT_cache_readPartialSector (partition->cache, entryData,
|
||||
_FAT_fat_clusterToSector(partition, gapEnd.cluster) + gapEnd.sector,
|
||||
_FAT_cache_readPartialSector (partition->cache, entryData,
|
||||
_FAT_fat_clusterToSector(partition, gapEnd.cluster) + gapEnd.sector,
|
||||
gapEnd.offset * DIR_ENTRY_DATA_SIZE, DIR_ENTRY_DATA_SIZE);
|
||||
if (entryData[0] == DIR_ENTRY_LAST) {
|
||||
gapStart = gapEnd;
|
||||
@ -706,7 +706,7 @@ static bool _FAT_directory_findEntryGap (PARTITION* partition, DIR_ENTRY* entry,
|
||||
} else {
|
||||
dirEntryRemain = size;
|
||||
}
|
||||
|
||||
|
||||
if (!endOfDirectory && (dirEntryRemain > 0)) {
|
||||
entryStillValid = _FAT_directory_incrementDirEntryPosition (partition, &gapEnd, true);
|
||||
}
|
||||
@ -731,7 +731,7 @@ static bool _FAT_directory_findEntryGap (PARTITION* partition, DIR_ENTRY* entry,
|
||||
-- dirEntryRemain;
|
||||
// Fill the entry with blanks
|
||||
_FAT_cache_writePartialSector (partition->cache, entryData,
|
||||
_FAT_fat_clusterToSector(partition, gapEnd.cluster) + gapEnd.sector,
|
||||
_FAT_fat_clusterToSector(partition, gapEnd.cluster) + gapEnd.sector,
|
||||
gapEnd.offset * DIR_ENTRY_DATA_SIZE, DIR_ENTRY_DATA_SIZE);
|
||||
}
|
||||
if (!entryStillValid) {
|
||||
@ -755,7 +755,7 @@ static bool _FAT_directory_entryExists (PARTITION* partition, const char* name,
|
||||
if (dirnameLength >= MAX_FILENAME_LENGTH) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// Make sure the entry doesn't already exist
|
||||
foundFile = _FAT_directory_getFirstEntry (partition, &tempEntry, dirCluster);
|
||||
|
||||
@ -776,9 +776,9 @@ static bool _FAT_directory_entryExists (PARTITION* partition, const char* name,
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
Creates an alias for a long file name. If the alias is not an exact match for the
|
||||
filename, it returns the number of characters in the alias. If the two names match,
|
||||
/*
|
||||
Creates an alias for a long file name. If the alias is not an exact match for the
|
||||
filename, it returns the number of characters in the alias. If the two names match,
|
||||
it returns 0. If there was an error, it returns -1.
|
||||
*/
|
||||
static int _FAT_directory_createAlias (char* alias, const char* lfn) {
|
||||
@ -791,13 +791,13 @@ static int _FAT_directory_createAlias (char* alias, const char* lfn) {
|
||||
int bytesUsed = 0;
|
||||
const char* lfnExt;
|
||||
int aliasExtLen;
|
||||
|
||||
|
||||
// Strip leading periods
|
||||
while (lfn[lfnPos] == '.') {
|
||||
lfnPos ++;
|
||||
lossyConversion = true;
|
||||
}
|
||||
|
||||
|
||||
// Primary portion of alias
|
||||
while (aliasPos < 8 && lfn[lfnPos] != '.' && lfn[lfnPos] != '\0') {
|
||||
bytesUsed = mbrtowc(&lfnChar, lfn + lfnPos, MAX_FILENAME_LENGTH - lfnPos, &ps);
|
||||
@ -824,17 +824,17 @@ static int _FAT_directory_createAlias (char* alias, const char* lfn) {
|
||||
oemChar = '_'; // Replace illegal characters with underscores
|
||||
lossyConversion = true;
|
||||
}
|
||||
|
||||
|
||||
alias[aliasPos] = (char)oemChar;
|
||||
aliasPos++;
|
||||
lfnPos += bytesUsed;
|
||||
}
|
||||
|
||||
|
||||
if (lfn[lfnPos] != '.' && lfn[lfnPos] != '\0') {
|
||||
// Name was more than 8 characters long
|
||||
lossyConversion = true;
|
||||
}
|
||||
|
||||
|
||||
// Alias extension
|
||||
lfnExt = strrchr (lfn, '.');
|
||||
if (lfnExt != NULL && lfnExt != strchr (lfn, '.')) {
|
||||
@ -871,7 +871,7 @@ static int _FAT_directory_createAlias (char* alias, const char* lfn) {
|
||||
oemChar = '_'; // Replace illegal characters with underscores
|
||||
lossyConversion = true;
|
||||
}
|
||||
|
||||
|
||||
alias[aliasPos] = (char)oemChar;
|
||||
aliasPos++;
|
||||
lfnExt += bytesUsed;
|
||||
@ -881,7 +881,7 @@ static int _FAT_directory_createAlias (char* alias, const char* lfn) {
|
||||
lossyConversion = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
alias[aliasPos] = '\0';
|
||||
if (lossyConversion) {
|
||||
return aliasPos;
|
||||
@ -955,14 +955,14 @@ bool _FAT_directory_addEntry (PARTITION* partition, DIR_ENTRY* entry, uint32_t d
|
||||
} else {
|
||||
// It's a long filename with an alias
|
||||
entrySize = ((lfnLen + LFN_ENTRY_LENGTH - 1) / LFN_ENTRY_LENGTH) + 1;
|
||||
|
||||
|
||||
// Generate full alias for all cases except when the alias is simply an upper case version of the LFN
|
||||
// and there isn't already a file with that name
|
||||
if (strncasecmp (alias, entry->filename, MAX_ALIAS_LENGTH) != 0 ||
|
||||
_FAT_directory_entryExists (partition, alias, dirCluster))
|
||||
_FAT_directory_entryExists (partition, alias, dirCluster))
|
||||
{
|
||||
// expand primary part to 8 characters long by padding the end with underscores
|
||||
i = MAX_ALIAS_PRI_LENGTH - 1;
|
||||
i = MAX_ALIAS_PRI_LENGTH - 1;
|
||||
// Move extension to last 3 characters
|
||||
while (alias[i] != '.' && i > 0) i--;
|
||||
if (i > 0) {
|
||||
@ -972,7 +972,7 @@ bool _FAT_directory_addEntry (PARTITION* partition, DIR_ENTRY* entry, uint32_t d
|
||||
memset (alias + i, '_', j - i);
|
||||
alias[MAX_ALIAS_LENGTH-1]=0;
|
||||
}
|
||||
|
||||
|
||||
// Generate numeric tail
|
||||
for (i = 1; i <= MAX_NUMERIC_TAIL; i++) {
|
||||
j = i;
|
||||
@ -1015,7 +1015,7 @@ bool _FAT_directory_addEntry (PARTITION* partition, DIR_ENTRY* entry, uint32_t d
|
||||
entry->entryData[j] = ' ';
|
||||
++ j;
|
||||
}
|
||||
|
||||
|
||||
// Generate alias checksum
|
||||
for (i=0; i < ALIAS_ENTRY_LENGTH; i++) {
|
||||
// NOTE: The operation is an unsigned char rotate right
|
||||
@ -1036,7 +1036,7 @@ bool _FAT_directory_addEntry (PARTITION* partition, DIR_ENTRY* entry, uint32_t d
|
||||
ucs2_t lfn[MAX_LFN_LENGTH] = {0};
|
||||
_FAT_directory_mbstoucs2 (lfn, entry->filename, MAX_LFN_LENGTH);
|
||||
|
||||
for (entryStillValid = true, i = entrySize; entryStillValid && i > 0;
|
||||
for (entryStillValid = true, i = entrySize; entryStillValid && i > 0;
|
||||
entryStillValid = _FAT_directory_incrementDirEntryPosition (partition, &curEntryPos, false), -- i )
|
||||
{
|
||||
if (i > 1) {
|
||||
@ -1066,7 +1066,7 @@ bool _FAT_directory_addEntry (PARTITION* partition, DIR_ENTRY* entry, uint32_t d
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool _FAT_directory_chdir (PARTITION* partition, const char* path) {
|
||||
@ -1097,7 +1097,7 @@ void _FAT_directory_entryStat (PARTITION* partition, DIR_ENTRY* entry, struct st
|
||||
st->st_uid = 1; // Faked for FAT
|
||||
st->st_gid = 2; // Faked for FAT
|
||||
st->st_rdev = st->st_dev;
|
||||
st->st_size = u8array_to_u32 (entry->entryData, DIR_ENTRY_fileSize); // File size
|
||||
st->st_size = u8array_to_u32 (entry->entryData, DIR_ENTRY_fileSize); // File size
|
||||
st->st_atime = _FAT_filetime_to_time_t (
|
||||
0,
|
||||
u8array_to_u16 (entry->entryData, DIR_ENTRY_aDate)
|
||||
@ -1113,8 +1113,8 @@ void _FAT_directory_entryStat (PARTITION* partition, DIR_ENTRY* entry, struct st
|
||||
u8array_to_u16 (entry->entryData, DIR_ENTRY_cDate)
|
||||
);
|
||||
st->st_spare3 = 0;
|
||||
st->st_blksize = BYTES_PER_READ; // Prefered file I/O block size
|
||||
st->st_blocks = (st->st_size + BYTES_PER_READ - 1) / BYTES_PER_READ; // File size in blocks
|
||||
st->st_blksize = partition->bytesPerSector; // Prefered file I/O block size
|
||||
st->st_blocks = (st->st_size + partition->bytesPerSector - 1) / partition->bytesPerSector; // File size in blocks
|
||||
st->st_spare4[0] = 0;
|
||||
st->st_spare4[1] = 0;
|
||||
}
|
||||
|
@ -216,8 +216,8 @@ int _FAT_open_r (struct _reent *r, void *fileStruct, const char *path, int flags
|
||||
|
||||
// Set append pointer to the end of the file
|
||||
file->appendPosition.cluster = _FAT_fat_lastCluster (partition, file->startCluster);
|
||||
file->appendPosition.sector = (file->filesize % partition->bytesPerCluster) / BYTES_PER_READ;
|
||||
file->appendPosition.byte = file->filesize % BYTES_PER_READ;
|
||||
file->appendPosition.sector = (file->filesize % partition->bytesPerCluster) / partition->bytesPerSector;
|
||||
file->appendPosition.byte = file->filesize % partition->bytesPerSector;
|
||||
|
||||
// Check if the end of the file is on the end of a cluster
|
||||
if ( (file->filesize > 0) && ((file->filesize % partition->bytesPerCluster)==0) ){
|
||||
@ -381,12 +381,12 @@ ssize_t _FAT_read_r (struct _reent *r, int fd, char *ptr, size_t len) {
|
||||
cache = file->partition->cache;
|
||||
|
||||
// Align to sector
|
||||
tempVar = BYTES_PER_READ - position.byte;
|
||||
tempVar = partition->bytesPerSector - position.byte;
|
||||
if (tempVar > remain) {
|
||||
tempVar = remain;
|
||||
}
|
||||
|
||||
if ((tempVar < BYTES_PER_READ) && flagNoError)
|
||||
if ((tempVar < partition->bytesPerSector) && flagNoError)
|
||||
{
|
||||
_FAT_cache_readPartialSector ( cache, ptr, _FAT_fat_clusterToSector (partition, position.cluster) + position.sector,
|
||||
position.byte, tempVar);
|
||||
@ -395,7 +395,7 @@ ssize_t _FAT_read_r (struct _reent *r, int fd, char *ptr, size_t len) {
|
||||
ptr += tempVar;
|
||||
|
||||
position.byte += tempVar;
|
||||
if (position.byte >= BYTES_PER_READ) {
|
||||
if (position.byte >= partition->bytesPerSector) {
|
||||
position.byte = 0;
|
||||
position.sector++;
|
||||
}
|
||||
@ -403,10 +403,10 @@ ssize_t _FAT_read_r (struct _reent *r, int fd, char *ptr, size_t len) {
|
||||
|
||||
// align to cluster
|
||||
// tempVar is number of sectors to read
|
||||
if (remain > (partition->sectorsPerCluster - position.sector) * BYTES_PER_READ) {
|
||||
if (remain > (partition->sectorsPerCluster - position.sector) * partition->bytesPerSector) {
|
||||
tempVar = partition->sectorsPerCluster - position.sector;
|
||||
} else {
|
||||
tempVar = remain / BYTES_PER_READ;
|
||||
tempVar = remain / partition->bytesPerSector;
|
||||
}
|
||||
|
||||
if ((tempVar > 0) && flagNoError) {
|
||||
@ -416,8 +416,8 @@ ssize_t _FAT_read_r (struct _reent *r, int fd, char *ptr, size_t len) {
|
||||
flagNoError = false;
|
||||
r->_errno = EIO;
|
||||
} else {
|
||||
ptr += tempVar * BYTES_PER_READ;
|
||||
remain -= tempVar * BYTES_PER_READ;
|
||||
ptr += tempVar * partition->bytesPerSector;
|
||||
remain -= tempVar * partition->bytesPerSector;
|
||||
position.sector += tempVar;
|
||||
}
|
||||
}
|
||||
@ -449,12 +449,12 @@ ssize_t _FAT_read_r (struct _reent *r, int fd, char *ptr, size_t len) {
|
||||
chunkSize += partition->bytesPerCluster;
|
||||
} while ((nextChunkStart == chunkEnd + 1) &&
|
||||
#ifdef LIMIT_SECTORS
|
||||
(chunkSize + partition->bytesPerCluster <= LIMIT_SECTORS * BYTES_PER_READ) &&
|
||||
(chunkSize + partition->bytesPerCluster <= LIMIT_SECTORS * partition->bytesPerSector) &&
|
||||
#endif
|
||||
(chunkSize + partition->bytesPerCluster <= remain));
|
||||
|
||||
if (!_FAT_cache_readSectors (cache, _FAT_fat_clusterToSector (partition, position.cluster),
|
||||
chunkSize / BYTES_PER_READ, ptr))
|
||||
chunkSize / partition->bytesPerSector, ptr))
|
||||
{
|
||||
flagNoError = false;
|
||||
r->_errno = EIO;
|
||||
@ -477,7 +477,7 @@ ssize_t _FAT_read_r (struct _reent *r, int fd, char *ptr, size_t len) {
|
||||
}
|
||||
|
||||
// Read remaining sectors
|
||||
tempVar = remain / BYTES_PER_READ; // Number of sectors left
|
||||
tempVar = remain / partition->bytesPerSector; // Number of sectors left
|
||||
if ((tempVar > 0) && flagNoError) {
|
||||
if (!_FAT_cache_readSectors (cache, _FAT_fat_clusterToSector (partition, position.cluster),
|
||||
tempVar, ptr))
|
||||
@ -485,8 +485,8 @@ ssize_t _FAT_read_r (struct _reent *r, int fd, char *ptr, size_t len) {
|
||||
flagNoError = false;
|
||||
r->_errno = EIO;
|
||||
} else {
|
||||
ptr += tempVar * BYTES_PER_READ;
|
||||
remain -= tempVar * BYTES_PER_READ;
|
||||
ptr += tempVar * partition->bytesPerSector;
|
||||
remain -= tempVar * partition->bytesPerSector;
|
||||
position.sector += tempVar;
|
||||
}
|
||||
}
|
||||
@ -555,13 +555,14 @@ static bool _FAT_file_extend_r (struct _reent *r, FILE_STRUCT* file) {
|
||||
PARTITION* partition = file->partition;
|
||||
CACHE* cache = file->partition->cache;
|
||||
FILE_POSITION position;
|
||||
uint8_t zeroBuffer [BYTES_PER_READ] = {0};
|
||||
uint8_t zeroBuffer [partition->bytesPerSector];
|
||||
memset(zeroBuffer, 0, partition->bytesPerSector);
|
||||
uint32_t remain;
|
||||
uint32_t tempNextCluster;
|
||||
unsigned int sector;
|
||||
|
||||
position.byte = file->filesize % BYTES_PER_READ;
|
||||
position.sector = (file->filesize % partition->bytesPerCluster) / BYTES_PER_READ;
|
||||
position.byte = file->filesize % partition->bytesPerSector;
|
||||
position.sector = (file->filesize % partition->bytesPerCluster) / partition->bytesPerSector;
|
||||
// It is assumed that there is always a startCluster
|
||||
// This will be true when _FAT_file_extend_r is called from _FAT_write_r
|
||||
position.cluster = _FAT_fat_lastCluster (partition, file->startCluster);
|
||||
@ -580,7 +581,7 @@ static bool _FAT_file_extend_r (struct _reent *r, FILE_STRUCT* file) {
|
||||
position.sector = 0;
|
||||
}
|
||||
|
||||
if (remain + position.byte < BYTES_PER_READ) {
|
||||
if (remain + position.byte < partition->bytesPerSector) {
|
||||
// Only need to clear to the end of the sector
|
||||
_FAT_cache_writePartialSector (cache, zeroBuffer,
|
||||
_FAT_fat_clusterToSector (partition, position.cluster) + position.sector, position.byte, remain);
|
||||
@ -589,13 +590,13 @@ static bool _FAT_file_extend_r (struct _reent *r, FILE_STRUCT* file) {
|
||||
if (position.byte > 0) {
|
||||
_FAT_cache_writePartialSector (cache, zeroBuffer,
|
||||
_FAT_fat_clusterToSector (partition, position.cluster) + position.sector, position.byte,
|
||||
BYTES_PER_READ - position.byte);
|
||||
remain -= (BYTES_PER_READ - position.byte);
|
||||
partition->bytesPerSector - position.byte);
|
||||
remain -= (partition->bytesPerSector - position.byte);
|
||||
position.byte = 0;
|
||||
position.sector ++;
|
||||
}
|
||||
|
||||
while (remain >= BYTES_PER_READ) {
|
||||
while (remain >= partition->bytesPerSector) {
|
||||
if (position.sector >= partition->sectorsPerCluster) {
|
||||
position.sector = 0;
|
||||
// Ran out of clusters so get a new one
|
||||
@ -611,7 +612,7 @@ static bool _FAT_file_extend_r (struct _reent *r, FILE_STRUCT* file) {
|
||||
sector = _FAT_fat_clusterToSector (partition, position.cluster) + position.sector;
|
||||
_FAT_cache_writeSectors (cache, sector, 1, zeroBuffer);
|
||||
|
||||
remain -= BYTES_PER_READ;
|
||||
remain -= partition->bytesPerSector;
|
||||
position.sector ++;
|
||||
}
|
||||
|
||||
@ -712,12 +713,12 @@ ssize_t _FAT_write_r (struct _reent *r, int fd, const char *ptr, size_t len) {
|
||||
_FAT_check_position_for_next_cluster(r, &position, partition, remain, &flagNoError);
|
||||
|
||||
// Align to sector
|
||||
tempVar = BYTES_PER_READ - position.byte;
|
||||
tempVar = partition->bytesPerSector - position.byte;
|
||||
if (tempVar > remain) {
|
||||
tempVar = remain;
|
||||
}
|
||||
|
||||
if ((tempVar < BYTES_PER_READ) && flagNoError) {
|
||||
if ((tempVar < partition->bytesPerSector) && flagNoError) {
|
||||
// Write partial sector to disk
|
||||
_FAT_cache_writePartialSector (cache, ptr,
|
||||
_FAT_fat_clusterToSector (partition, position.cluster) + position.sector, position.byte, tempVar);
|
||||
@ -728,7 +729,7 @@ ssize_t _FAT_write_r (struct _reent *r, int fd, const char *ptr, size_t len) {
|
||||
|
||||
|
||||
// Move onto next sector
|
||||
if (position.byte >= BYTES_PER_READ) {
|
||||
if (position.byte >= partition->bytesPerSector) {
|
||||
position.byte = 0;
|
||||
position.sector ++;
|
||||
}
|
||||
@ -736,10 +737,10 @@ ssize_t _FAT_write_r (struct _reent *r, int fd, const char *ptr, size_t len) {
|
||||
|
||||
// Align to cluster
|
||||
// tempVar is number of sectors to write
|
||||
if (remain > (partition->sectorsPerCluster - position.sector) * BYTES_PER_READ) {
|
||||
if (remain > (partition->sectorsPerCluster - position.sector) * partition->bytesPerSector) {
|
||||
tempVar = partition->sectorsPerCluster - position.sector;
|
||||
} else {
|
||||
tempVar = remain / BYTES_PER_READ;
|
||||
tempVar = remain / partition->bytesPerSector;
|
||||
}
|
||||
|
||||
if ((tempVar > 0 && tempVar < partition->sectorsPerCluster) && flagNoError) {
|
||||
@ -749,8 +750,8 @@ ssize_t _FAT_write_r (struct _reent *r, int fd, const char *ptr, size_t len) {
|
||||
flagNoError = false;
|
||||
r->_errno = EIO;
|
||||
} else {
|
||||
ptr += tempVar * BYTES_PER_READ;
|
||||
remain -= tempVar * BYTES_PER_READ;
|
||||
ptr += tempVar * partition->bytesPerSector;
|
||||
remain -= tempVar * partition->bytesPerSector;
|
||||
position.sector += tempVar;
|
||||
}
|
||||
}
|
||||
@ -769,11 +770,11 @@ ssize_t _FAT_write_r (struct _reent *r, int fd, const char *ptr, size_t len) {
|
||||
// group consecutive clusters
|
||||
while (flagNoError &&
|
||||
#ifdef LIMIT_SECTORS
|
||||
(chunkSize + partition->bytesPerCluster <= LIMIT_SECTORS * BYTES_PER_READ) &&
|
||||
(chunkSize + partition->bytesPerCluster <= LIMIT_SECTORS * partition->bytesPerSector) &&
|
||||
#endif
|
||||
(chunkSize + partition->bytesPerCluster < remain))
|
||||
{
|
||||
// pretend to use up all sectors in next_position
|
||||
// pretend to use up all sectors in next_position
|
||||
next_position.sector = partition->sectorsPerCluster;
|
||||
// get or allocate next cluster
|
||||
_FAT_check_position_for_next_cluster(r, &next_position, partition,
|
||||
@ -786,7 +787,7 @@ ssize_t _FAT_write_r (struct _reent *r, int fd, const char *ptr, size_t len) {
|
||||
}
|
||||
|
||||
if ( !_FAT_cache_writeSectors (cache,
|
||||
_FAT_fat_clusterToSector(partition, position.cluster), chunkSize / BYTES_PER_READ, ptr))
|
||||
_FAT_fat_clusterToSector(partition, position.cluster), chunkSize / partition->bytesPerSector, ptr))
|
||||
{
|
||||
flagNoError = false;
|
||||
r->_errno = EIO;
|
||||
@ -810,15 +811,15 @@ ssize_t _FAT_write_r (struct _reent *r, int fd, const char *ptr, size_t len) {
|
||||
_FAT_check_position_for_next_cluster(r, &position, partition, remain, &flagNoError);
|
||||
|
||||
// Write remaining sectors
|
||||
tempVar = remain / BYTES_PER_READ; // Number of sectors left
|
||||
tempVar = remain / partition->bytesPerSector; // Number of sectors left
|
||||
if ((tempVar > 0) && flagNoError) {
|
||||
if (!_FAT_cache_writeSectors (cache, _FAT_fat_clusterToSector (partition, position.cluster), tempVar, ptr))
|
||||
{
|
||||
flagNoError = false;
|
||||
r->_errno = EIO;
|
||||
} else {
|
||||
ptr += tempVar * BYTES_PER_READ;
|
||||
remain -= tempVar * BYTES_PER_READ;
|
||||
ptr += tempVar * partition->bytesPerSector;
|
||||
remain -= tempVar * partition->bytesPerSector;
|
||||
position.sector += tempVar;
|
||||
}
|
||||
}
|
||||
@ -927,8 +928,8 @@ off_t _FAT_seek_r (struct _reent *r, int fd, off_t pos, int dir) {
|
||||
}
|
||||
// Calculate the sector and byte of the current position,
|
||||
// and store them
|
||||
file->rwPosition.sector = (position % partition->bytesPerCluster) / BYTES_PER_READ;
|
||||
file->rwPosition.byte = position % BYTES_PER_READ;
|
||||
file->rwPosition.sector = (position % partition->bytesPerCluster) / partition->bytesPerSector;
|
||||
file->rwPosition.byte = position % partition->bytesPerSector;
|
||||
|
||||
nextCluster = _FAT_fat_nextCluster (partition, cluster);
|
||||
while ((clusCount > 0) && (nextCluster != CLUSTER_FREE) && (nextCluster != CLUSTER_EOF)) {
|
||||
@ -1087,13 +1088,13 @@ int _FAT_ftruncate_r (struct _reent *r, int fd, off_t len) {
|
||||
lastCluster = _FAT_fat_trimChain (partition, file->startCluster, chainLength);
|
||||
|
||||
if (file->append) {
|
||||
file->appendPosition.byte = newSize % BYTES_PER_READ;
|
||||
file->appendPosition.byte = newSize % partition->bytesPerSector;
|
||||
// Does the end of the file fall on the edge of a cluster?
|
||||
if (newSize % partition->bytesPerCluster == 0) {
|
||||
// Set a flag to allocate a new cluster
|
||||
file->appendPosition.sector = partition->sectorsPerCluster;
|
||||
} else {
|
||||
file->appendPosition.sector = (newSize % partition->bytesPerCluster) / BYTES_PER_READ;
|
||||
file->appendPosition.sector = (newSize % partition->bytesPerCluster) / partition->bytesPerSector;
|
||||
}
|
||||
file->appendPosition.cluster = lastCluster;
|
||||
}
|
||||
|
@ -54,15 +54,15 @@ uint32_t _FAT_fat_nextCluster(PARTITION* partition, uint32_t cluster)
|
||||
case FS_FAT12:
|
||||
{
|
||||
u32 nextCluster_h;
|
||||
sector = partition->fat.fatStart + (((cluster * 3) / 2) / BYTES_PER_READ);
|
||||
offset = ((cluster * 3) / 2) % BYTES_PER_READ;
|
||||
sector = partition->fat.fatStart + (((cluster * 3) / 2) / partition->bytesPerSector);
|
||||
offset = ((cluster * 3) / 2) % partition->bytesPerSector;
|
||||
|
||||
|
||||
_FAT_cache_readLittleEndianValue (partition->cache, &nextCluster, sector, offset, sizeof(u8));
|
||||
|
||||
offset++;
|
||||
|
||||
if (offset >= BYTES_PER_READ) {
|
||||
if (offset >= partition->bytesPerSector) {
|
||||
offset = 0;
|
||||
sector++;
|
||||
}
|
||||
@ -85,8 +85,8 @@ uint32_t _FAT_fat_nextCluster(PARTITION* partition, uint32_t cluster)
|
||||
break;
|
||||
}
|
||||
case FS_FAT16:
|
||||
sector = partition->fat.fatStart + ((cluster << 1) / BYTES_PER_READ);
|
||||
offset = (cluster % (BYTES_PER_READ >> 1)) << 1;
|
||||
sector = partition->fat.fatStart + ((cluster << 1) / partition->bytesPerSector);
|
||||
offset = (cluster % (partition->bytesPerSector >> 1)) << 1;
|
||||
|
||||
_FAT_cache_readLittleEndianValue (partition->cache, &nextCluster, sector, offset, sizeof(u16));
|
||||
|
||||
@ -96,8 +96,8 @@ uint32_t _FAT_fat_nextCluster(PARTITION* partition, uint32_t cluster)
|
||||
break;
|
||||
|
||||
case FS_FAT32:
|
||||
sector = partition->fat.fatStart + ((cluster << 2) / BYTES_PER_READ);
|
||||
offset = (cluster % (BYTES_PER_READ >> 2)) << 2;
|
||||
sector = partition->fat.fatStart + ((cluster << 2) / partition->bytesPerSector);
|
||||
offset = (cluster % (partition->bytesPerSector >> 2)) << 2;
|
||||
|
||||
_FAT_cache_readLittleEndianValue (partition->cache, &nextCluster, sector, offset, sizeof(u32));
|
||||
|
||||
@ -135,8 +135,8 @@ static bool _FAT_fat_writeFatEntry (PARTITION* partition, uint32_t cluster, uint
|
||||
break;
|
||||
|
||||
case FS_FAT12:
|
||||
sector = partition->fat.fatStart + (((cluster * 3) / 2) / BYTES_PER_READ);
|
||||
offset = ((cluster * 3) / 2) % BYTES_PER_READ;
|
||||
sector = partition->fat.fatStart + (((cluster * 3) / 2) / partition->bytesPerSector);
|
||||
offset = ((cluster * 3) / 2) % partition->bytesPerSector;
|
||||
|
||||
if (cluster & 0x01) {
|
||||
|
||||
@ -147,7 +147,7 @@ static bool _FAT_fat_writeFatEntry (PARTITION* partition, uint32_t cluster, uint
|
||||
_FAT_cache_writeLittleEndianValue (partition->cache, value & 0xFF, sector, offset, sizeof(u8));
|
||||
|
||||
offset++;
|
||||
if (offset >= BYTES_PER_READ) {
|
||||
if (offset >= partition->bytesPerSector) {
|
||||
offset = 0;
|
||||
sector++;
|
||||
}
|
||||
@ -159,7 +159,7 @@ static bool _FAT_fat_writeFatEntry (PARTITION* partition, uint32_t cluster, uint
|
||||
_FAT_cache_writeLittleEndianValue (partition->cache, value, sector, offset, sizeof(u8));
|
||||
|
||||
offset++;
|
||||
if (offset >= BYTES_PER_READ) {
|
||||
if (offset >= partition->bytesPerSector) {
|
||||
offset = 0;
|
||||
sector++;
|
||||
}
|
||||
@ -174,16 +174,16 @@ static bool _FAT_fat_writeFatEntry (PARTITION* partition, uint32_t cluster, uint
|
||||
break;
|
||||
|
||||
case FS_FAT16:
|
||||
sector = partition->fat.fatStart + ((cluster << 1) / BYTES_PER_READ);
|
||||
offset = (cluster % (BYTES_PER_READ >> 1)) << 1;
|
||||
sector = partition->fat.fatStart + ((cluster << 1) / partition->bytesPerSector);
|
||||
offset = (cluster % (partition->bytesPerSector >> 1)) << 1;
|
||||
|
||||
_FAT_cache_writeLittleEndianValue (partition->cache, value, sector, offset, sizeof(u16));
|
||||
|
||||
break;
|
||||
|
||||
case FS_FAT32:
|
||||
sector = partition->fat.fatStart + ((cluster << 2) / BYTES_PER_READ);
|
||||
offset = (cluster % (BYTES_PER_READ >> 2)) << 2;
|
||||
sector = partition->fat.fatStart + ((cluster << 2) / partition->bytesPerSector);
|
||||
offset = (cluster % (partition->bytesPerSector >> 2)) << 2;
|
||||
|
||||
_FAT_cache_writeLittleEndianValue (partition->cache, value, sector, offset, sizeof(u32));
|
||||
|
||||
@ -269,7 +269,7 @@ If an error occurs, return CLUSTER_ERROR
|
||||
uint32_t _FAT_fat_linkFreeClusterCleared (PARTITION* partition, uint32_t cluster) {
|
||||
uint32_t newCluster;
|
||||
uint32_t i;
|
||||
uint8_t emptySector[BYTES_PER_READ];
|
||||
uint8_t emptySector[partition->bytesPerSector];
|
||||
|
||||
// Link the cluster
|
||||
newCluster = _FAT_fat_linkFreeCluster(partition, cluster);
|
||||
@ -279,7 +279,7 @@ uint32_t _FAT_fat_linkFreeClusterCleared (PARTITION* partition, uint32_t cluster
|
||||
}
|
||||
|
||||
// Clear all the sectors within the cluster
|
||||
memset (emptySector, 0, BYTES_PER_READ);
|
||||
memset (emptySector, 0, partition->bytesPerSector);
|
||||
for (i = 0; i < partition->sectorsPerCluster; i++) {
|
||||
_FAT_cache_writeSectors (partition->cache,
|
||||
_FAT_fat_clusterToSector (partition, newCluster) + i,
|
||||
|
@ -103,16 +103,20 @@ static const char FAT_SIG[3] = {'F', 'A', 'T'};
|
||||
static const char FS_INFO_SIG1[4] = {'R', 'R', 'a', 'A'};
|
||||
static const char FS_INFO_SIG2[4] = {'r', 'r', 'A', 'a'};
|
||||
|
||||
static uint8_t sectorBuffer[BYTES_PER_READ] __attribute__((aligned(32)));
|
||||
|
||||
sec_t FindFirstValidPartition(const DISC_INTERFACE* disc)
|
||||
{
|
||||
uint8_t part_table[16*4];
|
||||
uint8_t *ptr;
|
||||
int i;
|
||||
|
||||
uint8_t *sectorBuffer = (uint8_t*) _FAT_mem_allocate(MAX_SECTOR_SIZE);
|
||||
if(!sectorBuffer) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Read first sector of disc
|
||||
if (!_FAT_disc_readSectors (disc, 0, 1, sectorBuffer)) {
|
||||
_FAT_mem_free(sectorBuffer);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -124,6 +128,7 @@ sec_t FindFirstValidPartition(const DISC_INTERFACE* disc)
|
||||
|
||||
if (!memcmp(sectorBuffer + BPB_FAT16_fileSysType, FAT_SIG, sizeof(FAT_SIG)) ||
|
||||
!memcmp(sectorBuffer + BPB_FAT32_fileSysType, FAT_SIG, sizeof(FAT_SIG))) {
|
||||
_FAT_mem_free(sectorBuffer);
|
||||
return part_lba;
|
||||
}
|
||||
|
||||
@ -136,29 +141,40 @@ sec_t FindFirstValidPartition(const DISC_INTERFACE* disc)
|
||||
|
||||
for(n=0;n<8;n++) // max 8 logic partitions
|
||||
{
|
||||
if(!_FAT_disc_readSectors (disc, part_lba+next_lba2, 1, sectorBuffer)) return 0;
|
||||
if(!_FAT_disc_readSectors (disc, part_lba+next_lba2, 1, sectorBuffer)) {
|
||||
_FAT_mem_free(sectorBuffer);
|
||||
return 0;
|
||||
}
|
||||
|
||||
part_lba2 = part_lba + next_lba2 + u8array_to_u32(sectorBuffer, 0x1C6) ;
|
||||
next_lba2 = u8array_to_u32(sectorBuffer, 0x1D6);
|
||||
|
||||
if(!_FAT_disc_readSectors (disc, part_lba2, 1, sectorBuffer)) return 0;
|
||||
if(!_FAT_disc_readSectors (disc, part_lba2, 1, sectorBuffer)) {
|
||||
_FAT_mem_free(sectorBuffer);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!memcmp(sectorBuffer + BPB_FAT16_fileSysType, FAT_SIG, sizeof(FAT_SIG)) ||
|
||||
!memcmp(sectorBuffer + BPB_FAT32_fileSysType, FAT_SIG, sizeof(FAT_SIG)))
|
||||
{
|
||||
!memcmp(sectorBuffer + BPB_FAT32_fileSysType, FAT_SIG, sizeof(FAT_SIG))) {
|
||||
_FAT_mem_free(sectorBuffer);
|
||||
return part_lba2;
|
||||
}
|
||||
|
||||
if(next_lba2==0) break;
|
||||
}
|
||||
} else {
|
||||
if(!_FAT_disc_readSectors (disc, part_lba, 1, sectorBuffer)) return 0;
|
||||
if(!_FAT_disc_readSectors (disc, part_lba, 1, sectorBuffer)) {
|
||||
_FAT_mem_free(sectorBuffer);
|
||||
return 0;
|
||||
}
|
||||
if (!memcmp(sectorBuffer + BPB_FAT16_fileSysType, FAT_SIG, sizeof(FAT_SIG)) ||
|
||||
!memcmp(sectorBuffer + BPB_FAT32_fileSysType, FAT_SIG, sizeof(FAT_SIG))) {
|
||||
_FAT_mem_free(sectorBuffer);
|
||||
return part_lba;
|
||||
}
|
||||
}
|
||||
}
|
||||
_FAT_mem_free(sectorBuffer);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -166,13 +182,20 @@ sec_t FindFirstValidPartition(const DISC_INTERFACE* disc)
|
||||
PARTITION* _FAT_partition_constructor (const DISC_INTERFACE* disc, uint32_t cacheSize, uint32_t sectorsPerPage, sec_t startSector) {
|
||||
PARTITION* partition;
|
||||
|
||||
uint8_t *sectorBuffer = (uint8_t*) _FAT_mem_allocate(MAX_SECTOR_SIZE);
|
||||
if(!sectorBuffer) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Read first sector of disc
|
||||
if (!_FAT_disc_readSectors (disc, startSector, 1, sectorBuffer)) {
|
||||
_FAT_mem_free(sectorBuffer);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Make sure it is a valid MBR or boot sector
|
||||
if ( (sectorBuffer[BPB_bootSig_55] != 0x55) || (sectorBuffer[BPB_bootSig_AA] != 0xAA)) {
|
||||
_FAT_mem_free(sectorBuffer);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -187,19 +210,21 @@ PARTITION* _FAT_partition_constructor (const DISC_INTERFACE* disc, uint32_t cach
|
||||
} else {
|
||||
startSector = FindFirstValidPartition(disc);
|
||||
if (!_FAT_disc_readSectors (disc, startSector, 1, sectorBuffer)) {
|
||||
_FAT_mem_free(sectorBuffer);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Now verify that this is indeed a FAT partition
|
||||
if (memcmp(sectorBuffer + BPB_FAT16_fileSysType, FAT_SIG, sizeof(FAT_SIG)) &&
|
||||
memcmp(sectorBuffer + BPB_FAT32_fileSysType, FAT_SIG, sizeof(FAT_SIG)))
|
||||
{
|
||||
memcmp(sectorBuffer + BPB_FAT32_fileSysType, FAT_SIG, sizeof(FAT_SIG))) {
|
||||
_FAT_mem_free(sectorBuffer);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
partition = (PARTITION*) _FAT_mem_allocate (sizeof(PARTITION));
|
||||
if (partition == NULL) {
|
||||
_FAT_mem_free(sectorBuffer);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -226,8 +251,15 @@ PARTITION* _FAT_partition_constructor (const DISC_INTERFACE* disc, uint32_t cach
|
||||
partition->numberOfSectors = u8array_to_u32( sectorBuffer, BPB_numSectors);
|
||||
}
|
||||
|
||||
partition->bytesPerSector = BYTES_PER_READ; // Sector size is redefined to be 512 bytes
|
||||
partition->sectorsPerCluster = sectorBuffer[BPB_sectorsPerCluster] * u8array_to_u16(sectorBuffer, BPB_bytesPerSector) / BYTES_PER_READ;
|
||||
partition->bytesPerSector = u8array_to_u16(sectorBuffer, BPB_bytesPerSector);
|
||||
if(partition->bytesPerSector < MIN_SECTOR_SIZE || partition->bytesPerSector > MAX_SECTOR_SIZE) {
|
||||
// Unsupported sector size
|
||||
_FAT_mem_free(sectorBuffer);
|
||||
_FAT_mem_free(partition);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
partition->sectorsPerCluster = sectorBuffer[BPB_sectorsPerCluster];
|
||||
partition->bytesPerCluster = partition->bytesPerSector * partition->sectorsPerCluster;
|
||||
partition->fat.fatStart = startSector + u8array_to_u16(sectorBuffer, BPB_reservedSectors);
|
||||
|
||||
@ -268,7 +300,7 @@ PARTITION* _FAT_partition_constructor (const DISC_INTERFACE* disc, uint32_t cach
|
||||
}
|
||||
|
||||
// Create a cache to use
|
||||
partition->cache = _FAT_cache_constructor (cacheSize, sectorsPerPage, partition->disc, startSector+partition->numberOfSectors);
|
||||
partition->cache = _FAT_cache_constructor (cacheSize, sectorsPerPage, partition->disc, startSector+partition->numberOfSectors, partition->bytesPerSector);
|
||||
|
||||
// Set current directory to the root
|
||||
partition->cwdCluster = partition->rootDirCluster;
|
||||
@ -282,6 +314,8 @@ PARTITION* _FAT_partition_constructor (const DISC_INTERFACE* disc, uint32_t cach
|
||||
|
||||
_FAT_partition_readFSinfo(partition);
|
||||
|
||||
_FAT_mem_free(sectorBuffer);
|
||||
|
||||
return partition;
|
||||
}
|
||||
|
||||
@ -328,8 +362,11 @@ void _FAT_partition_createFSinfo(PARTITION * partition)
|
||||
if(partition->readOnly || partition->filesysType != FS_FAT32)
|
||||
return;
|
||||
|
||||
uint8_t sectorBuffer[BYTES_PER_READ];
|
||||
memset(sectorBuffer, 0, sizeof(sectorBuffer));
|
||||
uint8_t *sectorBuffer = (uint8_t*) _FAT_mem_allocate(partition->bytesPerSector);
|
||||
if(!sectorBuffer) {
|
||||
return;
|
||||
}
|
||||
memset(sectorBuffer, 0, partition->bytesPerSector);
|
||||
|
||||
int i;
|
||||
for(i = 0; i < 4; ++i)
|
||||
@ -346,6 +383,8 @@ void _FAT_partition_createFSinfo(PARTITION * partition)
|
||||
sectorBuffer[FSIB_bootSig_AA] = 0xAA;
|
||||
|
||||
_FAT_disc_writeSectors (partition->disc, partition->fsInfoSector, 1, sectorBuffer);
|
||||
|
||||
_FAT_mem_free(sectorBuffer);
|
||||
}
|
||||
|
||||
void _FAT_partition_readFSinfo(PARTITION * partition)
|
||||
@ -353,24 +392,29 @@ void _FAT_partition_readFSinfo(PARTITION * partition)
|
||||
if(partition->filesysType != FS_FAT32)
|
||||
return;
|
||||
|
||||
uint8_t sectorBuffer[BYTES_PER_READ] = {0};
|
||||
|
||||
uint8_t *sectorBuffer = (uint8_t*) _FAT_mem_allocate(partition->bytesPerSector);
|
||||
if(!sectorBuffer) {
|
||||
return;
|
||||
}
|
||||
memset(sectorBuffer, 0, partition->bytesPerSector);
|
||||
// Read first sector of disc
|
||||
if (!_FAT_disc_readSectors (partition->disc, partition->fsInfoSector, 1, sectorBuffer)) {
|
||||
_FAT_mem_free(sectorBuffer);
|
||||
return;
|
||||
}
|
||||
|
||||
if(memcmp(sectorBuffer+FSIB_SIG1, FS_INFO_SIG1, 4) != 0 ||
|
||||
memcmp(sectorBuffer+FSIB_SIG2, FS_INFO_SIG2, 4) != 0 ||
|
||||
u8array_to_u32(sectorBuffer, FSIB_numberOfFreeCluster) == 0)
|
||||
{
|
||||
u8array_to_u32(sectorBuffer, FSIB_numberOfFreeCluster) == 0) {
|
||||
//sector does not yet exist, create one!
|
||||
_FAT_partition_createFSinfo(partition);
|
||||
_FAT_mem_free(sectorBuffer);
|
||||
return;
|
||||
}
|
||||
|
||||
partition->fat.numberFreeCluster = u8array_to_u32(sectorBuffer, FSIB_numberOfFreeCluster);
|
||||
partition->fat.numberLastAllocCluster = u8array_to_u32(sectorBuffer, FSIB_numberLastAllocCluster);
|
||||
_FAT_mem_free(sectorBuffer);
|
||||
}
|
||||
|
||||
void _FAT_partition_writeFSinfo(PARTITION * partition)
|
||||
@ -378,21 +422,26 @@ void _FAT_partition_writeFSinfo(PARTITION * partition)
|
||||
if(partition->filesysType != FS_FAT32)
|
||||
return;
|
||||
|
||||
uint8_t sectorBuffer[BYTES_PER_READ] = {0};
|
||||
|
||||
uint8_t *sectorBuffer = (uint8_t*) _FAT_mem_allocate(partition->bytesPerSector);
|
||||
if(!sectorBuffer) {
|
||||
return;
|
||||
}
|
||||
memset(sectorBuffer, 0, partition->bytesPerSector);
|
||||
// Read first sector of disc
|
||||
if (!_FAT_disc_readSectors (partition->disc, partition->fsInfoSector, 1, sectorBuffer)) {
|
||||
_FAT_mem_free(sectorBuffer);
|
||||
return;
|
||||
}
|
||||
|
||||
if(memcmp(sectorBuffer+FSIB_SIG1, FS_INFO_SIG1, 4) || memcmp(sectorBuffer+FSIB_SIG2, FS_INFO_SIG2, 4))
|
||||
if(memcmp(sectorBuffer+FSIB_SIG1, FS_INFO_SIG1, 4) || memcmp(sectorBuffer+FSIB_SIG2, FS_INFO_SIG2, 4)) {
|
||||
_FAT_mem_free(sectorBuffer);
|
||||
return;
|
||||
}
|
||||
|
||||
u32_to_u8array(sectorBuffer, FSIB_numberOfFreeCluster, partition->fat.numberFreeCluster);
|
||||
u32_to_u8array(sectorBuffer, FSIB_numberLastAllocCluster, partition->fat.numberLastAllocCluster);
|
||||
|
||||
// Read first sector of disc
|
||||
if (!_FAT_disc_writeSectors (partition->disc, partition->fsInfoSector, 1, sectorBuffer)) {
|
||||
return;
|
||||
}
|
||||
_FAT_disc_writeSectors (partition->disc, partition->fsInfoSector, 1, sectorBuffer);
|
||||
_FAT_mem_free(sectorBuffer);
|
||||
}
|
||||
|
@ -34,6 +34,9 @@
|
||||
#include "cache.h"
|
||||
#include "lock.h"
|
||||
|
||||
#define MIN_SECTOR_SIZE 512
|
||||
#define MAX_SECTOR_SIZE 4096
|
||||
|
||||
// Filesystem type
|
||||
typedef enum {FS_UNKNOWN, FS_FAT12, FS_FAT16, FS_FAT32} FS_TYPE;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user