mirror of
https://github.com/wiidev/usbloadergx.git
synced 2024-11-15 16:05:10 +01:00
Update libfat to 1.1.1 + Ustealth support (Greywolf, Cyan)
This commit is contained in:
parent
1fed6e83f2
commit
910f6f5f22
@ -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)
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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__
|
||||
|
@ -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 <stdint.h>
|
||||
#include <ogc/disc_io.h>
|
||||
|
||||
#if defined(__gamecube__) || defined (__wii__)
|
||||
# include <ogc/disc_io.h>
|
||||
#else
|
||||
# ifdef NDS
|
||||
# include <nds/disc_io.h>
|
||||
# else
|
||||
# include <disc_io.h>
|
||||
# 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
|
||||
|
@ -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;
|
||||
|
@ -31,13 +31,13 @@
|
||||
#define _DIRECTORY_H
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include <sys/syslimits.h>
|
||||
|
||||
#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
|
||||
|
@ -86,10 +86,11 @@ const INTERFACE_ID _FAT_disc_interfaces[] = {
|
||||
|
||||
/* ====================== NDS ====================== */
|
||||
#elif defined (NDS)
|
||||
#include <nds/system.h>
|
||||
#include <nds/arm9/dldi.h>
|
||||
|
||||
static const DISC_INTERFACE* get_io_dsisd (void) {
|
||||
return &__io_dsisd;
|
||||
return isDSiMode() ? &__io_dsisd : NULL;
|
||||
}
|
||||
|
||||
const INTERFACE_ID _FAT_disc_interfaces[] = {
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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.
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
||||
|
@ -30,7 +30,7 @@
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/param.h>
|
||||
#include <limits.h>
|
||||
|
||||
#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
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user