diff --git a/libcustomfat/Makefile b/libcustomfat/Makefile index d68f3bc7..44d825ad 100644 --- a/libcustomfat/Makefile +++ b/libcustomfat/Makefile @@ -5,8 +5,8 @@ endif export TOPDIR := $(CURDIR) export LIBFAT_MAJOR := 1 -export LIBFAT_MINOR := 0 -export LIBFAT_PATCH := 13 +export LIBFAT_MINOR := 1 +export LIBFAT_PATCH := 1 export VERSTRING := $(LIBFAT_MAJOR).$(LIBFAT_MINOR).$(LIBFAT_PATCH) diff --git a/libcustomfat/include/fat.h b/libcustomfat/include/fat.h index 03e83a21..7d828f6e 100644 --- a/libcustomfat/include/fat.h +++ b/libcustomfat/include/fat.h @@ -1,7 +1,7 @@ /* fat.h Simple functionality for startup, mounting and unmounting of FAT-based devices. - + Copyright (c) 2006 - 2012 Michael "Chishm" Chisholm Dave "WinterMute" Murphy @@ -73,7 +73,7 @@ extern bool fatInitDefault (void); /* Mount the device pointed to by interface, and set up a devoptab entry for it as "name:". You can then access the filesystem using "name:/". -This will mount the active partition or the first valid partition on the disc, +This will mount the active partition or the first valid partition on the disc, and will use a cache size optimized for the host system. */ extern bool fatMountSimple (const char* name, const DISC_INTERFACE* interface); @@ -111,7 +111,7 @@ extern void fatGetVolumeLabel (const char* name, char *label); Methods to modify DOS File Attributes */ int FAT_getAttr(const char *file); -int FAT_setAttr(const char *file, int attr ); +int FAT_setAttr(const char *file, uint8_t attr ); #define LIBFAT_FEOS_MULTICWD diff --git a/libcustomfat/include/libfatversion.h b/libcustomfat/include/libfatversion.h index 67a43e59..765ac2f3 100644 --- a/libcustomfat/include/libfatversion.h +++ b/libcustomfat/include/libfatversion.h @@ -2,9 +2,9 @@ #define __LIBFATVERSION_H__ #define _LIBFAT_MAJOR_ 1 -#define _LIBFAT_MINOR_ 0 -#define _LIBFAT_PATCH_ 13 +#define _LIBFAT_MINOR_ 1 +#define _LIBFAT_PATCH_ 1 -#define _LIBFAT_STRING "libFAT Release 1.0.13" +#define _LIBFAT_STRING "libFAT Release 1.1.1" #endif // __LIBFATVERSION_H__ diff --git a/libcustomfat/libogc/include/fat.h b/libcustomfat/libogc/include/fat.h index 31efbe02..7d828f6e 100644 --- a/libcustomfat/libogc/include/fat.h +++ b/libcustomfat/libogc/include/fat.h @@ -1,9 +1,11 @@ /* fat.h Simple functionality for startup, mounting and unmounting of FAT-based devices. - - Copyright (c) 2006 Michael "Chishm" Chisholm - + + Copyright (c) 2006 - 2012 + Michael "Chishm" Chisholm + Dave "WinterMute" Murphy + Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -34,8 +36,26 @@ extern "C" { #endif +#include "libfatversion.h" + +// When compiling for NDS, make sure NDS is defined +#ifndef NDS + #if defined ARM9 || defined ARM7 + #define NDS + #endif +#endif + #include -#include + +#if defined(__gamecube__) || defined (__wii__) +# include +#else +# ifdef NDS +# include +# else +# include +# endif +#endif /* Initialise any inserted block-devices. @@ -53,7 +73,7 @@ extern bool fatInitDefault (void); /* Mount the device pointed to by interface, and set up a devoptab entry for it as "name:". You can then access the filesystem using "name:/". -This will mount the active partition or the first valid partition on the disc, +This will mount the active partition or the first valid partition on the disc, and will use a cache size optimized for the host system. */ extern bool fatMountSimple (const char* name, const DISC_INTERFACE* interface); @@ -79,6 +99,22 @@ Get Volume Label */ extern void fatGetVolumeLabel (const char* name, char *label); +// File attributes +#define ATTR_ARCHIVE 0x20 // Archive +#define ATTR_DIRECTORY 0x10 // Directory +#define ATTR_VOLUME 0x08 // Volume +#define ATTR_SYSTEM 0x04 // System +#define ATTR_HIDDEN 0x02 // Hidden +#define ATTR_READONLY 0x01 // Read only + +/* +Methods to modify DOS File Attributes +*/ +int FAT_getAttr(const char *file); +int FAT_setAttr(const char *file, uint8_t attr ); + +#define LIBFAT_FEOS_MULTICWD + #ifdef __cplusplus } #endif diff --git a/libcustomfat/source/directory.c b/libcustomfat/source/directory.c index 69771b79..65906d84 100644 --- a/libcustomfat/source/directory.c +++ b/libcustomfat/source/directory.c @@ -45,9 +45,6 @@ #define DIR_ENTRY_LAST 0x00 #define DIR_ENTRY_FREE 0xE5 -#define LAST_LFN_POS (19*13) -#define LAST_LFN_POS_CORRECTION (MAX_LFN_LENGTH-15) - typedef unsigned short ucs2_t; // Long file name directory entry @@ -90,9 +87,9 @@ static int _FAT_directory_lfnLength (const char* name) { int ucsLength; const char* tempName = name; - nameLength = strnlen(name, MAX_FILENAME_LENGTH); + nameLength = strnlen(name, NAME_MAX); // Make sure the name is short enough to be valid - if ( nameLength >= MAX_FILENAME_LENGTH) { + if ( nameLength >= NAME_MAX) { return -1; } // Make sure it doesn't contain any invalid characters @@ -101,7 +98,8 @@ static int _FAT_directory_lfnLength (const char* name) { } // Make sure the name doesn't contain any control codes or codes not representable in UCS-2 for (i = 0; i < nameLength; i++) { - if (name[i] < 0x20 || name[i] >= ABOVE_UCS_RANGE) { + unsigned char ch = (unsigned char) name[i]; + if (ch < 0x20 || ch >= ABOVE_UCS_RANGE) { return -1; } } @@ -315,6 +313,7 @@ bool _FAT_directory_getNextEntry (PARTITION* partition, DIR_ENTRY* entry) { while (!found && !notFound) { if (_FAT_directory_incrementDirEntryPosition (partition, &entryEnd, false) == false) { notFound = true; + break; } _FAT_cache_readPartialSector (partition->cache, entryData, @@ -341,12 +340,10 @@ bool _FAT_directory_getNextEntry (PARTITION* partition, DIR_ENTRY* entry) { } if (lfnExists) { lfnPos = ((entryData[LFN_offset_ordinal] & ~LFN_END) - 1) * 13; - if (lfnPos > LAST_LFN_POS) { - // Force it within the buffer. Will corrupt the filename but prevent buffer overflows - lfnPos = LAST_LFN_POS; - } for (i = 0; i < 13; i++) { - lfn[lfnPos + i] = entryData[LFN_offset_table[i]] | (entryData[LFN_offset_table[i]+1] << 8); + if (lfnPos + i < MAX_LFN_LENGTH - 1) { + lfn[lfnPos + i] = entryData[LFN_offset_table[i]] | (entryData[LFN_offset_table[i]+1] << 8); + } } } } else if (entryData[DIR_ENTRY_attributes] & ATTRIB_VOL) { @@ -368,7 +365,7 @@ bool _FAT_directory_getNextEntry (PARTITION* partition, DIR_ENTRY* entry) { } if (lfnExists) { - if (_FAT_directory_ucs2tombs (entry->filename, lfn, MAX_FILENAME_LENGTH) == (size_t)-1) { + if (_FAT_directory_ucs2tombs (entry->filename, lfn, NAME_MAX) == (size_t)-1) { // Failed to convert the file name to UTF-8. Maybe the wrong locale is set? return false; } @@ -409,7 +406,7 @@ bool _FAT_directory_getRootEntry (PARTITION* partition, DIR_ENTRY* entry) { entry->dataEnd = entry->dataStart; - memset (entry->filename, '\0', MAX_FILENAME_LENGTH); + memset (entry->filename, '\0', NAME_MAX); entry->filename[0] = '.'; memset (entry->entryData, 0, DIR_ENTRY_DATA_SIZE); @@ -478,7 +475,7 @@ bool _FAT_directory_entryFromPosition (PARTITION* partition, DIR_ENTRY* entry) { int lfnPos; uint8_t entryData[DIR_ENTRY_DATA_SIZE]; - memset (entry->filename, '\0', MAX_FILENAME_LENGTH); + memset (entry->filename, '\0', NAME_MAX); // Create an empty directory entry to overwrite the old ones with for ( entryStillValid = true, finished = false; @@ -498,11 +495,10 @@ bool _FAT_directory_entryFromPosition (PARTITION* partition, DIR_ENTRY* entry) { } else { // Copy the long file name data lfnPos = ((entryData[LFN_offset_ordinal] & ~LFN_END) - 1) * 13; - if (lfnPos > LAST_LFN_POS) { - lfnPos = LAST_LFN_POS_CORRECTION; - } for (i = 0; i < 13; i++) { - lfn[lfnPos + i] = entryData[LFN_offset_table[i]] | (entryData[LFN_offset_table[i]+1] << 8); + if (lfnPos + i < MAX_LFN_LENGTH - 1) { + lfn[lfnPos + i] = entryData[LFN_offset_table[i]] | (entryData[LFN_offset_table[i]+1] << 8); + } } } } @@ -511,6 +507,7 @@ bool _FAT_directory_entryFromPosition (PARTITION* partition, DIR_ENTRY* entry) { return false; } + entryStart = entry->dataStart; if ((entryStart.cluster == entryEnd.cluster) && (entryStart.sector == entryEnd.sector) && (entryStart.offset == entryEnd.offset)) { @@ -520,7 +517,7 @@ bool _FAT_directory_entryFromPosition (PARTITION* partition, DIR_ENTRY* entry) { } } else { // Encode the long file name into a multibyte string - if (_FAT_directory_ucs2tombs (entry->filename, lfn, MAX_FILENAME_LENGTH) == (size_t)-1) { + if (_FAT_directory_ucs2tombs (entry->filename, lfn, NAME_MAX) == (size_t)-1) { return false; } } @@ -575,7 +572,7 @@ bool _FAT_directory_entryFromPath (PARTITION* partition, DIR_ENTRY* entry, const dirnameLength = strlen(pathPosition); } - if (dirnameLength > MAX_FILENAME_LENGTH) { + if (dirnameLength > NAME_MAX) { // The path is too long to bother with return false; } @@ -593,7 +590,7 @@ bool _FAT_directory_entryFromPath (PARTITION* partition, DIR_ENTRY* entry, const while (foundFile && !found && !notFound) { // It hasn't already found the file // Check if the filename matches - if ((dirnameLength == strnlen(entry->filename, MAX_FILENAME_LENGTH)) + if ((dirnameLength == strnlen(entry->filename, NAME_MAX)) && (_FAT_directory_mbsncasecmp(pathPosition, entry->filename, dirnameLength) == 0)) { found = true; } @@ -705,7 +702,9 @@ static bool _FAT_directory_findEntryGap (PARTITION* partition, DIR_ENTRY* entry, _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; + if (dirEntryRemain == size) { + gapStart = gapEnd; + } -- dirEntryRemain; endOfDirectory = true; } else if (entryData[0] == DIR_ENTRY_FREE) { @@ -760,9 +759,9 @@ static bool _FAT_directory_entryExists (PARTITION* partition, const char* name, char alias[MAX_ALIAS_LENGTH]; size_t dirnameLength; - dirnameLength = strnlen(name, MAX_FILENAME_LENGTH); + dirnameLength = strnlen(name, NAME_MAX); - if (dirnameLength >= MAX_FILENAME_LENGTH) { + if (dirnameLength >= NAME_MAX) { return false; } @@ -771,7 +770,7 @@ static bool _FAT_directory_entryExists (PARTITION* partition, const char* name, while (foundFile) { // It hasn't already found the file // Check if the filename matches - if ((dirnameLength == strnlen(tempEntry.filename, MAX_FILENAME_LENGTH)) + if ((dirnameLength == strnlen(tempEntry.filename, NAME_MAX)) && (_FAT_directory_mbsncasecmp(name, tempEntry.filename, dirnameLength) == 0)) { return true; } @@ -810,7 +809,7 @@ static int _FAT_directory_createAlias (char* alias, const char* lfn) { // Primary portion of alias while (aliasPos < 8 && lfn[lfnPos] != '.' && lfn[lfnPos] != '\0') { - bytesUsed = mbrtowc(&lfnChar, lfn + lfnPos, MAX_FILENAME_LENGTH - lfnPos, &ps); + bytesUsed = mbrtowc(&lfnChar, lfn + lfnPos, NAME_MAX - lfnPos, &ps); if (bytesUsed < 0) { return -1; } @@ -857,7 +856,7 @@ static int _FAT_directory_createAlias (char* alias, const char* lfn) { aliasPos++; memset (&ps, 0, sizeof(ps)); for (aliasExtLen = 0; aliasExtLen < MAX_ALIAS_EXT_LENGTH && *lfnExt != '\0'; aliasExtLen++) { - bytesUsed = mbrtowc(&lfnChar, lfnExt, MAX_FILENAME_LENGTH - lfnPos, &ps); + bytesUsed = mbrtowc(&lfnChar, lfnExt, NAME_MAX - lfnPos, &ps); if (bytesUsed < 0) { return -1; } @@ -912,8 +911,20 @@ bool _FAT_directory_addEntry (PARTITION* partition, DIR_ENTRY* entry, uint32_t d int aliasLen; int lfnLen; + // Remove trailing spaces + for (i = strlen (entry->filename) - 1; (i >= 0) && (entry->filename[i] == ' '); --i) { + entry->filename[i] = '\0'; + } +#if 0 + // Remove leading spaces + for (i = 0; entry->filename[i] == ' '; ++i) ; + if (i > 0) { + memmove (entry->filename, entry->filename + i, strlen (entry->filename + i)); + } +#endif + // Make sure the filename is not 0 length - if (strnlen (entry->filename, MAX_FILENAME_LENGTH) < 1) { + if (strnlen (entry->filename, NAME_MAX) < 1) { return false; } @@ -923,19 +934,9 @@ bool _FAT_directory_addEntry (PARTITION* partition, DIR_ENTRY* entry, uint32_t d return false; } - // Remove trailing spaces - for (i = strlen (entry->filename) - 1; (i > 0) && (entry->filename[i] == ' '); --i) { - entry->filename[i] = '\0'; - } - // Remove leading spaces - for (i = 0; (i < (int)strlen (entry->filename)) && (entry->filename[i] == ' '); ++i) ; - if (i > 0) { - memmove (entry->filename, entry->filename + i, strlen (entry->filename + i)); - } - // Remove junk in filename i = strlen (entry->filename); - memset (entry->filename + i, '\0', MAX_FILENAME_LENGTH - i); + memset (entry->filename + i, '\0', NAME_MAX - i); // Make sure the entry doesn't already exist if (_FAT_directory_entryExists (partition, entry->filename, dirCluster)) { @@ -945,11 +946,11 @@ bool _FAT_directory_addEntry (PARTITION* partition, DIR_ENTRY* entry, uint32_t d // Clear out alias, so we can generate a new one memset (entry->entryData, ' ', 11); - if ( strncmp(entry->filename, ".", MAX_FILENAME_LENGTH) == 0) { + if ( strncmp(entry->filename, ".", NAME_MAX) == 0) { // "." entry entry->entryData[0] = '.'; entrySize = 1; - } else if ( strncmp(entry->filename, "..", MAX_FILENAME_LENGTH) == 0) { + } else if ( strncmp(entry->filename, "..", NAME_MAX) == 0) { // ".." entry entry->entryData[0] = '.'; entry->entryData[1] = '.'; @@ -972,17 +973,15 @@ bool _FAT_directory_addEntry (PARTITION* partition, DIR_ENTRY* entry, uint32_t d _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 = 0; + j = MAX_ALIAS_PRI_LENGTH; // Move extension to last 3 characters - while (alias[i] != '.' && i > 0) i--; - if (i > 0) { - j = MAX_ALIAS_LENGTH - MAX_ALIAS_EXT_LENGTH - 2; // 1 char for '.', one for NUL, 3 for extension - memmove (alias + j, alias + i, strlen(alias) - i); + while (alias[i] != '.' && alias[i] != '\0') i++; + if (i < j) { + memmove (alias + j, alias + i, aliasLen - i + 1); // Pad primary component memset (alias + i, '_', j - i); - alias[MAX_ALIAS_LENGTH-1]=0; } - // Generate numeric tail for (i = 1; i <= MAX_NUMERIC_TAIL; i++) { j = i; diff --git a/libcustomfat/source/directory.h b/libcustomfat/source/directory.h index ac66c781..9f7af8ed 100644 --- a/libcustomfat/source/directory.h +++ b/libcustomfat/source/directory.h @@ -31,13 +31,13 @@ #define _DIRECTORY_H #include +#include #include "common.h" #include "partition.h" #define DIR_ENTRY_DATA_SIZE 0x20 #define MAX_LFN_LENGTH 256 -#define MAX_FILENAME_LENGTH 768 // 256 UCS-2 characters encoded into UTF-8 can use up to 768 UTF-8 chars #define MAX_ALIAS_LENGTH 13 #define LFN_ENTRY_LENGTH 13 #define ALIAS_ENTRY_LENGTH 11 @@ -72,7 +72,7 @@ typedef struct { uint8_t entryData[DIR_ENTRY_DATA_SIZE]; DIR_ENTRY_POSITION dataStart; // Points to the start of the LFN entries of a file, or the alias for no LFN DIR_ENTRY_POSITION dataEnd; // Always points to the file/directory's alias entry - char filename[MAX_FILENAME_LENGTH]; + char filename[NAME_MAX]; } DIR_ENTRY; // Directory entry offsets diff --git a/libcustomfat/source/disc.c b/libcustomfat/source/disc.c index 5f626b6b..d27da2a0 100644 --- a/libcustomfat/source/disc.c +++ b/libcustomfat/source/disc.c @@ -86,10 +86,11 @@ const INTERFACE_ID _FAT_disc_interfaces[] = { /* ====================== NDS ====================== */ #elif defined (NDS) +#include #include static const DISC_INTERFACE* get_io_dsisd (void) { - return &__io_dsisd; + return isDSiMode() ? &__io_dsisd : NULL; } const INTERFACE_ID _FAT_disc_interfaces[] = { diff --git a/libcustomfat/source/fatdir.c b/libcustomfat/source/fatdir.c index fe0e781e..1ef5aec6 100644 --- a/libcustomfat/source/fatdir.c +++ b/libcustomfat/source/fatdir.c @@ -136,7 +136,7 @@ int _FAT_unlink_r (struct _reent *r, const char *path) { if (!_FAT_directory_isDot (&dirContents)) { // The directory had something in it that isn't a reference to itself or it's parent _FAT_unlock(&partition->lock); - r->_errno = EPERM; + r->_errno = ENOTEMPTY; return -1; } nextEntry = _FAT_directory_getNextEntry (partition, &dirContents); @@ -292,7 +292,7 @@ int _FAT_rename_r (struct _reent *r, const char *oldName, const char *newName) { memcpy (&newDirEntry, &oldDirEntry, sizeof(DIR_ENTRY)); // Set the new name - strncpy (newDirEntry.filename, pathEnd, MAX_FILENAME_LENGTH - 1); + strncpy (newDirEntry.filename, pathEnd, NAME_MAX - 1); // Write the new entry if (!_FAT_directory_addEntry (partition, &newDirEntry, dirCluster)) { @@ -381,7 +381,7 @@ int _FAT_mkdir_r (struct _reent *r, const char *path, int mode) { pathEnd += 1; } // Create the entry data - strncpy (dirEntry.filename, pathEnd, MAX_FILENAME_LENGTH - 1); + strncpy (dirEntry.filename, pathEnd, NAME_MAX - 1); memset (dirEntry.entryData, 0, DIR_ENTRY_DATA_SIZE); // Set the creation time and date @@ -465,16 +465,13 @@ int _FAT_statvfs_r (struct _reent *r, const char *path, struct statvfs *buf) _FAT_lock(&partition->lock); - if(memcmp(&buf->f_flag, "SCAN", 4) == 0) - { - //Special command was given to sync the numberFreeCluster - _FAT_partition_createFSinfo(partition); - } - - if(partition->filesysType == FS_FAT32) + if(partition->filesysType == FS_FAT32) { + // Sync FSinfo block + _FAT_partition_readFSinfo(partition); freeClusterCount = partition->fat.numberFreeCluster; - else + } else { freeClusterCount = _FAT_fat_freeClusterCount (partition); + } // FAT clusters = POSIX blocks buf->f_bsize = partition->bytesPerCluster; // File system block size. @@ -496,7 +493,7 @@ int _FAT_statvfs_r (struct _reent *r, const char *path, struct statvfs *buf) buf->f_flag = ST_NOSUID /* No support for ST_ISUID and ST_ISGID file mode bits */ | (partition->readOnly ? ST_RDONLY /* Read only file system */ : 0 ) ; // Maximum filename length. - buf->f_namemax = MAX_FILENAME_LENGTH; + buf->f_namemax = NAME_MAX; _FAT_unlock(&partition->lock); return 0; @@ -588,12 +585,11 @@ int _FAT_dirnext_r (struct _reent *r, DIR_ITER *dirState, char *filename, struct // Make sure there is another file to report on if (! state->validEntry) { _FAT_unlock(&state->partition->lock); - r->_errno = ENOENT; return -1; } // Get the filename - strncpy (filename, state->currentEntry.filename, MAX_FILENAME_LENGTH); + strncpy (filename, state->currentEntry.filename, NAME_MAX); // Get the stats, if requested if (filestat != NULL) { _FAT_directory_entryStat (state->partition, &(state->currentEntry), filestat); diff --git a/libcustomfat/source/fatfile.c b/libcustomfat/source/fatfile.c index 99d0e767..06c2ca7c 100644 --- a/libcustomfat/source/fatfile.c +++ b/libcustomfat/source/fatfile.c @@ -48,6 +48,10 @@ bool _FAT_findEntry(const char *path, DIR_ENTRY *dirEntry) { PARTITION *partition = _FAT_partition_getPartitionFromPath(path); + // Check Partition + if( !partition ) + return false; + // Move the path pointer to the start of the actual path if (strchr (path, ':') != NULL) { path = strchr (path, ':') + 1; @@ -58,22 +62,22 @@ bool _FAT_findEntry(const char *path, DIR_ENTRY *dirEntry) { // Search for the file on the disc return _FAT_directory_entryFromPath (partition, dirEntry, path, NULL); - + } int FAT_getAttr(const char *file) { DIR_ENTRY dirEntry; if (!_FAT_findEntry(file,&dirEntry)) return -1; - + return dirEntry.entryData[DIR_ENTRY_attributes]; } -int FAT_setAttr(const char *file, int attr) { +int FAT_setAttr(const char *file, uint8_t attr) { // Defines... DIR_ENTRY_POSITION entryEnd; PARTITION *partition = NULL; - DIR_ENTRY* dirEntry = NULL; + DIR_ENTRY dirEntry; // Get Partition partition = _FAT_partition_getPartitionFromPath( file ); @@ -81,7 +85,7 @@ int FAT_setAttr(const char *file, int attr) { // Check Partition if( !partition ) return -1; - + // Move the path pointer to the start of the actual path if (strchr (file, ':') != NULL) file = strchr (file, ':') + 1; @@ -89,11 +93,11 @@ int FAT_setAttr(const char *file, int attr) { return -1; // Get DIR_ENTRY - if( !_FAT_directory_entryFromPath (partition, dirEntry, file, NULL) ) + if( !_FAT_directory_entryFromPath (partition, &dirEntry, file, NULL) ) return -1; // Get Entry-End - entryEnd = dirEntry->dataEnd; + entryEnd = dirEntry.dataEnd; // Lock Partition _FAT_lock(&partition->lock); @@ -222,7 +226,7 @@ int _FAT_open_r (struct _reent *r, void *fileStruct, const char *path, int flags pathEnd += 1; } // Create the entry data - strncpy (dirEntry.filename, pathEnd, MAX_FILENAME_LENGTH - 1); + strncpy (dirEntry.filename, pathEnd, NAME_MAX - 1); memset (dirEntry.entryData, 0, DIR_ENTRY_DATA_SIZE); // Set the creation time and date @@ -378,7 +382,7 @@ int _FAT_syncToDisc (FILE_STRUCT* file) { } -int _FAT_close_r (struct _reent *r, int fd) { +int _FAT_close_r (struct _reent *r, void *fd) { FILE_STRUCT* file = (FILE_STRUCT*) fd; int ret = 0; @@ -415,7 +419,7 @@ int _FAT_close_r (struct _reent *r, int fd) { return ret; } -ssize_t _FAT_read_r (struct _reent *r, int fd, char *ptr, size_t len) { +ssize_t _FAT_read_r (struct _reent *r, void *fd, char *ptr, size_t len) { FILE_STRUCT* file = (FILE_STRUCT*) fd; PARTITION* partition; CACHE* cache; @@ -598,7 +602,7 @@ static bool _FAT_check_position_for_next_cluster(struct _reent *r, // do nothing if no more data to write if (remain == 0) return true; if (flagNoError && *flagNoError == false) return false; - if ((remain < 0) || (position->sector > partition->sectorsPerCluster)) { + if (position->sector > partition->sectorsPerCluster) { // invalid arguments - internal error r->_errno = EINVAL; goto err; @@ -709,7 +713,7 @@ static bool _FAT_file_extend_r (struct _reent *r, FILE_STRUCT* file) { return true; } -ssize_t _FAT_write_r (struct _reent *r, int fd, const char *ptr, size_t len) { +ssize_t _FAT_write_r (struct _reent *r, void *fd, const char *ptr, size_t len) { FILE_STRUCT* file = (FILE_STRUCT*) fd; PARTITION* partition; CACHE* cache; @@ -937,7 +941,7 @@ ssize_t _FAT_write_r (struct _reent *r, int fd, const char *ptr, size_t len) { } -off_t _FAT_seek_r (struct _reent *r, int fd, off_t pos, int dir) { +off_t _FAT_seek_r (struct _reent *r, void *fd, off_t pos, int dir) { FILE_STRUCT* file = (FILE_STRUCT*) fd; PARTITION* partition; uint32_t cluster, nextCluster; @@ -1039,7 +1043,7 @@ off_t _FAT_seek_r (struct _reent *r, int fd, off_t pos, int dir) { -int _FAT_fstat_r (struct _reent *r, int fd, struct stat *st) { +int _FAT_fstat_r (struct _reent *r, void *fd, struct stat *st) { FILE_STRUCT* file = (FILE_STRUCT*) fd; PARTITION* partition; DIR_ENTRY fileEntry; @@ -1074,7 +1078,7 @@ int _FAT_fstat_r (struct _reent *r, int fd, struct stat *st) { return 0; } -int _FAT_ftruncate_r (struct _reent *r, int fd, off_t len) { +int _FAT_ftruncate_r (struct _reent *r, void *fd, off_t len) { FILE_STRUCT* file = (FILE_STRUCT*) fd; PARTITION* partition; int ret=0; @@ -1186,7 +1190,7 @@ int _FAT_ftruncate_r (struct _reent *r, int fd, off_t len) { return ret; } -int _FAT_fsync_r (struct _reent *r, int fd) { +int _FAT_fsync_r (struct _reent *r, void *fd) { FILE_STRUCT* file = (FILE_STRUCT*) fd; int ret = 0; diff --git a/libcustomfat/source/fatfile.h b/libcustomfat/source/fatfile.h index 5e4648df..3d9836c0 100644 --- a/libcustomfat/source/fatfile.h +++ b/libcustomfat/source/fatfile.h @@ -71,15 +71,15 @@ typedef struct _FILE_STRUCT FILE_STRUCT; int _FAT_open_r (struct _reent *r, void *fileStruct, const char *path, int flags, int mode); -int _FAT_close_r (struct _reent *r, int fd); +int _FAT_close_r (struct _reent *r, void *fd); -ssize_t _FAT_write_r (struct _reent *r,int fd, const char *ptr, size_t len); +ssize_t _FAT_write_r (struct _reent *r,void *fd, const char *ptr, size_t len); -ssize_t _FAT_read_r (struct _reent *r, int fd, char *ptr, size_t len); +ssize_t _FAT_read_r (struct _reent *r, void *fd, char *ptr, size_t len); -off_t _FAT_seek_r (struct _reent *r, int fd, off_t pos, int dir); +off_t _FAT_seek_r (struct _reent *r, void *fd, off_t pos, int dir); -int _FAT_fstat_r (struct _reent *r, int fd, struct stat *st); +int _FAT_fstat_r (struct _reent *r, void *fd, struct stat *st); int _FAT_stat_r (struct _reent *r, const char *path, struct stat *st); @@ -91,9 +91,9 @@ int _FAT_chdir_r (struct _reent *r, const char *name); int _FAT_rename_r (struct _reent *r, const char *oldName, const char *newName); -int _FAT_ftruncate_r (struct _reent *r, int fd, off_t len); +int _FAT_ftruncate_r (struct _reent *r, void *fd, off_t len); -int _FAT_fsync_r (struct _reent *r, int fd); +int _FAT_fsync_r (struct _reent *r, void *fd); /* Synchronizes the file data to disc. diff --git a/libcustomfat/source/fatfile_frag.c b/libcustomfat/source/fatfile_frag.c index 340b7155..2265f153 100644 --- a/libcustomfat/source/fatfile_frag.c +++ b/libcustomfat/source/fatfile_frag.c @@ -58,6 +58,6 @@ int _FAT_get_fragments (const char *path, _fat_frag_append_t append_fragment, vo out: _FAT_unlock(&partition->lock); - _FAT_close_r(&r, fd); + _FAT_close_r(&r, (void *)fd); return ret; } diff --git a/libcustomfat/source/file_allocation_table.h b/libcustomfat/source/file_allocation_table.h index 560c616d..d9c43614 100644 --- a/libcustomfat/source/file_allocation_table.h +++ b/libcustomfat/source/file_allocation_table.h @@ -36,7 +36,7 @@ #define CLUSTER_EOF_16 0xFFFF #define CLUSTER_EOF 0x0FFFFFFF #define CLUSTER_FREE 0x00000000 -#define CLUSTER_ROOT 0x00000000 +#define CLUSTER_ROOT 0x00000000 #define CLUSTER_FIRST 0x00000002 #define CLUSTER_ERROR 0xFFFFFFFF diff --git a/libcustomfat/source/libfat.c b/libcustomfat/source/libfat.c index aabb3ad6..4d323cae 100644 --- a/libcustomfat/source/libfat.c +++ b/libcustomfat/source/libfat.c @@ -30,7 +30,7 @@ #include #include #include -#include +#include #include "common.h" #include "partition.h" @@ -64,8 +64,9 @@ static const devoptab_t dotab_fat = { _FAT_ftruncate_r, _FAT_fsync_r, NULL, /* Device data */ - NULL, - NULL + NULL, // chmod_r + NULL, // fchmod_r + NULL // rmdir_r }; bool fatMount (const char* name, const DISC_INTERFACE* interface, sec_t startSector, uint32_t cacheSize, uint32_t SectorsPerPage) { @@ -153,6 +154,9 @@ bool fatInit (uint32_t cacheSize, bool setAsDefaultDevice) { i++) { disc = _FAT_disc_interfaces[i].getInterface(); + if (!disc) { + continue; + } if (fatMount (_FAT_disc_interfaces[i].name, disc, 0, cacheSize, DEFAULT_SECTORS_PAGE)) { // The first device to successfully mount is set as the default if (defaultDevice < 0) { @@ -167,7 +171,7 @@ bool fatInit (uint32_t cacheSize, bool setAsDefaultDevice) { } if (setAsDefaultDevice) { - char filePath[MAXPATHLEN * 2]; + char filePath[PATH_MAX]; strcpy (filePath, _FAT_disc_interfaces[defaultDevice].name); strcat (filePath, ":/"); #ifdef ARGV_MAGIC diff --git a/libcustomfat/source/mem_allocate.h b/libcustomfat/source/mem_allocate.h index 622a25ab..7cddbe9f 100644 --- a/libcustomfat/source/mem_allocate.h +++ b/libcustomfat/source/mem_allocate.h @@ -5,7 +5,7 @@ malloc is unavailable 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: @@ -35,16 +35,19 @@ #include "mem2.h" static inline void* _FAT_mem_allocate (size_t size) { - return MEM2_alloc(size); + return MEM2_alloc (size); } static inline void* _FAT_mem_align (size_t size) { - return MEM2_alloc(size); +#ifdef __wii__ + return memalign (32, size); +#else + return MEM2_alloc (size); +#endif } static inline void _FAT_mem_free (void* mem) { - //using normal free, it will decide which free to use (just to be on the safe side) - free(mem); + free (mem); } #endif // _MEM_ALLOCATE_H diff --git a/libcustomfat/source/partition.c b/libcustomfat/source/partition.c index 108776a6..6125cfd7 100644 --- a/libcustomfat/source/partition.c +++ b/libcustomfat/source/partition.c @@ -180,7 +180,7 @@ PARTITION* _FAT_partition_constructor_buf (const DISC_INTERFACE* disc, uint32_t } // 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 && sectorBuffer[BPB_bootSig_AA] != 0xAB)) { return NULL; } @@ -348,6 +348,13 @@ PARTITION* _FAT_partition_getPartitionFromPath (const char* path) { return (PARTITION*)devops->deviceData; } +static void _FAT_updateFS_INFO(PARTITION * partition, uint8_t *sectorBuffer) { + partition->fat.numberFreeCluster = _FAT_fat_freeClusterCount(partition); + u32_to_u8array(sectorBuffer, FSIB_numberOfFreeCluster, partition->fat.numberFreeCluster); + u32_to_u8array(sectorBuffer, FSIB_numberLastAllocCluster, partition->fat.numberLastAllocCluster); + _FAT_disc_writeSectors (partition->disc, partition->fsInfoSector, 1, sectorBuffer); +} + void _FAT_partition_createFSinfo(PARTITION * partition) { if(partition->readOnly || partition->filesysType != FS_FAT32) @@ -364,14 +371,10 @@ void _FAT_partition_createFSinfo(PARTITION * partition) sectorBuffer[FSIB_SIG2+i] = FS_INFO_SIG2[i]; } - partition->fat.numberFreeCluster = _FAT_fat_freeClusterCount(partition); - u32_to_u8array(sectorBuffer, FSIB_numberOfFreeCluster, partition->fat.numberFreeCluster); - u32_to_u8array(sectorBuffer, FSIB_numberLastAllocCluster, partition->fat.numberLastAllocCluster); - sectorBuffer[FSIB_bootSig_55] = 0x55; sectorBuffer[FSIB_bootSig_AA] = 0xAA; - _FAT_disc_writeSectors (partition->disc, partition->fsInfoSector, 1, sectorBuffer); + _FAT_updateFS_INFO(partition,sectorBuffer); _FAT_mem_free(sectorBuffer); } @@ -398,6 +401,10 @@ void _FAT_partition_readFSinfo(PARTITION * partition) _FAT_partition_createFSinfo(partition); } else { partition->fat.numberFreeCluster = u8array_to_u32(sectorBuffer, FSIB_numberOfFreeCluster); + if(partition->fat.numberFreeCluster == 0xffffffff) { + _FAT_updateFS_INFO(partition,sectorBuffer); + partition->fat.numberFreeCluster = u8array_to_u32(sectorBuffer, FSIB_numberOfFreeCluster); + } partition->fat.numberLastAllocCluster = u8array_to_u32(sectorBuffer, FSIB_numberLastAllocCluster); } _FAT_mem_free(sectorBuffer);