Update FatFS R0.13c -> R0.14

This commit is contained in:
d0k3 2019-12-11 00:08:35 +01:00
parent 9e1b5e0be2
commit e446bdbfa5
8 changed files with 807 additions and 470 deletions

View File

@ -328,3 +328,13 @@ R0.13c (October 14, 2018)
Fixed creating a sub-directory in the fragmented sub-directory on the exFAT volume collapses FAT chain of the parent directory. (appeared at R0.12) Fixed creating a sub-directory in the fragmented sub-directory on the exFAT volume collapses FAT chain of the parent directory. (appeared at R0.12)
Fixed f_getcwd() cause output buffer overrun when the buffer has a valid drive number. (appeared at R0.13b) Fixed f_getcwd() cause output buffer overrun when the buffer has a valid drive number. (appeared at R0.13b)
R0.14 (October 14, 2019)
Added support for 64-bit LBA and GUID partition table (FF_LBA64 = 1)
Changed some API functions, f_mkfs() and f_fdisk().
Fixed f_open() function cannot find the file with file name in length of FF_MAX_LFN characters.
Fixed f_readdir() function cannot retrieve long file names in length of FF_MAX_LFN - 1 characters.
Fixed f_readdir() function returns file names with wrong case conversion. (appeared at R0.12)
Fixed f_mkfs() function can fail to create exFAT volume in the second partition. (appeared at R0.12)

View File

@ -1,4 +1,4 @@
FatFs Module Source Files R0.13c FatFs Module Source Files R0.14
FILES FILES

File diff suppressed because it is too large Load Diff

View File

