mirror of
https://github.com/wiidev/usbloadergx.git
synced 2024-11-15 16:05:10 +01:00
*Added support for starting .wbfs game files from fat32/ntfs partitions on a sector size > 512 (tested with 4096)
*modified libcustomfat and ntfs fragment fetch function to support >512 bytes per sector *Added new ehcmodule (thanks rodries) *Added real support of using both ports simultaniously without shutting down the other (thanks rodries for the ehcmodule works on this). There is no longer the limitation that the settings have to be on SD card for this. (ONLY HERMES CIOS) *Moved a few settings to Feature Settings and added a new Hard Drive Settings *Changed Wiinnertag path to only point to the path and not to the file. You must correct the path manually in custom path settings or reset you configs for this change or Winnertag won't work!! *Removed a few compile warnings for devkitPPC R23
This commit is contained in:
parent
d657e03e5f
commit
f6c9003574
@ -46,7 +46,7 @@
|
|||||||
|
|
||||||
#define CACHE_FREE UINT_MAX
|
#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;
|
CACHE* cache;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
CACHE_ENTRY* cacheEntries;
|
CACHE_ENTRY* cacheEntries;
|
||||||
@ -68,6 +68,7 @@ CACHE* _FAT_cache_constructor (unsigned int numberOfPages, unsigned int sectorsP
|
|||||||
cache->endOfPartition = endOfPartition;
|
cache->endOfPartition = endOfPartition;
|
||||||
cache->numberOfPages = numberOfPages;
|
cache->numberOfPages = numberOfPages;
|
||||||
cache->sectorsPerPage = sectorsPerPage;
|
cache->sectorsPerPage = sectorsPerPage;
|
||||||
|
cache->bytesPerSector = bytesPerSector;
|
||||||
|
|
||||||
|
|
||||||
cacheEntries = (CACHE_ENTRY*) _FAT_mem_allocate ( sizeof(CACHE_ENTRY) * numberOfPages);
|
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].count = 0;
|
||||||
cacheEntries[i].last_access = 0;
|
cacheEntries[i].last_access = 0;
|
||||||
cacheEntries[i].dirty = false;
|
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;
|
cache->cacheEntries = cacheEntries;
|
||||||
@ -127,7 +128,7 @@ static CACHE_ENTRY* _FAT_cache_getPage(CACHE *cache,sec_t sector)
|
|||||||
cacheEntries[i].last_access = accessTime();
|
cacheEntries[i].last_access = accessTime();
|
||||||
return &(cacheEntries[i]);
|
return &(cacheEntries[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(foundFree==false && (cacheEntries[i].sector==CACHE_FREE || cacheEntries[i].last_access<oldAccess)) {
|
if(foundFree==false && (cacheEntries[i].sector==CACHE_FREE || cacheEntries[i].last_access<oldAccess)) {
|
||||||
if(cacheEntries[i].sector==CACHE_FREE) foundFree = true;
|
if(cacheEntries[i].sector==CACHE_FREE) foundFree = true;
|
||||||
oldUsed = i;
|
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;
|
secs_to_read = entry->count - sec;
|
||||||
if(secs_to_read>numSectors) secs_to_read = numSectors;
|
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;
|
sector += secs_to_read;
|
||||||
numSectors -= 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
|
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;
|
sec_t sec;
|
||||||
CACHE_ENTRY *entry;
|
CACHE_ENTRY *entry;
|
||||||
|
|
||||||
if (offset + size > BYTES_PER_READ) return false;
|
if (offset + size > cache->bytesPerSector) return false;
|
||||||
|
|
||||||
entry = _FAT_cache_getPage(cache,sector);
|
entry = _FAT_cache_getPage(cache,sector);
|
||||||
if(entry==NULL) return false;
|
if(entry==NULL) return false;
|
||||||
|
|
||||||
sec = sector - entry->sector;
|
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;
|
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.
|
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;
|
sec_t sec;
|
||||||
CACHE_ENTRY *entry;
|
CACHE_ENTRY *entry;
|
||||||
|
|
||||||
if (offset + size > BYTES_PER_READ) return false;
|
if (offset + size > cache->bytesPerSector) return false;
|
||||||
|
|
||||||
entry = _FAT_cache_getPage(cache,sector);
|
entry = _FAT_cache_getPage(cache,sector);
|
||||||
if(entry==NULL) return false;
|
if(entry==NULL) return false;
|
||||||
|
|
||||||
sec = sector - entry->sector;
|
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;
|
entry->dirty = true;
|
||||||
return 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
|
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;
|
sec_t sec;
|
||||||
CACHE_ENTRY *entry;
|
CACHE_ENTRY *entry;
|
||||||
|
|
||||||
if (offset + size > BYTES_PER_READ) return false;
|
if (offset + size > cache->bytesPerSector) return false;
|
||||||
|
|
||||||
entry = _FAT_cache_getPage(cache,sector);
|
entry = _FAT_cache_getPage(cache,sector);
|
||||||
if(entry==NULL) return false;
|
if(entry==NULL) return false;
|
||||||
|
|
||||||
sec = sector - entry->sector;
|
sec = sector - entry->sector;
|
||||||
memset(entry->cache + (sec*BYTES_PER_READ),0,BYTES_PER_READ);
|
memset(entry->cache + (sec*cache->bytesPerSector),0,cache->bytesPerSector);
|
||||||
memcpy(entry->cache + ((sec*BYTES_PER_READ) + offset),buffer,size);
|
memcpy(entry->cache + ((sec*cache->bytesPerSector) + offset),buffer,size);
|
||||||
|
|
||||||
entry->dirty = true;
|
entry->dirty = true;
|
||||||
return 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 sec;
|
||||||
sec_t secs_to_write;
|
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;
|
secs_to_write = entry->count - sec;
|
||||||
if(secs_to_write>numSectors) secs_to_write = numSectors;
|
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;
|
sector += secs_to_write;
|
||||||
numSectors -= secs_to_write;
|
numSectors -= secs_to_write;
|
||||||
|
|
||||||
|
@ -39,9 +39,6 @@
|
|||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "disc.h"
|
#include "disc.h"
|
||||||
|
|
||||||
#define PAGE_SECTORS 64
|
|
||||||
#define CACHE_PAGE_SIZE (BYTES_PER_READ * PAGE_SECTORS)
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
sec_t sector;
|
sec_t sector;
|
||||||
unsigned int count;
|
unsigned int count;
|
||||||
@ -55,6 +52,7 @@ typedef struct {
|
|||||||
sec_t endOfPartition;
|
sec_t endOfPartition;
|
||||||
unsigned int numberOfPages;
|
unsigned int numberOfPages;
|
||||||
unsigned int sectorsPerPage;
|
unsigned int sectorsPerPage;
|
||||||
|
unsigned int bytesPerSector;
|
||||||
CACHE_ENTRY* cacheEntries;
|
CACHE_ENTRY* cacheEntries;
|
||||||
} CACHE;
|
} 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
|
Read a full sector from the cache
|
||||||
*/
|
*/
|
||||||
static inline bool _FAT_cache_readSector (CACHE* cache, void* buffer, sec_t sector) {
|
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
|
Write a full sector to the cache
|
||||||
*/
|
*/
|
||||||
static inline bool _FAT_cache_writeSector (CACHE* cache, const void* buffer, sec_t sector) {
|
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);
|
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);
|
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);
|
void _FAT_cache_destructor (CACHE* cache);
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
Common definitions and included files for the FATlib
|
Common definitions and included files for the FATlib
|
||||||
|
|
||||||
Copyright (c) 2006 Michael "Chishm" Chisholm
|
Copyright (c) 2006 Michael "Chishm" Chisholm
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without modification,
|
Redistribution and use in source and binary forms, with or without modification,
|
||||||
are permitted provided that the following conditions are met:
|
are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
@ -29,7 +29,6 @@
|
|||||||
#ifndef _COMMON_H
|
#ifndef _COMMON_H
|
||||||
#define _COMMON_H
|
#define _COMMON_H
|
||||||
|
|
||||||
#define BYTES_PER_READ 512
|
|
||||||
#include <fat.h>
|
#include <fat.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
a FAT partition
|
a FAT partition
|
||||||
|
|
||||||
Copyright (c) 2006 Michael "Chishm" Chisholm
|
Copyright (c) 2006 Michael "Chishm" Chisholm
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without modification,
|
Redistribution and use in source and binary forms, with or without modification,
|
||||||
are permitted provided that the following conditions are met:
|
are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
@ -53,7 +53,7 @@ typedef unsigned short ucs2_t;
|
|||||||
// Long file name directory entry
|
// Long file name directory entry
|
||||||
enum LFN_offset {
|
enum LFN_offset {
|
||||||
LFN_offset_ordinal = 0x00, // Position within LFN
|
LFN_offset_ordinal = 0x00, // Position within LFN
|
||||||
LFN_offset_char0 = 0x01,
|
LFN_offset_char0 = 0x01,
|
||||||
LFN_offset_char1 = 0x03,
|
LFN_offset_char1 = 0x03,
|
||||||
LFN_offset_char2 = 0x05,
|
LFN_offset_char2 = 0x05,
|
||||||
LFN_offset_char3 = 0x07,
|
LFN_offset_char3 = 0x07,
|
||||||
@ -71,7 +71,7 @@ enum LFN_offset {
|
|||||||
LFN_offset_char11 = 0x1C,
|
LFN_offset_char11 = 0x1C,
|
||||||
LFN_offset_char12 = 0x1E
|
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_END 0x40
|
||||||
#define LFN_DEL 0x80
|
#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_ALIAS_CHARACTERS[] = "\\/:;*?\"<>|&+,=[] ";
|
||||||
static const char ILLEGAL_LFN_CHARACTERS[] = "\\/:*?\"<>|";
|
static const char ILLEGAL_LFN_CHARACTERS[] = "\\/:*?\"<>|";
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Returns number of UCS-2 characters needed to encode an LFN
|
Returns number of UCS-2 characters needed to encode an LFN
|
||||||
Returns -1 if it is an invalid LFN
|
Returns -1 if it is an invalid LFN
|
||||||
*/
|
*/
|
||||||
@ -89,7 +89,7 @@ static int _FAT_directory_lfnLength (const char* name) {
|
|||||||
size_t nameLength;
|
size_t nameLength;
|
||||||
int ucsLength;
|
int ucsLength;
|
||||||
const char* tempName = name;
|
const char* tempName = name;
|
||||||
|
|
||||||
nameLength = strnlen(name, MAX_FILENAME_LENGTH);
|
nameLength = strnlen(name, MAX_FILENAME_LENGTH);
|
||||||
// Make sure the name is short enough to be valid
|
// Make sure the name is short enough to be valid
|
||||||
if ( nameLength >= MAX_FILENAME_LENGTH) {
|
if ( nameLength >= MAX_FILENAME_LENGTH) {
|
||||||
@ -110,7 +110,7 @@ static int _FAT_directory_lfnLength (const char* name) {
|
|||||||
if (ucsLength < 0 || ucsLength >= MAX_LFN_LENGTH) {
|
if (ucsLength < 0 || ucsLength >= MAX_LFN_LENGTH) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Otherwise it is valid
|
// Otherwise it is valid
|
||||||
return ucsLength;
|
return ucsLength;
|
||||||
}
|
}
|
||||||
@ -153,7 +153,7 @@ static size_t _FAT_directory_ucs2tombs (char* dst, const ucs2_t* src, size_t len
|
|||||||
int bytes;
|
int bytes;
|
||||||
char buff[MB_CUR_MAX];
|
char buff[MB_CUR_MAX];
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
while (count < len - 1 && *src != '\0') {
|
while (count < len - 1 && *src != '\0') {
|
||||||
bytes = wcrtomb (buff, *src, &ps);
|
bytes = wcrtomb (buff, *src, &ps);
|
||||||
if (bytes < 0) {
|
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';
|
*dst = L'\0';
|
||||||
|
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -183,11 +183,11 @@ static int _FAT_directory_mbsncasecmp (const char* s1, const char* s2, size_t le
|
|||||||
mbstate_t ps2 = {0};
|
mbstate_t ps2 = {0};
|
||||||
size_t b1 = 0;
|
size_t b1 = 0;
|
||||||
size_t b2 = 0;
|
size_t b2 = 0;
|
||||||
|
|
||||||
if (len1 == 0) {
|
if (len1 == 0) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
do {
|
do {
|
||||||
s1 += b1;
|
s1 += b1;
|
||||||
s2 += b2;
|
s2 += b2;
|
||||||
@ -198,7 +198,7 @@ static int _FAT_directory_mbsncasecmp (const char* s1, const char* s2, size_t le
|
|||||||
}
|
}
|
||||||
len1 -= b1;
|
len1 -= b1;
|
||||||
} while (len1 > 0 && towlower(wc1) == towlower(wc2) && wc1 != 0);
|
} while (len1 > 0 && towlower(wc1) == towlower(wc2) && wc1 != 0);
|
||||||
|
|
||||||
return towlower(wc1) - towlower(wc2);
|
return towlower(wc1) - towlower(wc2);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -217,7 +217,7 @@ static bool _FAT_directory_entryGetAlias (const u8* entryData, char* destName) {
|
|||||||
} else {
|
} else {
|
||||||
destName[1] = '\0';
|
destName[1] = '\0';
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Copy the filename from the dirEntry to the string
|
// Copy the filename from the dirEntry to the string
|
||||||
for (i = 0; (i < 8) && (entryData[DIR_ENTRY_name + i] != ' '); i++) {
|
for (i = 0; (i < 8) && (entryData[DIR_ENTRY_name + i] != ' '); i++) {
|
||||||
destName[i] = entryData[DIR_ENTRY_name + 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
|
// Increment offset, wrapping at the end of a sector
|
||||||
++ position.offset;
|
++ position.offset;
|
||||||
if (position.offset == BYTES_PER_READ / DIR_ENTRY_DATA_SIZE) {
|
if (position.offset == partition->bytesPerSector / DIR_ENTRY_DATA_SIZE) {
|
||||||
position.offset = 0;
|
position.offset = 0;
|
||||||
// Increment sector when wrapping
|
// Increment sector when wrapping
|
||||||
++ position.sector;
|
++ position.sector;
|
||||||
@ -269,7 +269,7 @@ static bool _FAT_directory_incrementDirEntryPosition (PARTITION* partition, DIR_
|
|||||||
} else {
|
} else {
|
||||||
return false; // Got to the end of the directory, not extending it
|
return false; // Got to the end of the directory, not extending it
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
position.cluster = tempCluster;
|
position.cluster = tempCluster;
|
||||||
} else if ((position.cluster == FAT16_ROOT_DIR_CLUSTER) && (position.sector == (partition->dataStart - partition->rootDirStart))) {
|
} 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
|
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
|
lfn[lfnPos] = '\0'; // Set end of lfn to null character
|
||||||
lfnChkSum = entryData[LFN_offset_checkSum];
|
lfnChkSum = entryData[LFN_offset_checkSum];
|
||||||
}
|
}
|
||||||
if (lfnChkSum != entryData[LFN_offset_checkSum]) {
|
if (lfnChkSum != entryData[LFN_offset_checkSum]) {
|
||||||
lfnExists = false;
|
lfnExists = false;
|
||||||
}
|
}
|
||||||
@ -353,14 +353,14 @@ bool _FAT_directory_getNextEntry (PARTITION* partition, DIR_ENTRY* entry) {
|
|||||||
chkSum = 0;
|
chkSum = 0;
|
||||||
for (i=0; i < 11; i++) {
|
for (i=0; i < 11; i++) {
|
||||||
// NOTE: The operation is an unsigned char rotate right
|
// 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) {
|
if (chkSum != lfnChkSum) {
|
||||||
lfnExists = false;
|
lfnExists = false;
|
||||||
entry->filename[0] = '\0';
|
entry->filename[0] = '\0';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lfnExists) {
|
if (lfnExists) {
|
||||||
if (_FAT_directory_ucs2tombs (entry->filename, lfn, MAX_FILENAME_LENGTH) == (size_t)-1) {
|
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?
|
// 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.cluster = 0;
|
||||||
entry->dataStart.sector = 0;
|
entry->dataStart.sector = 0;
|
||||||
entry->dataStart.offset = 0;
|
entry->dataStart.offset = 0;
|
||||||
|
|
||||||
entry->dataEnd = entry->dataStart;
|
entry->dataEnd = entry->dataStart;
|
||||||
|
|
||||||
memset (entry->filename, '\0', MAX_FILENAME_LENGTH);
|
memset (entry->filename, '\0', MAX_FILENAME_LENGTH);
|
||||||
entry->filename[0] = '.';
|
entry->filename[0] = '.';
|
||||||
|
|
||||||
memset (entry->entryData, 0, DIR_ENTRY_DATA_SIZE);
|
memset (entry->entryData, 0, DIR_ENTRY_DATA_SIZE);
|
||||||
memset (entry->entryData, ' ', 11);
|
memset (entry->entryData, ' ', 11);
|
||||||
entry->entryData[0] = '.';
|
entry->entryData[0] = '.';
|
||||||
|
|
||||||
entry->entryData[DIR_ENTRY_attributes] = ATTRIB_DIR;
|
entry->entryData[DIR_ENTRY_attributes] = ATTRIB_DIR;
|
||||||
|
|
||||||
u16_to_u8array (entry->entryData, DIR_ENTRY_cluster, partition->rootDirCluster);
|
u16_to_u8array (entry->entryData, DIR_ENTRY_cluster, partition->rootDirCluster);
|
||||||
u16_to_u8array (entry->entryData, DIR_ENTRY_clusterHigh, partition->rootDirCluster >> 16);
|
u16_to_u8array (entry->entryData, DIR_ENTRY_clusterHigh, partition->rootDirCluster >> 16);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -438,7 +438,7 @@ bool _FAT_directory_getVolumeLabel (PARTITION* partition, char *label) {
|
|||||||
label[11]='\0';
|
label[11]='\0';
|
||||||
end = false;
|
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
|
//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,
|
if(!_FAT_cache_readPartialSector (partition->cache, entryData,
|
||||||
_FAT_fat_clusterToSector(partition, entryEnd.cluster) + entryEnd.sector,
|
_FAT_fat_clusterToSector(partition, entryEnd.cluster) + entryEnd.sector,
|
||||||
entryEnd.offset * DIR_ENTRY_DATA_SIZE, DIR_ENTRY_DATA_SIZE))
|
entryEnd.offset * DIR_ENTRY_DATA_SIZE, DIR_ENTRY_DATA_SIZE))
|
||||||
@ -446,15 +446,15 @@ bool _FAT_directory_getVolumeLabel (PARTITION* partition, char *label) {
|
|||||||
return false;
|
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++) {
|
for (i = 0; i < 11; i++) {
|
||||||
label[i] = entryData[DIR_ENTRY_name + i];
|
label[i] = entryData[DIR_ENTRY_name + i];
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
} else if (entryData[0] == DIR_ENTRY_LAST) {
|
} else if (entryData[0] == DIR_ENTRY_LAST) {
|
||||||
end = true;
|
end = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_FAT_directory_incrementDirEntryPosition (partition, &entryEnd, false) == false) {
|
if (_FAT_directory_incrementDirEntryPosition (partition, &entryEnd, false) == false) {
|
||||||
end = true;
|
end = true;
|
||||||
}
|
}
|
||||||
@ -471,18 +471,18 @@ bool _FAT_directory_entryFromPosition (PARTITION* partition, DIR_ENTRY* entry) {
|
|||||||
int i;
|
int i;
|
||||||
int lfnPos;
|
int lfnPos;
|
||||||
uint8_t entryData[DIR_ENTRY_DATA_SIZE];
|
uint8_t entryData[DIR_ENTRY_DATA_SIZE];
|
||||||
|
|
||||||
memset (entry->filename, '\0', MAX_FILENAME_LENGTH);
|
memset (entry->filename, '\0', MAX_FILENAME_LENGTH);
|
||||||
|
|
||||||
// Create an empty directory entry to overwrite the old ones with
|
// Create an empty directory entry to overwrite the old ones with
|
||||||
for ( entryStillValid = true, finished = false;
|
for ( entryStillValid = true, finished = false;
|
||||||
entryStillValid && !finished;
|
entryStillValid && !finished;
|
||||||
entryStillValid = _FAT_directory_incrementDirEntryPosition (partition, &entryStart, false))
|
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,
|
_FAT_fat_clusterToSector(partition, entryStart.cluster) + entryStart.sector,
|
||||||
entryStart.offset * DIR_ENTRY_DATA_SIZE, DIR_ENTRY_DATA_SIZE);
|
entryStart.offset * DIR_ENTRY_DATA_SIZE, DIR_ENTRY_DATA_SIZE);
|
||||||
|
|
||||||
if ((entryStart.cluster == entryEnd.cluster)
|
if ((entryStart.cluster == entryEnd.cluster)
|
||||||
&& (entryStart.sector == entryEnd.sector)
|
&& (entryStart.sector == entryEnd.sector)
|
||||||
&& (entryStart.offset == entryEnd.offset)) {
|
&& (entryStart.offset == entryEnd.offset)) {
|
||||||
@ -504,7 +504,7 @@ bool _FAT_directory_entryFromPosition (PARTITION* partition, DIR_ENTRY* entry) {
|
|||||||
if (!entryStillValid) {
|
if (!entryStillValid) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((entryStart.cluster == entryEnd.cluster)
|
if ((entryStart.cluster == entryEnd.cluster)
|
||||||
&& (entryStart.sector == entryEnd.sector)
|
&& (entryStart.sector == entryEnd.sector)
|
||||||
&& (entryStart.offset == entryEnd.offset)) {
|
&& (entryStart.offset == entryEnd.offset)) {
|
||||||
@ -518,7 +518,7 @@ bool _FAT_directory_entryFromPosition (PARTITION* partition, DIR_ENTRY* entry) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -534,7 +534,7 @@ bool _FAT_directory_entryFromPath (PARTITION* partition, DIR_ENTRY* entry, const
|
|||||||
bool found, notFound;
|
bool found, notFound;
|
||||||
|
|
||||||
pathPosition = path;
|
pathPosition = path;
|
||||||
|
|
||||||
found = false;
|
found = false;
|
||||||
notFound = false;
|
notFound = false;
|
||||||
|
|
||||||
@ -560,13 +560,13 @@ bool _FAT_directory_entryFromPath (PARTITION* partition, DIR_ENTRY* entry, const
|
|||||||
dirCluster = partition->cwdCluster;
|
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
|
// and this is the root directory, return it
|
||||||
if ((dirCluster == partition->rootDirCluster) && (strcmp(".", pathPosition) == 0)) {
|
if ((dirCluster == partition->rootDirCluster) && (strcmp(".", pathPosition) == 0)) {
|
||||||
_FAT_directory_getRootEntry (partition, entry);
|
_FAT_directory_getRootEntry (partition, entry);
|
||||||
found = true;
|
found = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (!found && !notFound) {
|
while (!found && !notFound) {
|
||||||
// Get the name of the next required subdirectory within the path
|
// Get the name of the next required subdirectory within the path
|
||||||
nextPathPosition = strchr (pathPosition, DIR_SEPARATOR);
|
nextPathPosition = strchr (pathPosition, DIR_SEPARATOR);
|
||||||
@ -633,7 +633,7 @@ bool _FAT_directory_entryFromPath (PARTITION* partition, DIR_ENTRY* entry, const
|
|||||||
|
|
||||||
if (found && !notFound) {
|
if (found && !notFound) {
|
||||||
if (partition->filesysType == FS_FAT32 && (entry->entryData[DIR_ENTRY_attributes] & ATTRIB_DIR) &&
|
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,
|
// On FAT32 it should specify an actual cluster for the root entry,
|
||||||
// not cluster 0 as on FAT16
|
// 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];
|
uint8_t entryData[DIR_ENTRY_DATA_SIZE];
|
||||||
|
|
||||||
// Create an empty directory entry to overwrite the old ones with
|
// Create an empty directory entry to overwrite the old ones with
|
||||||
for ( entryStillValid = true, finished = false;
|
for ( entryStillValid = true, finished = false;
|
||||||
entryStillValid && !finished;
|
entryStillValid && !finished;
|
||||||
entryStillValid = _FAT_directory_incrementDirEntryPosition (partition, &entryStart, false))
|
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);
|
_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;
|
entryStillValid = true;
|
||||||
dirEntryRemain = size;
|
dirEntryRemain = size;
|
||||||
endOfDirectory = false;
|
endOfDirectory = false;
|
||||||
|
|
||||||
while (entryStillValid && !endOfDirectory && (dirEntryRemain > 0)) {
|
while (entryStillValid && !endOfDirectory && (dirEntryRemain > 0)) {
|
||||||
_FAT_cache_readPartialSector (partition->cache, entryData,
|
_FAT_cache_readPartialSector (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);
|
gapEnd.offset * DIR_ENTRY_DATA_SIZE, DIR_ENTRY_DATA_SIZE);
|
||||||
if (entryData[0] == DIR_ENTRY_LAST) {
|
if (entryData[0] == DIR_ENTRY_LAST) {
|
||||||
gapStart = gapEnd;
|
gapStart = gapEnd;
|
||||||
@ -706,7 +706,7 @@ static bool _FAT_directory_findEntryGap (PARTITION* partition, DIR_ENTRY* entry,
|
|||||||
} else {
|
} else {
|
||||||
dirEntryRemain = size;
|
dirEntryRemain = size;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!endOfDirectory && (dirEntryRemain > 0)) {
|
if (!endOfDirectory && (dirEntryRemain > 0)) {
|
||||||
entryStillValid = _FAT_directory_incrementDirEntryPosition (partition, &gapEnd, true);
|
entryStillValid = _FAT_directory_incrementDirEntryPosition (partition, &gapEnd, true);
|
||||||
}
|
}
|
||||||
@ -731,7 +731,7 @@ static bool _FAT_directory_findEntryGap (PARTITION* partition, DIR_ENTRY* entry,
|
|||||||
-- dirEntryRemain;
|
-- dirEntryRemain;
|
||||||
// Fill the entry with blanks
|
// Fill the entry with blanks
|
||||||
_FAT_cache_writePartialSector (partition->cache, entryData,
|
_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);
|
gapEnd.offset * DIR_ENTRY_DATA_SIZE, DIR_ENTRY_DATA_SIZE);
|
||||||
}
|
}
|
||||||
if (!entryStillValid) {
|
if (!entryStillValid) {
|
||||||
@ -755,7 +755,7 @@ static bool _FAT_directory_entryExists (PARTITION* partition, const char* name,
|
|||||||
if (dirnameLength >= MAX_FILENAME_LENGTH) {
|
if (dirnameLength >= MAX_FILENAME_LENGTH) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make sure the entry doesn't already exist
|
// Make sure the entry doesn't already exist
|
||||||
foundFile = _FAT_directory_getFirstEntry (partition, &tempEntry, dirCluster);
|
foundFile = _FAT_directory_getFirstEntry (partition, &tempEntry, dirCluster);
|
||||||
|
|
||||||
@ -776,9 +776,9 @@ static bool _FAT_directory_entryExists (PARTITION* partition, const char* name,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Creates an alias for a long file name. If the alias is not an exact match for the
|
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,
|
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.
|
it returns 0. If there was an error, it returns -1.
|
||||||
*/
|
*/
|
||||||
static int _FAT_directory_createAlias (char* alias, const char* lfn) {
|
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;
|
int bytesUsed = 0;
|
||||||
const char* lfnExt;
|
const char* lfnExt;
|
||||||
int aliasExtLen;
|
int aliasExtLen;
|
||||||
|
|
||||||
// Strip leading periods
|
// Strip leading periods
|
||||||
while (lfn[lfnPos] == '.') {
|
while (lfn[lfnPos] == '.') {
|
||||||
lfnPos ++;
|
lfnPos ++;
|
||||||
lossyConversion = true;
|
lossyConversion = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Primary portion of alias
|
// Primary portion of alias
|
||||||
while (aliasPos < 8 && lfn[lfnPos] != '.' && lfn[lfnPos] != '\0') {
|
while (aliasPos < 8 && lfn[lfnPos] != '.' && lfn[lfnPos] != '\0') {
|
||||||
bytesUsed = mbrtowc(&lfnChar, lfn + lfnPos, MAX_FILENAME_LENGTH - lfnPos, &ps);
|
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
|
oemChar = '_'; // Replace illegal characters with underscores
|
||||||
lossyConversion = true;
|
lossyConversion = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
alias[aliasPos] = (char)oemChar;
|
alias[aliasPos] = (char)oemChar;
|
||||||
aliasPos++;
|
aliasPos++;
|
||||||
lfnPos += bytesUsed;
|
lfnPos += bytesUsed;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lfn[lfnPos] != '.' && lfn[lfnPos] != '\0') {
|
if (lfn[lfnPos] != '.' && lfn[lfnPos] != '\0') {
|
||||||
// Name was more than 8 characters long
|
// Name was more than 8 characters long
|
||||||
lossyConversion = true;
|
lossyConversion = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Alias extension
|
// Alias extension
|
||||||
lfnExt = strrchr (lfn, '.');
|
lfnExt = strrchr (lfn, '.');
|
||||||
if (lfnExt != NULL && lfnExt != strchr (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
|
oemChar = '_'; // Replace illegal characters with underscores
|
||||||
lossyConversion = true;
|
lossyConversion = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
alias[aliasPos] = (char)oemChar;
|
alias[aliasPos] = (char)oemChar;
|
||||||
aliasPos++;
|
aliasPos++;
|
||||||
lfnExt += bytesUsed;
|
lfnExt += bytesUsed;
|
||||||
@ -881,7 +881,7 @@ static int _FAT_directory_createAlias (char* alias, const char* lfn) {
|
|||||||
lossyConversion = true;
|
lossyConversion = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
alias[aliasPos] = '\0';
|
alias[aliasPos] = '\0';
|
||||||
if (lossyConversion) {
|
if (lossyConversion) {
|
||||||
return aliasPos;
|
return aliasPos;
|
||||||
@ -955,14 +955,14 @@ bool _FAT_directory_addEntry (PARTITION* partition, DIR_ENTRY* entry, uint32_t d
|
|||||||
} else {
|
} else {
|
||||||
// It's a long filename with an alias
|
// It's a long filename with an alias
|
||||||
entrySize = ((lfnLen + LFN_ENTRY_LENGTH - 1) / LFN_ENTRY_LENGTH) + 1;
|
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
|
// 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
|
// and there isn't already a file with that name
|
||||||
if (strncasecmp (alias, entry->filename, MAX_ALIAS_LENGTH) != 0 ||
|
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
|
// 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
|
// Move extension to last 3 characters
|
||||||
while (alias[i] != '.' && i > 0) i--;
|
while (alias[i] != '.' && i > 0) i--;
|
||||||
if (i > 0) {
|
if (i > 0) {
|
||||||
@ -972,7 +972,7 @@ bool _FAT_directory_addEntry (PARTITION* partition, DIR_ENTRY* entry, uint32_t d
|
|||||||
memset (alias + i, '_', j - i);
|
memset (alias + i, '_', j - i);
|
||||||
alias[MAX_ALIAS_LENGTH-1]=0;
|
alias[MAX_ALIAS_LENGTH-1]=0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generate numeric tail
|
// Generate numeric tail
|
||||||
for (i = 1; i <= MAX_NUMERIC_TAIL; i++) {
|
for (i = 1; i <= MAX_NUMERIC_TAIL; i++) {
|
||||||
j = i;
|
j = i;
|
||||||
@ -1015,7 +1015,7 @@ bool _FAT_directory_addEntry (PARTITION* partition, DIR_ENTRY* entry, uint32_t d
|
|||||||
entry->entryData[j] = ' ';
|
entry->entryData[j] = ' ';
|
||||||
++ j;
|
++ j;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generate alias checksum
|
// Generate alias checksum
|
||||||
for (i=0; i < ALIAS_ENTRY_LENGTH; i++) {
|
for (i=0; i < ALIAS_ENTRY_LENGTH; i++) {
|
||||||
// NOTE: The operation is an unsigned char rotate right
|
// 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};
|
ucs2_t lfn[MAX_LFN_LENGTH] = {0};
|
||||||
_FAT_directory_mbstoucs2 (lfn, entry->filename, MAX_LFN_LENGTH);
|
_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 )
|
entryStillValid = _FAT_directory_incrementDirEntryPosition (partition, &curEntryPos, false), -- i )
|
||||||
{
|
{
|
||||||
if (i > 1) {
|
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) {
|
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_uid = 1; // Faked for FAT
|
||||||
st->st_gid = 2; // Faked for FAT
|
st->st_gid = 2; // Faked for FAT
|
||||||
st->st_rdev = st->st_dev;
|
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 (
|
st->st_atime = _FAT_filetime_to_time_t (
|
||||||
0,
|
0,
|
||||||
u8array_to_u16 (entry->entryData, DIR_ENTRY_aDate)
|
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)
|
u8array_to_u16 (entry->entryData, DIR_ENTRY_cDate)
|
||||||
);
|
);
|
||||||
st->st_spare3 = 0;
|
st->st_spare3 = 0;
|
||||||
st->st_blksize = BYTES_PER_READ; // Prefered file I/O block size
|
st->st_blksize = partition->bytesPerSector; // 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_blocks = (st->st_size + partition->bytesPerSector - 1) / partition->bytesPerSector; // File size in blocks
|
||||||
st->st_spare4[0] = 0;
|
st->st_spare4[0] = 0;
|
||||||
st->st_spare4[1] = 0;
|
st->st_spare4[1] = 0;
|
||||||
}
|
}
|
||||||
|
@ -54,6 +54,7 @@ static const DISC_INTERFACE* get_io_usbstorage (void) {
|
|||||||
static const DISC_INTERFACE* get_io_gcsda (void) {
|
static const DISC_INTERFACE* get_io_gcsda (void) {
|
||||||
return &__io_gcsda;
|
return &__io_gcsda;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const DISC_INTERFACE* get_io_gcsdb (void) {
|
static const DISC_INTERFACE* get_io_gcsdb (void) {
|
||||||
return &__io_gcsdb;
|
return &__io_gcsdb;
|
||||||
}
|
}
|
||||||
@ -87,7 +88,12 @@ const INTERFACE_ID _FAT_disc_interfaces[] = {
|
|||||||
#elif defined (NDS)
|
#elif defined (NDS)
|
||||||
#include <nds/arm9/dldi.h>
|
#include <nds/arm9/dldi.h>
|
||||||
|
|
||||||
|
static const DISC_INTERFACE* get_io_dsisd (void) {
|
||||||
|
return &__io_dsisd;
|
||||||
|
}
|
||||||
|
|
||||||
const INTERFACE_ID _FAT_disc_interfaces[] = {
|
const INTERFACE_ID _FAT_disc_interfaces[] = {
|
||||||
|
{"sd", get_io_dsisd},
|
||||||
{"fat", dldiGetInternal},
|
{"fat", dldiGetInternal},
|
||||||
{NULL, NULL}
|
{NULL, NULL}
|
||||||
};
|
};
|
||||||
|
@ -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
|
// Set append pointer to the end of the file
|
||||||
file->appendPosition.cluster = _FAT_fat_lastCluster (partition, file->startCluster);
|
file->appendPosition.cluster = _FAT_fat_lastCluster (partition, file->startCluster);
|
||||||
file->appendPosition.sector = (file->filesize % partition->bytesPerCluster) / BYTES_PER_READ;
|
file->appendPosition.sector = (file->filesize % partition->bytesPerCluster) / partition->bytesPerSector;
|
||||||
file->appendPosition.byte = file->filesize % BYTES_PER_READ;
|
file->appendPosition.byte = file->filesize % partition->bytesPerSector;
|
||||||
|
|
||||||
// Check if the end of the file is on the end of a cluster
|
// Check if the end of the file is on the end of a cluster
|
||||||
if ( (file->filesize > 0) && ((file->filesize % partition->bytesPerCluster)==0) ){
|
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;
|
cache = file->partition->cache;
|
||||||
|
|
||||||
// Align to sector
|
// Align to sector
|
||||||
tempVar = BYTES_PER_READ - position.byte;
|
tempVar = partition->bytesPerSector - position.byte;
|
||||||
if (tempVar > remain) {
|
if (tempVar > remain) {
|
||||||
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,
|
_FAT_cache_readPartialSector ( cache, ptr, _FAT_fat_clusterToSector (partition, position.cluster) + position.sector,
|
||||||
position.byte, tempVar);
|
position.byte, tempVar);
|
||||||
@ -395,7 +395,7 @@ ssize_t _FAT_read_r (struct _reent *r, int fd, char *ptr, size_t len) {
|
|||||||
ptr += tempVar;
|
ptr += tempVar;
|
||||||
|
|
||||||
position.byte += tempVar;
|
position.byte += tempVar;
|
||||||
if (position.byte >= BYTES_PER_READ) {
|
if (position.byte >= partition->bytesPerSector) {
|
||||||
position.byte = 0;
|
position.byte = 0;
|
||||||
position.sector++;
|
position.sector++;
|
||||||
}
|
}
|
||||||
@ -403,10 +403,10 @@ ssize_t _FAT_read_r (struct _reent *r, int fd, char *ptr, size_t len) {
|
|||||||
|
|
||||||
// align to cluster
|
// align to cluster
|
||||||
// tempVar is number of sectors to read
|
// 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;
|
tempVar = partition->sectorsPerCluster - position.sector;
|
||||||
} else {
|
} else {
|
||||||
tempVar = remain / BYTES_PER_READ;
|
tempVar = remain / partition->bytesPerSector;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((tempVar > 0) && flagNoError) {
|
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;
|
flagNoError = false;
|
||||||
r->_errno = EIO;
|
r->_errno = EIO;
|
||||||
} else {
|
} else {
|
||||||
ptr += tempVar * BYTES_PER_READ;
|
ptr += tempVar * partition->bytesPerSector;
|
||||||
remain -= tempVar * BYTES_PER_READ;
|
remain -= tempVar * partition->bytesPerSector;
|
||||||
position.sector += tempVar;
|
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;
|
chunkSize += partition->bytesPerCluster;
|
||||||
} while ((nextChunkStart == chunkEnd + 1) &&
|
} while ((nextChunkStart == chunkEnd + 1) &&
|
||||||
#ifdef LIMIT_SECTORS
|
#ifdef LIMIT_SECTORS
|
||||||
(chunkSize + partition->bytesPerCluster <= LIMIT_SECTORS * BYTES_PER_READ) &&
|
(chunkSize + partition->bytesPerCluster <= LIMIT_SECTORS * partition->bytesPerSector) &&
|
||||||
#endif
|
#endif
|
||||||
(chunkSize + partition->bytesPerCluster <= remain));
|
(chunkSize + partition->bytesPerCluster <= remain));
|
||||||
|
|
||||||
if (!_FAT_cache_readSectors (cache, _FAT_fat_clusterToSector (partition, position.cluster),
|
if (!_FAT_cache_readSectors (cache, _FAT_fat_clusterToSector (partition, position.cluster),
|
||||||
chunkSize / BYTES_PER_READ, ptr))
|
chunkSize / partition->bytesPerSector, ptr))
|
||||||
{
|
{
|
||||||
flagNoError = false;
|
flagNoError = false;
|
||||||
r->_errno = EIO;
|
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
|
// 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 ((tempVar > 0) && flagNoError) {
|
||||||
if (!_FAT_cache_readSectors (cache, _FAT_fat_clusterToSector (partition, position.cluster),
|
if (!_FAT_cache_readSectors (cache, _FAT_fat_clusterToSector (partition, position.cluster),
|
||||||
tempVar, ptr))
|
tempVar, ptr))
|
||||||
@ -485,8 +485,8 @@ ssize_t _FAT_read_r (struct _reent *r, int fd, char *ptr, size_t len) {
|
|||||||
flagNoError = false;
|
flagNoError = false;
|
||||||
r->_errno = EIO;
|
r->_errno = EIO;
|
||||||
} else {
|
} else {
|
||||||
ptr += tempVar * BYTES_PER_READ;
|
ptr += tempVar * partition->bytesPerSector;
|
||||||
remain -= tempVar * BYTES_PER_READ;
|
remain -= tempVar * partition->bytesPerSector;
|
||||||
position.sector += tempVar;
|
position.sector += tempVar;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -555,13 +555,14 @@ static bool _FAT_file_extend_r (struct _reent *r, FILE_STRUCT* file) {
|
|||||||
PARTITION* partition = file->partition;
|
PARTITION* partition = file->partition;
|
||||||
CACHE* cache = file->partition->cache;
|
CACHE* cache = file->partition->cache;
|
||||||
FILE_POSITION position;
|
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 remain;
|
||||||
uint32_t tempNextCluster;
|
uint32_t tempNextCluster;
|
||||||
unsigned int sector;
|
unsigned int sector;
|
||||||
|
|
||||||
position.byte = file->filesize % BYTES_PER_READ;
|
position.byte = file->filesize % partition->bytesPerSector;
|
||||||
position.sector = (file->filesize % partition->bytesPerCluster) / BYTES_PER_READ;
|
position.sector = (file->filesize % partition->bytesPerCluster) / partition->bytesPerSector;
|
||||||
// It is assumed that there is always a startCluster
|
// It is assumed that there is always a startCluster
|
||||||
// This will be true when _FAT_file_extend_r is called from _FAT_write_r
|
// This will be true when _FAT_file_extend_r is called from _FAT_write_r
|
||||||
position.cluster = _FAT_fat_lastCluster (partition, file->startCluster);
|
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;
|
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
|
// Only need to clear to the end of the sector
|
||||||
_FAT_cache_writePartialSector (cache, zeroBuffer,
|
_FAT_cache_writePartialSector (cache, zeroBuffer,
|
||||||
_FAT_fat_clusterToSector (partition, position.cluster) + position.sector, position.byte, remain);
|
_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) {
|
if (position.byte > 0) {
|
||||||
_FAT_cache_writePartialSector (cache, zeroBuffer,
|
_FAT_cache_writePartialSector (cache, zeroBuffer,
|
||||||
_FAT_fat_clusterToSector (partition, position.cluster) + position.sector, position.byte,
|
_FAT_fat_clusterToSector (partition, position.cluster) + position.sector, position.byte,
|
||||||
BYTES_PER_READ - position.byte);
|
partition->bytesPerSector - position.byte);
|
||||||
remain -= (BYTES_PER_READ - position.byte);
|
remain -= (partition->bytesPerSector - position.byte);
|
||||||
position.byte = 0;
|
position.byte = 0;
|
||||||
position.sector ++;
|
position.sector ++;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (remain >= BYTES_PER_READ) {
|
while (remain >= partition->bytesPerSector) {
|
||||||
if (position.sector >= partition->sectorsPerCluster) {
|
if (position.sector >= partition->sectorsPerCluster) {
|
||||||
position.sector = 0;
|
position.sector = 0;
|
||||||
// Ran out of clusters so get a new one
|
// 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;
|
sector = _FAT_fat_clusterToSector (partition, position.cluster) + position.sector;
|
||||||
_FAT_cache_writeSectors (cache, sector, 1, zeroBuffer);
|
_FAT_cache_writeSectors (cache, sector, 1, zeroBuffer);
|
||||||
|
|
||||||
remain -= BYTES_PER_READ;
|
remain -= partition->bytesPerSector;
|
||||||
position.sector ++;
|
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);
|
_FAT_check_position_for_next_cluster(r, &position, partition, remain, &flagNoError);
|
||||||
|
|
||||||
// Align to sector
|
// Align to sector
|
||||||
tempVar = BYTES_PER_READ - position.byte;
|
tempVar = partition->bytesPerSector - position.byte;
|
||||||
if (tempVar > remain) {
|
if (tempVar > remain) {
|
||||||
tempVar = remain;
|
tempVar = remain;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((tempVar < BYTES_PER_READ) && flagNoError) {
|
if ((tempVar < partition->bytesPerSector) && flagNoError) {
|
||||||
// Write partial sector to disk
|
// Write partial sector to disk
|
||||||
_FAT_cache_writePartialSector (cache, ptr,
|
_FAT_cache_writePartialSector (cache, ptr,
|
||||||
_FAT_fat_clusterToSector (partition, position.cluster) + position.sector, position.byte, tempVar);
|
_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
|
// Move onto next sector
|
||||||
if (position.byte >= BYTES_PER_READ) {
|
if (position.byte >= partition->bytesPerSector) {
|
||||||
position.byte = 0;
|
position.byte = 0;
|
||||||
position.sector ++;
|
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
|
// Align to cluster
|
||||||
// tempVar is number of sectors to write
|
// 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;
|
tempVar = partition->sectorsPerCluster - position.sector;
|
||||||
} else {
|
} else {
|
||||||
tempVar = remain / BYTES_PER_READ;
|
tempVar = remain / partition->bytesPerSector;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((tempVar > 0 && tempVar < partition->sectorsPerCluster) && flagNoError) {
|
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;
|
flagNoError = false;
|
||||||
r->_errno = EIO;
|
r->_errno = EIO;
|
||||||
} else {
|
} else {
|
||||||
ptr += tempVar * BYTES_PER_READ;
|
ptr += tempVar * partition->bytesPerSector;
|
||||||
remain -= tempVar * BYTES_PER_READ;
|
remain -= tempVar * partition->bytesPerSector;
|
||||||
position.sector += tempVar;
|
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
|
// group consecutive clusters
|
||||||
while (flagNoError &&
|
while (flagNoError &&
|
||||||
#ifdef LIMIT_SECTORS
|
#ifdef LIMIT_SECTORS
|
||||||
(chunkSize + partition->bytesPerCluster <= LIMIT_SECTORS * BYTES_PER_READ) &&
|
(chunkSize + partition->bytesPerCluster <= LIMIT_SECTORS * partition->bytesPerSector) &&
|
||||||
#endif
|
#endif
|
||||||
(chunkSize + partition->bytesPerCluster < remain))
|
(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;
|
next_position.sector = partition->sectorsPerCluster;
|
||||||
// get or allocate next cluster
|
// get or allocate next cluster
|
||||||
_FAT_check_position_for_next_cluster(r, &next_position, partition,
|
_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,
|
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;
|
flagNoError = false;
|
||||||
r->_errno = EIO;
|
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);
|
_FAT_check_position_for_next_cluster(r, &position, partition, remain, &flagNoError);
|
||||||
|
|
||||||
// Write remaining sectors
|
// 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 ((tempVar > 0) && flagNoError) {
|
||||||
if (!_FAT_cache_writeSectors (cache, _FAT_fat_clusterToSector (partition, position.cluster), tempVar, ptr))
|
if (!_FAT_cache_writeSectors (cache, _FAT_fat_clusterToSector (partition, position.cluster), tempVar, ptr))
|
||||||
{
|
{
|
||||||
flagNoError = false;
|
flagNoError = false;
|
||||||
r->_errno = EIO;
|
r->_errno = EIO;
|
||||||
} else {
|
} else {
|
||||||
ptr += tempVar * BYTES_PER_READ;
|
ptr += tempVar * partition->bytesPerSector;
|
||||||
remain -= tempVar * BYTES_PER_READ;
|
remain -= tempVar * partition->bytesPerSector;
|
||||||
position.sector += tempVar;
|
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,
|
// Calculate the sector and byte of the current position,
|
||||||
// and store them
|
// and store them
|
||||||
file->rwPosition.sector = (position % partition->bytesPerCluster) / BYTES_PER_READ;
|
file->rwPosition.sector = (position % partition->bytesPerCluster) / partition->bytesPerSector;
|
||||||
file->rwPosition.byte = position % BYTES_PER_READ;
|
file->rwPosition.byte = position % partition->bytesPerSector;
|
||||||
|
|
||||||
nextCluster = _FAT_fat_nextCluster (partition, cluster);
|
nextCluster = _FAT_fat_nextCluster (partition, cluster);
|
||||||
while ((clusCount > 0) && (nextCluster != CLUSTER_FREE) && (nextCluster != CLUSTER_EOF)) {
|
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);
|
lastCluster = _FAT_fat_trimChain (partition, file->startCluster, chainLength);
|
||||||
|
|
||||||
if (file->append) {
|
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?
|
// Does the end of the file fall on the edge of a cluster?
|
||||||
if (newSize % partition->bytesPerCluster == 0) {
|
if (newSize % partition->bytesPerCluster == 0) {
|
||||||
// Set a flag to allocate a new cluster
|
// Set a flag to allocate a new cluster
|
||||||
file->appendPosition.sector = partition->sectorsPerCluster;
|
file->appendPosition.sector = partition->sectorsPerCluster;
|
||||||
} else {
|
} else {
|
||||||
file->appendPosition.sector = (newSize % partition->bytesPerCluster) / BYTES_PER_READ;
|
file->appendPosition.sector = (newSize % partition->bytesPerCluster) / partition->bytesPerSector;
|
||||||
}
|
}
|
||||||
file->appendPosition.cluster = lastCluster;
|
file->appendPosition.cluster = lastCluster;
|
||||||
}
|
}
|
||||||
|
@ -32,7 +32,7 @@ int _FAT_get_fragments (const char *path, _fat_frag_append_t append_fragment, vo
|
|||||||
partition = file.partition;
|
partition = file.partition;
|
||||||
_FAT_lock(&partition->lock);
|
_FAT_lock(&partition->lock);
|
||||||
|
|
||||||
size = file.filesize / BYTES_PER_READ;
|
size = file.filesize / partition->bytesPerSector;
|
||||||
cluster = file.startCluster;
|
cluster = file.startCluster;
|
||||||
offset = 0;
|
offset = 0;
|
||||||
|
|
||||||
|
@ -30,6 +30,7 @@
|
|||||||
|
|
||||||
#include "file_allocation_table.h"
|
#include "file_allocation_table.h"
|
||||||
#include "partition.h"
|
#include "partition.h"
|
||||||
|
#include "mem_allocate.h"
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -54,15 +55,15 @@ uint32_t _FAT_fat_nextCluster(PARTITION* partition, uint32_t cluster)
|
|||||||
case FS_FAT12:
|
case FS_FAT12:
|
||||||
{
|
{
|
||||||
u32 nextCluster_h;
|
u32 nextCluster_h;
|
||||||
sector = partition->fat.fatStart + (((cluster * 3) / 2) / BYTES_PER_READ);
|
sector = partition->fat.fatStart + (((cluster * 3) / 2) / partition->bytesPerSector);
|
||||||
offset = ((cluster * 3) / 2) % BYTES_PER_READ;
|
offset = ((cluster * 3) / 2) % partition->bytesPerSector;
|
||||||
|
|
||||||
|
|
||||||
_FAT_cache_readLittleEndianValue (partition->cache, &nextCluster, sector, offset, sizeof(u8));
|
_FAT_cache_readLittleEndianValue (partition->cache, &nextCluster, sector, offset, sizeof(u8));
|
||||||
|
|
||||||
offset++;
|
offset++;
|
||||||
|
|
||||||
if (offset >= BYTES_PER_READ) {
|
if (offset >= partition->bytesPerSector) {
|
||||||
offset = 0;
|
offset = 0;
|
||||||
sector++;
|
sector++;
|
||||||
}
|
}
|
||||||
@ -85,8 +86,8 @@ uint32_t _FAT_fat_nextCluster(PARTITION* partition, uint32_t cluster)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case FS_FAT16:
|
case FS_FAT16:
|
||||||
sector = partition->fat.fatStart + ((cluster << 1) / BYTES_PER_READ);
|
sector = partition->fat.fatStart + ((cluster << 1) / partition->bytesPerSector);
|
||||||
offset = (cluster % (BYTES_PER_READ >> 1)) << 1;
|
offset = (cluster % (partition->bytesPerSector >> 1)) << 1;
|
||||||
|
|
||||||
_FAT_cache_readLittleEndianValue (partition->cache, &nextCluster, sector, offset, sizeof(u16));
|
_FAT_cache_readLittleEndianValue (partition->cache, &nextCluster, sector, offset, sizeof(u16));
|
||||||
|
|
||||||
@ -96,8 +97,8 @@ uint32_t _FAT_fat_nextCluster(PARTITION* partition, uint32_t cluster)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case FS_FAT32:
|
case FS_FAT32:
|
||||||
sector = partition->fat.fatStart + ((cluster << 2) / BYTES_PER_READ);
|
sector = partition->fat.fatStart + ((cluster << 2) / partition->bytesPerSector);
|
||||||
offset = (cluster % (BYTES_PER_READ >> 2)) << 2;
|
offset = (cluster % (partition->bytesPerSector >> 2)) << 2;
|
||||||
|
|
||||||
_FAT_cache_readLittleEndianValue (partition->cache, &nextCluster, sector, offset, sizeof(u32));
|
_FAT_cache_readLittleEndianValue (partition->cache, &nextCluster, sector, offset, sizeof(u32));
|
||||||
|
|
||||||
@ -135,8 +136,8 @@ static bool _FAT_fat_writeFatEntry (PARTITION* partition, uint32_t cluster, uint
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case FS_FAT12:
|
case FS_FAT12:
|
||||||
sector = partition->fat.fatStart + (((cluster * 3) / 2) / BYTES_PER_READ);
|
sector = partition->fat.fatStart + (((cluster * 3) / 2) / partition->bytesPerSector);
|
||||||
offset = ((cluster * 3) / 2) % BYTES_PER_READ;
|
offset = ((cluster * 3) / 2) % partition->bytesPerSector;
|
||||||
|
|
||||||
if (cluster & 0x01) {
|
if (cluster & 0x01) {
|
||||||
|
|
||||||
@ -147,7 +148,7 @@ static bool _FAT_fat_writeFatEntry (PARTITION* partition, uint32_t cluster, uint
|
|||||||
_FAT_cache_writeLittleEndianValue (partition->cache, value & 0xFF, sector, offset, sizeof(u8));
|
_FAT_cache_writeLittleEndianValue (partition->cache, value & 0xFF, sector, offset, sizeof(u8));
|
||||||
|
|
||||||
offset++;
|
offset++;
|
||||||
if (offset >= BYTES_PER_READ) {
|
if (offset >= partition->bytesPerSector) {
|
||||||
offset = 0;
|
offset = 0;
|
||||||
sector++;
|
sector++;
|
||||||
}
|
}
|
||||||
@ -159,7 +160,7 @@ static bool _FAT_fat_writeFatEntry (PARTITION* partition, uint32_t cluster, uint
|
|||||||
_FAT_cache_writeLittleEndianValue (partition->cache, value, sector, offset, sizeof(u8));
|
_FAT_cache_writeLittleEndianValue (partition->cache, value, sector, offset, sizeof(u8));
|
||||||
|
|
||||||
offset++;
|
offset++;
|
||||||
if (offset >= BYTES_PER_READ) {
|
if (offset >= partition->bytesPerSector) {
|
||||||
offset = 0;
|
offset = 0;
|
||||||
sector++;
|
sector++;
|
||||||
}
|
}
|
||||||
@ -174,16 +175,16 @@ static bool _FAT_fat_writeFatEntry (PARTITION* partition, uint32_t cluster, uint
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case FS_FAT16:
|
case FS_FAT16:
|
||||||
sector = partition->fat.fatStart + ((cluster << 1) / BYTES_PER_READ);
|
sector = partition->fat.fatStart + ((cluster << 1) / partition->bytesPerSector);
|
||||||
offset = (cluster % (BYTES_PER_READ >> 1)) << 1;
|
offset = (cluster % (partition->bytesPerSector >> 1)) << 1;
|
||||||
|
|
||||||
_FAT_cache_writeLittleEndianValue (partition->cache, value, sector, offset, sizeof(u16));
|
_FAT_cache_writeLittleEndianValue (partition->cache, value, sector, offset, sizeof(u16));
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FS_FAT32:
|
case FS_FAT32:
|
||||||
sector = partition->fat.fatStart + ((cluster << 2) / BYTES_PER_READ);
|
sector = partition->fat.fatStart + ((cluster << 2) / partition->bytesPerSector);
|
||||||
offset = (cluster % (BYTES_PER_READ >> 2)) << 2;
|
offset = (cluster % (partition->bytesPerSector >> 2)) << 2;
|
||||||
|
|
||||||
_FAT_cache_writeLittleEndianValue (partition->cache, value, sector, offset, sizeof(u32));
|
_FAT_cache_writeLittleEndianValue (partition->cache, value, sector, offset, sizeof(u32));
|
||||||
|
|
||||||
@ -269,7 +270,7 @@ If an error occurs, return CLUSTER_ERROR
|
|||||||
uint32_t _FAT_fat_linkFreeClusterCleared (PARTITION* partition, uint32_t cluster) {
|
uint32_t _FAT_fat_linkFreeClusterCleared (PARTITION* partition, uint32_t cluster) {
|
||||||
uint32_t newCluster;
|
uint32_t newCluster;
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
uint8_t emptySector[BYTES_PER_READ];
|
uint8_t *emptySector;
|
||||||
|
|
||||||
// Link the cluster
|
// Link the cluster
|
||||||
newCluster = _FAT_fat_linkFreeCluster(partition, cluster);
|
newCluster = _FAT_fat_linkFreeCluster(partition, cluster);
|
||||||
@ -278,14 +279,18 @@ uint32_t _FAT_fat_linkFreeClusterCleared (PARTITION* partition, uint32_t cluster
|
|||||||
return CLUSTER_ERROR;
|
return CLUSTER_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
emptySector = (uint8_t*) _FAT_mem_allocate(partition->bytesPerSector);
|
||||||
|
|
||||||
// Clear all the sectors within the 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++) {
|
for (i = 0; i < partition->sectorsPerCluster; i++) {
|
||||||
_FAT_cache_writeSectors (partition->cache,
|
_FAT_cache_writeSectors (partition->cache,
|
||||||
_FAT_fat_clusterToSector (partition, newCluster) + i,
|
_FAT_fat_clusterToSector (partition, newCluster) + i,
|
||||||
1, emptySector);
|
1, emptySector);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_FAT_mem_free(emptySector);
|
||||||
|
|
||||||
return newCluster;
|
return newCluster;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -40,11 +40,6 @@
|
|||||||
|
|
||||||
sec_t _FAT_startSector;
|
sec_t _FAT_startSector;
|
||||||
|
|
||||||
/*
|
|
||||||
This device name, as known by devkitPro toolchains
|
|
||||||
*/
|
|
||||||
const char* DEVICE_NAME = "fat";
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Data offsets
|
Data offsets
|
||||||
*/
|
*/
|
||||||
@ -110,17 +105,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_SIG1[4] = {'R', 'R', 'a', 'A'};
|
||||||
static const char FS_INFO_SIG2[4] = {'r', 'r', 'A', 'a'};
|
static const char FS_INFO_SIG2[4] = {'r', 'r', 'A', 'a'};
|
||||||
|
|
||||||
|
|
||||||
sec_t FindFirstValidPartition(const DISC_INTERFACE* disc)
|
sec_t FindFirstValidPartition(const DISC_INTERFACE* disc)
|
||||||
{
|
{
|
||||||
uint8_t part_table[16*4];
|
uint8_t part_table[16*4];
|
||||||
uint8_t *ptr;
|
uint8_t *ptr;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
uint8_t sectorBuffer[BYTES_PER_READ] = {0};
|
uint8_t *sectorBuffer = (uint8_t*) _FAT_mem_allocate(MAX_SECTOR_SIZE);
|
||||||
|
if(!sectorBuffer) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
// Read first sector of disc
|
// Read first sector of disc
|
||||||
if (!_FAT_disc_readSectors (disc, 0, 1, sectorBuffer)) {
|
if (!_FAT_disc_readSectors (disc, 0, 1, sectorBuffer)) {
|
||||||
|
_FAT_mem_free(sectorBuffer);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -132,6 +130,7 @@ sec_t FindFirstValidPartition(const DISC_INTERFACE* disc)
|
|||||||
|
|
||||||
if (!memcmp(sectorBuffer + BPB_FAT16_fileSysType, FAT_SIG, sizeof(FAT_SIG)) ||
|
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_lba;
|
return part_lba;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -144,43 +143,61 @@ sec_t FindFirstValidPartition(const DISC_INTERFACE* disc)
|
|||||||
|
|
||||||
for(n=0;n<8;n++) // max 8 logic partitions
|
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) ;
|
part_lba2 = part_lba + next_lba2 + u8array_to_u32(sectorBuffer, 0x1C6) ;
|
||||||
next_lba2 = u8array_to_u32(sectorBuffer, 0x1D6);
|
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)) ||
|
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;
|
return part_lba2;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(next_lba2==0) break;
|
if(next_lba2==0) break;
|
||||||
}
|
}
|
||||||
} else {
|
} 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)) ||
|
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_lba;
|
return part_lba;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
_FAT_mem_free(sectorBuffer);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
PARTITION* _FAT_partition_constructor (const DISC_INTERFACE* disc, uint32_t cacheSize, uint32_t sectorsPerPage, sec_t startSector) {
|
PARTITION* _FAT_partition_constructor (const DISC_INTERFACE* disc, uint32_t cacheSize, uint32_t sectorsPerPage, sec_t startSector) {
|
||||||
PARTITION* partition;
|
PARTITION* partition;
|
||||||
uint8_t sectorBuffer[BYTES_PER_READ] = {0};
|
|
||||||
|
uint8_t *sectorBuffer = (uint8_t*) _FAT_mem_allocate(MAX_SECTOR_SIZE);
|
||||||
|
if(!sectorBuffer) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
// Read first sector of disc
|
// Read first sector of disc
|
||||||
if (!_FAT_disc_readSectors (disc, startSector, 1, sectorBuffer)) {
|
if (!_FAT_disc_readSectors (disc, startSector, 1, sectorBuffer)) {
|
||||||
|
_FAT_mem_free(sectorBuffer);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make sure it is a valid MBR or boot sector
|
// Make sure it is a valid MBR or boot sector
|
||||||
if ( (sectorBuffer[BPB_bootSig_55] != 0x55) || (sectorBuffer[BPB_bootSig_AA] != 0xAA)) {
|
if ( (sectorBuffer[BPB_bootSig_55] != 0x55) || (sectorBuffer[BPB_bootSig_AA] != 0xAA)) {
|
||||||
|
_FAT_mem_free(sectorBuffer);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -195,27 +212,29 @@ PARTITION* _FAT_partition_constructor (const DISC_INTERFACE* disc, uint32_t cach
|
|||||||
} else {
|
} else {
|
||||||
startSector = FindFirstValidPartition(disc);
|
startSector = FindFirstValidPartition(disc);
|
||||||
if (!_FAT_disc_readSectors (disc, startSector, 1, sectorBuffer)) {
|
if (!_FAT_disc_readSectors (disc, startSector, 1, sectorBuffer)) {
|
||||||
|
_FAT_mem_free(sectorBuffer);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_FAT_startSector = startSector;
|
||||||
|
|
||||||
// Now verify that this is indeed a FAT partition
|
// Now verify that this is indeed a FAT partition
|
||||||
if (memcmp(sectorBuffer + BPB_FAT16_fileSysType, FAT_SIG, sizeof(FAT_SIG)) &&
|
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;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
partition = (PARTITION*) _FAT_mem_allocate (sizeof(PARTITION));
|
partition = (PARTITION*) _FAT_mem_allocate (sizeof(PARTITION));
|
||||||
if (partition == NULL) {
|
if (partition == NULL) {
|
||||||
|
_FAT_mem_free(sectorBuffer);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Init the partition lock
|
// Init the partition lock
|
||||||
_FAT_lock_init(&partition->lock);
|
_FAT_lock_init(&partition->lock);
|
||||||
|
|
||||||
_FAT_startSector = startSector;
|
|
||||||
|
|
||||||
if (!memcmp(sectorBuffer + BPB_FAT16_fileSysType, FAT_SIG, sizeof(FAT_SIG)))
|
if (!memcmp(sectorBuffer + BPB_FAT16_fileSysType, FAT_SIG, sizeof(FAT_SIG)))
|
||||||
strncpy(partition->label, (char*)(sectorBuffer + BPB_FAT16_volumeLabel), 11);
|
strncpy(partition->label, (char*)(sectorBuffer + BPB_FAT16_volumeLabel), 11);
|
||||||
else
|
else
|
||||||
@ -236,8 +255,19 @@ PARTITION* _FAT_partition_constructor (const DISC_INTERFACE* disc, uint32_t cach
|
|||||||
partition->numberOfSectors = u8array_to_u32( sectorBuffer, BPB_numSectors);
|
partition->numberOfSectors = u8array_to_u32( sectorBuffer, BPB_numSectors);
|
||||||
}
|
}
|
||||||
|
|
||||||
partition->bytesPerSector = BYTES_PER_READ; // Sector size is redefined to be 512 bytes
|
if(disc->features & FEATURE_WII_USB)
|
||||||
partition->sectorsPerCluster = sectorBuffer[BPB_sectorsPerCluster] * u8array_to_u16(sectorBuffer, BPB_bytesPerSector) / BYTES_PER_READ;
|
partition->bytesPerSector = u8array_to_u16(sectorBuffer, BPB_bytesPerSector);
|
||||||
|
else
|
||||||
|
partition->bytesPerSector = MIN_SECTOR_SIZE;
|
||||||
|
|
||||||
|
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] * u8array_to_u16(sectorBuffer, BPB_bytesPerSector) / partition->bytesPerSector;
|
||||||
partition->bytesPerCluster = partition->bytesPerSector * partition->sectorsPerCluster;
|
partition->bytesPerCluster = partition->bytesPerSector * partition->sectorsPerCluster;
|
||||||
partition->fat.fatStart = startSector + u8array_to_u16(sectorBuffer, BPB_reservedSectors);
|
partition->fat.fatStart = startSector + u8array_to_u16(sectorBuffer, BPB_reservedSectors);
|
||||||
|
|
||||||
@ -278,7 +308,7 @@ PARTITION* _FAT_partition_constructor (const DISC_INTERFACE* disc, uint32_t cach
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Create a cache to use
|
// 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
|
// Set current directory to the root
|
||||||
partition->cwdCluster = partition->rootDirCluster;
|
partition->cwdCluster = partition->rootDirCluster;
|
||||||
@ -292,6 +322,8 @@ PARTITION* _FAT_partition_constructor (const DISC_INTERFACE* disc, uint32_t cach
|
|||||||
|
|
||||||
_FAT_partition_readFSinfo(partition);
|
_FAT_partition_readFSinfo(partition);
|
||||||
|
|
||||||
|
_FAT_mem_free(sectorBuffer);
|
||||||
|
|
||||||
return partition;
|
return partition;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -338,8 +370,11 @@ void _FAT_partition_createFSinfo(PARTITION * partition)
|
|||||||
if(partition->readOnly || partition->filesysType != FS_FAT32)
|
if(partition->readOnly || partition->filesysType != FS_FAT32)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
uint8_t sectorBuffer[BYTES_PER_READ];
|
uint8_t *sectorBuffer = (uint8_t*) _FAT_mem_allocate(partition->bytesPerSector);
|
||||||
memset(sectorBuffer, 0, sizeof(sectorBuffer));
|
if(!sectorBuffer) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
memset(sectorBuffer, 0, partition->bytesPerSector);
|
||||||
|
|
||||||
int i;
|
int i;
|
||||||
for(i = 0; i < 4; ++i)
|
for(i = 0; i < 4; ++i)
|
||||||
@ -356,6 +391,8 @@ void _FAT_partition_createFSinfo(PARTITION * partition)
|
|||||||
sectorBuffer[FSIB_bootSig_AA] = 0xAA;
|
sectorBuffer[FSIB_bootSig_AA] = 0xAA;
|
||||||
|
|
||||||
_FAT_disc_writeSectors (partition->disc, partition->fsInfoSector, 1, sectorBuffer);
|
_FAT_disc_writeSectors (partition->disc, partition->fsInfoSector, 1, sectorBuffer);
|
||||||
|
|
||||||
|
_FAT_mem_free(sectorBuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _FAT_partition_readFSinfo(PARTITION * partition)
|
void _FAT_partition_readFSinfo(PARTITION * partition)
|
||||||
@ -363,24 +400,29 @@ void _FAT_partition_readFSinfo(PARTITION * partition)
|
|||||||
if(partition->filesysType != FS_FAT32)
|
if(partition->filesysType != FS_FAT32)
|
||||||
return;
|
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
|
// Read first sector of disc
|
||||||
if (!_FAT_disc_readSectors (partition->disc, partition->fsInfoSector, 1, sectorBuffer)) {
|
if (!_FAT_disc_readSectors (partition->disc, partition->fsInfoSector, 1, sectorBuffer)) {
|
||||||
|
_FAT_mem_free(sectorBuffer);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(memcmp(sectorBuffer+FSIB_SIG1, FS_INFO_SIG1, 4) != 0 ||
|
if(memcmp(sectorBuffer+FSIB_SIG1, FS_INFO_SIG1, 4) != 0 ||
|
||||||
memcmp(sectorBuffer+FSIB_SIG2, FS_INFO_SIG2, 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!
|
//sector does not yet exist, create one!
|
||||||
_FAT_partition_createFSinfo(partition);
|
_FAT_partition_createFSinfo(partition);
|
||||||
|
_FAT_mem_free(sectorBuffer);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
partition->fat.numberFreeCluster = u8array_to_u32(sectorBuffer, FSIB_numberOfFreeCluster);
|
partition->fat.numberFreeCluster = u8array_to_u32(sectorBuffer, FSIB_numberOfFreeCluster);
|
||||||
partition->fat.numberLastAllocCluster = u8array_to_u32(sectorBuffer, FSIB_numberLastAllocCluster);
|
partition->fat.numberLastAllocCluster = u8array_to_u32(sectorBuffer, FSIB_numberLastAllocCluster);
|
||||||
|
_FAT_mem_free(sectorBuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _FAT_partition_writeFSinfo(PARTITION * partition)
|
void _FAT_partition_writeFSinfo(PARTITION * partition)
|
||||||
@ -388,21 +430,26 @@ void _FAT_partition_writeFSinfo(PARTITION * partition)
|
|||||||
if(partition->filesysType != FS_FAT32)
|
if(partition->filesysType != FS_FAT32)
|
||||||
return;
|
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
|
// Read first sector of disc
|
||||||
if (!_FAT_disc_readSectors (partition->disc, partition->fsInfoSector, 1, sectorBuffer)) {
|
if (!_FAT_disc_readSectors (partition->disc, partition->fsInfoSector, 1, sectorBuffer)) {
|
||||||
|
_FAT_mem_free(sectorBuffer);
|
||||||
return;
|
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;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
u32_to_u8array(sectorBuffer, FSIB_numberOfFreeCluster, partition->fat.numberFreeCluster);
|
u32_to_u8array(sectorBuffer, FSIB_numberOfFreeCluster, partition->fat.numberFreeCluster);
|
||||||
u32_to_u8array(sectorBuffer, FSIB_numberLastAllocCluster, partition->fat.numberLastAllocCluster);
|
u32_to_u8array(sectorBuffer, FSIB_numberLastAllocCluster, partition->fat.numberLastAllocCluster);
|
||||||
|
|
||||||
// Read first sector of disc
|
// Read first sector of disc
|
||||||
if (!_FAT_disc_writeSectors (partition->disc, partition->fsInfoSector, 1, sectorBuffer)) {
|
_FAT_disc_writeSectors (partition->disc, partition->fsInfoSector, 1, sectorBuffer);
|
||||||
return;
|
_FAT_mem_free(sectorBuffer);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -34,8 +34,8 @@
|
|||||||
#include "cache.h"
|
#include "cache.h"
|
||||||
#include "lock.h"
|
#include "lock.h"
|
||||||
|
|
||||||
// Device name
|
#define MIN_SECTOR_SIZE 512
|
||||||
extern const char* DEVICE_NAME;
|
#define MAX_SECTOR_SIZE 4096
|
||||||
|
|
||||||
// Filesystem type
|
// Filesystem type
|
||||||
typedef enum {FS_UNKNOWN, FS_FAT12, FS_FAT16, FS_FAT32} FS_TYPE;
|
typedef enum {FS_UNKNOWN, FS_FAT12, FS_FAT16, FS_FAT32} FS_TYPE;
|
||||||
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user