summaryrefslogtreecommitdiffstatshomepage
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/fatfs/00readme.txt166
-rw-r--r--lib/fatfs/diskio.c12
-rw-r--r--lib/fatfs/ff.c752
-rw-r--r--lib/fatfs/ff.h36
-rw-r--r--lib/fatfs/ffconf_template.h76
-rw-r--r--lib/fatfs/history.txt180
-rw-r--r--lib/fatfs/option/unicode.c2
7 files changed, 647 insertions, 577 deletions
diff --git a/lib/fatfs/00readme.txt b/lib/fatfs/00readme.txt
index b30f7d3879..70994eda7d 100644
--- a/lib/fatfs/00readme.txt
+++ b/lib/fatfs/00readme.txt
@@ -1,163 +1,21 @@
-FatFs Module Source Files R0.10c (C)ChaN, 2014
+FatFs Module Source Files R0.11
FILES
- ffconf.h Configuration file for FatFs module.
- ff.h Common include file for FatFs and application module.
- ff.c FatFs module.
- diskio.h Common include file for FatFs and disk I/O module.
- diskio.c An example of glue function to attach existing disk I/O module to FatFs.
- integer.h Integer type definitions for FatFs.
- option Optional external functions.
+ 00readme.txt This file.
+ history.txt Revision history.
+ ffconf.h Configuration file for FatFs module.
+ ff.h Common include file for FatFs and application module.
+ ff.c FatFs module.
+ diskio.h Common include file for FatFs and disk I/O module.
+ diskio.c An example of glue function to attach existing disk I/O module to FatFs.
+ integer.h Integer type definitions for FatFs.
+ option Optional external functions.
+
Low level disk I/O module is not included in this archive because the FatFs
module is only a generic file system layer and not depend on any specific
storage device. You have to provide a low level disk I/O module that written
- to control your storage device.
-
-
-
-AGREEMENTS
-
- FatFs module is an open source software to implement FAT file system to
- small embedded systems. This is a free software and is opened for education,
- research and commercial developments under license policy of following trems.
-
- Copyright (C) 2014, ChaN, all right reserved.
-
- * The FatFs module is a free software and there is NO WARRANTY.
- * No restriction on use. You can use, modify and redistribute it for
- personal, non-profit or commercial product UNDER YOUR RESPONSIBILITY.
- * Redistributions of source code must retain the above copyright notice.
-
-
-
-REVISION HISTORY
-
- Feb 26, 2006 R0.00 Prototype
-
- Apr 29, 2006 R0.01 First release.
-
- Jun 01, 2006 R0.02 Added FAT12.
- Removed unbuffered mode.
- Fixed a problem on small (<32M) patition.
-
- Jun 10, 2006 R0.02a Added a configuration option _FS_MINIMUM.
-
- Sep 22, 2006 R0.03 Added f_rename.
- Changed option _FS_MINIMUM to _FS_MINIMIZE.
-
- Dec 11, 2006 R0.03a Improved cluster scan algolithm to write files fast.
- Fixed f_mkdir creates incorrect directory on FAT32.
-
- Feb 04, 2007 R0.04 Supported multiple drive system. (FatFs)
- Changed some APIs for multiple drive system.
- Added f_mkfs. (FatFs)
- Added _USE_FAT32 option. (Tiny-FatFs)
-
- Apr 01, 2007 R0.04a Supported multiple partitions on a plysical drive. (FatFs)
- Fixed an endian sensitive code in f_mkfs. (FatFs)
- Added a capability of extending the file size to f_lseek.
- Added minimization level 3.
- Fixed a problem that can collapse a sector when recreate an
- existing file in any sub-directory at non FAT32 cfg. (Tiny-FatFs)
-
- May 05, 2007 R0.04b Added _USE_NTFLAG option.
- Added FSInfo support.
- Fixed some problems corresponds to FAT32. (Tiny-FatFs)
- Fixed DBCS name can result FR_INVALID_NAME.
- Fixed short seek (0 < ofs <= csize) collapses the file object.
-
- Aug 25, 2007 R0.05 Changed arguments of f_read, f_write.
- Changed arguments of f_mkfs. (FatFs)
- Fixed f_mkfs on FAT32 creates incorrect FSInfo. (FatFs)
- Fixed f_mkdir on FAT32 creates incorrect directory. (FatFs)
-
- Feb 03, 2008 R0.05a Added f_truncate().
- Added f_utime().
- Fixed off by one error at FAT sub-type determination.
- Fixed btr in f_read() can be mistruncated.
- Fixed cached sector is not flushed when create and close without write.
-
- Apr 01, 2008 R0.06 Added f_forward(). (Tiny-FatFs)
- Added string functions: fputc(), fputs(), fprintf() and fgets().
- Improved performance of f_lseek() on move to the same or following cluster.
-
- Apr 01, 2009, R0.07 Merged Tiny-FatFs as a buffer configuration option.
- Added long file name support.
- Added multiple code page support.
- Added re-entrancy for multitask operation.
- Added auto cluster size selection to f_mkfs().
- Added rewind option to f_readdir().
- Changed result code of critical errors.
- Renamed string functions to avoid name collision.
-
- Apr 14, 2009, R0.07a Separated out OS dependent code on reentrant cfg.
- Added multiple sector size support.
-
- Jun 21, 2009, R0.07c Fixed f_unlink() may return FR_OK on error.
- Fixed wrong cache control in f_lseek().
- Added relative path feature.
- Added f_chdir().
- Added f_chdrive().
- Added proper case conversion for extended characters.
-
- Nov 03, 2009 R0.07e Separated out configuration options from ff.h to ffconf.h.
- Added a configuration option, _LFN_UNICODE.
- Fixed f_unlink() fails to remove a sub-dir on _FS_RPATH.
- Fixed name matching error on the 13 char boundary.
- Changed f_readdir() to return the SFN with always upper case on non-LFN cfg.
-
- May 15, 2010, R0.08 Added a memory configuration option. (_USE_LFN)
- Added file lock feature. (_FS_SHARE)
- Added fast seek feature. (_USE_FASTSEEK)
- Changed some types on the API, XCHAR->TCHAR.
- Changed fname member in the FILINFO structure on Unicode cfg.
- String functions support UTF-8 encoding files on Unicode cfg.
-
- Aug 16,'10 R0.08a Added f_getcwd(). (_FS_RPATH = 2)
- Added sector erase feature. (_USE_ERASE)
- Moved file lock semaphore table from fs object to the bss.
- Fixed a wrong directory entry is created on non-LFN cfg when the given name contains ';'.
- Fixed f_mkfs() creates wrong FAT32 volume.
-
- Jan 15,'11 R0.08b Fast seek feature is also applied to f_read() and f_write().
- f_lseek() reports required table size on creating CLMP.
- Extended format syntax of f_printf function.
- Ignores duplicated directory separators in given path names.
-
- Sep 06,'11 R0.09 f_mkfs() supports multiple partition to finish the multiple partition feature.
- Added f_fdisk(). (_MULTI_PARTITION = 2)
-
- Aug 27,'12 R0.09a Fixed assertion failure due to OS/2 EA on FAT12/16.
- Changed f_open() and f_opendir() reject null object pointer to avoid crash.
- Changed option name _FS_SHARE to _FS_LOCK.
-
- Jan 23,'13 R0.09b Added f_getlabel() and f_setlabel(). (_USE_LABEL)
-
- Oct 02,'13 R0.10 Added selection of character encoding on the file. (_STRF_ENCODE)
- Added f_closedir().
- Added forced full FAT scan for f_getfree(). (_FS_NOFSINFO)
- Added forced mount feature with changes of f_mount().
- Improved behavior of volume auto detection.
- Improved write throughput of f_puts() and f_printf().
- Changed argument of f_chdrive(), f_mkfs(), disk_read() and disk_write().
- Fixed f_write() can be truncated when the file size is close to 4GB.
- Fixed f_open(), f_mkdir() and f_setlabel() can return incorrect error code.
-
- Jan 15,'14 R0.10a Added arbitrary strings as drive number in the path name. (_STR_VOLUME_ID)
- Added a configuration option of minimum sector size. (_MIN_SS)
- 2nd argument of f_rename() can have a drive number and it will be ignored.
- Fixed f_mount() with forced mount fails when drive number is >= 1.
- Fixed f_close() invalidates the file object without volume lock.
- Fixed f_closedir() returns but the volume lock is left acquired.
- Fixed creation of an entry with LFN fails on too many SFN collisions.
-
- Mar 19,'14 R0.10b Fixed a hard error in the disk I/O layer can collapse the directory entry.
- Fixed LFN entry is not deleted on delete/rename an object with lossy converted SFN.
+ to control the target storage device.
- Nov 09,'14 R0.10c Added a configuration option for the platforms without RTC. (_FS_NORTC)
- Fixed volume label created by Mac OS X cannot be retrieved with f_getlabel().
- Fixed a potential problem of FAT access that can appear on disk error.
- Fixed null pointer dereference on attempting to delete the root direcotry.
diff --git a/lib/fatfs/diskio.c b/lib/fatfs/diskio.c
index 169ae95ead..82200ad0fa 100644
--- a/lib/fatfs/diskio.c
+++ b/lib/fatfs/diskio.c
@@ -8,14 +8,14 @@
/*-----------------------------------------------------------------------*/
#include "diskio.h" /* FatFs lower layer API */
-#include "usbdisk.h" /* Example: USB drive control */
-#include "atadrive.h" /* Example: ATA drive control */
-#include "sdcard.h" /* Example: MMC/SDC contorl */
+#include "usbdisk.h" /* Example: Header file of existing USB MSD control module */
+#include "atadrive.h" /* Example: Header file of existing ATA harddisk control module */
+#include "sdcard.h" /* Example: Header file of existing MMC/SDC contorl module */
/* Definitions of physical drive number for each drive */
-#define ATA 0 /* Example: Map ATA drive to drive number 0 */
-#define MMC 1 /* Example: Map MMC/SD card to drive number 1 */
-#define USB 2 /* Example: Map USB drive to drive number 2 */
+#define ATA 0 /* Example: Map ATA harddisk to physical drive 0 */
+#define MMC 1 /* Example: Map MMC/SD card to physical drive 1 */
+#define USB 2 /* Example: Map USB MSD to physical drive 2 */
/*-----------------------------------------------------------------------*/
diff --git a/lib/fatfs/ff.c b/lib/fatfs/ff.c
index e13391b6c6..774d37a45a 100644
--- a/lib/fatfs/ff.c
+++ b/lib/fatfs/ff.c
@@ -1,139 +1,33 @@
/*----------------------------------------------------------------------------/
-/ FatFs - FAT file system module R0.10c (C)ChaN, 2014
+/ FatFs - FAT file system module R0.11 (C)ChaN, 2015
/-----------------------------------------------------------------------------/
-/ FatFs module is a generic FAT file system module for small embedded systems.
-/ This is a free software that opened for education, research and commercial
-/ developments under license policy of following terms.
+/ FatFs module is a free software that opened under license policy of
+/ following conditions.
/
-/ Copyright (C) 2014, ChaN, all right reserved.
+/ Copyright (C) 2015, ChaN, all right reserved.
/
-/ * The FatFs module is a free software and there is NO WARRANTY.
-/ * No restriction on use. You can use, modify and redistribute it for
-/ personal, non-profit or commercial products UNDER YOUR RESPONSIBILITY.
-/ * Redistributions of source code must retain the above copyright notice.
+/ 1. Redistributions of source code must retain the above copyright notice,
+/ this condition and the following disclaimer.
/
-/-----------------------------------------------------------------------------/
-/ Feb 26,'06 R0.00 Prototype.
-/
-/ Apr 29,'06 R0.01 First stable version.
-/
-/ Jun 01,'06 R0.02 Added FAT12 support.
-/ Removed unbuffered mode.
-/ Fixed a problem on small (<32M) partition.
-/ Jun 10,'06 R0.02a Added a configuration option (_FS_MINIMUM).
-/
-/ Sep 22,'06 R0.03 Added f_rename().
-/ Changed option _FS_MINIMUM to _FS_MINIMIZE.
-/ Dec 11,'06 R0.03a Improved cluster scan algorithm to write files fast.
-/ Fixed f_mkdir() creates incorrect directory on FAT32.
-/
-/ Feb 04,'07 R0.04 Supported multiple drive system.
-/ Changed some interfaces for multiple drive system.
-/ Changed f_mountdrv() to f_mount().
-/ Added f_mkfs().
-/ Apr 01,'07 R0.04a Supported multiple partitions on a physical drive.
-/ Added a capability of extending file size to f_lseek().
-/ Added minimization level 3.
-/ Fixed an endian sensitive code in f_mkfs().
-/ May 05,'07 R0.04b Added a configuration option _USE_NTFLAG.
-/ Added FSINFO support.
-/ Fixed DBCS name can result FR_INVALID_NAME.
-/ Fixed short seek (<= csize) collapses the file object.
-/
-/ Aug 25,'07 R0.05 Changed arguments of f_read(), f_write() and f_mkfs().
-/ Fixed f_mkfs() on FAT32 creates incorrect FSINFO.
-/ Fixed f_mkdir() on FAT32 creates incorrect directory.
-/ Feb 03,'08 R0.05a Added f_truncate() and f_utime().
-/ Fixed off by one error at FAT sub-type determination.
-/ Fixed btr in f_read() can be mistruncated.
-/ Fixed cached sector is not flushed when create and close without write.
-/
-/ Apr 01,'08 R0.06 Added fputc(), fputs(), fprintf() and fgets().
-/ Improved performance of f_lseek() on moving to the same or following cluster.
-/
-/ Apr 01,'09 R0.07 Merged Tiny-FatFs as a configuration option. (_FS_TINY)
-/ Added long file name feature.
-/ Added multiple code page feature.
-/ Added re-entrancy for multitask operation.
-/ Added auto cluster size selection to f_mkfs().
-/ Added rewind option to f_readdir().
-/ Changed result code of critical errors.
-/ Renamed string functions to avoid name collision.
-/ Apr 14,'09 R0.07a Separated out OS dependent code on reentrant cfg.
-/ Added multiple sector size feature.
-/ Jun 21,'09 R0.07c Fixed f_unlink() can return FR_OK on error.
-/ Fixed wrong cache control in f_lseek().
-/ Added relative path feature.
-/ Added f_chdir() and f_chdrive().
-/ Added proper case conversion to extended character.
-/ Nov 03,'09 R0.07e Separated out configuration options from ff.h to ffconf.h.
-/ Fixed f_unlink() fails to remove a sub-directory on _FS_RPATH.
-/ Fixed name matching error on the 13 character boundary.
-/ Added a configuration option, _LFN_UNICODE.
-/ Changed f_readdir() to return the SFN with always upper case on non-LFN cfg.
-/
-/ May 15,'10 R0.08 Added a memory configuration option. (_USE_LFN = 3)
-/ Added file lock feature. (_FS_SHARE)
-/ Added fast seek feature. (_USE_FASTSEEK)
-/ Changed some types on the API, XCHAR->TCHAR.
-/ Changed .fname in the FILINFO structure on Unicode cfg.
-/ String functions support UTF-8 encoding files on Unicode cfg.
-/ Aug 16,'10 R0.08a Added f_getcwd().
-/ Added sector erase feature. (_USE_ERASE)
-/ Moved file lock semaphore table from fs object to the bss.
-/ Fixed a wrong directory entry is created on non-LFN cfg when the given name contains ';'.
-/ Fixed f_mkfs() creates wrong FAT32 volume.
-/ Jan 15,'11 R0.08b Fast seek feature is also applied to f_read() and f_write().
-/ f_lseek() reports required table size on creating CLMP.
-/ Extended format syntax of f_printf().
-/ Ignores duplicated directory separators in given path name.
-/
-/ Sep 06,'11 R0.09 f_mkfs() supports multiple partition to complete the multiple partition feature.
-/ Added f_fdisk().
-/ Aug 27,'12 R0.09a Changed f_open() and f_opendir() reject null object pointer to avoid crash.
-/ Changed option name _FS_SHARE to _FS_LOCK.
-/ Fixed assertion failure due to OS/2 EA on FAT12/16 volume.
-/ Jan 24,'13 R0.09b Added f_setlabel() and f_getlabel().
-/
-/ Oct 02,'13 R0.10 Added selection of character encoding on the file. (_STRF_ENCODE)
-/ Added f_closedir().
-/ Added forced full FAT scan for f_getfree(). (_FS_NOFSINFO)
-/ Added forced mount feature with changes of f_mount().
-/ Improved behavior of volume auto detection.
-/ Improved write throughput of f_puts() and f_printf().
-/ Changed argument of f_chdrive(), f_mkfs(), disk_read() and disk_write().
-/ Fixed f_write() can be truncated when the file size is close to 4GB.
-/ Fixed f_open(), f_mkdir() and f_setlabel() can return incorrect error code.
-/ Jan 15,'14 R0.10a Added arbitrary strings as drive number in the path name. (_STR_VOLUME_ID)
-/ Added a configuration option of minimum sector size. (_MIN_SS)
-/ 2nd argument of f_rename() can have a drive number and it will be ignored.
-/ Fixed f_mount() with forced mount fails when drive number is >= 1.
-/ Fixed f_close() invalidates the file object without volume lock.
-/ Fixed f_closedir() returns but the volume lock is left acquired.
-/ Fixed creation of an entry with LFN fails on too many SFN collisions.
-/ May 19,'14 R0.10b Fixed a hard error in the disk I/O layer can collapse the directory entry.
-/ Fixed LFN entry is not deleted on delete/rename an object with lossy converted SFN.
-/ Nov 09,'14 R0.10c Added a configuration option for the platforms without RTC. (_FS_NORTC)
-/ Fixed volume label created by Mac OS X cannot be retrieved with f_getlabel().
-/ Fixed a potential problem of FAT access that can appear on disk error.
-/ Fixed null pointer dereference on attempting to delete the root direcotry.
-/---------------------------------------------------------------------------*/
-
-#include <string.h>
+/ This software is provided by the copyright holder and contributors "AS IS"
+/ and any warranties related to this software are DISCLAIMED.
+/ The copyright owner or contributors be NOT LIABLE for any damages caused
+/ by use of this software.
+/----------------------------------------------------------------------------*/
+
+#include <string.h> // dpgeorge: needed to use the stdlib versions of memset and memcmp
#include "ff.h" /* Declarations of FatFs API */
#include "diskio.h" /* Declarations of disk I/O functions */
-
-
/*--------------------------------------------------------------------------
Module Private Definitions
---------------------------------------------------------------------------*/
-#if _FATFS != 80376 /* Revision ID */
+#if _FATFS != 32020 /* Revision ID */
#error Wrong include file (ff.h).
#endif
@@ -165,8 +59,11 @@
/* Timestamp feature */
-#if _FS_NORTC
-#define GET_FATTIME() ((DWORD)_NORTC_YEAR << 25 | (DWORD)_NORTC_MON << 21 | (DWORD)_NORTC_MDAY << 16)
+#if _FS_NORTC == 1
+#if _NORTC_YEAR < 1980 || _NORTC_YEAR > 2107 || _NORTC_MON < 1 || _NORTC_MON > 12 || _NORTC_MDAY < 1 || _NORTC_MDAY > 31
+#error Invalid _FS_NORTC settings
+#endif
+#define GET_FATTIME() ((DWORD)(_NORTC_YEAR - 1980) << 25 | (DWORD)_NORTC_MON << 21 | (DWORD)_NORTC_MDAY << 16)
#else
#define GET_FATTIME() get_fattime()
#endif
@@ -470,7 +367,7 @@ typedef struct {
#define DIR_Name 0 /* Short file name (11) */
#define DIR_Attr 11 /* Attribute (1) */
-#define DIR_NTres 12 /* NT flag (1) */
+#define DIR_NTres 12 /* Lower case flag (1) */
#define DIR_CrtTimeTenth 13 /* Created time sub-second (1) */
#define DIR_CrtTime 14 /* Created time (2) */
#define DIR_CrtDate 16 /* Created date (2) */
@@ -484,11 +381,11 @@ typedef struct {
#define LDIR_Attr 11 /* LFN attribute (1) */
#define LDIR_Type 12 /* LFN type (1) */
#define LDIR_Chksum 13 /* Sum of corresponding SFN entry */
-#define LDIR_FstClusLO 26 /* Filled by zero (0) */
-#define SZ_DIR 32 /* Size of a directory entry */
-#define LLE 0x40 /* Last long entry flag in LDIR_Ord */
-#define DDE 0xE5 /* Deleted directory entry mark in DIR_Name[0] */
-#define NDDE 0x05 /* Replacement of the character collides with DDE */
+#define LDIR_FstClusLO 26 /* Must be zero (0) */
+#define SZ_DIRE 32 /* Size of a directory entry */
+#define LLEF 0x40 /* Last long entry flag in LDIR_Ord */
+#define DDEM 0xE5 /* Deleted directory entry mark at DIR_Name[0] */
+#define RDDEM 0x05 /* Replacement of the character collides with DDEM */
@@ -508,8 +405,8 @@ static FATFS *FatFs[_VOLUMES]; /* Pointer to the file system objects (logical dr
static WORD Fsid; /* File system mount ID */
#if _FS_RPATH && _VOLUMES >= 2
-// dpgeorge: changed name and made non-static
-BYTE ff_CurrVol; /* Current drive */
+// dpgeorge: changed name and made public to support our volume names
+BYTE ff_CurrVol; /* Current drive */
#endif
#if _FS_LOCK
@@ -517,7 +414,7 @@ static FILESEM Files[_FS_LOCK]; /* Open object lock semaphores */
#endif
#if _USE_LFN == 0 /* Non LFN feature */
-#define DEF_NAMEBUF BYTE sfn[12]
+#define DEFINE_NAMEBUF BYTE sfn[12]
#define INIT_BUF(dobj) (dobj).fn = sfn
#define FREE_BUF()
#else
@@ -525,16 +422,16 @@ static FILESEM Files[_FS_LOCK]; /* Open object lock semaphores */
#error Wrong _MAX_LFN setting
#endif
#if _USE_LFN == 1 /* LFN feature with static working buffer */
-static WCHAR LfnBuf[_MAX_LFN+1];
-#define DEF_NAMEBUF BYTE sfn[12]
+static WCHAR LfnBuf[_MAX_LFN + 1];
+#define DEFINE_NAMEBUF BYTE sfn[12]
#define INIT_BUF(dobj) { (dobj).fn = sfn; (dobj).lfn = LfnBuf; }
#define FREE_BUF()
#elif _USE_LFN == 2 /* LFN feature with dynamic working buffer on the stack */
-#define DEF_NAMEBUF BYTE sfn[12]; WCHAR lbuf[_MAX_LFN+1]
+#define DEFINE_NAMEBUF BYTE sfn[12]; WCHAR lbuf[_MAX_LFN + 1]
#define INIT_BUF(dobj) { (dobj).fn = sfn; (dobj).lfn = lbuf; }
#define FREE_BUF()
#elif _USE_LFN == 3 /* LFN feature with dynamic working buffer on the heap */
-#define DEF_NAMEBUF BYTE sfn[12]; WCHAR *lfn
+#define DEFINE_NAMEBUF BYTE sfn[12]; WCHAR *lfn
#define INIT_BUF(dobj) { lfn = ff_memalloc((_MAX_LFN + 1) * 2); if (!lfn) LEAVE_FF((dobj).fs, FR_NOT_ENOUGH_CORE); (dobj).lfn = lfn; (dobj).fn = sfn; }
#define FREE_BUF() ff_memfree(lfn)
#else
@@ -571,28 +468,28 @@ static const BYTE ExCvt[] = _EXCVT; /* Upper conversion table for extended chara
/* Copy memory to memory */
static
void mem_cpy (void* dst, const void* src, UINT cnt) {
- BYTE *d = (BYTE*)dst;
- const BYTE *s = (const BYTE*)src;
+ BYTE *d = (BYTE*)dst;
+ const BYTE *s = (const BYTE*)src;
#if _WORD_ACCESS == 1
- while (cnt >= sizeof (int)) {
- *(int*)d = *(int*)s;
- d += sizeof (int); s += sizeof (int);
- cnt -= sizeof (int);
- }
+ while (cnt >= sizeof (int)) {
+ *(int*)d = *(int*)s;
+ d += sizeof (int); s += sizeof (int);
+ cnt -= sizeof (int);
+ }
#endif
- while (cnt--)
- *d++ = *s++;
+ while (cnt--)
+ *d++ = *s++;
}
/* Fill memory */
-#if 0
+#if 0 // dpgeorge: see comment above
static
void mem_set (void* dst, int val, UINT cnt) {
- BYTE *d = (BYTE*)dst;
+ BYTE *d = (BYTE*)dst;
- while (cnt--)
- *d++ = (BYTE)val;
+ while (cnt--)
+ *d++ = (BYTE)val;
}
#else
// use stdlib
@@ -600,14 +497,14 @@ void mem_set (void* dst, int val, UINT cnt) {
#endif
/* Compare memory to memory */
-#if 0
+#if 0 // dpgeorge: see comment above
static
int mem_cmp (const void* dst, const void* src, UINT cnt) {
- const BYTE *d = (const BYTE *)dst, *s = (const BYTE *)src;
- int r = 0;
+ const BYTE *d = (const BYTE *)dst, *s = (const BYTE *)src;
+ int r = 0;
- while (cnt-- && (r = *d++ - *s++) == 0) ;
- return r;
+ while (cnt-- && (r = *d++ - *s++) == 0) ;
+ return r;
}
#else
// use stdlib
@@ -846,11 +743,11 @@ FRESULT sync_fs ( /* FR_OK: successful, FR_DISK_ERR: failed */
if (fs->fs_type == FS_FAT32 && fs->fsi_flag == 1) {
/* Create FSINFO structure */
mem_set(fs->win, 0, SS(fs));
- ST_WORD(fs->win+BS_55AA, 0xAA55);
- ST_DWORD(fs->win+FSI_LeadSig, 0x41615252);
- ST_DWORD(fs->win+FSI_StrucSig, 0x61417272);
- ST_DWORD(fs->win+FSI_Free_Count, fs->free_clust);
- ST_DWORD(fs->win+FSI_Nxt_Free, fs->last_clust);
+ ST_WORD(fs->win + BS_55AA, 0xAA55);
+ ST_DWORD(fs->win + FSI_LeadSig, 0x41615252);
+ ST_DWORD(fs->win + FSI_StrucSig, 0x61417272);
+ ST_DWORD(fs->win + FSI_Free_Count, fs->free_clust);
+ ST_DWORD(fs->win + FSI_Nxt_Free, fs->last_clust);
/* Write it into the FSINFO sector */
fs->winsect = fs->volbase + 1;
disk_write(fs->drv, fs->win, fs->winsect, 1);
@@ -897,7 +794,7 @@ DWORD clust2sect ( /* !=0: Sector number, 0: Failed - invalid cluster# */
static
DWORD get_fat ( /* 0xFFFFFFFF:Disk error, 1:Internal error, 2..0x0FFFFFFF:Cluster status */
FATFS* fs, /* File system object */
- DWORD clst /* FAT item index (cluster#) to get the value */
+ DWORD clst /* FAT index number (cluster number) to get the value */
)
{
UINT wc, bc;
@@ -954,8 +851,8 @@ DWORD get_fat ( /* 0xFFFFFFFF:Disk error, 1:Internal error, 2..0x0FFFFFFF:Cluste
static
FRESULT put_fat (
FATFS* fs, /* File system object */
- DWORD clst, /* FAT item index (cluster#) to be set */
- DWORD val /* New value to mark the cluster */
+ DWORD clst, /* FAT index number (cluster number) to be changed */
+ DWORD val /* New value to be set to the entry */
)
{
UINT bc;
@@ -1181,7 +1078,7 @@ FRESULT dir_sdi (
sect = dp->fs->dirbase;
}
else { /* Dynamic table (root-directory in FAT32 or sub-directory) */
- ic = SS(dp->fs) / SZ_DIR * dp->fs->csize; /* Entries per cluster */
+ ic = SS(dp->fs) / SZ_DIRE * dp->fs->csize; /* Entries per cluster */
while (idx >= ic) { /* Follow cluster chain */
clst = get_fat(dp->fs, clst); /* Get next cluster */
if (clst == 0xFFFFFFFF) return FR_DISK_ERR; /* Disk error */
@@ -1193,8 +1090,8 @@ FRESULT dir_sdi (
}
dp->clust = clst; /* Current cluster# */
if (!sect) return FR_INT_ERR;
- dp->sect = sect + idx / (SS(dp->fs) / SZ_DIR); /* Sector# of the directory entry */
- dp->dir = dp->fs->win + (idx % (SS(dp->fs) / SZ_DIR)) * SZ_DIR; /* Ptr to the entry in the sector */
+ dp->sect = sect + idx / (SS(dp->fs) / SZ_DIRE); /* Sector# of the directory entry */
+ dp->dir = dp->fs->win + (idx % (SS(dp->fs) / SZ_DIRE)) * SZ_DIRE; /* Ptr to the entry in the sector */
return FR_OK;
}
@@ -1214,13 +1111,16 @@ FRESULT dir_next ( /* FR_OK:Succeeded, FR_NO_FILE:End of table, FR_DENIED:Could
{
DWORD clst;
UINT i;
+#if !_FS_READONLY
+ UINT c;
+#endif
i = dp->index + 1;
if (!(i & 0xFFFF) || !dp->sect) /* Report EOT when index has reached 65535 */
return FR_NO_FILE;
- if (!(i % (SS(dp->fs) / SZ_DIR))) { /* Sector changed? */
+ if (!(i % (SS(dp->fs) / SZ_DIRE))) { /* Sector changed? */
dp->sect++; /* Next sector */
if (!dp->clust) { /* Static table */
@@ -1228,13 +1128,12 @@ FRESULT dir_next ( /* FR_OK:Succeeded, FR_NO_FILE:End of table, FR_DENIED:Could
return FR_NO_FILE;
}
else { /* Dynamic table */
- if (((i / (SS(dp->fs) / SZ_DIR)) & (dp->fs->csize - 1)) == 0) { /* Cluster changed? */
+ if (((i / (SS(dp->fs) / SZ_DIRE)) & (dp->fs->csize - 1)) == 0) { /* Cluster changed? */
clst = get_fat(dp->fs, dp->clust); /* Get next cluster */
if (clst <= 1) return FR_INT_ERR;
if (clst == 0xFFFFFFFF) return FR_DISK_ERR;
if (clst >= dp->fs->n_fatent) { /* If it reached end of dynamic table, */
#if !_FS_READONLY
- UINT c;
if (!stretch) return FR_NO_FILE; /* If do not stretch, report EOT */
clst = create_chain(dp->fs, dp->clust); /* Stretch cluster chain */
if (clst == 0) return FR_DENIED; /* No free cluster */
@@ -1262,7 +1161,7 @@ FRESULT dir_next ( /* FR_OK:Succeeded, FR_NO_FILE:End of table, FR_DENIED:Could
}
dp->index = (WORD)i; /* Current index */
- dp->dir = dp->fs->win + (i % (SS(dp->fs) / SZ_DIR)) * SZ_DIR; /* Current entry in the window */
+ dp->dir = dp->fs->win + (i % (SS(dp->fs) / SZ_DIRE)) * SZ_DIRE; /* Current entry in the window */
return FR_OK;
}
@@ -1291,7 +1190,7 @@ FRESULT dir_alloc (
do {
res = move_window(dp->fs, dp->sect);
if (res != FR_OK) break;
- if (dp->dir[0] == DDE || dp->dir[0] == 0) { /* Is it a free entry? */
+ if (dp->dir[0] == DDEM || dp->dir[0] == 0) { /* Is it a free entry? */
if (++n == nent) break; /* A block of contiguous free entries is found */
} else {
n = 0; /* Not a blank entry. Restart to search */
@@ -1319,9 +1218,9 @@ DWORD ld_clust (
{
DWORD cl;
- cl = LD_WORD(dir+DIR_FstClusLO);
+ cl = LD_WORD(dir + DIR_FstClusLO);
if (fs->fs_type == FS_FAT32)
- cl |= (DWORD)LD_WORD(dir+DIR_FstClusHI) << 16;
+ cl |= (DWORD)LD_WORD(dir + DIR_FstClusHI) << 16;
return cl;
}
@@ -1334,8 +1233,8 @@ void st_clust (
DWORD cl /* Value to be set */
)
{
- ST_WORD(dir+DIR_FstClusLO, cl);
- ST_WORD(dir+DIR_FstClusHI, cl >> 16);
+ ST_WORD(dir + DIR_FstClusLO, cl);
+ ST_WORD(dir + DIR_FstClusHI, cl >> 16);
}
#endif
@@ -1360,10 +1259,10 @@ int cmp_lfn ( /* 1:Matched, 0:Not matched */
WCHAR wc, uc;
- i = ((dir[LDIR_Ord] & ~LLE) - 1) * 13; /* Get offset in the LFN buffer */
+ i = ((dir[LDIR_Ord] & ~LLEF) - 1) * 13; /* Get offset in the LFN buffer */
s = 0; wc = 1;
do {
- uc = LD_WORD(dir+LfnOfs[s]); /* Pick an LFN character from the entry */
+ uc = LD_WORD(dir + LfnOfs[s]); /* Pick an LFN character from the entry */
if (wc) { /* Last character has not been processed */
wc = ff_wtoupper(uc); /* Convert it to upper case */
if (i >= _MAX_LFN || wc != ff_wtoupper(lfnbuf[i++])) /* Compare it */
@@ -1373,7 +1272,7 @@ int cmp_lfn ( /* 1:Matched, 0:Not matched */
}
} while (++s < 13); /* Repeat until all characters in the entry are checked */
- if ((dir[LDIR_Ord] & LLE) && wc && lfnbuf[i]) /* Last segment matched but different length */
+ if ((dir[LDIR_Ord] & LLEF) && wc && lfnbuf[i]) /* Last segment matched but different length */
return 0;
return 1; /* The part of LFN matched */
@@ -1395,7 +1294,7 @@ int pick_lfn ( /* 1:Succeeded, 0:Buffer overflow */
s = 0; wc = 1;
do {
- uc = LD_WORD(dir+LfnOfs[s]); /* Pick an LFN character from the entry */
+ uc = LD_WORD(dir + LfnOfs[s]); /* Pick an LFN character from the entry */
if (wc) { /* Last character has not been processed */
if (i >= _MAX_LFN) return 0; /* Buffer overflow? */
lfnbuf[i++] = wc = uc; /* Store it */
@@ -1404,7 +1303,7 @@ int pick_lfn ( /* 1:Succeeded, 0:Buffer overflow */
}
} while (++s < 13); /* Read all character in the entry */
- if (dir[LDIR_Ord] & LLE) { /* Put terminator if it is the last LFN part */
+ if (dir[LDIR_Ord] & LLEF) { /* Put terminator if it is the last LFN part */
if (i >= _MAX_LFN) return 0; /* Buffer overflow? */
lfnbuf[i] = 0;
}
@@ -1429,7 +1328,7 @@ void fit_lfn (
dir[LDIR_Chksum] = sum; /* Set check sum */
dir[LDIR_Attr] = AM_LFN; /* Set attribute. LFN entry */
dir[LDIR_Type] = 0;
- ST_WORD(dir+LDIR_FstClusLO, 0);
+ ST_WORD(dir + LDIR_FstClusLO, 0);
i = (ord - 1) * 13; /* Get offset in the LFN buffer */
s = wc = 0;
@@ -1438,7 +1337,7 @@ void fit_lfn (
ST_WORD(dir+LfnOfs[s], wc); /* Put it */
if (!wc) wc = 0xFFFF; /* Padding characters following last character */
} while (++s < 13);
- if (wc == 0xFFFF || !lfnbuf[i]) ord |= LLE; /* Bottom LFN part is the start of LFN sequence */
+ if (wc == 0xFFFF || !lfnbuf[i]) ord |= LLEF; /* Bottom LFN part is the start of LFN sequence */
dir[LDIR_Ord] = ord; /* Set the LFN order */
}
@@ -1462,14 +1361,14 @@ void gen_numname (
{
BYTE ns[8], c;
UINT i, j;
+ WCHAR wc;
+ DWORD sr;
mem_cpy(dst, src, 11);
if (seq > 5) { /* On many collisions, generate a hash number instead of sequential number */
- WCHAR wc;
- DWORD sr = seq;
-
+ sr = seq;
while (*lfn) { /* Create a CRC */
wc = *lfn++;
for (i = 0; i < 16; i++) {
@@ -1556,14 +1455,14 @@ FRESULT dir_find (
if (c == 0) { res = FR_NO_FILE; break; } /* Reached to end of table */
#if _USE_LFN /* LFN configuration */
a = dir[DIR_Attr] & AM_MASK;
- if (c == DDE || ((a & AM_VOL) && a != AM_LFN)) { /* An entry without valid data */
+ if (c == DDEM || ((a & AM_VOL) && a != AM_LFN)) { /* An entry without valid data */
ord = 0xFF; dp->lfn_idx = 0xFFFF; /* Reset LFN sequence */
} else {
if (a == AM_LFN) { /* An LFN entry is found */
if (dp->lfn) {
- if (c & LLE) { /* Is it start of LFN sequence? */
+ if (c & LLEF) { /* Is it start of LFN sequence? */
sum = dir[LDIR_Chksum];
- c &= ~LLE; ord = c; /* LFN start order */
+ c &= ~LLEF; ord = c; /* LFN start order */
dp->lfn_idx = dp->index; /* Start index of LFN */
}
/* Check validity of the LFN entry and compare it with given name */
@@ -1613,13 +1512,13 @@ FRESULT dir_read (
if (c == 0) { res = FR_NO_FILE; break; } /* Reached to end of table */
a = dir[DIR_Attr] & AM_MASK;
#if _USE_LFN /* LFN configuration */
- if (c == DDE || (!_FS_RPATH && c == '.') || (int)((a & ~AM_ARC) == AM_VOL) != vol) { /* An entry without valid data */
+ if (c == DDEM || (!_FS_RPATH && c == '.') || (int)((a & ~AM_ARC) == AM_VOL) != vol) { /* An entry without valid data */
ord = 0xFF;
} else {
if (a == AM_LFN) { /* An LFN entry is found */
- if (c & LLE) { /* Is it start of LFN sequence? */
+ if (c & LLEF) { /* Is it start of LFN sequence? */
sum = dir[LDIR_Chksum];
- c &= ~LLE; ord = c;
+ c &= ~LLEF; ord = c;
dp->lfn_idx = dp->index;
}
/* Check LFN validity and capture it */
@@ -1631,7 +1530,7 @@ FRESULT dir_read (
}
}
#else /* Non LFN configuration */
- if (c != DDE && (_FS_RPATH || c != '.') && a != AM_LFN && (int)((a & ~AM_ARC) == AM_VOL) == vol) /* Is it a valid entry? */
+ if (c != DDEM && (_FS_RPATH || c != '.') && a != AM_LFN && (int)((a & ~AM_ARC) == AM_VOL) == vol) /* Is it a valid entry? */
break;
#endif
res = dir_next(dp, 0); /* Next entry */
@@ -1709,7 +1608,7 @@ FRESULT dir_register ( /* FR_OK:Successful, FR_DENIED:No free entry or too many
if (res == FR_OK) { /* Set SFN entry */
res = move_window(dp->fs, dp->sect);
if (res == FR_OK) {
- mem_set(dp->dir, 0, SZ_DIR); /* Clean the entry */
+ mem_set(dp->dir, 0, SZ_DIRE); /* Clean the entry */
mem_cpy(dp->dir, dp->fn, 11); /* Put SFN */
#if _USE_LFN
dp->dir[DIR_NTres] = dp->fn[NSFLAG] & (NS_BODY | NS_EXT); /* Put NT flag */
@@ -1744,8 +1643,8 @@ FRESULT dir_remove ( /* FR_OK: Successful, FR_DISK_ERR: A disk error */
do {
res = move_window(dp->fs, dp->sect);
if (res != FR_OK) break;
- mem_set(dp->dir, 0, SZ_DIR); /* Clear and mark the entry "deleted" */
- *dp->dir = DDE;
+ mem_set(dp->dir, 0, SZ_DIRE); /* Clear and mark the entry "deleted" */
+ *dp->dir = DDEM;
dp->fs->wflag = 1;
if (dp->index >= i) break; /* When reached SFN, all entries of the object has been deleted. */
res = dir_next(dp, 0); /* Next entry */
@@ -1758,8 +1657,8 @@ FRESULT dir_remove ( /* FR_OK: Successful, FR_DISK_ERR: A disk error */
if (res == FR_OK) {
res = move_window(dp->fs, dp->sect);
if (res == FR_OK) {
- mem_set(dp->dir, 0, SZ_DIR); /* Clear and mark the entry "deleted" */
- *dp->dir = DDE;
+ mem_set(dp->dir, 0, SZ_DIRE); /* Clear and mark the entry "deleted" */
+ *dp->dir = DDEM;
dp->fs->wflag = 1;
}
}
@@ -1784,18 +1683,20 @@ void get_fileinfo ( /* No return code */
{
UINT i;
TCHAR *p, c;
-
+ BYTE *dir;
+#if _USE_LFN
+ WCHAR w, *lfn;
+#endif
p = fno->fname;
if (dp->sect) { /* Get SFN */
- BYTE *dir = dp->dir;
-
+ dir = dp->dir;
i = 0;
while (i < 11) { /* Copy name body and extension */
c = (TCHAR)dir[i++];
- if (c == ' ') continue; /* Skip padding spaces */
- if (c == NDDE) c = (TCHAR)DDE; /* Restore replaced DDE character */
- if (i == 9) *p++ = '.'; /* Insert a . if extension is exist */
+ if (c == ' ') continue; /* Skip padding spaces */
+ if (c == RDDEM) c = (TCHAR)DDEM; /* Restore replaced DDEM character */
+ if (i == 9) *p++ = '.'; /* Insert a . if extension is exist */
#if _USE_LFN
if (IsUpper(c) && (dir[DIR_NTres] & (i >= 9 ? NS_EXT : NS_BODY)))
c += 0x20; /* To lower */
@@ -1809,16 +1710,14 @@ void get_fileinfo ( /* No return code */
*p++ = c;
}
fno->fattrib = dir[DIR_Attr]; /* Attribute */
- fno->fsize = LD_DWORD(dir+DIR_FileSize); /* Size */
- fno->fdate = LD_WORD(dir+DIR_WrtDate); /* Date */
- fno->ftime = LD_WORD(dir+DIR_WrtTime); /* Time */
+ fno->fsize = LD_DWORD(dir + DIR_FileSize); /* Size */
+ fno->fdate = LD_WORD(dir + DIR_WrtDate); /* Date */
+ fno->ftime = LD_WORD(dir + DIR_WrtTime); /* Time */
}
*p = 0; /* Terminate SFN string by a \0 */
#if _USE_LFN
if (fno->lfname) {
- WCHAR w, *lfn;
-
i = 0; p = fno->lfname;
if (dp->sect && fno->lfsize && dp->lfn_idx != 0xFFFF) { /* Get LFN if available */
lfn = dp->lfn;
@@ -1837,7 +1736,77 @@ void get_fileinfo ( /* No return code */
}
#endif
}
-#endif /* _FS_MINIMIZE <= 1 || _FS_RPATH >= 2*/
+#endif /* _FS_MINIMIZE <= 1 || _FS_RPATH >= 2 */
+
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Pattern matching */
+/*-----------------------------------------------------------------------*/
+#if _USE_FIND && _FS_MINIMIZE <= 1
+static
+WCHAR get_achar ( /* Get a character and advances ptr 1 or 2 */
+ const TCHAR** ptr /* Pointer to pointer to the SBCS/DBCS/Unicode string */
+)
+{
+ WCHAR chr;
+
+#if !_LFN_UNICODE
+ chr = (BYTE)*(*ptr)++; /* Get a byte */
+ if (IsLower(chr)) chr -= 0x20; /* To upper ASCII char */
+ if (IsDBCS1(chr) && IsDBCS2(**ptr)) /* Get DBC 2nd byte if needed */
+ chr = chr << 8 | (BYTE)*(*ptr)++;
+#ifdef _EXCVT
+ if (chr >= 0x80) chr = ExCvt[chr - 0x80]; /* To upper SBCS extended char */
+#endif
+#else
+ chr = ff_wtoupper(*(*ptr)++); /* Get a word and to upper */
+#endif
+ return chr;
+}
+
+
+static
+int pattern_matching ( /* Return value: 0:mismatched, 1:matched */
+ const TCHAR* pat, /* Matching pattern */
+ const TCHAR* nam, /* String to be tested */
+ int skip, /* Number of pre-skip chars (number of ?s) */
+ int inf /* Infinite search (* specified) */
+)
+{
+ const TCHAR *pp, *np;
+ WCHAR pc, nc;
+ int nm, nx;
+
+
+ while (skip--) { /* Pre-skip name chars */
+ if (!get_achar(&nam)) return 0; /* Branch mismatched if less name chars */
+ }
+ if (!*pat && inf) return 1; /* (short circuit) */
+
+ do {
+ pp = pat; np = nam; /* Top of pattern and name to match */
+ for (;;) {
+ if (*pp == '?' || *pp == '*') { /* Wildcard? */
+ nm = nx = 0;
+ do { /* Analyze the wildcard chars */
+ if (*pp++ == '?') nm++; else nx = 1;
+ } while (*pp == '?' || *pp == '*');
+ if (pattern_matching(pp, np, nm, nx)) return 1; /* Test new branch (recurs upto number of wildcard blocks in the pattern) */
+ nc = *np; break; /* Branch mismatched */
+ }
+ pc = get_achar(&pp); /* Get a pattern char */
+ nc = get_achar(&np); /* Get a name char */
+ if (pc != nc) break; /* Branch mismatched? */
+ if (!pc) return 1; /* Branch matched? (matched at end of both strings) */
+ }
+ get_achar(&nam); /* nam++ */
+ } while (inf && nc); /* Retry until end of name if infinite search is specified */
+
+ return 0;
+}
+#endif /* _USE_FIND && _FS_MINIMIZE <= 1 */
@@ -1871,9 +1840,9 @@ FRESULT create_name (
w &= 0xFF;
if (IsDBCS1(w)) { /* Check if it is a DBC 1st byte (always false on SBCS cfg) */
b = (BYTE)p[si++]; /* Get 2nd byte */
+ w = (w << 8) + b; /* Create a DBC */
if (!IsDBCS2(b))
return FR_INVALID_NAME; /* Reject invalid sequence */
- w = (w << 8) + b; /* Create a DBC */
}
w = ff_convert(w, 1); /* Convert ANSI/OEM to Unicode */
if (!w) return FR_INVALID_NAME; /* Reject invalid code */
@@ -1885,8 +1854,8 @@ FRESULT create_name (
*path = &p[si]; /* Return pointer to the next segment */
cf = (w < ' ') ? NS_LAST : 0; /* Set last segment flag if end of path */
#if _FS_RPATH
- if ((di == 1 && lfn[di-1] == '.') || /* Is this a dot entry? */
- (di == 2 && lfn[di-1] == '.' && lfn[di-2] == '.')) {
+ if ((di == 1 && lfn[di - 1] == '.') || /* Is this a dot entry? */
+ (di == 2 && lfn[di - 1] == '.' && lfn[di - 2] == '.')) {
lfn[di] = 0;
for (i = 0; i < 11; i++)
dp->fn[i] = (i < di) ? '.' : ' ';
@@ -1895,7 +1864,7 @@ FRESULT create_name (
}
#endif
while (di) { /* Strip trailing spaces and dots */
- w = lfn[di-1];
+ w = lfn[di - 1];
if (w != ' ' && w != '.') break;
di--;
}
@@ -1937,12 +1906,12 @@ FRESULT create_name (
cf |= NS_LFN; /* Force create LFN entry */
}
- if (_DF1S && w >= 0x100) { /* Double byte character (always false on SBCS cfg) */
+ if (_DF1S && w >= 0x100) { /* DBC (always false at SBCS cfg) */
if (i >= ni - 1) {
cf |= NS_LOSS | NS_LFN; i = ni; continue;
}
dp->fn[i++] = (BYTE)(w >> 8);
- } else { /* Single byte character */
+ } else { /* SBC */
if (!w || chk_chr("+,;=[]", w)) { /* Replace illegal characters for SFN */
w = '_'; cf |= NS_LOSS | NS_LFN;/* Lossy conversion */
} else {
@@ -1958,7 +1927,7 @@ FRESULT create_name (
dp->fn[i++] = (BYTE)w;
}
- if (dp->fn[0] == DDE) dp->fn[0] = NDDE; /* If the first character collides with deleted mark, replace it with 0x05 */
+ if (dp->fn[0] == DDEM) dp->fn[0] = RDDEM; /* If the first character collides with deleted mark, replace it with RDDEM */
if (ni == 8) b <<= 2;
if ((b & 0x0C) == 0x0C || (b & 0x03) == 0x03) /* Create LFN entry when there are composite capitals */
@@ -2020,7 +1989,7 @@ FRESULT create_name (
return FR_INVALID_NAME;
sfn[i++] = c;
sfn[i++] = d;
- } else { /* Single byte code */
+ } else { /* SBC */
if (chk_chr("\"*+,:;<=>\?[]|\x7F", c)) /* Reject illegal chrs for SFN */
return FR_INVALID_NAME;
if (IsUpper(c)) { /* ASCII large capital? */
@@ -2037,7 +2006,7 @@ FRESULT create_name (
c = (c <= ' ') ? NS_LAST : 0; /* Set last segment flag if end of path */
if (!i) return FR_INVALID_NAME; /* Reject nul string */
- if (sfn[0] == DDE) sfn[0] = NDDE; /* When first character collides with DDE, replace it with 0x05 */
+ if (sfn[0] == DDEM) sfn[0] = RDDEM; /* When first character collides with DDEM, replace it with RDDEM */
if (ni == 8) b <<= 2;
if ((b & 0x03) == 0x01) c |= NS_EXT; /* NT flag (Name extension has only small capital) */
@@ -2118,8 +2087,7 @@ FRESULT follow_path ( /* FR_OK(0): successful, !=0: error code */
/* Get logical drive number from path name */
/*-----------------------------------------------------------------------*/
-// dpgeorge: replaced with custom ff_get_ldnumber
-#if 0
+#if 0 // dpgeorge: replaced with custom ff_get_ldnumber
static
int get_ldnumber ( /* Returns logical drive number (-1:invalid drive) */
const TCHAR** path /* Pointer to pointer to the path name */
@@ -2128,6 +2096,12 @@ int get_ldnumber ( /* Returns logical drive number (-1:invalid drive) */
const TCHAR *tp, *tt;
UINT i;
int vol = -1;
+#if _STR_VOLUME_ID /* Find string drive id */
+ static const char* const str[] = {_VOLUME_STRS};
+ const char *sp;
+ char c;
+ TCHAR tc;
+#endif
if (*path) { /* If the pointer is not a null */
@@ -2140,13 +2114,9 @@ int get_ldnumber ( /* Returns logical drive number (-1:invalid drive) */
vol = (int)i;
*path = ++tt;
}
- } else { /* No numeric drive number */
-#if _STR_VOLUME_ID /* Find string drive id */
- static const char* const str[] = {_VOLUME_STRS};
- const char *sp;
- char c;
- TCHAR tc;
-
+ }
+#if _STR_VOLUME_ID
+ else { /* No numeric drive number, find string drive id */
i = 0; tt++;
do {
sp = str[i]; tp = *path;
@@ -2159,8 +2129,8 @@ int get_ldnumber ( /* Returns logical drive number (-1:invalid drive) */
vol = (int)i;
*path = tt;
}
-#endif
}
+#endif
return vol;
}
#if _FS_RPATH && _VOLUMES >= 2
@@ -2171,7 +2141,7 @@ int get_ldnumber ( /* Returns logical drive number (-1:invalid drive) */
}
return vol;
}
-#endif
+#endif // dpgeorge: replaced with custom ff_get_ldnumber
@@ -2215,17 +2185,18 @@ FRESULT find_volume ( /* FR_OK(0): successful, !=0: any error occurred */
BYTE wmode /* !=0: Check write protection for write access */
)
{
- BYTE fmt;
+ BYTE fmt, *pt;
int vol;
DSTATUS stat;
- DWORD bsect, fasize, tsect, sysect, nclst, szbfat;
+ DWORD bsect, fasize, tsect, sysect, nclst, szbfat, br[4];
WORD nrsv;
FATFS *fs;
+ UINT i;
/* Get logical drive number from the path name */
*rfs = 0;
- vol = ff_get_ldnumber(path);
+ vol = ff_get_ldnumber(path); // dpgeorge: custom ff_get_ldnumber
if (vol < 0) return FR_INVALID_DRIVE;
/* Check if the file system object is valid or not */
@@ -2262,11 +2233,8 @@ FRESULT find_volume ( /* FR_OK(0): successful, !=0: any error occurred */
bsect = 0;
fmt = check_fs(fs, bsect); /* Load sector 0 and check if it is an FAT boot sector as SFD */
if (fmt == 1 || (!fmt && (LD2PT(vol)))) { /* Not an FAT boot sector or forced partition number */
- UINT i;
- DWORD br[4];
-
for (i = 0; i < 4; i++) { /* Get partition offset */
- BYTE *pt = fs->win+MBR_Table + i * SZ_PTE;
+ pt = fs->win + MBR_Table + i * SZ_PTE;
br[i] = pt[4] ? LD_DWORD(&pt[8]) : 0;
}
i = LD2PT(vol); /* Partition number: 0:auto, 1-4:forced */
@@ -2281,11 +2249,11 @@ FRESULT find_volume ( /* FR_OK(0): successful, !=0: any error occurred */
/* An FAT volume is found. Following code initializes the file system object */
- if (LD_WORD(fs->win+BPB_BytsPerSec) != SS(fs)) /* (BPB_BytsPerSec must be equal to the physical sector size) */
+ if (LD_WORD(fs->win + BPB_BytsPerSec) != SS(fs)) /* (BPB_BytsPerSec must be equal to the physical sector size) */
return FR_NO_FILESYSTEM;
- fasize = LD_WORD(fs->win+BPB_FATSz16); /* Number of sectors per FAT */
- if (!fasize) fasize = LD_DWORD(fs->win+BPB_FATSz32);
+ fasize = LD_WORD(fs->win + BPB_FATSz16); /* Number of sectors per FAT */
+ if (!fasize) fasize = LD_DWORD(fs->win + BPB_FATSz32);
fs->fsize = fasize;
fs->n_fats = fs->win[BPB_NumFATs]; /* Number of FAT copies */
@@ -2297,18 +2265,18 @@ FRESULT find_volume ( /* FR_OK(0): successful, !=0: any error occurred */
if (!fs->csize || (fs->csize & (fs->csize - 1))) /* (Must be power of 2) */
return FR_NO_FILESYSTEM;
- fs->n_rootdir = LD_WORD(fs->win+BPB_RootEntCnt); /* Number of root directory entries */
- if (fs->n_rootdir % (SS(fs) / SZ_DIR)) /* (Must be sector aligned) */
+ fs->n_rootdir = LD_WORD(fs->win + BPB_RootEntCnt); /* Number of root directory entries */
+ if (fs->n_rootdir % (SS(fs) / SZ_DIRE)) /* (Must be sector aligned) */
return FR_NO_FILESYSTEM;
- tsect = LD_WORD(fs->win+BPB_TotSec16); /* Number of sectors on the volume */
- if (!tsect) tsect = LD_DWORD(fs->win+BPB_TotSec32);
+ tsect = LD_WORD(fs->win + BPB_TotSec16); /* Number of sectors on the volume */
+ if (!tsect) tsect = LD_DWORD(fs->win + BPB_TotSec32);
- nrsv = LD_WORD(fs->win+BPB_RsvdSecCnt); /* Number of reserved sectors */
+ nrsv = LD_WORD(fs->win + BPB_RsvdSecCnt); /* Number of reserved sectors */
if (!nrsv) return FR_NO_FILESYSTEM; /* (Must not be 0) */
/* Determine the FAT sub type */
- sysect = nrsv + fasize + fs->n_rootdir / (SS(fs) / SZ_DIR); /* RSV+FAT+DIR */
+ sysect = nrsv + fasize + fs->n_rootdir / (SS(fs) / SZ_DIRE); /* RSV + FAT + DIR */
if (tsect < sysect) return FR_NO_FILESYSTEM; /* (Invalid volume size) */
nclst = (tsect - sysect) / fs->csize; /* Number of clusters */
if (!nclst) return FR_NO_FILESYSTEM; /* (Invalid volume size) */
@@ -2323,7 +2291,7 @@ FRESULT find_volume ( /* FR_OK(0): successful, !=0: any error occurred */
fs->database = bsect + sysect; /* Data start sector */
if (fmt == FS_FAT32) {
if (fs->n_rootdir) return FR_NO_FILESYSTEM; /* (BPB_RootEntCnt must be 0) */
- fs->dirbase = LD_DWORD(fs->win+BPB_RootClus); /* Root directory start cluster */
+ fs->dirbase = LD_DWORD(fs->win + BPB_RootClus); /* Root directory start cluster */
szbfat = fs->n_fatent * 4; /* (Needed FAT size) */
} else {
if (!fs->n_rootdir) return FR_NO_FILESYSTEM; /* (BPB_RootEntCnt must not be 0) */
@@ -2342,19 +2310,19 @@ FRESULT find_volume ( /* FR_OK(0): successful, !=0: any error occurred */
fs->fsi_flag = 0x80;
#if (_FS_NOFSINFO & 3) != 3
if (fmt == FS_FAT32 /* Enable FSINFO only if FAT32 and BPB_FSInfo is 1 */
- && LD_WORD(fs->win+BPB_FSInfo) == 1
+ && LD_WORD(fs->win + BPB_FSInfo) == 1
&& move_window(fs, bsect + 1) == FR_OK)
{
fs->fsi_flag = 0;
- if (LD_WORD(fs->win+BS_55AA) == 0xAA55 /* Load FSINFO data if available */
- && LD_DWORD(fs->win+FSI_LeadSig) == 0x41615252
- && LD_DWORD(fs->win+FSI_StrucSig) == 0x61417272)
+ if (LD_WORD(fs->win + BS_55AA) == 0xAA55 /* Load FSINFO data if available */
+ && LD_DWORD(fs->win + FSI_LeadSig) == 0x41615252
+ && LD_DWORD(fs->win + FSI_StrucSig) == 0x61417272)
{
#if (_FS_NOFSINFO & 1) == 0
- fs->free_clust = LD_DWORD(fs->win+FSI_Free_Count);
+ fs->free_clust = LD_DWORD(fs->win + FSI_Free_Count);
#endif
#if (_FS_NOFSINFO & 2) == 0
- fs->last_clust = LD_DWORD(fs->win+FSI_Nxt_Free);
+ fs->last_clust = LD_DWORD(fs->win + FSI_Nxt_Free);
#endif
}
}
@@ -2387,14 +2355,11 @@ FRESULT validate ( /* FR_OK(0): The object is valid, !=0: Invalid */
FIL *fil = (FIL*)obj; /* Assuming offset of .fs and .id in the FIL/DIR structure is identical */
- if (!fil || !fil->fs || !fil->fs->fs_type || fil->fs->id != fil->id)
+ if (!fil || !fil->fs || !fil->fs->fs_type || fil->fs->id != fil->id || (disk_status(fil->fs->drv) & STA_NOINIT))
return FR_INVALID_OBJECT;
ENTER_FF(fil->fs); /* Lock file system */
- if (disk_status(fil->fs->drv) & STA_NOINIT)
- return FR_NOT_READY;
-
return FR_OK;
}
@@ -2425,7 +2390,7 @@ FRESULT f_mount (
const TCHAR *rp = path;
- vol = ff_get_ldnumber(&rp);
+ vol = ff_get_ldnumber(&rp); // dpgeorge: custom ff_get_ldnumber
if (vol < 0) return FR_INVALID_DRIVE;
cfs = FatFs[vol]; /* Pointer to fs object */
@@ -2469,7 +2434,10 @@ FRESULT f_open (
FRESULT res;
DIR dj;
BYTE *dir;
- DEF_NAMEBUF;
+ DEFINE_NAMEBUF;
+#if !_FS_READONLY
+ DWORD dw, cl;
+#endif
if (!fp) return FR_INVALID_OBJECT;
@@ -2498,8 +2466,6 @@ FRESULT f_open (
}
/* Create or Open a file */
if (mode & (FA_CREATE_ALWAYS | FA_OPEN_ALWAYS | FA_CREATE_NEW)) {
- DWORD dw, cl;
-
if (res != FR_OK) { /* No file, create new */
if (res == FR_NO_FILE) /* There is no file to open, create a new entry */
#if _FS_LOCK
@@ -2520,9 +2486,9 @@ FRESULT f_open (
}
if (res == FR_OK && (mode & FA_CREATE_ALWAYS)) { /* Truncate it if overwrite mode */
dw = GET_FATTIME(); /* Created time */
- ST_DWORD(dir+DIR_CrtTime, dw);
+ ST_DWORD(dir + DIR_CrtTime, dw);
dir[DIR_Attr] = 0; /* Reset attribute */
- ST_DWORD(dir+DIR_FileSize, 0); /* size = 0 */
+ ST_DWORD(dir + DIR_FileSize, 0);/* size = 0 */
cl = ld_clust(dj.fs, dir); /* Get start cluster */
st_clust(dir, 0); /* cluster = 0 */
dj.fs->wflag = 1;
@@ -2574,7 +2540,7 @@ FRESULT f_open (
fp->flag = mode; /* File access mode */
fp->err = 0; /* Clear error flag */
fp->sclust = ld_clust(dj.fs, dir); /* File start cluster */
- fp->fsize = LD_DWORD(dir+DIR_FileSize); /* File size */
+ fp->fsize = LD_DWORD(dir + DIR_FileSize); /* File size */
fp->fptr = 0; /* File pointer */
fp->dsect = 0;
#if _USE_FASTSEEK
@@ -2843,11 +2809,11 @@ FRESULT f_sync (
if (res == FR_OK) {
dir = fp->dir_ptr;
dir[DIR_Attr] |= AM_ARC; /* Set archive bit */
- ST_DWORD(dir+DIR_FileSize, fp->fsize); /* Update file size */
+ ST_DWORD(dir + DIR_FileSize, fp->fsize); /* Update file size */
st_clust(dir, fp->sclust); /* Update start cluster */
tm = GET_FATTIME(); /* Update updated time */
- ST_DWORD(dir+DIR_WrtTime, tm);
- ST_WORD(dir+DIR_LstAccDate, 0);
+ ST_DWORD(dir + DIR_WrtTime, tm);
+ ST_WORD(dir + DIR_LstAccDate, 0);
fp->flag &= ~FA__WRITTEN;
fp->fs->wflag = 1;
res = sync_fs(fp->fs);
@@ -2913,10 +2879,10 @@ FRESULT f_chdrive (
int vol;
- vol = ff_get_ldnumber(&path);
+ vol = ff_get_ldnumber(&path); // dpgeorge: custom ff_get_ldnumber
if (vol < 0) return FR_INVALID_DRIVE;
- ff_CurrVol = (BYTE)vol;
+ ff_CurrVol = (BYTE)vol; // dpgeorge: custom ff_get_ldnumber
return FR_OK;
}
@@ -2929,7 +2895,7 @@ FRESULT f_chdir (
{
FRESULT res;
DIR dj;
- DEF_NAMEBUF;
+ DEFINE_NAMEBUF;
/* Get logical drive number */
@@ -2967,7 +2933,7 @@ FRESULT f_getcwd (
DWORD ccl;
TCHAR *tp;
FILINFO fno;
- DEF_NAMEBUF;
+ DEFINE_NAMEBUF;
*buff = 0;
@@ -3016,7 +2982,7 @@ FRESULT f_getcwd (
#if 0
*tp++ = '0' + CurrVol; /* Put drive number */
*tp++ = ':';
- #else
+ #else
ff_get_volname(ff_CurrVol, &tp);
#endif
#endif
@@ -3053,6 +3019,10 @@ FRESULT f_lseek (
)
{
FRESULT res;
+ DWORD clst, bcs, nsect, ifptr;
+#if _USE_FASTSEEK
+ DWORD cl, pcl, ncl, tcl, dsc, tlen, ulen, *tbl;
+#endif
res = validate(fp); /* Check validity of the object */
@@ -3062,8 +3032,6 @@ FRESULT f_lseek (
#if _USE_FASTSEEK
if (fp->cltbl) { /* Fast seek */
- DWORD cl, pcl, ncl, tcl, dsc, tlen, ulen, *tbl;
-
if (ofs == CREATE_LINKMAP) { /* Create CLMT */
tbl = fp->cltbl;
tlen = *tbl++; ulen = 2; /* Given table size and required table size */
@@ -3119,8 +3087,6 @@ FRESULT f_lseek (
/* Normal Seek */
{
- DWORD clst, bcs, nsect, ifptr;
-
if (ofs > fp->fsize /* In read-only mode, clip offset with the file size */
#if !_FS_READONLY
&& !(fp->flag & FA_WRITE)
@@ -3212,7 +3178,7 @@ FRESULT f_opendir (
{
FRESULT res;
FATFS* fs;
- DEF_NAMEBUF;
+ DEFINE_NAMEBUF;
if (!dp) return FR_INVALID_OBJECT;
@@ -3299,7 +3265,7 @@ FRESULT f_readdir (
)
{
FRESULT res;
- DEF_NAMEBUF;
+ DEFINE_NAMEBUF;
res = validate(dp); /* Check validity of the object */
@@ -3330,6 +3296,58 @@ FRESULT f_readdir (
+#if _USE_FIND
+/*-----------------------------------------------------------------------*/
+/* Find next file */
+/*-----------------------------------------------------------------------*/
+
+FRESULT f_findnext (
+ DIR* dp, /* Pointer to the open directory object */
+ FILINFO* fno /* Pointer to the file information structure */
+)
+{
+ FRESULT res;
+
+
+ for (;;) {
+ res = f_readdir(dp, fno); /* Get a directory item */
+ if (res != FR_OK || !fno || !fno->fname[0]) break; /* Terminate if any error or end of directory */
+#if _USE_LFN
+ if (fno->lfname && pattern_matching(dp->pat, fno->lfname, 0, 0)) break; /* Test for LFN if exist */
+#endif
+ if (pattern_matching(dp->pat, fno->fname, 0, 0)) break; /* Test for SFN */
+ }
+ return res;
+
+}
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Find first file */
+/*-----------------------------------------------------------------------*/
+
+FRESULT f_findfirst (
+ DIR* dp, /* Pointer to the blank directory object */
+ FILINFO* fno, /* Pointer to the file information structure */
+ const TCHAR* path, /* Pointer to the directory to open */
+ const TCHAR* pattern /* Pointer to the matching pattern */
+)
+{
+ FRESULT res;
+
+
+ dp->pat = pattern; /* Save pointer to pattern string */
+ res = f_opendir(dp, path); /* Open the target directory */
+ if (res == FR_OK)
+ res = f_findnext(dp, fno); /* Find the first item */
+ return res;
+}
+
+#endif /* _USE_FIND */
+
+
+
#if _FS_MINIMIZE == 0
/*-----------------------------------------------------------------------*/
/* Get File Status */
@@ -3342,7 +3360,7 @@ FRESULT f_stat (
{
FRESULT res;
DIR dj;
- DEF_NAMEBUF;
+ DEFINE_NAMEBUF;
/* Get logical drive number */
@@ -3501,7 +3519,7 @@ FRESULT f_unlink (
DIR dj, sdj;
BYTE *dir;
DWORD dclst = 0;
- DEF_NAMEBUF;
+ DEFINE_NAMEBUF;
/* Get logical drive number */
@@ -3522,22 +3540,23 @@ FRESULT f_unlink (
if (dir[DIR_Attr] & AM_RDO)
res = FR_DENIED; /* Cannot remove R/O object */
}
- if (res == FR_OK && (dir[DIR_Attr] & AM_DIR)) { /* Is it a sub-dir? */
+ if (res == FR_OK) {
dclst = ld_clust(dj.fs, dir);
- if (!dclst) {
- res = FR_INT_ERR;
- } else { /* Make sure the sub-directory is empty */
- mem_cpy(&sdj, &dj, sizeof (DIR));
- sdj.sclust = dclst;
- res = dir_sdi(&sdj, 2); /* Exclude dot entries */
- if (res == FR_OK) {
- res = dir_read(&sdj, 0); /* Read an item */
- if (res == FR_OK /* Not empty directory */
+ if (dclst && (dir[DIR_Attr] & AM_DIR)) { /* Is it a sub-directory ? */
#if _FS_RPATH
- || dclst == dj.fs->cdir /* or current directory */
+ if (dclst == dj.fs->cdir) { /* Is it the current directory? */
+ res = FR_DENIED;
+ } else
#endif
- ) res = FR_DENIED;
- if (res == FR_NO_FILE) res = FR_OK; /* It is empty */
+ {
+ mem_cpy(&sdj, &dj, sizeof (DIR)); /* Open the sub-directory */
+ sdj.sclust = dclst;
+ res = dir_sdi(&sdj, 2);
+ if (res == FR_OK) {
+ res = dir_read(&sdj, 0); /* Read an item (excluding dot entries) */
+ if (res == FR_OK) res = FR_DENIED; /* Not empty? (cannot remove) */
+ if (res == FR_NO_FILE) res = FR_OK; /* Empty? (can remove) */
+ }
}
}
}
@@ -3569,7 +3588,7 @@ FRESULT f_mkdir (
DIR dj;
BYTE *dir, n;
DWORD dsc, dcl, pcl, tm = GET_FATTIME();
- DEF_NAMEBUF;
+ DEFINE_NAMEBUF;
/* Get logical drive number */
@@ -3592,16 +3611,16 @@ FRESULT f_mkdir (
dsc = clust2sect(dj.fs, dcl);
dir = dj.fs->win;
mem_set(dir, 0, SS(dj.fs));
- mem_set(dir+DIR_Name, ' ', 11); /* Create "." entry */
+ mem_set(dir + DIR_Name, ' ', 11); /* Create "." entry */
dir[DIR_Name] = '.';
dir[DIR_Attr] = AM_DIR;
- ST_DWORD(dir+DIR_WrtTime, tm);
+ ST_DWORD(dir + DIR_WrtTime, tm);
st_clust(dir, dcl);
- mem_cpy(dir+SZ_DIR, dir, SZ_DIR); /* Create ".." entry */
- dir[SZ_DIR+1] = '.'; pcl = dj.sclust;
+ mem_cpy(dir + SZ_DIRE, dir, SZ_DIRE); /* Create ".." entry */
+ dir[SZ_DIRE + 1] = '.'; pcl = dj.sclust;
if (dj.fs->fs_type == FS_FAT32 && pcl == dj.fs->dirbase)
pcl = 0;
- st_clust(dir+SZ_DIR, pcl);
+ st_clust(dir + SZ_DIRE, pcl);
for (n = dj.fs->csize; n; n--) { /* Write dot entries and clear following sectors */
dj.fs->winsect = dsc++;
dj.fs->wflag = 1;
@@ -3616,7 +3635,7 @@ FRESULT f_mkdir (
} else {
dir = dj.dir;
dir[DIR_Attr] = AM_DIR; /* Attribute */
- ST_DWORD(dir+DIR_WrtTime, tm); /* Created time */
+ ST_DWORD(dir + DIR_WrtTime, tm); /* Created time */
st_clust(dir, dcl); /* Table start cluster */
dj.fs->wflag = 1;
res = sync_fs(dj.fs);
@@ -3637,14 +3656,14 @@ FRESULT f_mkdir (
FRESULT f_chmod (
const TCHAR* path, /* Pointer to the file path */
- BYTE value, /* Attribute bits */
+ BYTE attr, /* Attribute bits */
BYTE mask /* Attribute mask to change */
)
{
FRESULT res;
DIR dj;
BYTE *dir;
- DEF_NAMEBUF;
+ DEFINE_NAMEBUF;
/* Get logical drive number */
@@ -3661,7 +3680,7 @@ FRESULT f_chmod (
res = FR_INVALID_NAME;
} else { /* File or sub directory */
mask &= AM_RDO|AM_HID|AM_SYS|AM_ARC; /* Valid attribute mask */
- dir[DIR_Attr] = (value & mask) | (dir[DIR_Attr] & (BYTE)~mask); /* Apply attribute change */
+ dir[DIR_Attr] = (attr & mask) | (dir[DIR_Attr] & (BYTE)~mask); /* Apply attribute change */
dj.fs->wflag = 1;
res = sync_fs(dj.fs);
}
@@ -3687,7 +3706,7 @@ FRESULT f_rename (
DIR djo, djn;
BYTE buf[21], *dir;
DWORD dw;
- DEF_NAMEBUF;
+ DEFINE_NAMEBUF;
/* Get logical drive number of the source object */
@@ -3705,28 +3724,29 @@ FRESULT f_rename (
if (!djo.dir) { /* Is root dir? */
res = FR_NO_FILE;
} else {
- mem_cpy(buf, djo.dir+DIR_Attr, 21); /* Save the object information except name */
+ mem_cpy(buf, djo.dir + DIR_Attr, 21); /* Save information about object except name */
mem_cpy(&djn, &djo, sizeof (DIR)); /* Duplicate the directory object */
- if (ff_get_ldnumber(&path_new) >= 0) /* Snip drive number off and ignore it */
+ // dpgeorge: custom ff_get_ldnumber
+ if (ff_get_ldnumber(&path_new) >= 0) /* Snip drive number off and ignore it */
res = follow_path(&djn, path_new); /* and make sure if new object name is not conflicting */
else
res = FR_INVALID_DRIVE;
if (res == FR_OK) res = FR_EXIST; /* The new object name is already existing */
if (res == FR_NO_FILE) { /* It is a valid path and no name collision */
-/* Start of critical section that any interruption can cause a cross-link */
res = dir_register(&djn); /* Register the new entry */
if (res == FR_OK) {
- dir = djn.dir; /* Copy object information except name */
- mem_cpy(dir+13, buf+2, 19);
+/* Start of critical section where any interruption can cause a cross-link */
+ dir = djn.dir; /* Copy information about object except name */
+ mem_cpy(dir + 13, buf + 2, 19);
dir[DIR_Attr] = buf[0] | AM_ARC;
djo.fs->wflag = 1;
- if ((dir[DIR_Attr] & AM_DIR) && djo.sclust != djn.sclust) { /* Update .. entry in the directory if needed */
+ if ((dir[DIR_Attr] & AM_DIR) && djo.sclust != djn.sclust) { /* Update .. entry in the sub-directory if needed */
dw = clust2sect(djo.fs, ld_clust(djo.fs, dir));
if (!dw) {
res = FR_INT_ERR;
} else {
res = move_window(djo.fs, dw);
- dir = djo.fs->win+SZ_DIR; /* .. entry */
+ dir = djo.fs->win + SZ_DIRE * 1; /* Ptr to .. entry */
if (res == FR_OK && dir[1] == '.') {
st_clust(dir, djn.sclust);
djo.fs->wflag = 1;
@@ -3738,8 +3758,8 @@ FRESULT f_rename (
if (res == FR_OK)
res = sync_fs(djo.fs);
}
- }
/* End of critical section */
+ }
}
}
}
@@ -3764,7 +3784,7 @@ FRESULT f_utime (
FRESULT res;
DIR dj;
BYTE *dir;
- DEF_NAMEBUF;
+ DEFINE_NAMEBUF;
/* Get logical drive number */
@@ -3780,8 +3800,8 @@ FRESULT f_utime (
if (!dir) { /* Root directory */
res = FR_INVALID_NAME;
} else { /* File or sub-directory */
- ST_WORD(dir+DIR_WrtTime, fno->ftime);
- ST_WORD(dir+DIR_WrtDate, fno->fdate);
+ ST_WORD(dir + DIR_WrtTime, fno->ftime);
+ ST_WORD(dir + DIR_WrtDate, fno->fdate);
dj.fs->wflag = 1;
res = sync_fs(dj.fs);
}
@@ -3798,6 +3818,7 @@ FRESULT f_utime (
+
#if _USE_LABEL
/*-----------------------------------------------------------------------*/
/* Get volume label */
@@ -3812,6 +3833,9 @@ FRESULT f_getlabel (
FRESULT res;
DIR dj;
UINT i, j;
+#if _USE_LFN && _LFN_UNICODE
+ WCHAR w;
+#endif
/* Get logical drive number */
@@ -3825,7 +3849,6 @@ FRESULT f_getlabel (
res = dir_read(&dj, 1); /* Get an entry with AM_VOL */
if (res == FR_OK) { /* A volume label is exist */
#if _USE_LFN && _LFN_UNICODE
- WCHAR w;
i = j = 0;
do {
w = (i < 11) ? dj.dir[i++] : ' ';
@@ -3888,7 +3911,7 @@ FRESULT f_setlabel (
vn[0] = 0;
if (label[0] == '/') label++; // dpgeorge: skip '/' to handle our volume names
for (sl = 0; label[sl]; sl++) ; /* Get name length */
- for ( ; sl && label[sl-1] == ' '; sl--) ; /* Remove trailing spaces */
+ for ( ; sl && label[sl - 1] == ' '; sl--) ; /* Remove trailing spaces */
if (sl) { /* Create volume label in directory form */
i = j = 0;
do {
@@ -3914,7 +3937,8 @@ FRESULT f_setlabel (
if (w >= 0x100) vn[j++] = (BYTE)(w >> 8);
vn[j++] = (BYTE)w;
} while (i < sl);
- while (j < 11) vn[j++] = ' ';
+ while (j < 11) vn[j++] = ' '; /* Fill remaining name field */
+ if (vn[0] == DDEM) LEAVE_FF(dj.fs, FR_INVALID_NAME); /* Reject illegal name (heading DDEM) */
}
/* Set volume label */
@@ -3926,9 +3950,9 @@ FRESULT f_setlabel (
if (vn[0]) {
mem_cpy(dj.dir, vn, 11); /* Change the volume label name */
tm = GET_FATTIME();
- ST_DWORD(dj.dir+DIR_WrtTime, tm);
+ ST_DWORD(dj.dir + DIR_WrtTime, tm);
} else {
- dj.dir[0] = DDE; /* Remove the volume label */
+ dj.dir[0] = DDEM; /* Remove the volume label */
}
dj.fs->wflag = 1;
res = sync_fs(dj.fs);
@@ -3938,11 +3962,11 @@ FRESULT f_setlabel (
if (vn[0]) { /* Create volume label as new */
res = dir_alloc(&dj, 1); /* Allocate an entry for volume label */
if (res == FR_OK) {
- mem_set(dj.dir, 0, SZ_DIR); /* Set volume label */
+ mem_set(dj.dir, 0, SZ_DIRE); /* Set volume label */
mem_cpy(dj.dir, vn, 11);
dj.dir[DIR_Attr] = AM_VOL;
tm = GET_FATTIME();
- ST_DWORD(dj.dir+DIR_WrtTime, tm);
+ ST_DWORD(dj.dir + DIR_WrtTime, tm);
dj.fs->wflag = 1;
res = sync_fs(dj.fs);
}
@@ -4021,7 +4045,7 @@ FRESULT f_forward (
#if _USE_MKFS && !_FS_READONLY
/*-----------------------------------------------------------------------*/
-/* Create File System on the Drive */
+/* Create file system on the logical drive */
/*-----------------------------------------------------------------------*/
#define N_ROOTDIR 512 /* Number of root directory entries for FAT12/16 */
#define N_FATS 1 /* Number of FATs (1 or 2) */
@@ -4043,11 +4067,14 @@ FRESULT f_mkfs (
DWORD n_vol, n_rsv, n_fat, n_dir; /* Size */
FATFS *fs;
DSTATUS stat;
+#if _USE_TRIM
+ DWORD eb[2];
+#endif
/* Check mounted drive and clear work area */
if (sfd > 1) return FR_INVALID_PARAMETER;
- vol = ff_get_ldnumber(&path);
+ vol = ff_get_ldnumber(&path); // dpgeorge: custom ff_get_ldnumber
if (vol < 0) return FR_INVALID_DRIVE;
fs = FatFs[vol];
if (!fs) return FR_NOT_ENABLED;
@@ -4066,14 +4093,14 @@ FRESULT f_mkfs (
if (_MULTI_PARTITION && part) {
/* Get partition information from partition table in the MBR */
if (disk_read(pdrv, fs->win, 0, 1) != RES_OK) return FR_DISK_ERR;
- if (LD_WORD(fs->win+BS_55AA) != 0xAA55) return FR_MKFS_ABORTED;
+ if (LD_WORD(fs->win + BS_55AA) != 0xAA55) return FR_MKFS_ABORTED;
tbl = &fs->win[MBR_Table + (part - 1) * SZ_PTE];
if (!tbl[4]) return FR_MKFS_ABORTED; /* No partition? */
- b_vol = LD_DWORD(tbl+8); /* Volume start sector */
- n_vol = LD_DWORD(tbl+12); /* Volume size */
+ b_vol = LD_DWORD(tbl + 8); /* Volume start sector */
+ n_vol = LD_DWORD(tbl + 12); /* Volume size */
} else {
/* Create a partition in this function */
- if (disk_ioctl(pdrv, GET_SECTOR_COUNT, &n_vol) != RES_OK || n_vol < 48) /* dpgeorge: allow smaller minimum volume; 48 was 128 */
+ if (disk_ioctl(pdrv, GET_SECTOR_COUNT, &n_vol) != RES_OK || n_vol < 48) // dpgeorge: allow smaller minimum volume; 48 was 128
return FR_DISK_ERR;
b_vol = (sfd) ? 0 : 63; /* Volume start sector */
n_vol -= b_vol; /* Volume size */
@@ -4104,7 +4131,7 @@ FRESULT f_mkfs (
n_fat = (fmt == FS_FAT12) ? (n_clst * 3 + 1) / 2 + 3 : (n_clst * 2) + 4;
n_fat = (n_fat + SS(fs) - 1) / SS(fs);
n_rsv = 1;
- n_dir = (DWORD)N_ROOTDIR * SZ_DIR / SS(fs);
+ n_dir = (DWORD)N_ROOTDIR * SZ_DIRE / SS(fs);
}
b_fat = b_vol + n_rsv; /* FAT area start sector */
b_dir = b_fat + n_fat * N_FATS; /* Directory area start sector */
@@ -4151,7 +4178,7 @@ FRESULT f_mkfs (
md = 0xF0;
} else { /* Create partition table (FDISK) */
mem_set(fs->win, 0, SS(fs));
- tbl = fs->win+MBR_Table; /* Create partition table for single partition in the drive */
+ tbl = fs->win + MBR_Table; /* Create partition table for single partition in the drive */
tbl[1] = 1; /* Partition start head */
tbl[2] = 1; /* Partition start sector */
tbl[3] = 0; /* Partition start cylinder */
@@ -4160,9 +4187,9 @@ FRESULT f_mkfs (
n = (b_vol + n_vol) / 63 / 255;
tbl[6] = (BYTE)(n >> 2 | 63); /* Partition end sector */
tbl[7] = (BYTE)n; /* End cylinder */
- ST_DWORD(tbl+8, 63); /* Partition start in LBA */
- ST_DWORD(tbl+12, n_vol); /* Partition size in LBA */
- ST_WORD(fs->win+BS_55AA, 0xAA55); /* MBR signature */
+ ST_DWORD(tbl + 8, 63); /* Partition start in LBA */
+ ST_DWORD(tbl + 12, n_vol); /* Partition size in LBA */
+ ST_WORD(fs->win + BS_55AA, 0xAA55); /* MBR signature */
if (disk_write(pdrv, fs->win, 0, 1) != RES_OK) /* Write it to the MBR */
return FR_DISK_ERR;
md = 0xF8;
@@ -4174,42 +4201,42 @@ FRESULT f_mkfs (
mem_set(tbl, 0, SS(fs));
mem_cpy(tbl, "\xEB\xFE\x90" "MSDOS5.0", 11);/* Boot jump code, OEM name */
i = SS(fs); /* Sector size */
- ST_WORD(tbl+BPB_BytsPerSec, i);
+ ST_WORD(tbl + BPB_BytsPerSec, i);
tbl[BPB_SecPerClus] = (BYTE)au; /* Sectors per cluster */
- ST_WORD(tbl+BPB_RsvdSecCnt, n_rsv); /* Reserved sectors */
+ ST_WORD(tbl + BPB_RsvdSecCnt, n_rsv); /* Reserved sectors */
tbl[BPB_NumFATs] = N_FATS; /* Number of FATs */
i = (fmt == FS_FAT32) ? 0 : N_ROOTDIR; /* Number of root directory entries */
- ST_WORD(tbl+BPB_RootEntCnt, i);
+ ST_WORD(tbl + BPB_RootEntCnt, i);
if (n_vol < 0x10000) { /* Number of total sectors */
- ST_WORD(tbl+BPB_TotSec16, n_vol);
+ ST_WORD(tbl + BPB_TotSec16, n_vol);
} else {
- ST_DWORD(tbl+BPB_TotSec32, n_vol);
+ ST_DWORD(tbl + BPB_TotSec32, n_vol);
}
tbl[BPB_Media] = md; /* Media descriptor */
- ST_WORD(tbl+BPB_SecPerTrk, 63); /* Number of sectors per track */
- ST_WORD(tbl+BPB_NumHeads, 255); /* Number of heads */
- ST_DWORD(tbl+BPB_HiddSec, b_vol); /* Hidden sectors */
+ ST_WORD(tbl + BPB_SecPerTrk, 63); /* Number of sectors per track */
+ ST_WORD(tbl + BPB_NumHeads, 255); /* Number of heads */
+ ST_DWORD(tbl + BPB_HiddSec, b_vol); /* Hidden sectors */
n = GET_FATTIME(); /* Use current time as VSN */
if (fmt == FS_FAT32) {
- ST_DWORD(tbl+BS_VolID32, n); /* VSN */
- ST_DWORD(tbl+BPB_FATSz32, n_fat); /* Number of sectors per FAT */
- ST_DWORD(tbl+BPB_RootClus, 2); /* Root directory start cluster (2) */
- ST_WORD(tbl+BPB_FSInfo, 1); /* FSINFO record offset (VBR+1) */
- ST_WORD(tbl+BPB_BkBootSec, 6); /* Backup boot record offset (VBR+6) */
+ ST_DWORD(tbl + BS_VolID32, n); /* VSN */
+ ST_DWORD(tbl + BPB_FATSz32, n_fat); /* Number of sectors per FAT */
+ ST_DWORD(tbl + BPB_RootClus, 2); /* Root directory start cluster (2) */
+ ST_WORD(tbl + BPB_FSInfo, 1); /* FSINFO record offset (VBR + 1) */
+ ST_WORD(tbl + BPB_BkBootSec, 6); /* Backup boot record offset (VBR + 6) */
tbl[BS_DrvNum32] = 0x80; /* Drive number */
tbl[BS_BootSig32] = 0x29; /* Extended boot signature */
- mem_cpy(tbl+BS_VolLab32, "NO NAME " "FAT32 ", 19); /* Volume label, FAT signature */
+ mem_cpy(tbl + BS_VolLab32, "NO NAME " "FAT32 ", 19); /* Volume label, FAT signature */
} else {
- ST_DWORD(tbl+BS_VolID, n); /* VSN */
- ST_WORD(tbl+BPB_FATSz16, n_fat); /* Number of sectors per FAT */
+ ST_DWORD(tbl + BS_VolID, n); /* VSN */
+ ST_WORD(tbl + BPB_FATSz16, n_fat); /* Number of sectors per FAT */
tbl[BS_DrvNum] = 0x80; /* Drive number */
tbl[BS_BootSig] = 0x29; /* Extended boot signature */
- mem_cpy(tbl+BS_VolLab, "NO NAME " "FAT ", 19); /* Volume label, FAT signature */
+ mem_cpy(tbl + BS_VolLab, "NO NAME " "FAT ", 19); /* Volume label, FAT signature */
}
- ST_WORD(tbl+BS_55AA, 0xAA55); /* Signature (Offset is fixed here regardless of sector size) */
+ ST_WORD(tbl + BS_55AA, 0xAA55); /* Signature (Offset is fixed here regardless of sector size) */
if (disk_write(pdrv, tbl, b_vol, 1) != RES_OK) /* Write it to the VBR sector */
return FR_DISK_ERR;
- if (fmt == FS_FAT32) /* Write backup VBR if needed (VBR+6) */
+ if (fmt == FS_FAT32) /* Write backup VBR if needed (VBR + 6) */
disk_write(pdrv, tbl, b_vol + 6, 1);
/* Initialize FAT area */
@@ -4219,12 +4246,12 @@ FRESULT f_mkfs (
n = md; /* Media descriptor byte */
if (fmt != FS_FAT32) {
n |= (fmt == FS_FAT12) ? 0x00FFFF00 : 0xFFFFFF00;
- ST_DWORD(tbl+0, n); /* Reserve cluster #0-1 (FAT12/16) */
+ ST_DWORD(tbl + 0, n); /* Reserve cluster #0-1 (FAT12/16) */
} else {
n |= 0xFFFFFF00;
- ST_DWORD(tbl+0, n); /* Reserve cluster #0-1 (FAT32) */
- ST_DWORD(tbl+4, 0xFFFFFFFF);
- ST_DWORD(tbl+8, 0x0FFFFFFF); /* Reserve cluster #2 for root directory */
+ ST_DWORD(tbl + 0, n); /* Reserve cluster #0-1 (FAT32) */
+ ST_DWORD(tbl + 4, 0xFFFFFFFF);
+ ST_DWORD(tbl + 8, 0x0FFFFFFF); /* Reserve cluster #2 for root directory */
}
if (disk_write(pdrv, tbl, wsect++, 1) != RES_OK)
return FR_DISK_ERR;
@@ -4244,8 +4271,6 @@ FRESULT f_mkfs (
#if _USE_TRIM /* Erase data area if needed */
{
- DWORD eb[2];
-
eb[0] = wsect; eb[1] = wsect + (n_clst - ((fmt == FS_FAT32) ? 1 : 0)) * au - 1;
disk_ioctl(pdrv, CTRL_TRIM, eb);
}
@@ -4253,13 +4278,13 @@ FRESULT f_mkfs (
/* Create FSINFO if needed */
if (fmt == FS_FAT32) {
- ST_DWORD(tbl+FSI_LeadSig, 0x41615252);
- ST_DWORD(tbl+FSI_StrucSig, 0x61417272);
- ST_DWORD(tbl+FSI_Free_Count, n_clst - 1); /* Number of free clusters */
- ST_DWORD(tbl+FSI_Nxt_Free, 2); /* Last allocated cluster# */
- ST_WORD(tbl+BS_55AA, 0xAA55);
- disk_write(pdrv, tbl, b_vol + 1, 1); /* Write original (VBR+1) */
- disk_write(pdrv, tbl, b_vol + 7, 1); /* Write backup (VBR+7) */
+ ST_DWORD(tbl + FSI_LeadSig, 0x41615252);
+ ST_DWORD(tbl + FSI_StrucSig, 0x61417272);
+ ST_DWORD(tbl + FSI_Free_Count, n_clst - 1); /* Number of free clusters */
+ ST_DWORD(tbl + FSI_Nxt_Free, 2); /* Last allocated cluster# */
+ ST_WORD(tbl + BS_55AA, 0xAA55);
+ disk_write(pdrv, tbl, b_vol + 1, 1); /* Write original (VBR + 1) */
+ disk_write(pdrv, tbl, b_vol + 7, 1); /* Write backup (VBR + 7) */
}
return (disk_ioctl(pdrv, CTRL_SYNC, 0) == RES_OK) ? FR_OK : FR_DISK_ERR;
@@ -4269,7 +4294,7 @@ FRESULT f_mkfs (
#if _MULTI_PARTITION
/*-----------------------------------------------------------------------*/
-/* Divide Physical Drive */
+/* Create partition table on the physical drive */
/*-----------------------------------------------------------------------*/
FRESULT f_fdisk (
@@ -4417,6 +4442,7 @@ TCHAR* f_gets (
+
#if !_FS_READONLY
#include <stdarg.h>
/*-----------------------------------------------------------------------*/
diff --git a/lib/fatfs/ff.h b/lib/fatfs/ff.h
index 6f7c86debf..31d58b4427 100644
--- a/lib/fatfs/ff.h
+++ b/lib/fatfs/ff.h
@@ -1,21 +1,23 @@
/*---------------------------------------------------------------------------/
-/ FatFs - FAT file system module include file R0.10c (C)ChaN, 2014
+/ FatFs - FAT file system module include R0.11 (C)ChaN, 2015
/----------------------------------------------------------------------------/
-/ FatFs module is a generic FAT file system module for small embedded systems.
-/ This is a free software that opened for education, research and commercial
-/ developments under license policy of following terms.
+/ FatFs module is a free software that opened under license policy of
+/ following conditions.
/
-/ Copyright (C) 2014, ChaN, all right reserved.
+/ Copyright (C) 2015, ChaN, all right reserved.
/
-/ * The FatFs module is a free software and there is NO WARRANTY.
-/ * No restriction on use. You can use, modify and redistribute it for
-/ personal, non-profit or commercial product UNDER YOUR RESPONSIBILITY.
-/ * Redistributions of source code must retain the above copyright notice.
+/ 1. Redistributions of source code must retain the above copyright notice,
+/ this condition and the following disclaimer.
/
-/----------------------------------------------------------------------------*/
+/ This software is provided by the copyright holder and contributors "AS IS"
+/ and any warranties related to this software are DISCLAIMED.
+/ The copyright owner or contributors be NOT LIABLE for any damages caused
+/ by use of this software.
+/---------------------------------------------------------------------------*/
+
#ifndef _FATFS
-#define _FATFS 80376 /* Revision ID */
+#define _FATFS 32020 /* Revision ID */
#ifdef __cplusplus
extern "C" {
@@ -36,6 +38,7 @@ typedef struct {
BYTE pd; /* Physical drive number */
BYTE pt; /* Partition: 0:Auto detect, 1-4:Forced partition) */
} PARTITION;
+// dpgeorge: make the partition config table const
extern const PARTITION VolToPart[]; /* Volume - Partition resolution table */
#define LD2PD(vol) (VolToPart[vol].pd) /* Get physical drive number */
#define LD2PT(vol) (VolToPart[vol].pt) /* Get partition index */
@@ -154,11 +157,14 @@ typedef struct {
WCHAR* lfn; /* Pointer to the LFN working buffer */
WORD lfn_idx; /* Last matched LFN index number (0xFFFF:No LFN) */
#endif
+#if _USE_FIND
+ const TCHAR* pat; /* Pointer to the name matching pattern */
+#endif
} DIR;
-/* File status structure (FILINFO) */
+/* File information structure (FILINFO) */
typedef struct {
DWORD fsize; /* File size */
@@ -215,11 +221,13 @@ FRESULT f_sync (FIL* fp); /* Flush cached data of a writing file */
FRESULT f_opendir (DIR* dp, const TCHAR* path); /* Open a directory */
FRESULT f_closedir (DIR* dp); /* Close an open directory */
FRESULT f_readdir (DIR* dp, FILINFO* fno); /* Read a directory item */
+FRESULT f_findfirst (DIR* dp, FILINFO* fno, const TCHAR* path, const TCHAR* pattern); /* Find first file */
+FRESULT f_findnext (DIR* dp, FILINFO* fno); /* Find next file */
FRESULT f_mkdir (const TCHAR* path); /* Create a sub directory */
FRESULT f_unlink (const TCHAR* path); /* Delete an existing file or directory */
FRESULT f_rename (const TCHAR* path_old, const TCHAR* path_new); /* Rename/Move a file or directory */
FRESULT f_stat (const TCHAR* path, FILINFO* fno); /* Get file status */
-FRESULT f_chmod (const TCHAR* path, BYTE value, BYTE mask); /* Change attribute of the file/dir */
+FRESULT f_chmod (const TCHAR* path, BYTE attr, BYTE mask); /* Change attribute of the file/dir */
FRESULT f_utime (const TCHAR* path, const FILINFO* fno); /* Change times-tamp of the file/dir */
FRESULT f_chdir (const TCHAR* path); /* Change current directory */
FRESULT f_chdrive (const TCHAR* path); /* Change current drive */
@@ -239,6 +247,8 @@ TCHAR* f_gets (TCHAR* buff, int len, FIL* fp); /* Get a string from the fil
#define f_error(fp) ((fp)->err)
#define f_tell(fp) ((fp)->fptr)
#define f_size(fp) ((fp)->fsize)
+#define f_rewind(fp) f_lseek((fp), 0)
+#define f_rewinddir(dp) f_readdir((dp), 0)
#ifndef EOF
#define EOF (-1)
diff --git a/lib/fatfs/ffconf_template.h b/lib/fatfs/ffconf_template.h
index f968d7e077..4dc4beb493 100644
--- a/lib/fatfs/ffconf_template.h
+++ b/lib/fatfs/ffconf_template.h
@@ -1,8 +1,8 @@
/*---------------------------------------------------------------------------/
-/ FatFs - FAT file system module configuration file R0.10c (C)ChaN, 2014
+/ FatFs - FAT file system module configuration file R0.11 (C)ChaN, 2015
/---------------------------------------------------------------------------*/
-#define _FFCONF 80376 /* Revision ID */
+#define _FFCONF 32020 /* Revision ID */
/*---------------------------------------------------------------------------/
/ Functions and Buffer Configurations
@@ -18,13 +18,13 @@
#define _FS_READONLY 0
/* This option switches read-only configuration. (0:Read/Write or 1:Read-only)
-/ Read-only configuration removes basic writing API functions, f_write(),
-/ f_sync(), f_unlink(), f_mkdir(), f_chmod(), f_rename(), f_truncate(),
-/ f_getfree() and optional writing functions as well. */
+/ Read-only configuration removes writing API functions, f_write(), f_sync(),
+/ f_unlink(), f_mkdir(), f_chmod(), f_rename(), f_truncate(), f_getfree()
+/ and optional writing functions as well. */
#define _FS_MINIMIZE 0
-/* This option defines minimization level to remove some API functions.
+/* This option defines minimization level to remove some basic API functions.
/
/ 0: All basic functions are enabled.
/ 1: f_stat(), f_getfree(), f_unlink(), f_mkdir(), f_chmod(), f_utime(),
@@ -42,9 +42,13 @@
/ 2: Enable with LF-CRLF conversion. */
+#define _USE_FIND 0
+/* This option switches filtered directory read feature and related functions,
+/ f_findfirst() and f_findnext(). (0:Disable or 1:Enable) */
+
+
#define _USE_MKFS 0
-/* This option switches f_mkfs() function. (0:Disable or 1:Enable)
-/ To enable it, also _FS_READONLY need to be set to 0. */
+/* This option switches f_mkfs() function. (0:Disable or 1:Enable) */
#define _USE_FASTSEEK 0
@@ -57,8 +61,8 @@
#define _USE_FORWARD 0
-/* This option switches f_forward() function. (0:Disable or 1:Enable) */
-/* To enable it, also _FS_TINY need to be set to 1. */
+/* This option switches f_forward() function. (0:Disable or 1:Enable)
+/ To enable it, also _FS_TINY need to be set to 1. */
/*---------------------------------------------------------------------------/
@@ -69,32 +73,24 @@
/* This option specifies the OEM code page to be used on the target system.
/ Incorrect setting of the code page can cause a file open failure.
/
-/ 932 - Japanese Shift_JIS (DBCS, OEM, Windows)
-/ 936 - Simplified Chinese GBK (DBCS, OEM, Windows)
-/ 949 - Korean (DBCS, OEM, Windows)
-/ 950 - Traditional Chinese Big5 (DBCS, OEM, Windows)
-/ 1250 - Central Europe (Windows)
-/ 1251 - Cyrillic (Windows)
-/ 1252 - Latin 1 (Windows)
-/ 1253 - Greek (Windows)
-/ 1254 - Turkish (Windows)
-/ 1255 - Hebrew (Windows)
-/ 1256 - Arabic (Windows)
-/ 1257 - Baltic (Windows)
-/ 1258 - Vietnam (OEM, Windows)
-/ 437 - U.S. (OEM)
-/ 720 - Arabic (OEM)
-/ 737 - Greek (OEM)
-/ 775 - Baltic (OEM)
-/ 850 - Multilingual Latin 1 (OEM)
-/ 858 - Multilingual Latin 1 + Euro (OEM)
-/ 852 - Latin 2 (OEM)
-/ 855 - Cyrillic (OEM)
-/ 866 - Russian (OEM)
-/ 857 - Turkish (OEM)
-/ 862 - Hebrew (OEM)
-/ 874 - Thai (OEM, Windows)
-/ 1 - ASCII (No extended character. Valid for only non-LFN configuration.) */
+/ 1 - ASCII (No extended character. Non-LFN cfg. only)
+/ 437 - U.S.
+/ 720 - Arabic
+/ 737 - Greek
+/ 775 - Baltic
+/ 850 - Multilingual Latin 1
+/ 852 - Latin 2
+/ 855 - Cyrillic
+/ 857 - Turkish
+/ 858 - Multilingual Latin 1 + Euro
+/ 862 - Hebrew
+/ 866 - Russian
+/ 874 - Thai
+/ 932 - Japanese Shift_JIS (DBCS)
+/ 936 - Simplified Chinese GBK (DBCS)
+/ 949 - Korean (DBCS)
+/ 950 - Traditional Chinese Big5 (DBCS)
+*/
#define _USE_LFN 0
@@ -163,7 +159,7 @@
/ number is bound to the same physical drive number and only an FAT volume found on
/ the physical drive will be mounted. When multi-partition feature is enabled (1),
/ each logical drive number is bound to arbitrary physical drive and partition
-/ listed in the VolToPart[]. Also f_fdisk() funciton will be enabled. */
+/ listed in the VolToPart[]. Also f_fdisk() funciton will be available. */
#define _MIN_SS 512
@@ -200,9 +196,9 @@
/---------------------------------------------------------------------------*/
#define _FS_NORTC 0
-#define _NORTC_MON 11
-#define _NORTC_MDAY 9
-#define _NORTC_YEAR 2014
+#define _NORTC_MON 2
+#define _NORTC_MDAY 1
+#define _NORTC_YEAR 2015
/* The _FS_NORTC option switches timestamp feature. If the system does not have
/ an RTC function or valid timestamp is not needed, set _FS_NORTC to 1 to disable
/ the timestamp feature. All objects modified by FatFs will have a fixed timestamp
diff --git a/lib/fatfs/history.txt b/lib/fatfs/history.txt
new file mode 100644
index 0000000000..b00f58c018
--- /dev/null
+++ b/lib/fatfs/history.txt
@@ -0,0 +1,180 @@
+----------------------------------------------------------------------------
+ Revision history of FatFs module
+----------------------------------------------------------------------------
+
+R0.00 (February 26, 2006)
+ Prototype.
+
+
+R0.01 (April 29, 2006)
+ First stable version.
+
+
+R0.02 (June 01, 2006)
+ Added FAT12 support.
+ Removed unbuffered mode.
+ Fixed a problem on small (<32M) partition.
+
+
+R0.02a (June 10, 2006)
+ Added a configuration option (_FS_MINIMUM).
+
+
+R0.03 (September 22, 2006)
+ Added f_rename().
+ Changed option _FS_MINIMUM to _FS_MINIMIZE.
+
+
+R0.03a (December 11, 2006)
+ Improved cluster scan algorithm to write files fast.
+ Fixed f_mkdir() creates incorrect directory on FAT32.
+
+
+R0.04 (February 04, 2007)
+ Added f_mkfs().
+ Supported multiple drive system.
+ Changed some interfaces for multiple drive system.
+ Changed f_mountdrv() to f_mount().
+
+
+R0.04a (April 01, 2007)
+ Supported multiple partitions on a physical drive.
+ Added a capability of extending file size to f_lseek().
+ Added minimization level 3.
+ Fixed an endian sensitive code in f_mkfs().
+
+
+R0.04b (May 05, 2007)
+ Added a configuration option _USE_NTFLAG.
+ Added FSINFO support.
+ Fixed DBCS name can result FR_INVALID_NAME.
+ Fixed short seek (<= csize) collapses the file object.
+
+
+R0.05 (August 25, 2007)
+ Changed arguments of f_read(), f_write() and f_mkfs().
+ Fixed f_mkfs() on FAT32 creates incorrect FSINFO.
+ Fixed f_mkdir() on FAT32 creates incorrect directory.
+
+
+R0.05a (February 03, 2008)
+ Added f_truncate() and f_utime().
+ Fixed off by one error at FAT sub-type determination.
+ Fixed btr in f_read() can be mistruncated.
+ Fixed cached sector is not flushed when create and close without write.
+
+
+R0.06 (April 01, 2008)
+ Added fputc(), fputs(), fprintf() and fgets().
+ Improved performance of f_lseek() on moving to the same or following cluster.
+
+
+R0.07 (April 01, 2009)
+ Merged Tiny-FatFs as a configuration option. (_FS_TINY)
+ Added long file name feature. (_USE_LFN)
+ Added multiple code page feature. (_CODE_PAGE)
+ Added re-entrancy for multitask operation. (_FS_REENTRANT)
+ Added auto cluster size selection to f_mkfs().
+ Added rewind option to f_readdir().
+ Changed result code of critical errors.
+ Renamed string functions to avoid name collision.
+
+
+R0.07a (April 14, 2009)
+ Septemberarated out OS dependent code on reentrant cfg.
+ Added multiple sector size feature.
+
+
+R0.07c (June 21, 2009)
+ Fixed f_unlink() can return FR_OK on error.
+ Fixed wrong cache control in f_lseek().
+ Added relative path feature.
+ Added f_chdir() and f_chdrive().
+ Added proper case conversion to extended character.
+
+
+R0.07e (November 03, 2009)
+ Septemberarated out configuration options from ff.h to ffconf.h.
+ Fixed f_unlink() fails to remove a sub-directory on _FS_RPATH.
+ Fixed name matching error on the 13 character boundary.
+ Added a configuration option, _LFN_UNICODE.
+ Changed f_readdir() to return the SFN with always upper case on non-LFN cfg.
+
+
+R0.08 (May 15, 2010)
+ Added a memory configuration option. (_USE_LFN = 3)
+ Added file lock feature. (_FS_SHARE)
+ Added fast seek feature. (_USE_FASTSEEK)
+ Changed some types on the API, XCHAR->TCHAR.
+ Changed .fname in the FILINFO structure on Unicode cfg.
+ String functions support UTF-8 encoding files on Unicode cfg.
+
+
+R0.08a (August 16, 2010)
+ Added f_getcwd(). (_FS_RPATH = 2)
+ Added sector erase feature. (_USE_ERASE)
+ Moved file lock semaphore table from fs object to the bss.
+ Fixed f_mkfs() creates wrong FAT32 volume.
+
+
+R0.08b (January 15, 2011)
+ Fast seek feature is also applied to f_read() and f_write().
+ f_lseek() reports required table size on creating CLMP.
+ Extended format syntax of f_printf().
+ Ignores duplicated directory separators in given path name.
+
+
+R0.09 (September 06, 2011)
+ f_mkfs() supports multiple partition to complete the multiple partition feature.
+ Added f_fdisk().
+
+
+R0.09a (August 27, 2012)
+ Changed f_open() and f_opendir() reject null object pointer to avoid crash.
+ Changed option name _FS_SHARE to _FS_LOCK.
+ Fixed assertion failure due to OS/2 EA on FAT12/16 volume.
+
+
+R0.09b (January 24, 2013)
+ Added f_setlabel() and f_getlabel().
+
+
+R0.10 (October 02, 2013)
+ Added selection of character encoding on the file. (_STRF_ENCODE)
+ Added f_closedir().
+ Added forced full FAT scan for f_getfree(). (_FS_NOFSINFO)
+ Added forced mount feature with changes of f_mount().
+ Improved behavior of volume auto detection.
+ Improved write throughput of f_puts() and f_printf().
+ Changed argument of f_chdrive(), f_mkfs(), disk_read() and disk_write().
+ Fixed f_write() can be truncated when the file size is close to 4GB.
+ Fixed f_open(), f_mkdir() and f_setlabel() can return incorrect error code.
+
+
+R0.10a (January 15, 2014)
+ Added arbitrary strings as drive number in the path name. (_STR_VOLUME_ID)
+ Added a configuration option of minimum sector size. (_MIN_SS)
+ 2nd argument of f_rename() can have a drive number and it will be ignored.
+ Fixed f_mount() with forced mount fails when drive number is >= 1. (appeared at R0.10)
+ Fixed f_close() invalidates the file object without volume lock.
+ Fixed f_closedir() returns but the volume lock is left acquired. (appeared at R0.10)
+ Fixed creation of an entry with LFN fails on too many SFN collisions. (appeared at R0.07)
+
+
+R0.10b (May 19, 2014)
+ Fixed a hard error in the disk I/O layer can collapse the directory entry.
+ Fixed LFN entry is not deleted on delete/rename an object with lossy converted SFN. (appeared at R0.07)
+
+
+R0.10c (November 09, 2014)
+ Added a configuration option for the platforms without RTC. (_FS_NORTC)
+ Changed option name _USE_ERASE to _USE_TRIM.
+ Fixed volume label created by Mac OS X cannot be retrieved with f_getlabel(). (appeared at R0.09b)
+ Fixed a potential problem of FAT access that can appear on disk error.
+ Fixed null pointer dereference on attempting to delete the root direcotry. (appeared at R0.08)
+
+
+R0.11 (February 09, 2015)
+ Added f_findfirst(), f_findnext() and f_findclose(). (_USE_FIND)
+ Fixed f_unlink() does not remove cluster chain of the file. (appeared at R0.10c)
+ Fixed _FS_NORTC option does not work properly. (appeared at R0.10c)
diff --git a/lib/fatfs/option/unicode.c b/lib/fatfs/option/unicode.c
index 22e0320ae0..170e2e09e0 100644
--- a/lib/fatfs/option/unicode.c
+++ b/lib/fatfs/option/unicode.c
@@ -10,7 +10,7 @@
#include "cc949.c"
#elif _CODE_PAGE == 950 /* Traditional Chinese Big5 */
#include "cc950.c"
-#else /* Small character-set */
+#else /* Single Byte Character-Set */
#include "ccsbcs.c"
#endif