@ -1,8 +1,8 @@
/*----------------------------------------------------------------------------/ /*----------------------------------------------------------------------------/
/ FatFs - Generic FAT Filesystem module R0.13c / / FatFs - Generic FAT Filesystem module R0.14 /
/-----------------------------------------------------------------------------/ /-----------------------------------------------------------------------------/
/ /
/ Copyright (C) 2018, ChaN, all right reserved. / Copyright (C) 2019, ChaN, all right reserved.
/ /
/ FatFs module is an open source software. Redistribution and use of FatFs in / FatFs module is an open source software. Redistribution and use of FatFs in
/ source and binary forms, with or without modification, are permitted provided / source and binary forms, with or without modification, are permitted provided
@ -20,7 +20,7 @@
#ifndef FF_DEFINED #ifndef FF_DEFINED
#define FF_DEFINED 86604 /* Revision ID */ #define FF_DEFINED 86606 /* Revision ID */
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
@ -45,16 +45,16 @@ typedef unsigned __int64 QWORD;
typedef unsigned int UINT; /* int must be 16-bit or 32-bit */ typedef unsigned int UINT; /* int must be 16-bit or 32-bit */
typedef unsigned char BYTE; /* char must be 8-bit */ typedef unsigned char BYTE; /* char must be 8-bit */
typedef uint16_t WORD; /* 16-bit unsigned integer */ typedef uint16_t WORD; /* 16-bit unsigned integer */
typedef uint16_t WCHAR; /* 16-bit unsigned integer */
typedef uint32_t DWORD; /* 32-bit unsigned integer */ typedef uint32_t DWORD; /* 32-bit unsigned integer */
typedef uint64_t QWORD; /* 64-bit unsigned integer */ typedef uint64_t QWORD; /* 64-bit unsigned integer */
typedef WORD WCHAR; /* UTF-16 character type */
#else /* Earlier than C99 */ #else /* Earlier than C99 */
#define FF_INTDEF 1 #define FF_INTDEF 1
typedef unsigned int UINT; /* int must be 16-bit or 32-bit */ typedef unsigned int UINT; /* int must be 16-bit or 32-bit */
typedef unsigned char BYTE; /* char must be 8-bit */ typedef unsigned char BYTE; /* char must be 8-bit */
typedef unsigned short WORD; /* 16-bit unsigned integer */ typedef unsigned short WORD; /* 16-bit unsigned integer */
typedef unsigned short WCHAR; /* 16-bit unsigned integer */
typedef unsigned long DWORD; /* 32-bit unsigned integer */ typedef unsigned long DWORD; /* 32-bit unsigned integer */
typedef WORD WCHAR; /* UTF-16 character type */
#endif #endif
@ -65,7 +65,7 @@ typedef struct {
BYTE pd; /* Physical drive number */ BYTE pd; /* Physical drive number */
BYTE pt; /* Partition: 0:Auto detect, 1-4:Forced partition) */ BYTE pt; /* Partition: 0:Auto detect, 1-4:Forced partition) */
} PARTITION; } PARTITION;
extern PARTITION VolToPart[]; /* Volume - Partition resolution table */ extern PARTITION VolToPart[]; /* Volume - Partition mapping table */
#endif #endif
#if FF_STR_VOLUME_ID #if FF_STR_VOLUME_ID
@ -105,15 +105,24 @@ typedef char TCHAR;
/* Type of file size variables */ /* Type of file size and LBA variables */
#if FF_FS_EXFAT #if FF_FS_EXFAT
#if FF_INTDEF != 2 #if FF_INTDEF != 2
#error exFAT feature wants C99 or later #error exFAT feature wants C99 or later
#endif #endif
typedef QWORD FSIZE_t; typedef QWORD FSIZE_t;
#if FF_LBA64
typedef QWORD LBA_t;
#else #else
typedef DWORD LBA_t;
#endif
#else
#if FF_LBA64
#error exFAT needs to be enabled when enable 64-bit LBA
#endif
typedef DWORD FSIZE_t; typedef DWORD FSIZE_t;
typedef DWORD LBA_t;
#endif #endif
@ -155,14 +164,14 @@ typedef struct {
#endif #endif
DWORD n_fatent; /* Number of FAT entries (number of clusters + 2) */ DWORD n_fatent; /* Number of FAT entries (number of clusters + 2) */
DWORD fsize; /* Size of an FAT [sectors] */ DWORD fsize; /* Size of an FAT [sectors] */
DWORD volbase; /* Volume base sector */ LBA_t volbase; /* Volume base sector */
DWORD fatbase; /* FAT base sector */ LBA_t fatbase; /* FAT base sector */
DWORD dirbase; /* Root directory base sector/cluster */ LBA_t dirbase; /* Root directory base sector/cluster */
DWORD database; /* Data base sector */ LBA_t database; /* Data base sector */
#if FF_FS_EXFAT #if FF_FS_EXFAT
DWORD bitbase; /* Allocation bitmap base sector */ LBA_t bitbase; /* Allocation bitmap base sector */
#endif #endif
DWORD winsect; /* Current sector appearing in the win[] */ LBA_t winsect; /* Current sector appearing in the win[] */
BYTE win[FF_MAX_SS]; /* Disk access window for Directory, FAT (and file data at tiny cfg) */ BYTE win[FF_MAX_SS]; /* Disk access window for Directory, FAT (and file data at tiny cfg) */
} FATFS; } FATFS;
@ -199,9 +208,9 @@ typedef struct {
BYTE err; /* Abort flag (error code) */ BYTE err; /* Abort flag (error code) */
FSIZE_t fptr; /* File read/write pointer (Zeroed on file open) */ FSIZE_t fptr; /* File read/write pointer (Zeroed on file open) */
DWORD clust; /* Current cluster of fpter (invalid when fptr is 0) */ DWORD clust; /* Current cluster of fpter (invalid when fptr is 0) */
DWORD sect; /* Sector number appearing in buf[] (0:invalid) */ LBA_t sect; /* Sector number appearing in buf[] (0:invalid) */
#if !FF_FS_READONLY #if !FF_FS_READONLY
DWORD dir_sect; /* Sector number containing the directory entry (not used at exFAT) */ LBA_t dir_sect; /* Sector number containing the directory entry (not used at exFAT) */
BYTE* dir_ptr; /* Pointer to the directory entry in the win[] (not used at exFAT) */ BYTE* dir_ptr; /* Pointer to the directory entry in the win[] (not used at exFAT) */
#endif #endif
#if FF_USE_FASTSEEK #if FF_USE_FASTSEEK
@ -220,7 +229,7 @@ typedef struct {
FFOBJID obj; /* Object identifier */ FFOBJID obj; /* Object identifier */
DWORD dptr; /* Current read/write offset */ DWORD dptr; /* Current read/write offset */
DWORD clust; /* Current cluster */ DWORD clust; /* Current cluster */
DWORD sect; /* Current sector (0:Read operation has terminated) */ LBA_t sect; /* Current sector (0:Read operation has terminated) */
BYTE* dir; /* Pointer to the directory item in the win[] */ BYTE* dir; /* Pointer to the directory item in the win[] */
BYTE fn[12]; /* SFN (in/out) {body[8],ext[3],status[1]} */ BYTE fn[12]; /* SFN (in/out) {body[8],ext[3],status[1]} */
#if FF_USE_LFN #if FF_USE_LFN
@ -250,6 +259,18 @@ typedef struct {
/* Format parameter structure (MKFS_PARM) */
typedef struct {
BYTE fmt; /* Format option (FM_FAT, FM_FAT32, FM_EXFAT and FM_SFD) */
BYTE n_fat; /* Number of FATs */
UINT align; /* Data area alignment (sector) */
UINT n_root; /* Number of root directory entries */
DWORD au_size; /* Cluster size (byte) */
} MKFS_PARM;
/* File function return code (FRESULT) */ /* File function return code (FRESULT) */
typedef enum { typedef enum {
@ -305,10 +326,10 @@ FRESULT f_getfree (const TCHAR* path, DWORD* nclst, FATFS** fatfs); /* Get numbe
FRESULT f_getlabel (const TCHAR* path, TCHAR* label, DWORD* vsn); /* Get volume label */ FRESULT f_getlabel (const TCHAR* path, TCHAR* label, DWORD* vsn); /* Get volume label */
FRESULT f_setlabel (const TCHAR* label); /* Set volume label */ FRESULT f_setlabel (const TCHAR* label); /* Set volume label */
FRESULT f_forward (FIL* fp, UINT(*func)(const BYTE*,UINT), UINT btf, UINT* bf); /* Forward data to the stream */ FRESULT f_forward (FIL* fp, UINT(*func)(const BYTE*,UINT), UINT btf, UINT* bf); /* Forward data to the stream */
FRESULT f_expand (FIL* fp, FSIZE_t szf, BYTE opt); /* Allocate a contiguous block to the file */ FRESULT f_expand (FIL* fp, FSIZE_t fsz, BYTE opt); /* Allocate a contiguous block to the file */
FRESULT f_mount (FATFS* fs, const TCHAR* path, BYTE opt); /* Mount/Unmount a logical drive */ FRESULT f_mount (FATFS* fs, const TCHAR* path, BYTE opt); /* Mount/Unmount a logical drive */
FRESULT f_mkfs (const TCHAR* path, BYTE opt, DWORD au, void* work, UINT len); /* Create a FAT volume */ FRESULT f_mkfs (const TCHAR* path, const MKFS_PARM* opt, void* work, UINT len); /* Create a FAT volume */
FRESULT f_fdisk (BYTE pdrv, const DWORD* szt, void* work); /* Divide a physical drive into some partitions */ FRESULT f_fdisk (BYTE pdrv, const LBA_t ptbl[], void* work); /* Divide a physical drive into some partitions */
FRESULT f_setcp (WORD cp); /* Set current code page */ FRESULT f_setcp (WORD cp); /* Set current code page */
int f_putc (TCHAR c, FIL* fp); /* Put a character to the file */ int f_putc (TCHAR c, FIL* fp); /* Put a character to the file */
int f_puts (const TCHAR* str, FIL* cp); /* Put a string to the file */ int f_puts (const TCHAR* str, FIL* cp); /* Put a string to the file */

View File

@ -2,7 +2,7 @@
/ FatFs Functional Configurations / FatFs Functional Configurations
/---------------------------------------------------------------------------*/ /---------------------------------------------------------------------------*/
#define FFCONF_DEF 86604 /* Revision ID */ #define FFCONF_DEF 86606 /* Revision ID */
/*---------------------------------------------------------------------------/ /*---------------------------------------------------------------------------/
/ Function Configurations / Function Configurations
@ -110,11 +110,11 @@
/ requiers certain internal working buffer occupies (FF_MAX_LFN + 1) * 2 bytes and / requiers certain internal working buffer occupies (FF_MAX_LFN + 1) * 2 bytes and
/ additional (FF_MAX_LFN + 44) / 15 * 32 bytes when exFAT is enabled. / additional (FF_MAX_LFN + 44) / 15 * 32 bytes when exFAT is enabled.
/ The FF_MAX_LFN defines size of the working buffer in UTF-16 code unit and it can / The FF_MAX_LFN defines size of the working buffer in UTF-16 code unit and it can
/ be in range of 12 to 255. It is recommended to be set 255 to fully support LFN / be in range of 12 to 255. It is recommended to be set it 255 to fully support LFN
/ specification. / specification.
/ When use stack for the working buffer, take care on stack overflow. When use heap / When use stack for the working buffer, take care on stack overflow. When use heap
/ memory for the working buffer, memory management functions, ff_memalloc() and / memory for the working buffer, memory management functions, ff_memalloc() and
/ ff_memfree() in ffsystem.c, need to be added to the project. */ / ff_memfree() exemplified in ffsystem.c, need to be added to the project. */
#define FF_LFN_UNICODE 2 #define FF_LFN_UNICODE 2
@ -200,24 +200,22 @@
/ GET_SECTOR_SIZE command. */ / GET_SECTOR_SIZE command. */
#define FF_LBA64 0
/* This option switches support for 64-bit LBA. (0:Disable or 1:Enable)
/ To enable the 64-bit LBA, also exFAT needs to be enabled. (FF_FS_EXFAT == 1) */
#define FF_MIN_GPT 0x100000000
/* Minimum number of sectors to switch GPT format to create partition in f_mkfs and
/ f_fdisk function. 0x100000000 max. This option has no effect when FF_LBA64 == 0. */
#define FF_USE_TRIM 0 #define FF_USE_TRIM 0
/* This option switches support for ATA-TRIM. (0:Disable or 1:Enable) /* This option switches support for ATA-TRIM. (0:Disable or 1:Enable)
/ To enable Trim function, also CTRL_TRIM command should be implemented to the / To enable Trim function, also CTRL_TRIM command should be implemented to the
/ disk_ioctl() function. */ / disk_ioctl() function. */
#define FF_FS_NOFSINFO 0
/* If you need to know correct free space on the FAT32 volume, set bit 0 of this
/ option, and f_getfree() function at first time after volume mount will force
/ a full FAT scan. Bit 1 controls the use of last allocated cluster number.
/
/ bit0=0: Use free cluster count in the FSINFO if available.
/ bit0=1: Do not trust free cluster count in the FSINFO.
/ bit1=0: Use last allocated cluster number in the FSINFO if available.
/ bit1=1: Do not trust last allocated cluster number in the FSINFO.
*/
/*---------------------------------------------------------------------------/ /*---------------------------------------------------------------------------/
/ System Configurations / System Configurations
@ -232,14 +230,14 @@
#define FF_FS_EXFAT 0 #define FF_FS_EXFAT 0
/* This option switches support for exFAT filesystem. (0:Disable or 1:Enable) /* This option switches support for exFAT filesystem. (0:Disable or 1:Enable)
/ To enable exFAT, also LFN needs to be enabled. / To enable exFAT, also LFN needs to be enabled. (FF_USE_LFN >= 1)
/ Note that enabling exFAT discards ANSI C (C89) compatibility. */ / Note that enabling exFAT discards ANSI C (C89) compatibility. */
#define FF_FS_NORTC 0 #define FF_FS_NORTC 0
#define FF_NORTC_MON 1 #define FF_NORTC_MON 1
#define FF_NORTC_MDAY 1 #define FF_NORTC_MDAY 1
#define FF_NORTC_YEAR 2018 #define FF_NORTC_YEAR 2019
/* The option FF_FS_NORTC switches timestamp functiton. If the system does not have /* The option FF_FS_NORTC switches timestamp functiton. If the system does not have
/ any RTC function or valid timestamp is not needed, set FF_FS_NORTC = 1 to disable / any RTC function or valid timestamp is not needed, set FF_FS_NORTC = 1 to disable
/ the timestamp function. Every object modified by FatFs will have a fixed timestamp / the timestamp function. Every object modified by FatFs will have a fixed timestamp
@ -247,7 +245,19 @@
/ To enable timestamp function (FF_FS_NORTC = 0), get_fattime() function need to be / To enable timestamp function (FF_FS_NORTC = 0), get_fattime() function need to be
/ added to the project to read current time form real-time clock. FF_NORTC_MON, / added to the project to read current time form real-time clock. FF_NORTC_MON,
/ FF_NORTC_MDAY and FF_NORTC_YEAR have no effect. / FF_NORTC_MDAY and FF_NORTC_YEAR have no effect.
/ These options have no effect at read-only configuration (FF_FS_READONLY = 1). */ / These options have no effect in read-only configuration (FF_FS_READONLY = 1). */
#define FF_FS_NOFSINFO 0
/* If you need to know correct free space on the FAT32 volume, set bit 0 of this
/ option, and f_getfree() function at first time after volume mount will force
/ a full FAT scan. Bit 1 controls the use of last allocated cluster number.
/
/ bit0=0: Use free cluster count in the FSINFO if available.
/ bit0=1: Do not trust free cluster count in the FSINFO.
/ bit1=0: Use last allocated cluster number in the FSINFO if available.
/ bit1=1: Do not trust last allocated cluster number in the FSINFO.
*/
#define FF_FS_LOCK 32 #define FF_FS_LOCK 32

View File

@ -1,5 +1,5 @@
/*------------------------------------------------------------------------*/ /*------------------------------------------------------------------------*/
/* Unicode handling functions for FatFs R0.13c */ /* Unicode handling functions for FatFs R0.13+ */
/*------------------------------------------------------------------------*/ /*------------------------------------------------------------------------*/
/* This module will occupy a huge memory in the .const section when the / /* This module will occupy a huge memory in the .const section when the /
/ FatFs is configured for LFN with DBCS. If the system has any Unicode / / FatFs is configured for LFN with DBCS. If the system has any Unicode /
@ -7,7 +7,7 @@
/ that function to avoid silly memory consumption. / / that function to avoid silly memory consumption. /
/-------------------------------------------------------------------------*/ /-------------------------------------------------------------------------*/
/* /*
/ Copyright (C) 2018, ChaN, all right reserved. / Copyright (C) 2014, ChaN, all right reserved.
/ /
/ FatFs module is an open source software. Redistribution and use of FatFs in / FatFs module is an open source software. Redistribution and use of FatFs in
/ source and binary forms, with or without modification, are permitted provided / source and binary forms, with or without modification, are permitted provided
@ -25,11 +25,7 @@
#include "ff.h" #include "ff.h"
#if FF_USE_LFN /* This module will be blanked at non-LFN configuration */ #if FF_USE_LFN /* This module will be blanked if non-LFN configuration */
#if FF_DEFINED != 86604 /* Revision ID */
#error Wrong include file (ff.h).
#endif
#define MERGE2(a, b) a ## b #define MERGE2(a, b) a ## b
#define CVTBL(tbl, cp) MERGE2(tbl, cp) #define CVTBL(tbl, cp) MERGE2(tbl, cp)
@ -15245,7 +15241,7 @@ WCHAR ff_uni2oem ( /* Returns OEM code character, zero on error */
return c; return c;
} }
WCHAR ff_oem2uni ( /* Returns Unicode character, zero on error */ WCHAR ff_oem2uni ( /* Returns Unicode character in UTF-16, zero on error */
WCHAR oem, /* OEM code to be converted */ WCHAR oem, /* OEM code to be converted */
WORD cp /* Code page for the conversion */ WORD cp /* Code page for the conversion */
) )
@ -15312,7 +15308,7 @@ WCHAR ff_uni2oem ( /* Returns OEM code character, zero on error */
} }
WCHAR ff_oem2uni ( /* Returns Unicode character, zero on error */ WCHAR ff_oem2uni ( /* Returns Unicode character in UTF-16, zero on error */
WCHAR oem, /* OEM code to be converted */ WCHAR oem, /* OEM code to be converted */
WORD cp /* Code page for the conversion */ WORD cp /* Code page for the conversion */
) )
@ -15411,7 +15407,7 @@ WCHAR ff_uni2oem ( /* Returns OEM code character, zero on error */
} }
WCHAR ff_oem2uni ( /* Returns Unicode character, zero on error */ WCHAR ff_oem2uni ( /* Returns Unicode character in UTF-16, zero on error */
WCHAR oem, /* OEM code to be converted (DBC if >=0x100) */ WCHAR oem, /* OEM code to be converted (DBC if >=0x100) */
WORD cp /* Code page for the conversion */ WORD cp /* Code page for the conversion */
) )

View File

@ -27,7 +27,7 @@ bool InitExtFS() {
if ((!fs_mounted[i] || !ramdrv_ready) && (i == NORM_FS - 1) && !(GetMountState() & IMG_NAND)) { if ((!fs_mounted[i] || !ramdrv_ready) && (i == NORM_FS - 1) && !(GetMountState() & IMG_NAND)) {
u8* buffer = (u8*) malloc(STD_BUFFER_SIZE); u8* buffer = (u8*) malloc(STD_BUFFER_SIZE);
if (!buffer) bkpt; // whatever, this won't go wrong anyways if (!buffer) bkpt; // whatever, this won't go wrong anyways
f_mkfs(fsname, FM_ANY, 0, buffer, STD_BUFFER_SIZE); // format ramdrive if required f_mkfs(fsname, NULL, buffer, STD_BUFFER_SIZE); // format ramdrive if required
free(buffer); free(buffer);
f_mount(NULL, fsname, 1); f_mount(NULL, fsname, 1);
fs_mounted[i] = (f_mount(fs + i, fsname, 1) == FR_OK); fs_mounted[i] = (f_mount(fs + i, fsname, 1) == FR_OK);

View File

@ -82,12 +82,18 @@ bool FormatSDCard(u64 hidden_mb, u32 cluster_size, const char* label) {
// format the SD card // format the SD card
VolToPart[0].pt = 1; // workaround to prevent FatFS rebuilding the MBR VolToPart[0].pt = 1; // workaround to prevent FatFS rebuilding the MBR
InitSDCardFS(); InitSDCardFS();
UINT c_size = cluster_size;
u8* buffer = (u8*) malloc(STD_BUFFER_SIZE); u8* buffer = (u8*) malloc(STD_BUFFER_SIZE);
if (!buffer) bkpt; // will not happen if (!buffer) bkpt; // will not happen
bool ret = ((f_mkfs("0:", FM_FAT32, c_size, buffer, STD_BUFFER_SIZE) == FR_OK) || MKFS_PARM opt0, opt1;
(f_mkfs("0:", FM_FAT32, 0, buffer, STD_BUFFER_SIZE) == FR_OK)) && opt0.fmt = opt1.fmt = FM_FAT32;
opt0.au_size = cluster_size;
opt1.au_size = 0;
opt0.align = opt1.align = 0;
opt0.n_fat = opt1.n_fat = 1;
opt0.n_root = opt1.n_root = 0;
bool ret = ((f_mkfs("0:", &opt0, buffer, STD_BUFFER_SIZE) == FR_OK) ||
(f_mkfs("0:", &opt1, buffer, STD_BUFFER_SIZE) == FR_OK)) &&
(f_setlabel((label) ? label : "0:GM9SD") == FR_OK); (f_setlabel((label) ? label : "0:GM9SD") == FR_OK);
free(buffer); free(buffer);
@ -105,7 +111,7 @@ bool SetupBonusDrive(void) {
u8* buffer = (u8*) malloc(STD_BUFFER_SIZE); u8* buffer = (u8*) malloc(STD_BUFFER_SIZE);
if (!buffer) bkpt; if (!buffer) bkpt;
bool ret = (f_mkfs("8:", FM_ANY, 0, buffer, STD_BUFFER_SIZE) == FR_OK); bool ret = (f_mkfs("8:", NULL, buffer, STD_BUFFER_SIZE) == FR_OK);
free(buffer); free(buffer);
if (ret) { if (ret) {
@ -786,7 +792,9 @@ bool PathRename(const char* path, const char* newname) {
strncpy(npath + (oldname - path), newname, 255 - (oldname - path)); strncpy(npath + (oldname - path), newname, 255 - (oldname - path));
if (fvx_rename(path, npath) != FR_OK) return false; if (fvx_rename(path, npath) != FR_OK) return false;
if ((fvx_stat(path, NULL) == FR_OK) || (fvx_stat(npath, NULL) != FR_OK)) return false; // safety check if ((strncasecmp(path, npath, 256) != 0) &&
((fvx_stat(path, NULL) == FR_OK) || (fvx_stat(npath, NULL) != FR_OK)))
return false; // safety check
return true; return true;
} }