diff --git a/source/cache.c b/source/cache.c index 164d340..07576b9 100644 --- a/source/cache.c +++ b/source/cache.c @@ -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_accesscount - 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; diff --git a/source/cache.h b/source/cache.h index c6e48d0..07bb14c 100644 --- a/source/cache.h +++ b/source/cache.h @@ -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); diff --git a/source/common.h b/source/common.h index b3358f0..c5c5632 100644 --- a/source/common.h +++ b/source/common.h @@ -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 #include #include diff --git a/source/directory.c b/source/directory.c index c2d9313..55de3bb 100644 --- a/source/directory.c +++ b/source/directory.c @@ -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; } diff --git a/source/fatfile.c b/source/fatfile.c index 293707c..e2a99f6 100644 --- a/source/fatfile.c +++ b/source/fatfile.c @@ -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; } diff --git a/source/file_allocation_table.c b/source/file_allocation_table.c index 7690209..e6a6835 100644 --- a/source/file_allocation_table.c +++ b/source/file_allocation_table.c @@ -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, diff --git a/source/partition.c b/source/partition.c index 7f68f00..0f5d12d 100644 --- a/source/partition.c +++ b/source/partition.c @@ -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); } diff --git a/source/partition.h b/source/partition.h index 24f2067..ec27a0e 100644 --- a/source/partition.h +++ b/source/partition.h @@ -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;