From 491c4efe9c6c4e9e882308832402de112f2a0137 Mon Sep 17 00:00:00 2001 From: Kostas Missos Date: Wed, 13 Mar 2019 12:27:43 +0200 Subject: [PATCH] [FatFS] Update to R0.13c (p3) --- bootloader/libs/fatfs/diskio.c | 17 +- bootloader/libs/fatfs/diskio.h | 11 +- bootloader/libs/fatfs/ff.c | 335 +++++++++++++++--------------- bootloader/libs/fatfs/ff.h | 13 +- bootloader/libs/fatfs/ffconf.h | 9 +- bootloader/libs/fatfs/ffsystem.c | 6 +- bootloader/libs/fatfs/ffunicode.c | 8 +- 7 files changed, 207 insertions(+), 192 deletions(-) diff --git a/bootloader/libs/fatfs/diskio.c b/bootloader/libs/fatfs/diskio.c index bfc17ed..438520e 100644 --- a/bootloader/libs/fatfs/diskio.c +++ b/bootloader/libs/fatfs/diskio.c @@ -15,6 +15,9 @@ extern sdmmc_storage_t sd_storage; +/*-----------------------------------------------------------------------*/ +/* Get Drive Status */ +/*-----------------------------------------------------------------------*/ DSTATUS disk_status ( BYTE pdrv /* Physical drive nmuber to identify the drive */ ) @@ -22,6 +25,9 @@ DSTATUS disk_status ( return 0; } +/*-----------------------------------------------------------------------*/ +/* Inidialize a Drive */ +/*-----------------------------------------------------------------------*/ DSTATUS disk_initialize ( BYTE pdrv /* Physical drive nmuber to identify the drive */ ) @@ -29,6 +35,9 @@ DSTATUS disk_initialize ( return 0; } +/*-----------------------------------------------------------------------*/ +/* Read Sector(s) */ +/*-----------------------------------------------------------------------*/ DRESULT disk_read ( BYTE pdrv, /* Physical drive nmuber to identify the drive */ BYTE *buff, /* Data buffer to store read data */ @@ -38,7 +47,7 @@ DRESULT disk_read ( { if ((u32)buff >= 0x90000000) return sdmmc_storage_read(&sd_storage, sector, count, buff) ? RES_OK : RES_ERROR; - u8 *buf = (u8 *)SDMMC_UPPER_BUFFER; //TODO: define this somewhere. + u8 *buf = (u8 *)SDMMC_UPPER_BUFFER; if (sdmmc_storage_read(&sd_storage, sector, count, buf)) { memcpy(buff, buf, 512 * count); @@ -47,6 +56,9 @@ DRESULT disk_read ( return RES_ERROR; } +/*-----------------------------------------------------------------------*/ +/* Write Sector(s) */ +/*-----------------------------------------------------------------------*/ DRESULT disk_write ( BYTE pdrv, /* Physical drive nmuber to identify the drive */ const BYTE *buff, /* Data to be written */ @@ -63,6 +75,9 @@ DRESULT disk_write ( return RES_ERROR; } +/*-----------------------------------------------------------------------*/ +/* Miscellaneous Functions */ +/*-----------------------------------------------------------------------*/ DRESULT disk_ioctl ( BYTE pdrv, /* Physical drive nmuber (0..) */ BYTE cmd, /* Control code */ diff --git a/bootloader/libs/fatfs/diskio.h b/bootloader/libs/fatfs/diskio.h index 8a1ba8e..d6ae8f8 100644 --- a/bootloader/libs/fatfs/diskio.h +++ b/bootloader/libs/fatfs/diskio.h @@ -11,7 +11,6 @@ extern "C" { #include "../../utils/types.h" - /* Status of Disk Functions */ typedef BYTE DSTATUS; @@ -46,11 +45,11 @@ DRESULT disk_ioctl (BYTE pdrv, BYTE cmd, void* buff); /* Command code for disk_ioctrl fucntion */ /* Generic command (Used by FatFs) */ -#define CTRL_SYNC 0 /* Complete pending write process (needed at _FS_READONLY == 0) */ -#define GET_SECTOR_COUNT 1 /* Get media size (needed at _USE_MKFS == 1) */ -#define GET_SECTOR_SIZE 2 /* Get sector size (needed at _MAX_SS != _MIN_SS) */ -#define GET_BLOCK_SIZE 3 /* Get erase block size (needed at _USE_MKFS == 1) */ -#define CTRL_TRIM 4 /* Inform device that the data on the block of sectors is no longer used (needed at _USE_TRIM == 1) */ +#define CTRL_SYNC 0 /* Complete pending write process (needed at FF_FS_READONLY == 0) */ +#define GET_SECTOR_COUNT 1 /* Get media size (needed at FF_USE_MKFS == 1) */ +#define GET_SECTOR_SIZE 2 /* Get sector size (needed at FF_MAX_SS != FF_MIN_SS) */ +#define GET_BLOCK_SIZE 3 /* Get erase block size (needed at FF_USE_MKFS == 1) */ +#define CTRL_TRIM 4 /* Inform device that the data on the block of sectors is no longer used (needed at FF_USE_TRIM == 1) */ /* Generic command (Not used by FatFs) */ #define CTRL_POWER 5 /* Get/Set power status */ diff --git a/bootloader/libs/fatfs/ff.c b/bootloader/libs/fatfs/ff.c index 24721fa..652dbdd 100644 --- a/bootloader/libs/fatfs/ff.c +++ b/bootloader/libs/fatfs/ff.c @@ -1,10 +1,10 @@ /*----------------------------------------------------------------------------/ -/ FatFs - Generic FAT Filesystem Module R0.13b / +/ FatFs - Generic FAT Filesystem Module R0.13c (p3) / /-----------------------------------------------------------------------------/ / / Copyright (C) 2018, ChaN, all right reserved. / Copyright (c) 2018 naehrwert -/ Copyright (C) 2018 CTCaer +/ Copyright (C) 2018-2019 CTCaer / / FatFs module is an open source software. Redistribution and use of FatFs in / source and binary forms, with or without modification, are permitted provided @@ -34,11 +34,20 @@ ---------------------------------------------------------------------------*/ -#if FF_DEFINED != 63463 /* Revision ID */ +#if FF_DEFINED != 86604 /* Revision ID */ #error Wrong include file (ff.h). #endif +/* Limits and boundaries */ +#define MAX_DIR 0x200000 /* Max size of FAT directory */ +#define MAX_DIR_EX 0x10000000 /* Max size of exFAT directory */ +#define MAX_FAT12 0xFF5 /* Max FAT12 clusters (differs from specs, but right for real DOS/Windows behavior) */ +#define MAX_FAT16 0xFFF5 /* Max FAT16 clusters (differs from specs, but right for real DOS/Windows behavior) */ +#define MAX_FAT32 0x0FFFFFF5 /* Max FAT32 clusters (not specified, practical limit) */ +#define MAX_EXFAT 0x7FFFFFFD /* Max exFAT clusters (differs from specs, implementation limit) */ + + /* Character code support macros */ #define IsUpper(c) ((c) >= 'A' && (c) <= 'Z') #define IsLower(c) ((c) >= 'a' && (c) <= 'z') @@ -48,18 +57,18 @@ #define IsSurrogateL(c) ((c) >= 0xDC00 && (c) <= 0xDFFF) -/* Additional file attribute bits for internal use */ -#define AM_VOL 0x08 /* Volume label */ -#define AM_LFN 0x0F /* LFN entry */ -#define AM_MASK 0x3F /* Mask of defined bits */ - - /* Additional file access control and file status flags for internal use */ #define FA_SEEKEND 0x20 /* Seek to end of the file on file open */ #define FA_MODIFIED 0x40 /* File has been modified */ #define FA_DIRTY 0x80 /* FIL.buf[] needs to be written-back */ +/* Additional file attribute bits for internal use */ +#define AM_VOL 0x08 /* Volume label */ +#define AM_LFN 0x0F /* LFN entry */ +#define AM_MASK 0x3F /* Mask of defined bits */ + + /* Name status flags in fn[11] */ #define NSFLAG 11 /* Index of the name status byte */ #define NS_LOSS 0x01 /* Out of 8.3 format */ @@ -72,13 +81,13 @@ #define NS_NONAME 0x80 /* Not followed */ -/* Limits and boundaries */ -#define MAX_DIR 0x200000 /* Max size of FAT directory */ -#define MAX_DIR_EX 0x10000000 /* Max size of exFAT directory */ -#define MAX_FAT12 0xFF5 /* Max FAT12 clusters (differs from specs, but right for real DOS/Windows behavior) */ -#define MAX_FAT16 0xFFF5 /* Max FAT16 clusters (differs from specs, but right for real DOS/Windows behavior) */ -#define MAX_FAT32 0x0FFFFFF5 /* Max FAT32 clusters (not specified, practical limit) */ -#define MAX_EXFAT 0x7FFFFFFD /* Max exFAT clusters (differs from specs, implementation limit) */ +/* exFAT directory entry types */ +#define ET_BITMAP 0x81 /* Allocation bitmap */ +#define ET_UPCASE 0x82 /* Up-case table */ +#define ET_VLABEL 0x83 /* Volume label */ +#define ET_FILEDIR 0x85 /* File and directory */ +#define ET_STREAM 0xC0 /* Stream extension */ +#define ET_FILENAME 0xC1 /* Name extension */ /* FatFs refers the FAT structure as simple byte array instead of structure member @@ -526,6 +535,7 @@ static WCHAR LfnBuf[FF_MAX_LFN + 1]; /* LFN working buffer */ #define CODEPAGE CodePage static WORD CodePage; /* Current code page */ static const BYTE *ExCvt, *DbcTbl; /* Pointer to current SBCS up-case table and DBCS code range table below */ + static const BYTE Ct437[] = TBL_CT437; static const BYTE Ct720[] = TBL_CT720; static const BYTE Ct737[] = TBL_CT737; @@ -1107,7 +1117,7 @@ static FRESULT sync_fs ( /* Returns FR_OK or FR_DISK_ERR */ if (res == FR_OK) { if (fs->fs_type == FS_FAT32 && fs->fsi_flag == 1) { /* FAT32: Update FSInfo sector if needed */ /* Create FSInfo structure */ - mem_set(fs->win, 0, SS(fs)); + mem_set(fs->win, 0, sizeof fs->win); st_word(fs->win + BS_55AA, 0xAA55); st_dword(fs->win + FSI_LeadSig, 0x41615252); st_dword(fs->win + FSI_StrucSig, 0x61417272); @@ -1307,7 +1317,7 @@ static DWORD find_bitmap ( /* 0:Not found, 2..:Cluster block found, 0xFFFFFFFF:D if (clst >= fs->n_fatent - 2) clst = 0; scl = val = clst; ctr = 0; for (;;) { - if (move_window(fs, fs->database + val / 8 / SS(fs)) != FR_OK) return 0xFFFFFFFF; /* (assuming bitmap is located top of the cluster heap) */ + if (move_window(fs, fs->bitbase + val / 8 / SS(fs)) != FR_OK) return 0xFFFFFFFF; i = val / 8 % SS(fs); bm = 1 << (val % 8); do { do { @@ -1345,9 +1355,9 @@ static FRESULT change_bitmap ( clst -= 2; /* The first bit corresponds to cluster #2 */ - sect = fs->database + clst / 8 / SS(fs); /* Sector address (assuming bitmap is located top of the cluster heap) */ - i = clst / 8 % SS(fs); /* Byte offset in the sector */ - bm = 1 << (clst % 8); /* Bit mask in the byte */ + sect = fs->bitbase + clst / 8 / SS(fs); /* Sector address */ + i = clst / 8 % SS(fs); /* Byte offset in the sector */ + bm = 1 << (clst % 8); /* Bit mask in the byte */ for (;;) { if (move_window(fs, sect++) != FR_OK) return FR_DISK_ERR; do { @@ -1420,7 +1430,7 @@ static FRESULT fill_last_frag ( static FRESULT remove_chain ( /* FR_OK(0):succeeded, !=0:error */ FFOBJID* obj, /* Corresponding object */ DWORD clst, /* Cluster to remove a chain from */ - DWORD pclst /* Previous cluster of clst (0:entire chain) */ + DWORD pclst /* Previous cluster of clst (0 if entire chain) */ ) { FRESULT res = FR_OK; @@ -1658,7 +1668,7 @@ static FRESULT dir_clear ( /* Returns FR_OK or FR_DISK_ERR */ if (sync_window(fs) != FR_OK) return FR_DISK_ERR; /* Flush disk access window */ sect = clst2sect(fs, clst); /* Top of the cluster */ fs->winsect = sect; /* Set window to top of the cluster */ - mem_set(fs->win, 0, SS(fs)); /* Clear window buffer */ + mem_set(fs->win, 0, sizeof fs->win); /* Clear window buffer */ #if FF_USE_LFN == 3 /* Quick table clear by using multi-secter write */ /* Allocate a temporary buffer */ for (szb = ((DWORD)fs->csize * SS(fs) >= MAX_MALLOC) ? MAX_MALLOC : fs->csize * SS(fs), ibuf = 0; szb > SS(fs) && (ibuf = ff_memalloc(szb)) == 0; szb /= 2) ; @@ -1888,7 +1898,7 @@ static int cmp_lfn ( /* 1:matched, 0:not matched */ for (wc = 1, s = 0; s < 13; s++) { /* Process all characters in the entry */ uc = ld_word(dir + LfnOfs[s]); /* Pick an LFN character */ if (wc != 0) { - if (i >= FF_MAX_LFN || ff_wtoupper(uc) != ff_wtoupper(lfnbuf[i++])) { /* Compare it */ + if (i >= FF_MAX_LFN + 1 || ff_wtoupper(uc) != ff_wtoupper(lfnbuf[i++])) { /* Compare it */ return 0; /* Not matched */ } wc = uc; @@ -1924,15 +1934,15 @@ static int pick_lfn ( /* 1:succeeded, 0:buffer overflow or invalid LFN entry */ for (wc = 1, s = 0; s < 13; s++) { /* Process all characters in the entry */ uc = ld_word(dir + LfnOfs[s]); /* Pick an LFN character */ if (wc != 0) { - if (i >= FF_MAX_LFN) return 0; /* Buffer overflow? */ + if (i >= FF_MAX_LFN + 1) return 0; /* Buffer overflow? */ lfnbuf[i++] = wc = uc; /* Store it */ } else { if (uc != 0xFFFF) return 0; /* Check filler */ } } - if (dir[LDIR_Ord] & LLEF) { /* Put terminator if it is the last LFN part */ - if (i >= FF_MAX_LFN) return 0; /* Buffer overflow? */ + if (dir[LDIR_Ord] & LLEF && wc != 0) { /* Put terminator if it is the last LFN part and not terminated */ + if (i >= FF_MAX_LFN + 1) return 0; /* Buffer overflow? */ lfnbuf[i] = 0; } @@ -2168,33 +2178,33 @@ static FRESULT load_xdir ( /* FR_INT_ERR: invalid entry block */ BYTE* dirb = dp->obj.fs->dirbuf; /* Pointer to the on-memory direcotry entry block 85+C0+C1s */ - /* Load 85 entry */ + /* Load file-directory entry */ res = move_window(dp->obj.fs, dp->sect); if (res != FR_OK) return res; - if (dp->dir[XDIR_Type] != 0x85) return FR_INT_ERR; /* Invalid order */ + if (dp->dir[XDIR_Type] != ET_FILEDIR) return FR_INT_ERR; /* Invalid order */ mem_cpy(dirb + 0 * SZDIRE, dp->dir, SZDIRE); sz_ent = (dirb[XDIR_NumSec] + 1) * SZDIRE; if (sz_ent < 3 * SZDIRE || sz_ent > 19 * SZDIRE) return FR_INT_ERR; - /* Load C0 entry */ + /* Load stream-extension entry */ res = dir_next(dp, 0); if (res == FR_NO_FILE) res = FR_INT_ERR; /* It cannot be */ if (res != FR_OK) return res; res = move_window(dp->obj.fs, dp->sect); if (res != FR_OK) return res; - if (dp->dir[XDIR_Type] != 0xC0) return FR_INT_ERR; /* Invalid order */ + if (dp->dir[XDIR_Type] != ET_STREAM) return FR_INT_ERR; /* Invalid order */ mem_cpy(dirb + 1 * SZDIRE, dp->dir, SZDIRE); if (MAXDIRB(dirb[XDIR_NumName]) > sz_ent) return FR_INT_ERR; - /* Load C1 entries */ - i = 2 * SZDIRE; /* C1 offset to load */ + /* Load file-name entries */ + i = 2 * SZDIRE; /* Name offset to load */ do { res = dir_next(dp, 0); if (res == FR_NO_FILE) res = FR_INT_ERR; /* It cannot be */ if (res != FR_OK) return res; res = move_window(dp->obj.fs, dp->sect); if (res != FR_OK) return res; - if (dp->dir[XDIR_Type] != 0xC1) return FR_INT_ERR; /* Invalid order */ + if (dp->dir[XDIR_Type] != ET_FILENAME) return FR_INT_ERR; /* Invalid order */ if (i < MAXDIRB(FF_MAX_LFN)) mem_cpy(dirb + i, dp->dir, SZDIRE); } while ((i += SZDIRE) < sz_ent); @@ -2299,16 +2309,16 @@ static void create_xdir ( WCHAR wc; - /* Create 85,C0 entry */ + /* Create file-directory and stream-extension entry */ mem_set(dirb, 0, 2 * SZDIRE); - dirb[0 * SZDIRE + XDIR_Type] = 0x85; /* 85 entry */ - dirb[1 * SZDIRE + XDIR_Type] = 0xC0; /* C0 entry */ + dirb[0 * SZDIRE + XDIR_Type] = ET_FILEDIR; + dirb[1 * SZDIRE + XDIR_Type] = ET_STREAM; - /* Create C1 entries */ - i = SZDIRE * 2; /* Top of C1 entries */ + /* Create file-name entries */ + i = SZDIRE * 2; /* Top of file_name entries */ nlen = nc1 = 0; wc = 1; do { - dirb[i++] = 0xC1; dirb[i++] = 0; /* Entry type C1 */ + dirb[i++] = ET_FILENAME; dirb[i++] = 0; do { /* Fill name field */ if (wc != 0 && (wc = lfn[nlen]) != 0) nlen++; /* Get a character if exist */ st_word(dirb + i, wc); /* Store it */ @@ -2332,8 +2342,8 @@ static void create_xdir ( /* Read an object from the directory */ /*-----------------------------------------------------------------------*/ -#define dir_read_file(dp) dir_read(dp, 0) -#define dir_read_label(dp) dir_read(dp, 1) +#define DIR_READ_FILE(dp) dir_read(dp, 0) +#define DIR_READ_LABEL(dp) dir_read(dp, 1) static FRESULT dir_read ( DIR* dp, /* Pointer to the directory object */ @@ -2342,7 +2352,7 @@ static FRESULT dir_read ( { FRESULT res = FR_NO_FILE; FATFS *fs = dp->obj.fs; - BYTE a, c; + BYTE attr, b; #if FF_USE_LFN BYTE ord = 0xFF, sum = 0xFF; #endif @@ -2350,16 +2360,16 @@ static FRESULT dir_read ( while (dp->sect) { res = move_window(fs, dp->sect); if (res != FR_OK) break; - c = dp->dir[DIR_Name]; /* Test for the entry type */ - if (c == 0) { + b = dp->dir[DIR_Name]; /* Test for the entry type */ + if (b == 0) { res = FR_NO_FILE; break; /* Reached to end of the directory */ } #if FF_FS_EXFAT if (fs->fs_type == FS_EXFAT) { /* On the exFAT volume */ if (FF_USE_LABEL && vol) { - if (c == 0x83) break; /* Volume label entry? */ + if (b == ET_VLABEL) break; /* Volume label entry? */ } else { - if (c == 0x85) { /* Start of the file entry block? */ + if (b == ET_FILEDIR) { /* Start of the file entry block? */ dp->blk_ofs = dp->dptr; /* Get location of the block */ res = load_xdir(dp); /* Load the entry block */ if (res == FR_OK) { @@ -2371,19 +2381,19 @@ static FRESULT dir_read ( } else #endif { /* On the FAT/FAT32 volume */ - dp->obj.attr = a = dp->dir[DIR_Attr] & AM_MASK; /* Get attribute */ + dp->obj.attr = attr = dp->dir[DIR_Attr] & AM_MASK; /* Get attribute */ #if FF_USE_LFN /* LFN configuration */ - if (c == DDEM || c == '.' || (int)((a & ~AM_ARC) == AM_VOL) != vol) { /* An entry without valid data */ + if (b == DDEM || b == '.' || (int)((attr & ~AM_ARC) == AM_VOL) != vol) { /* An entry without valid data */ ord = 0xFF; } else { - if (a == AM_LFN) { /* An LFN entry is found */ - if (c & LLEF) { /* Is it start of an LFN sequence? */ + if (attr == AM_LFN) { /* An LFN entry is found */ + if (b & LLEF) { /* Is it start of an LFN sequence? */ sum = dp->dir[LDIR_Chksum]; - c &= (BYTE)~LLEF; ord = c; + b &= (BYTE)~LLEF; ord = b; dp->blk_ofs = dp->dptr; } /* Check LFN validity and capture it */ - ord = (c == ord && sum == dp->dir[LDIR_Chksum] && pick_lfn(fs->lfnbuf, dp->dir)) ? ord - 1 : 0xFF; + ord = (b == ord && sum == dp->dir[LDIR_Chksum] && pick_lfn(fs->lfnbuf, dp->dir)) ? ord - 1 : 0xFF; } else { /* An SFN entry is found */ if (ord != 0 || sum != sum_sfn(dp->dir)) { /* Is there a valid LFN? */ dp->blk_ofs = 0xFFFFFFFF; /* It has no LFN. */ @@ -2392,7 +2402,7 @@ static FRESULT dir_read ( } } #else /* Non LFN configuration */ - if (c != DDEM && c != '.' && a != AM_LFN && (int)((a & ~AM_ARC) == AM_VOL) == vol) { /* Is it a valid entry? */ + if (b != DDEM && b != '.' && attr != AM_LFN && (int)((attr & ~AM_ARC) == AM_VOL) == vol) { /* Is it a valid entry? */ break; } #endif @@ -2432,7 +2442,7 @@ static FRESULT dir_find ( /* FR_OK(0):succeeded, !=0:error */ UINT di, ni; WORD hash = xname_sum(fs->lfnbuf); /* Hash value of the name to find */ - while ((res = dir_read_file(dp)) == FR_OK) { /* Read an item */ + while ((res = DIR_READ_FILE(dp)) == FR_OK) { /* Read an item */ #if FF_MAX_LFN < 255 if (fs->dirbuf[XDIR_NumName] > FF_MAX_LFN) continue; /* Skip comparison if inaccessible object name */ #endif @@ -2511,17 +2521,17 @@ static FRESULT dir_register ( /* FR_OK:succeeded, FR_DENIED:no free entry or too #if FF_FS_EXFAT if (fs->fs_type == FS_EXFAT) { /* On the exFAT volume */ nent = (nlen + 14) / 15 + 2; /* Number of entries to allocate (85+C0+C1s) */ - res = dir_alloc(dp, nent); /* Allocate entries */ + res = dir_alloc(dp, nent); /* Allocate directory entries */ if (res != FR_OK) return res; dp->blk_ofs = dp->dptr - SZDIRE * (nent - 1); /* Set the allocated entry block offset */ - if (dp->obj.stat & 4) { /* Has the directory been stretched? */ + if (dp->obj.stat & 4) { /* Has the directory been stretched by new allocation? */ dp->obj.stat &= ~4; res = fill_first_frag(&dp->obj); /* Fill the first fragment on the FAT if needed */ if (res != FR_OK) return res; res = fill_last_frag(&dp->obj, dp->clust, 0xFFFFFFFF); /* Fill the last fragment on the FAT if needed */ if (res != FR_OK) return res; - if (dp->obj.sclust != 0) { /* Is it a sub directory? */ + if (dp->obj.sclust != 0) { /* Is it a sub-directory? */ DIR dj; res = load_obj_xdir(&dj, &dp->obj); /* Load the object status */ @@ -2653,6 +2663,7 @@ static void get_fileinfo ( { UINT si, di; #if FF_USE_LFN + BYTE lcf; WCHAR wc, hs; FATFS *fs = dp->obj.fs; #else @@ -2713,9 +2724,10 @@ static void get_fileinfo ( if (di == 0) { /* If LFN and SFN both are invalid, this object is inaccesible */ fno->fname[di++] = '?'; } else { - for (si = di = 0; fno->altname[si]; si++, di++) { /* Copy altname[] to fname[] with case information */ + for (si = di = 0, lcf = NS_BODY; fno->altname[si]; si++, di++) { /* Copy altname[] to fname[] with case information */ wc = (WCHAR)fno->altname[si]; - if (IsUpper(wc) && (dp->dir[DIR_NTres] & ((si >= 9) ? NS_EXT : NS_BODY))) wc += 0x20; + if (wc == '.') lcf = NS_EXT; + if (IsUpper(wc) && (dp->dir[DIR_NTres] & lcf)) wc += 0x20; fno->fname[di] = (TCHAR)wc; } } @@ -3272,7 +3284,7 @@ static FRESULT find_volume ( /* FR_OK(0): successful, !=0: an error occurred */ if (SS(fs) > FF_MAX_SS || SS(fs) < FF_MIN_SS || (SS(fs) & (SS(fs) - 1))) return FR_DISK_ERR; #endif - /* Find an FAT partition on the drive. Supports only generic partitioning rules, FDISK and SFD. */ + /* Find an FAT partition on the drive. Supports only generic partitioning rules, FDISK (MBR) and SFD (w/o partition). */ bsect = 0; fmt = check_fs(fs, bsect); /* Load sector 0 and check if it is an FAT-VBR as SFD */ if (fmt == 2 || (fmt < 2 && LD2PT(vol) != 0)) { /* Not an FAT-VBR or forced partition number */ @@ -3301,13 +3313,12 @@ static FRESULT find_volume ( /* FR_OK(0): successful, !=0: an error occurred */ #if FF_FS_EXFAT if (fmt == 1) { QWORD maxlba; + DWORD so, cv, bcl; for (i = BPB_ZeroedEx; i < BPB_ZeroedEx + 53 && fs->win[i] == 0; i++) ; /* Check zero filler */ - if (i < BPB_ZeroedEx + 53) - return FR_NO_FILESYSTEM; + if (i < BPB_ZeroedEx + 53) return FR_NO_FILESYSTEM; - if (ld_word(fs->win + BPB_FSVerEx) != 0x100) - return FR_NO_FILESYSTEM; /* Check exFAT version (must be version 1.0) */ + if (ld_word(fs->win + BPB_FSVerEx) != 0x100) return FR_NO_FILESYSTEM; /* Check exFAT version (must be version 1.0) */ if (1 << fs->win[BPB_BytsPerSecEx] != SS(fs)) { /* (BPB_BytsPerSecEx must be equal to the physical sector size) */ EFSPRINTF("EXSPS"); @@ -3315,8 +3326,7 @@ static FRESULT find_volume ( /* FR_OK(0): successful, !=0: an error occurred */ } maxlba = ld_qword(fs->win + BPB_TotSecEx) + bsect; /* Last LBA + 1 of the volume */ - if (maxlba >= 0x100000000) - return FR_NO_FILESYSTEM; /* (It cannot be handled in 32-bit LBA) */ + if (maxlba >= 0x100000000) return FR_NO_FILESYSTEM; /* (It cannot be handled in 32-bit LBA) */ fs->fsize = ld_dword(fs->win + BPB_FatSzEx); /* Number of sectors per FAT */ @@ -3327,35 +3337,49 @@ static FRESULT find_volume ( /* FR_OK(0): successful, !=0: an error occurred */ } fs->csize = 1 << fs->win[BPB_SecPerClusEx]; /* Cluster size */ - if (fs->csize == 0) { - return FR_NO_FILESYSTEM; /* (Must be 1..32768) */ - } + if (fs->csize == 0) return FR_NO_FILESYSTEM; /* (Must be 1..32768) */ nclst = ld_dword(fs->win + BPB_NumClusEx); /* Number of clusters */ - if (nclst > MAX_EXFAT) - return FR_NO_FILESYSTEM; /* (Too many clusters) */ + if (nclst > MAX_EXFAT) return FR_NO_FILESYSTEM; /* (Too many clusters) */ fs->n_fatent = nclst + 2; /* Boundaries and Limits */ fs->volbase = bsect; fs->database = bsect + ld_dword(fs->win + BPB_DataOfsEx); fs->fatbase = bsect + ld_dword(fs->win + BPB_FatOfsEx); - if (maxlba < (QWORD)fs->database + nclst * fs->csize) - return FR_NO_FILESYSTEM; /* (Volume size must not be smaller than the size required) */ + if (maxlba < (QWORD)fs->database + nclst * fs->csize) return FR_NO_FILESYSTEM; /* (Volume size must not be smaller than the size requiered) */ fs->dirbase = ld_dword(fs->win + BPB_RootClusEx); - /* Check if bitmap location is in assumption (at the first cluster) */ - if (move_window(fs, clst2sect(fs, fs->dirbase)) != FR_OK) { - EFSPRINTF("EXBM1C"); - return FR_DISK_ERR; + /* Get bitmap location and check if it is contiguous (implementation assumption) */ + so = i = 0; + for (;;) { /* Find the bitmap entry in the root directory (in only first cluster) */ + if (i == 0) { + if (so >= fs->csize) return FR_NO_FILESYSTEM; /* Not found? */ + if (move_window(fs, clst2sect(fs, fs->dirbase) + so) != FR_OK) { + EFSPRINTF("EXBM1C"); + return FR_DISK_ERR; + } + so++; + } + if (fs->win[i] == ET_BITMAP) break; /* Is it a bitmap entry? */ + i = (i + SZDIRE) % SS(fs); /* Next entry */ } - for (i = 0; i < SS(fs); i += SZDIRE) { - if (fs->win[i] == 0x81 && ld_dword(fs->win + i + 20) == 2) break; /* 81 entry with cluster #2? */ - } - if (i == SS(fs)) { + bcl = ld_dword(fs->win + i + 20); /* Bitmap cluster */ + if (bcl < 2 || bcl >= fs->n_fatent) { EFSPRINTF("EXBMM"); return FR_NO_FILESYSTEM; } + fs->bitbase = fs->database + fs->csize * (bcl - 2); /* Bitmap sector */ + for (;;) { /* Check if bitmap is contiguous */ + if (move_window(fs, fs->fatbase + bcl / (SS(fs) / 4)) != FR_OK) return FR_DISK_ERR; + cv = ld_dword(fs->win + bcl % (SS(fs) / 4) * 4); + if (cv == 0xFFFFFFFF) break; /* Last link? */ + if (cv != ++bcl) { + EFSPRINTF("EXBMM"); + return FR_NO_FILESYSTEM; /* Fragmented? */ + } + } + #if !FF_FS_READONLY fs->last_clst = fs->free_clst = 0xFFFFFFFF; /* Initialize cluster allocation information */ #endif @@ -3373,38 +3397,31 @@ static FRESULT find_volume ( /* FR_OK(0): successful, !=0: an error occurred */ fs->fsize = fasize; fs->n_fats = fs->win[BPB_NumFATs]; /* Number of FATs */ - if (fs->n_fats != 1 && fs->n_fats != 2) - return FR_NO_FILESYSTEM; /* (Must be 1 or 2) */ + if (fs->n_fats != 1 && fs->n_fats != 2) return FR_NO_FILESYSTEM; /* (Must be 1 or 2) */ fasize *= fs->n_fats; /* Number of sectors for FAT area */ fs->csize = fs->win[BPB_SecPerClus]; /* Cluster size */ - if (fs->csize == 0 || (fs->csize & (fs->csize - 1))) - return FR_NO_FILESYSTEM; /* (Must be power of 2) */ + if (fs->csize == 0 || (fs->csize & (fs->csize - 1))) return FR_NO_FILESYSTEM; /* (Must be power of 2) */ fs->n_rootdir = ld_word(fs->win + BPB_RootEntCnt); /* Number of root directory entries */ - if (fs->n_rootdir % (SS(fs) / SZDIRE)) - return FR_NO_FILESYSTEM; /* (Must be sector aligned) */ + if (fs->n_rootdir % (SS(fs) / SZDIRE)) return FR_NO_FILESYSTEM; /* (Must be sector aligned) */ tsect = ld_word(fs->win + BPB_TotSec16); /* Number of sectors on the volume */ if (tsect == 0) tsect = ld_dword(fs->win + BPB_TotSec32); nrsv = ld_word(fs->win + BPB_RsvdSecCnt); /* Number of reserved sectors */ - if (nrsv == 0) - return FR_NO_FILESYSTEM; /* (Must not be 0) */ + if (nrsv == 0) return FR_NO_FILESYSTEM; /* (Must not be 0) */ /* Determine the FAT sub type */ sysect = nrsv + fasize + fs->n_rootdir / (SS(fs) / SZDIRE); /* RSV + FAT + DIR */ - if (tsect < sysect) - return FR_NO_FILESYSTEM; /* (Invalid volume size) */ + if (tsect < sysect) return FR_NO_FILESYSTEM; /* (Invalid volume size) */ nclst = (tsect - sysect) / fs->csize; /* Number of clusters */ - if (nclst == 0) - return FR_NO_FILESYSTEM; /* (Invalid volume size) */ + if (nclst == 0) return FR_NO_FILESYSTEM; /* (Invalid volume size) */ fmt = 0; if (nclst <= MAX_FAT32) fmt = FS_FAT32; if (nclst <= MAX_FAT16) fmt = FS_FAT16; if (nclst <= MAX_FAT12) fmt = FS_FAT12; - if (fmt == 0) - return FR_NO_FILESYSTEM; + if (fmt == 0) return FR_NO_FILESYSTEM; /* Boundaries and Limits */ fs->n_fatent = nclst + 2; /* Number of FAT entries */ @@ -3412,21 +3429,17 @@ static FRESULT find_volume ( /* FR_OK(0): successful, !=0: an error occurred */ fs->fatbase = bsect + nrsv; /* FAT start sector */ fs->database = bsect + sysect; /* Data start sector */ if (fmt == FS_FAT32) { - if (ld_word(fs->win + BPB_FSVer32) != 0) - return FR_NO_FILESYSTEM; /* (Must be FAT32 revision 0.0) */ - if (fs->n_rootdir != 0) - return FR_NO_FILESYSTEM; /* (BPB_RootEntCnt must be 0) */ + if (ld_word(fs->win + BPB_FSVer32) != 0) return FR_NO_FILESYSTEM; /* (Must be FAT32 revision 0.0) */ + if (fs->n_rootdir != 0) return FR_NO_FILESYSTEM; /* (BPB_RootEntCnt must be 0) */ fs->dirbase = ld_dword(fs->win + BPB_RootClus32); /* Root directory start cluster */ szbfat = fs->n_fatent * 4; /* (Needed FAT size) */ } else { - if (fs->n_rootdir == 0) - return FR_NO_FILESYSTEM; /* (BPB_RootEntCnt must not be 0) */ + if (fs->n_rootdir == 0) return FR_NO_FILESYSTEM; /* (BPB_RootEntCnt must not be 0) */ fs->dirbase = fs->fatbase + fasize; /* Root directory start sector */ szbfat = (fmt == FS_FAT16) ? /* (Needed FAT size) */ fs->n_fatent * 2 : fs->n_fatent * 3 / 2 + (fs->n_fatent & 1); } - if (fs->fsize < (szbfat + (SS(fs) - 1)) / SS(fs)) - return FR_NO_FILESYSTEM; /* (BPB_FATSz must not be less than the size needed) */ + if (fs->fsize < (szbfat + (SS(fs) - 1)) / SS(fs)) return FR_NO_FILESYSTEM; /* (BPB_FATSz must not be less than the size needed) */ #if !FF_FS_READONLY /* Get FSInfo if available */ @@ -3459,7 +3472,7 @@ static FRESULT find_volume ( /* FR_OK(0): successful, !=0: an error occurred */ #if FF_USE_LFN == 1 fs->lfnbuf = LfnBuf; /* Static LFN working buffer */ #if FF_FS_EXFAT - fs->dirbuf = DirBuf; /* Static directory block scratchpad buffer */ + fs->dirbuf = DirBuf; /* Static directory block scratchpad buuffer */ #endif #endif #if FF_FS_RPATH != 0 @@ -3722,7 +3735,7 @@ FRESULT f_open ( fp->fptr = 0; /* Set file pointer top of the file */ #if !FF_FS_READONLY #if !FF_FS_TINY - mem_set(fp->buf, 0, FF_MAX_SS); /* Clear sector buffer */ + mem_set(fp->buf, 0, sizeof fp->buf); /* Clear sector buffer */ #endif if ((mode & FA_SEEKEND) && fp->obj.objsize > 0) { /* Seek to end of file if FA_OPEN_APPEND is specified */ fp->fptr = fp->obj.objsize; /* Offset to seek */ @@ -3819,9 +3832,7 @@ FRESULT f_read ( fp->clust = clst; /* Update current cluster */ } sect = clst2sect(fs, fp->clust); /* Get current sector */ - if (sect == 0) { - ABORT(fs, FR_INT_ERR); - } + if (sect == 0) ABORT(fs, FR_INT_ERR); sect += csect; cc = btr / SS(fs); /* When remaining bytes >= sector size, */ if (cc > 0) { /* Read maximum contiguous sectors directly */ @@ -3906,10 +3917,7 @@ FRESULT f_write ( EFSPRINTF("FOV"); LEAVE_FF(fs, res); /* Check validity */ } - if (!(fp->flag & FA_WRITE)) { - EFSPRINTF("NOACCESS"); - LEAVE_FF(fs, FR_DENIED); /* Check access mode */ - } + if (!(fp->flag & FA_WRITE)) LEAVE_FF(fs, FR_DENIED); /* Check access mode */ /* Check fptr wrap-around (file size cannot reach 4 GiB at FAT volume) */ if ((!FF_FS_EXFAT || fs->fs_type != FS_EXFAT) && (DWORD)(fp->fptr + btw) < (DWORD)fp->fptr) { @@ -3955,15 +3963,12 @@ FRESULT f_write ( if (fs->winsect == fp->sect && sync_window(fs) != FR_OK) ABORT(fs, FR_DISK_ERR); /* Write-back sector cache */ #else if (fp->flag & FA_DIRTY) { /* Write-back sector cache */ - if (disk_write(fs->pdrv, fp->buf, fp->sect, 1) != RES_OK) - ABORT(fs, FR_DISK_ERR); + if (disk_write(fs->pdrv, fp->buf, fp->sect, 1) != RES_OK) ABORT(fs, FR_DISK_ERR); fp->flag &= (BYTE)~FA_DIRTY; } #endif sect = clst2sect(fs, fp->clust); /* Get current sector */ - if (sect == 0) { - ABORT(fs, FR_INT_ERR); - } + if (sect == 0) ABORT(fs, FR_INT_ERR); sect += csect; cc = btw / SS(fs); /* When remaining bytes >= sector size, */ if (cc > 0) { /* Write maximum contiguous sectors directly */ @@ -3998,8 +4003,9 @@ FRESULT f_write ( #else if (fp->sect != sect && /* Fill sector cache with file data */ fp->fptr < fp->obj.objsize && - disk_read(fs->pdrv, fp->buf, sect, 1) != RES_OK) + disk_read(fs->pdrv, fp->buf, sect, 1) != RES_OK) { ABORT(fs, FR_DISK_ERR); + } #endif fp->sect = sect; } @@ -4245,6 +4251,7 @@ FRESULT f_getcwd ( /* Get logical drive */ + buff[0] = 0; /* Set null string to get current volume */ res = find_volume((const TCHAR**)&buff, &fs, 0); /* Get current volume */ if (res == FR_OK) { dj.obj.fs = fs; @@ -4263,7 +4270,7 @@ FRESULT f_getcwd ( res = dir_sdi(&dj, 0); if (res != FR_OK) break; do { /* Find the entry links to the child directory */ - res = dir_read_file(&dj); + res = DIR_READ_FILE(&dj); if (res != FR_OK) break; if (ccl == ld_clust(fs, dj.dir)) break; /* Found the entry */ res = dir_next(&dj, 0); @@ -4595,7 +4602,7 @@ FRESULT f_readdir ( res = dir_sdi(dp, 0); /* Rewind the directory object */ } else { INIT_NAMBUF(fs); - res = dir_read_file(dp); /* Read an item */ + res = DIR_READ_FILE(dp); /* Read an item */ if (res == FR_NO_FILE) res = FR_OK; /* Ignore end of directory */ if (res == FR_OK) { /* A valid entry is found */ get_fileinfo(dp, fno); /* Get the object information */ @@ -4740,7 +4747,7 @@ FRESULT f_getfree ( UINT b; clst = fs->n_fatent - 2; /* Number of clusters */ - sect = fs->database; /* Assuming bitmap starts at cluster 2 */ + sect = fs->bitbase; /* Bitmap sector */ i = 0; /* Offset in the sector */ do { /* Counts numbuer of bits with zero in the bitmap */ if (i == 0) { @@ -4903,7 +4910,7 @@ FRESULT f_unlink ( #endif res = dir_sdi(&sdj, 0); if (res == FR_OK) { - res = dir_read_file(&sdj); /* Test if the directory is empty */ + res = DIR_READ_FILE(&sdj); /* Test if the directory is empty */ if (res == FR_OK) res = FR_DENIED; /* Not empty? */ if (res == FR_NO_FILE) res = FR_OK; /* Empty? */ } @@ -4943,47 +4950,43 @@ FRESULT f_mkdir ( DIR dj; FFOBJID sobj; FATFS *fs; - BYTE *dir; DWORD dcl, pcl, tm; DEF_NAMBUF - /* Get logical drive */ - res = find_volume(&path, &fs, FA_WRITE); + res = find_volume(&path, &fs, FA_WRITE); /* Get logical drive */ if (res == FR_OK) { dj.obj.fs = fs; INIT_NAMBUF(fs); res = follow_path(&dj, path); /* Follow the file path */ - if (res == FR_OK) res = FR_EXIST; /* Any object with same name is already existing */ - if (FF_FS_RPATH && res == FR_NO_FILE && (dj.fn[NSFLAG] & NS_DOT)) { + if (res == FR_OK) res = FR_EXIST; /* Name collision? */ + if (FF_FS_RPATH && res == FR_NO_FILE && (dj.fn[NSFLAG] & NS_DOT)) { /* Invalid name? */ res = FR_INVALID_NAME; } - if (res == FR_NO_FILE) { /* Can create a new directory */ + if (res == FR_NO_FILE) { /* It is clear to create a new directory */ sobj.fs = fs; /* New object id to create a new chain */ dcl = create_chain(&sobj, 0); /* Allocate a cluster for the new directory */ res = FR_OK; - if (dcl == 0) res = FR_DENIED; /* No space to allocate a new cluster */ - if (dcl == 1) res = FR_INT_ERR; - if (dcl == 0xFFFFFFFF) res = FR_DISK_ERR; - if (res == FR_OK) res = sync_window(fs); /* Flush FAT */ + if (dcl == 0) res = FR_DENIED; /* No space to allocate a new cluster? */ + if (dcl == 1) res = FR_INT_ERR; /* Any insanity? */ + if (dcl == 0xFFFFFFFF) res = FR_DISK_ERR; /* Disk error? */ tm = GET_FATTIME(); - if (res == FR_OK) { /* Initialize the new directory table */ - res = dir_clear(fs, dcl); /* Clean up the new table */ - if (res == FR_OK && (!FF_FS_EXFAT || fs->fs_type != FS_EXFAT)) { /* Create dot entries (FAT only) */ - dir = fs->win; - mem_set(dir + DIR_Name, ' ', 11); /* Create "." entry */ - dir[DIR_Name] = '.'; - dir[DIR_Attr] = AM_DIR; - st_dword(dir + DIR_ModTime, tm); - st_clust(fs, dir, dcl); - mem_cpy(dir + SZDIRE, dir, SZDIRE); /* Create ".." entry */ - dir[SZDIRE + 1] = '.'; pcl = dj.obj.sclust; - st_clust(fs, dir + SZDIRE, pcl); - fs->wflag = 1; - } - } if (res == FR_OK) { - res = dir_register(&dj); /* Register the object to the directoy */ + res = dir_clear(fs, dcl); /* Clean up the new table */ + if (res == FR_OK) { + if (!FF_FS_EXFAT || fs->fs_type != FS_EXFAT) { /* Create dot entries (FAT only) */ + mem_set(fs->win + DIR_Name, ' ', 11); /* Create "." entry */ + fs->win[DIR_Name] = '.'; + fs->win[DIR_Attr] = AM_DIR; + st_dword(fs->win + DIR_ModTime, tm); + st_clust(fs, fs->win, dcl); + mem_cpy(fs->win + SZDIRE, fs->win, SZDIRE); /* Create ".." entry */ + fs->win[SZDIRE + 1] = '.'; pcl = dj.obj.sclust; + st_clust(fs, fs->win + SZDIRE, pcl); + fs->wflag = 1; + } + res = dir_register(&dj); /* Register the object to the parent directoy */ + } } if (res == FR_OK) { #if FF_FS_EXFAT @@ -4998,17 +5001,16 @@ FRESULT f_mkdir ( } else #endif { - dir = dj.dir; - st_dword(dir + DIR_ModTime, tm); /* Created time */ - st_clust(fs, dir, dcl); /* Table start cluster */ - dir[DIR_Attr] = AM_DIR; /* Attribute */ + st_dword(dj.dir + DIR_ModTime, tm); /* Created time */ + st_clust(fs, dj.dir, dcl); /* Table start cluster */ + dj.dir[DIR_Attr] = AM_DIR; /* Attribute */ fs->wflag = 1; } if (res == FR_OK) { res = sync_fs(fs); } } else { - remove_chain(&dj.obj, dcl, 0); /* Could not register, remove cluster chain */ + remove_chain(&sobj, dcl, 0); /* Could not register, remove the allocated cluster */ } } FREE_NAMBUF(); @@ -5248,7 +5250,7 @@ FRESULT f_getlabel ( dj.obj.fs = fs; dj.obj.sclust = 0; /* Open root directory */ res = dir_sdi(&dj, 0); if (res == FR_OK) { - res = dir_read_label(&dj); /* Find a volume label entry */ + res = DIR_READ_LABEL(&dj); /* Find a volume label entry */ if (res == FR_OK) { #if FF_FS_EXFAT if (fs->fs_type == FS_EXFAT) { @@ -5393,7 +5395,7 @@ FRESULT f_setlabel ( dj.obj.fs = fs; dj.obj.sclust = 0; /* Open root directory */ res = dir_sdi(&dj, 0); if (res == FR_OK) { - res = dir_read_label(&dj); /* Get volume label entry */ + res = DIR_READ_LABEL(&dj); /* Get volume label entry */ if (res == FR_OK) { if (FF_FS_EXFAT && fs->fs_type == FS_EXFAT) { dj.dir[XDIR_NumLabel] = (BYTE)di; /* Change the volume label */ @@ -5415,7 +5417,7 @@ FRESULT f_setlabel ( if (res == FR_OK) { mem_set(dj.dir, 0, SZDIRE); /* Clean the entry */ if (FF_FS_EXFAT && fs->fs_type == FS_EXFAT) { - dj.dir[XDIR_Type] = 0x83; /* Create 83 entry */ + dj.dir[XDIR_Type] = ET_VLABEL; /* Create volume label entry */ dj.dir[XDIR_NumLabel] = (BYTE)di; mem_cpy(dj.dir + XDIR_Label, dirvn, 22); } else { @@ -5720,7 +5722,7 @@ FRESULT f_mkfs ( b_fat = b_vol + 32; /* FAT start at offset 32 */ sz_fat = ((sz_vol / au + 2) * 4 + ss - 1) / ss; /* Number of FAT sectors */ b_data = (b_fat + sz_fat + sz_blk - 1) & ~(sz_blk - 1); /* Align data area to the erase block boundary */ - if (b_data >= sz_vol / 2) LEAVE_MKFS(FR_MKFS_ABORTED); /* Too small volume? */ + if (b_data - b_vol >= sz_vol / 2) LEAVE_MKFS(FR_MKFS_ABORTED); /* Too small volume? */ n_clst = (sz_vol - (b_data - b_vol)) / au; /* Number of clusters */ if (n_clst <16) LEAVE_MKFS(FR_MKFS_ABORTED); /* Too few clusters? */ if (n_clst > MAX_EXFAT) LEAVE_MKFS(FR_MKFS_ABORTED); /* Too many clusters? */ @@ -5801,11 +5803,11 @@ FRESULT f_mkfs ( /* Initialize the root directory */ mem_set(buf, 0, szb_buf); - buf[SZDIRE * 0 + 0] = 0x83; /* 83 entry (volume label) */ - buf[SZDIRE * 1 + 0] = 0x81; /* 81 entry (allocation bitmap) */ + buf[SZDIRE * 0 + 0] = ET_VLABEL; /* Volume label entry */ + buf[SZDIRE * 1 + 0] = ET_BITMAP; /* Bitmap entry */ st_dword(buf + SZDIRE * 1 + 20, 2); /* cluster */ st_dword(buf + SZDIRE * 1 + 24, szb_bit); /* size */ - buf[SZDIRE * 2 + 0] = 0x82; /* 82 entry (up-case table) */ + buf[SZDIRE * 2 + 0] = ET_UPCASE; /* Up-case table entry */ st_dword(buf + SZDIRE * 2 + 4, sum); /* sum */ st_dword(buf + SZDIRE * 2 + 20, 2 + tbl[0]); /* cluster */ st_dword(buf + SZDIRE * 2 + 24, szb_case); /* size */ @@ -6293,8 +6295,7 @@ typedef struct { /* Putchar output buffer and work area */ } putbuff; -static -void putc_bfd ( /* Buffered write with code conversion */ +static void putc_bfd ( /* Buffered write with code conversion */ putbuff* pb, TCHAR c ) @@ -6405,7 +6406,7 @@ void putc_bfd ( /* Buffered write with code conversion */ #else /* Write it in ANSI/OEM */ if (hs != 0) return; wc = ff_uni2oem(wc, CODEPAGE); /* UTF-16 ==> ANSI/OEM */ - if (wc == 0) return;; + if (wc == 0) return; if (wc >= 0x100) { pb->buf[i++] = (BYTE)(wc >> 8); nc++; } @@ -6425,8 +6426,7 @@ void putc_bfd ( /* Buffered write with code conversion */ } -static -int putc_flush ( /* Flush left characters in the buffer */ +static int putc_flush ( /* Flush left characters in the buffer */ putbuff* pb ) { @@ -6439,8 +6439,7 @@ int putc_flush ( /* Flush left characters in the buffer */ } -static -void putc_init ( /* Initialize write buffer */ +static void putc_init ( /* Initialize write buffer */ putbuff* pb, FIL* fp ) diff --git a/bootloader/libs/fatfs/ff.h b/bootloader/libs/fatfs/ff.h index a8065d4..4751209 100644 --- a/bootloader/libs/fatfs/ff.h +++ b/bootloader/libs/fatfs/ff.h @@ -1,5 +1,5 @@ /*----------------------------------------------------------------------------/ -/ FatFs - Generic FAT Filesystem module R0.13b / +/ FatFs - Generic FAT Filesystem module R0.13c / /-----------------------------------------------------------------------------/ / / Copyright (C) 2018, ChaN, all right reserved. @@ -20,7 +20,7 @@ #ifndef FF_DEFINED -#define FF_DEFINED 63463 /* Revision ID */ +#define FF_DEFINED 86604 /* Revision ID */ #ifdef __cplusplus extern "C" { @@ -95,8 +95,8 @@ typedef DWORD FSIZE_t; /* Filesystem object structure (FATFS) */ typedef struct { - BYTE fs_type; /* Filesystem type (0:N/A) */ - BYTE pdrv; /* Physical drive number */ + BYTE fs_type; /* Filesystem type (0:not mounted) */ + BYTE pdrv; /* Associated physical drive */ BYTE n_fats; /* Number of FATs (1 or 2) */ BYTE wflag; /* win[] flag (b0:dirty) */ BYTE fsi_flag; /* FSINFO flags (b7:disabled, b0:dirty) */ @@ -133,6 +133,9 @@ typedef struct { DWORD fatbase; /* FAT base sector */ DWORD dirbase; /* Root directory base sector/cluster */ DWORD database; /* Data base sector */ +#if FF_FS_EXFAT + DWORD bitbase; /* Allocation bitmap base sector */ +#endif DWORD winsect; /* Current sector appearing in the win[] */ BYTE win[FF_MAX_SS]; /* Disk access window for Directory, FAT (and file data at tiny cfg) */ } FATFS; @@ -145,7 +148,7 @@ typedef struct { FATFS* fs; /* Pointer to the hosting volume of this object */ WORD id; /* Hosting volume mount ID */ BYTE attr; /* Object attribute */ - BYTE stat; /* Object chain status (b1-0: =0:not contiguous, =2:contiguous, =3:flagmented in this session, b2:sub-directory stretched) */ + BYTE stat; /* Object chain status (b1-0: =0:not contiguous, =2:contiguous, =3:fragmented in this session, b2:sub-directory stretched) */ DWORD sclust; /* Object data start cluster (0:no cluster or root directory) */ FSIZE_t objsize; /* Object size (valid when sclust != 0) */ #if FF_FS_EXFAT diff --git a/bootloader/libs/fatfs/ffconf.h b/bootloader/libs/fatfs/ffconf.h index 337445e..b4b4947 100644 --- a/bootloader/libs/fatfs/ffconf.h +++ b/bootloader/libs/fatfs/ffconf.h @@ -1,8 +1,8 @@ /*---------------------------------------------------------------------------/ -/ FatFs - Configuration file +/ FatFs Functional Configurations /---------------------------------------------------------------------------*/ -#define FFCONF_DEF 63463 /* Revision ID */ +#define FFCONF_DEF 86604 /* Revision ID */ /*---------------------------------------------------------------------------/ / Function Configurations @@ -232,7 +232,7 @@ #define FF_FS_EXFAT 1 /* 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. */ @@ -262,6 +262,7 @@ / lock control is independent of re-entrancy. */ +/* #include // O/S definitions */ #define FF_FS_REENTRANT 0 #define FF_FS_TIMEOUT 1000 #define FF_SYNC_t HANDLE @@ -282,8 +283,6 @@ / SemaphoreHandle_t and etc. A header file for O/S definitions needs to be / included somewhere in the scope of ff.h. */ -/* #include // O/S definitions */ - /*--- End of configuration options ---*/ diff --git a/bootloader/libs/fatfs/ffsystem.c b/bootloader/libs/fatfs/ffsystem.c index c15d0db..fa44f8e 100644 --- a/bootloader/libs/fatfs/ffsystem.c +++ b/bootloader/libs/fatfs/ffsystem.c @@ -1,6 +1,6 @@ /*------------------------------------------------------------------------*/ /* Sample Code of OS Dependent Functions for FatFs */ -/* (C) ChaN, 2017 */ +/* (C) ChaN, 2018 */ /* (C) CTCaer, 2018 */ /*------------------------------------------------------------------------*/ @@ -16,7 +16,7 @@ /* Allocate a memory block */ /*------------------------------------------------------------------------*/ -void* ff_memalloc ( /* Returns pointer to the allocated memory block (null on not enough core) */ +void* ff_memalloc ( /* Returns pointer to the allocated memory block (null if not enough core) */ UINT msize /* Number of bytes to allocate */ ) { @@ -29,7 +29,7 @@ void* ff_memalloc ( /* Returns pointer to the allocated memory block (null on no /*------------------------------------------------------------------------*/ void ff_memfree ( - void* mblock /* Pointer to the memory block to free (nothing to do for null) */ + void* mblock /* Pointer to the memory block to free (nothing to do if null) */ ) { free(mblock); /* Free the memory block with POSIX API */ diff --git a/bootloader/libs/fatfs/ffunicode.c b/bootloader/libs/fatfs/ffunicode.c index a57b4aa..bc23f80 100644 --- a/bootloader/libs/fatfs/ffunicode.c +++ b/bootloader/libs/fatfs/ffunicode.c @@ -1,5 +1,5 @@ /*------------------------------------------------------------------------*/ -/* Unicode handling functions for FatFs R0.13a */ +/* Unicode handling functions for FatFs R0.13c */ /*------------------------------------------------------------------------*/ /* 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 / @@ -7,7 +7,7 @@ / that function to avoid silly memory consumption. / /-------------------------------------------------------------------------*/ /* -/ Copyright (C) 2017, ChaN, all right reserved. +/ Copyright (C) 2018, ChaN, all right reserved. / / FatFs module is an open source software. Redistribution and use of FatFs in / source and binary forms, with or without modification, are permitted provided @@ -25,9 +25,9 @@ #include "ff.h" -#if FF_USE_LFN /* This module is blanked when non-LFN configuration */ +#if FF_USE_LFN /* This module will be blanked at non-LFN configuration */ -#if FF_DEFINED != 63463 /* Revision ID */ +#if FF_DEFINED != 86604 /* Revision ID */ #error Wrong include file (ff.h). #endif