diff --git a/doc/00index_e.html b/doc/00index_e.html index 8d8e6c7..d70f5e2 100644 --- a/doc/00index_e.html +++ b/doc/00index_e.html @@ -121,7 +121,7 @@

Resources

The FatFs module is a free software opened for education, research and development. You can use, modify and/or redistribute it for personal projects or commercial products without any restriction under your responsibility. For further information, refer to the application note.

-

When opt is 0, the function finds a contiguous data area and set it as suggested point for next allocation instead of allocating it to the file. The next cluster allocation is started at top of the contiguous area found by this function. Thus the write file is guaranteed be contiguous and no allocation delay until the size reaches that size at least unless any other operation to the volume with changes of FAT is performed.

+

When opt is 0, the function finds a contiguous data area and set it as suggested point for next allocation instead of allocating it to the file. The next cluster allocation is started at top of the contiguous area found by this function. Thus the write file is guaranteed be contiguous and no allocation delay until the size reaches that size at least unless any other changes to the volume is performed.

The contiguous file would have an advantage at time-critical read/write operations. It reduces some overheads in the file system and the storage media caused by random access due to fragmented file data. Especially, at the exFAT volume, any FAT access for the contiguous file is completely eliminated and storage media will be accessed sequentially.

Also the contiguous file data can be easily accessed directly via low-level disk functions but it is not recommended in consideration for future compatibility.

diff --git a/doc/en/fattime.html b/doc/en/fattime.html index 4ca8593..da3dc29 100644 --- a/doc/en/fattime.html +++ b/doc/en/fattime.html @@ -13,7 +13,7 @@

get_fattime

-

The get_fattime function gets current time.

+

The get_fattime function gets the current time.

 DWORD get_fattime (void);
 
@@ -22,7 +22,7 @@ DWORD get_fattime (void);

Return Value

-

Currnet local time is returned with packed into a DWORD value. The bit field is as follows:

+

Currnet local time is returned in bit-fields packed into a DWORD value. The bit field is as follows:

bit31:25
Year origin from the 1980 (0..127)
diff --git a/doc/en/filename.html b/doc/en/filename.html index 9bdb966..07916a2 100644 --- a/doc/en/filename.html +++ b/doc/en/filename.html @@ -36,7 +36,7 @@ /..Invalid nameThe root directory (sticks the top level)

When option _STR_VOLUME_ID is specified, also pre-defined strings can be used as drive identifier in the path name instead of a numeral. e.g. "sd:file1.txt", "ram:swapfile.dat" and DOS/Windows style drive letter, of course.

-

Remark: In this revision, R0.12, double dot name ".." cannot follow the parent directory on the exFAT volume. It will work as "." and stay there.

+

Remark: In this revision, double dot name ".." cannot follow the parent directory on the exFAT volume. It will work as "." and stay there.

diff --git a/doc/en/findfirst.html b/doc/en/findfirst.html index 35122c0..80b621e 100644 --- a/doc/en/findfirst.html +++ b/doc/en/findfirst.html @@ -61,11 +61,11 @@ FRESULT f_findfirst (

Description

-

After the directory specified by path could be opened, it starts to search the directory for the items with a name specified by pattern. If found, the information about the object is stored into the file information structure. For more information about file information structure, refer to f_readdir function.

+

After the directory specified by path could be opened, it starts to search the directory for items with the name specified by pattern. If the first item is found, the information about the object is stored into the file information structure. For more information about file information structure, refer to f_readdir function.

The matching pattern can contain wildcard characters (? and *). A ? matches an any character and an * matches an any string in length of zero or longer. When support of long file name is enabled, only fname[] is tested at _USE_FIND == 1 and also altname[] is tested at _USE_FIND == 2. In this revision, there are some differences listed below between FatFs and standard systems in matching condition.

    -
  • "*.*" never matches any name without extension while it matches any names at the standard systems.
  • -
  • Any patterns terminated with a period never matches any name while it matches any names without extensiton at the standard systems.
  • +
  • "*.*" never matches any name without extension while it matches any name with or without extension at the standard systems.
  • +
  • Any patterns terminated with a period never matches any name while it matches any name without extensiton at the standard systems.
  • DBCS extended characters are compared in case-sensitive at LFN with non-Unicode configuration.
diff --git a/doc/en/getcwd.html b/doc/en/getcwd.html index 156ed6d..4843c7c 100644 --- a/doc/en/getcwd.html +++ b/doc/en/getcwd.html @@ -51,7 +51,7 @@ FRESULT f_getcwd (

Description

The f_getcwd function retrieves full path name of the current directory of the current drive. When _VOLUMES is larger than 1, a logical drive number is added to top of the path name.

-

Note: In this revision, R0.12, this function cannot retrieve the current directory path on the exFAT volume. It always returns the root directory path.

+

Note: In this revision, this function cannot retrieve the current directory path on the exFAT volume. It always returns the root directory path.

diff --git a/doc/en/mkfs.html b/doc/en/mkfs.html index 1216c0f..b10e370 100644 --- a/doc/en/mkfs.html +++ b/doc/en/mkfs.html @@ -29,13 +29,13 @@ FRESULT f_mkfs (

Parameters

path
-
Pointer to the null-terminated string specifies the logical drive to be formatted. If there is no drive number in it, it means the default drive. The logical drive does not need to be mounted.
+
Pointer to the null-terminated string specifies the logical drive to be formatted. If there is no drive number in it, it means the default drive. The logical drive may or may not be mounted for the format process.
opt
Specifies the format option in combination of FM_FAT, FM_FAT32, FM_EXFAT and bitwise-or of these three, FM_ANY. FM_EXFAT is ignored when exFAT is not enabled. These flags specify which FAT type to be created on the volume. If two or more types are specified, one out of them will be selected depends on the volume size. The flag FM_SFD specifies to place the volume on the drive in SFD format.
au
Specifies size of the allocation unit (cluter) in unit of byte. The valid value is N times the sector size. N is power of 2 from 1 to 128 for FAT volume and upto 16MiB for exFAT volume. If zero is given, the default allocation unit size is selected depends on the volume size.
work
-
Pointer to the working buffer for the format process.
+
Pointer to the working buffer used for the format process.
len
Size of the working buffer in unit of byte. It needs to be the sector size at least. Plenty of working buffer reduces number of write transaction to the device and the format process will be finished quickly.
diff --git a/doc/en/mount.html b/doc/en/mount.html index 9c5334e..35462ee 100644 --- a/doc/en/mount.html +++ b/doc/en/mount.html @@ -31,7 +31,7 @@ FRESULT f_mount (
path
Pointer to the null-terminated string that specifies the logical drive. The string without drive number means the default drive.
opt
-
Initialization option. 0: Do not mount now (to be mounted later), 1: Force mounted the volume to check if the volume is ready to work.
+
Mounting option. 0: Do not mount now (to be mounted on the first access to the volume), 1: Force mounted the volume to check if it is ready to work.
@@ -54,15 +54,15 @@ FRESULT f_mount (
  • Determines the logical drive which specified by path.
  • Clears and unregisters the regsitered work area of the drive if exist.
  • Clears and registers the new work area to the drive if fs is not NULL.
  • -
  • Performs volume mount process to the drive if forced mount is specified.
  • +
  • Performs volume mount process to the drive if forced mounting is specified.
  • -

    The file system object is the work area needed for each logical drive. It must be given to the logical drive with this function prior to use any other file functions except for f_fdisk function to the logical drive. To unregister the work area, specify a NULL to the fs, and then the work area can be discarded.

    -

    If forced mounting is not specified, this function always succeeds regardless of the physical drive status due to delayed mount feature. It only clears (de-initializes) the given work area and registers its address to the internal table. There is no activity of the physical drive in this function. It can also be used to force de-initialized the registered work area of a logical drive. The volume mount processes, initialize the corresponding physical drive, find the FAT volume in it and initialize the work area, is performed in the subsequent file access functions when either or both of following condition is true.

    +

    The file system object is the work area needed for each logical drive. It must be given to the logical drive with this function prior to use any API functions except for f_mkfs/f_fdisk function to the logical drive.

    +

    If forced mounting is not specified (opt = 0), this function always succeeds regardless of the physical drive status. It only clears (de-initializes) the given work area and registers its address to the internal table and no activity of the physical drive in this function. To unregister the work area, specify a NULL to the fs, and then the work area can be discarded. The volume mount processes, initialize the corresponding physical drive, find the FAT volume in it and initialize the work area, is performed in the subsequent file access functions when either or both of following condition is true.

    -

    If the function with forced mounting failed, it means that the file system object has been registered successfully but the volume is currently not ready to work. The volume mount process will also be attempted at subsequent file access functions.

    +

    If the function with forced mounting (opt = 1) failed, it means that the file system object has been registered successfully but the volume is currently not ready to work. The volume mount process will be attempted at subsequent file access functions if the file system object is not initialized. (delayed mounting)

    If implementation of the disk I/O layer lacks media change detection, application program needs to perform a f_mount function after each media change to force cleared the file system object.

    diff --git a/doc/en/open.html b/doc/en/open.html index ae24740..7435142 100644 --- a/doc/en/open.html +++ b/doc/en/open.html @@ -74,7 +74,7 @@ FRESULT f_open (

    Description

    -

    Before using any file function, a work area (file system object) must be registered to the logical drive with f_mount function. All API functions except for f_mkfs and f_fdisk function can work after this procedure.

    +

    Before using any file function, a work area (file system object) needs to be registered to the logical drive with f_mount function. All API functions except for f_mkfs/f_fdisk function get ready to work after this procedure.

    After f_open function succeeded, the file object is valid. The file object is used for subsequent operations to the file to identify the file. Open file must be closed prior to power down, media removal or re-mount, or the file can be collapsed. To close an open file, use f_close function.

    If duplicated file open is needed, read here carefully. However duplicated open of a file with any write mode flag is always prohibited.

    diff --git a/doc/en/printf.html b/doc/en/printf.html index 7d91751..f603052 100644 --- a/doc/en/printf.html +++ b/doc/en/printf.html @@ -39,7 +39,7 @@ int f_printf (

    Return Values

    -

    When the function succeeded, it returns number of characters written. When the function failed due to disk full or any error, an EOF (-1) will be returned.

    +

    When the function succeeded, it returns number of characters written. If the function could not write the generated string to the file due to disk full or an error, EOF (-1) will be returned.

    diff --git a/doc/en/rc.html b/doc/en/rc.html index 3cdee6a..81e801d 100644 --- a/doc/en/rc.html +++ b/doc/en/rc.html @@ -6,12 +6,12 @@ -FatFs - Return Codes +FatFs - API Return Code -

    Return Code of the File Functions

    -

    On the FatFs API, most of file functions return common result code as enum type FRESULT. When a function succeeded, it returns zero, otherwise returns non-zero value that indicates type of error.

    +

    Return Code of API Functions

    +

    Most of API functions return common result code as enum type FRESULT. When an API function succeeded, it returns zero (FR_OK), otherwise it returns non-zero value indicates type of error.

    @@ -25,7 +25,8 @@
    Assertion failed. An insanity is detected in the internal process. One of the following possibilities is suspected. Note that if once this error occured at any operation to an open file, the file object is aborted and all operations to the file except for close will be rejected.
    @@ -50,25 +51,25 @@ Note that if once this error occured at any operation to an open file, the file
  • Deleting the non-empty directory or current directory.
  • Reading the file opened without FA_READ flag.
  • Any modification to the file opened without FA_WRITE flag.
  • -
  • Could not create the file or directory due to the directory table is full.
  • +
  • Could not create the object due to root directory full or disk full.
  • Could not allocate a contiguous area to the file.
  • FR_EXIST
    -
    Name collision. Any object that has the same name is already existing.
    +
    Name collision. An object with the same name is already existing.
    FR_INVALID_OBJECT
    The file/directory object is invalid or a null pointer is given. There are some reasons as follows:
    FR_WRITE_PROTECTED
    -
    Any write mode operation against the write-protected media.
    +
    A write mode operation against the write-protected media.
    FR_INVALID_DRIVE
    Invalid drive number is specified in the path name. A null pointer is given as the path name. (Related option: _VOLUMES)
    @@ -107,7 +108,7 @@ Note that if once this error occured at any operation to an open file, the file
    Number of open objects has been reached maximum value and no more object can be opened. (Related option: _FS_LOCK)
    FR_INVALID_PARAMETER
    -
    The given parameter is invalid or there is any inconsistent.
    +
    The given parameter is invalid or there is an inconsistent for the volume.

    Return

    diff --git a/doc/en/read.html b/doc/en/read.html index ae27adf..2d5b397 100644 --- a/doc/en/read.html +++ b/doc/en/read.html @@ -53,7 +53,7 @@ FRESULT f_read (

    Description

    -

    The function starts to read data from the file at the position pointed by the read/write pointer. The read/write pointer advances as number of bytes read. After the function succeeded, *br should be checked to detect end of the file. In case of *br is less than btr, it means the read/write pointer reached end of the file during read operation.

    +

    The function starts to read data from the file at the position pointed by the read/write pointer. The read/write pointer advances as number of bytes read. After the function succeeded, *br should be checked to detect end of the file. In case of *br < btr, it means the read/write pointer reached end of the file during read operation.

    diff --git a/doc/en/rename.html b/doc/en/rename.html index b671088..c172a74 100644 --- a/doc/en/rename.html +++ b/doc/en/rename.html @@ -13,7 +13,7 @@

    f_rename

    -

    Renames a file or sub-directory.

    +

    The f_rename function renames and/or moves a file or sub-directory.

     FRESULT f_rename (
       const TCHAR* old_name, /* [IN] Old object name */
    @@ -28,7 +28,7 @@ FRESULT f_rename (
     
    old_name
    Pointer to a null-terminated string that specifies the existing file or sub-directory to be renamed.
    new_name
    -
    Pointer to a null-terminated string that specifies the new object name. Any drive number may be specified in this string but it is ignored and assumed as the same drive of the old_name.
    +
    Pointer to a null-terminated string that specifies the new object name. A drive number may be specified in this string but it is ignored and assumed as the same drive of the old_name. Any object with this path name except old_name must not be exist, or the function fails with FR_EXIST.
    @@ -58,7 +58,7 @@ FRESULT f_rename (

    Description

    -

    Renames a file or sub-directory and can also move it to other directory in the same logical drive. The object to be renamed must not be an open object, or the FAT volume can be collapsed. Such the wrong operation can be rejected safely when file lock feature is enabled.

    +

    Renames a file or sub-directory and can also move it to other directory in the same volume. The object to be renamed must not be an open object, or the FAT volume can be collapsed. Such the wrong operation is rejected safely when file lock function is enabled.

    @@ -77,7 +77,7 @@ FRESULT f_rename ( /* Rename an object in the drive 2 */ f_rename("2:oldname.txt", "newname.txt"); - /* Rename an object and move it to other directory */ + /* Rename an object and move it to other directory in the volume */ f_rename("log.txt", "old/log0001.txt"); diff --git a/doc/en/sfileinfo.html b/doc/en/sfileinfo.html index c5ade6c..2439317 100644 --- a/doc/en/sfileinfo.html +++ b/doc/en/sfileinfo.html @@ -33,7 +33,7 @@

    Members

    fsize
    -
    Indicates size of the file in unit of byte. Always zero for directories. FSIZE_t is an alias of integer type either DWORD(32-bit) or QWORD(64-bit) depends on the configuration option _FS_EXFAT.
    +
    Indicates size of the file in unit of byte. FSIZE_t is an alias of integer type either DWORD(32-bit) or QWORD(64-bit) depends on the configuration option _FS_EXFAT. Do not care when the item is a directory.
    fdate
    Indicates the date when the file was modified or the directory was created.
    diff --git a/doc/en/write.html b/doc/en/write.html index 175212d..48ef4ad 100644 --- a/doc/en/write.html +++ b/doc/en/write.html @@ -53,7 +53,7 @@ FRESULT f_write (

    Description

    -

    The function starts to write data to the file at the position pointed by the read/write pointer. The read/write pointer advances as number of bytes written. After the function succeeded, *bw should be checked to detect the disk full. In case of *bw is less than btw, it means the volume got full during the write operation. The function can take a time when the volume is full or close to full.

    +

    The function starts to write data to the file at the position pointed by the read/write pointer. The read/write pointer advances as number of bytes written. After the function succeeded, *bw should be checked to detect the disk full. In case of *bw < btw, it means the volume got full during the write operation. The function can take a time when the volume is full or close to full.

    diff --git a/doc/ja/appnote.html b/doc/ja/appnote.html index 472638d..06cd95e 100644 --- a/doc/ja/appnote.html +++ b/doc/ja/appnote.html @@ -47,7 +47,7 @@ FatFsモジュールはANSI C(C89)準拠で記述されているので、普通

    functional diagram

    ユーザの作成する関数

    -

    ポーティング作業は、要求されるデバイス制御関数を用意することが全てで、それ以外にすることは何もありません。既に動作しているデバイス制御モジュールがあるなら、そのAPIをFatFsに合わせるかグルー関数を介してつなぐだけで済みますが、無い場合はほかから移植するか最初から書くかする必要があります。定義されている全ての関数が常に必要なわけではありません。例えば、リード オンリ構成では書き込み系関数は必要ありません。次の表に構成オプションと要求される関数の対応を示します。

    +

    ポーティング作業は、要求されるデバイス制御関数を用意することが全てで、それ以外にすることは何もありません。既に動作しているデバイス制御モジュールがあるなら、そのインターフェースをFatFsに合わせるかグルー関数を介してつなぐだけで済みますが、無い場合はほかから移植するか最初から書くかする必要があります。定義されている全ての関数が常に必要なわけではありません。例えば、リード オンリ構成では書き込み系関数は必要ありません。次の表に構成オプションと要求される関数の対応を示します。

    @@ -81,16 +81,16 @@ FatFsモジュールはANSI C(C89)準拠で記述されているので、普通 - - - - + + + +
    必要な関数必要となる条件備考
    disk_status
    disk_initialize
    disk_read
    常時ffsample.zip (サンプル)
    その他web上に多数
    ARM7
    32bit
    ARM7
    Thumb
    CM3
    Thumb-2
    AVRH8/300HPIC24RL78V850ESSH-2ARX600IA-32
    CompilerGCCGCCGCCGCCCH38C30CC78K0RCA850SHCRXCMSC
    text (Full, R/W)10.1k6.6k6.2k12.1k10.5k11.2k12.6k8.5k8.7k6.3k8.4k
    text (Min, R/W) 6.6k4.5k4.2k 7.9k 7.0k 7.6k 8.8k5.9k5.8k4.3k5.8k
    text (Full, R/O) 4.8k3.1k2.9k 5.8k 5.1k 5.5k 6.4k4.1k4.0k3.1k4.0k
    text (Min, R/O) 3.5k2.4k2.3k 4.4k 3.9k 4.2k 5.0k3.3k3.1k2.4k3.1k
    text (Full, R/W)10.4k6.8k6.3k12.4k 9.8k11.1k12.8k8.6k8.9k6.4k8.5k
    text (Min, R/W) 6.8k4.6k4.3k 8.2k 6.7k 7.6k 9.1k6.0k5.9k4.5k5.9k
    text (Full, R/O) 4.8k3.1k2.8k 5.6k 4.6k 5.3k 6.3k4.0k3.9k3.0k3.9k
    text (Min, R/O) 3.6k2.4k2.3k 4.4k 3.5k 4.0k 4.9k3.3k3.0k2.4k3.1k
    bssV*4 + 2V*4 + 2V*4 + 2V*2 + 2V*4 + 2V*2 + 2V*2 + 2V*4 + 2V*4 + 2V*4 + 2V*4 + 2
    Work area
    (_FS_TINY == 0)
    V*564
    + F*552
    V*564
    + F*552
    V*564
    + F*552
    V*560
    + F*546
    V*560
    + F*546
    V*560
    + F*546
    V*560
    + F*546
    V*564
    + F*552
    V*564
    + F*552
    V*564
    + F*552
    V*564
    + F*552
    Work area
    (_FS_TINY == 1)
    V*564
    + F*40
    V*564
    + F*40
    V*564
    + F*40
    V*560
    + F*34
    V*560
    + F*34
    V*560
    + F*34
    V*560
    + F*34
    V*564
    + F*40
    V*564
    + F*40
    V*564
    + F*40
    V*564
    + F*40
    -FatFs R0.12 options:
    +FatFs R0.12b options:
     _FS_READONLY   0 (R/W) or 1 (R/O)
     _FS_MINIMIZE   0 (Full, with all basic functions) or 3 (Min, with fully minimized)
     _FS_TINY       0 (Default) or 1 (Tiny file object)
    @@ -254,7 +254,7 @@ And any other options are left not changed from default setting.
     
     

    FatFsのライセンスについて

    -

    FatFsは、作者(ChaN)の個人プロジェクトとして開発されています。現在のリビジョンにおいてコントリビューターはいないため、作者の書いたソース コード以外は含まれません。ソース ファイルにライセンス条件が記述されているので、利用の際はそれに従うこと。原文は英語ですが、参考までに以下に日本語訳を示しておきます。

    +

    FatFsは、作者(ChaN)の個人プロジェクトとして開発されています。現在までのリビジョンにおいてコントリビューターはいないため、作者以外の書いたソース コードは含まれません。ソース ファイルにライセンス条件が記述されているので、利用の際はそれに従うこと。原文は英語ですが、参考までに以下に日本語訳を示しておきます。

     /*----------------------------------------------------------------------------/
     /  FatFs - Generic FAT file system module  R0.12a                             /
    diff --git a/doc/ja/mount.html b/doc/ja/mount.html
    index 5f969b5..2ce701f 100644
    --- a/doc/ja/mount.html
    +++ b/doc/ja/mount.html
    @@ -52,8 +52,8 @@ FRESULT f_mount (
     

    FatFsモジュールでは、それぞれの論理ドライブにファイル システム オブジェクトというワーク エリアが必要です。この関数は論理ドライブにファイル システム オブジェクトを登録したり抹消したりします。何らかのファイル関数を使用する前に、この関数でその論理ドライブのファイル システム オブジェクトを与えておかなければなりません。fsにヌル ポインタを指定すると、その論理ドライブのファイル システム オブジェクトの登録は抹消されるだけです。登録抹消されたファイル システム オブジェクトのメモリは解放できます。操作の対象の論理ドライブ上に開かれたままのファイルやディレクトリがあった場合、それらに対して作成された構造体は全て無効になります。この関数の内部処理は次のような順に行われます。

    1. 対象の論理ドライブをpathから得る。
    2. -
    3. 既に登録されているファイル システム オブジェクトはクリア(無効化)し、登録を解除する。
    4. -
    5. fsが有効なポインタのときは、そのファイル システム オブジェクトをクリアし登録する。
    6. +
    7. 登録されているファイル システム オブジェクトがあるときは、それをクリア(無効化)し、登録を解除する。
    8. +
    9. fsが有効なポインタのときは、そのファイル システム オブジェクトをクリアし、登録する。
    10. マウント動作が指定されているときは、それを実行する。

    optに0を指定すると、マウント動作(物理ドライブの初期化、FATボリュームの検索、BPBを解析しファイル システム オブジェクトを初期化)は行われず、関数は物理ドライブの状態に関わらず常に成功します。関数内では下位レイヤへのアクセスは発生せず、指定されたファイル システム オブジェクトをクリア(無効化)し、そのアドレスを内部配列に登録するだけです。単に登録済みのファイル システム オブジェクトをクリアする目的にも使えます。実際のマウント動作は、ボリュームへのアクセス(パス名を渡すもの全て)が行われたときに、次のうちいずれかの条件が真の場合に行われます。

    diff --git a/doc/ja/rc.html b/doc/ja/rc.html index 78ac221..82da6f2 100644 --- a/doc/ja/rc.html +++ b/doc/ja/rc.html @@ -11,22 +11,23 @@

    ファイル関数の戻り値

    -

    FatFsのAPIでは、一部の関数を除き結果に応じた共通のリザルト コード(FRESULT型(enum))を返します。関数が成功した場合は0を返します。失敗した場合は0以外の値を返し、値はエラーの種類を示します。

    +

    FatFsのAPIでは、一部の関数を除き結果に応じた共通のリザルト コード(FRESULT型(enum))を返します。関数が成功した場合は0 (FR_OK)を返します。失敗した場合は0以外の値を返し、値はエラーの種類を示します。

    FR_OK (0)
    関数は成功した。
    FR_DISK_ERR
    -
    下位レイヤ(disk_read/disk_write/disk_ioctl関数)で回復不能なエラーが発生した。
    ※開かれたファイルの操作においてこのエラーが発生すると、そのファイル オブジェクトはアボート状態となり、クローズ以外のの操作ができなくなります。
    +
    下位レイヤ(disk_read/disk_write/disk_ioctl関数)で回復不能なエラーが発生した。
    ※開かれたファイルの操作においてこのエラーが発生すると、そのファイル オブジェクトはアボート状態となり、クローズ以外の操作ができなくなります。
    FR_INT_ERR
    -
    内部処理の健全性に異常が検出された。原因としては次のようなことが考えられます。 +
    内部処理の健全性チェックで何らかの異常が検出された。原因としては次のようなことが考えられます。
      -
    • ボリューム上のFAT構造にエラーがある。
    • スタック不足や不正なメモリ操作等によるワーク エリアの破壊。多くはこれが原因。
    • +
    • ボリューム上のFAT構造にエラーがある。
    • +
    • FatFsモジュール自体のバグ。
    ※開かれたファイルの操作においてこのエラーが発生すると、そのファイル オブジェクトはアボート状態となり、クローズ以外の操作ができなくなります。
    FR_NOT_READY
    -
    disk_initialize関数の失敗。物理ドライブが動作可能な状態にない。
    +
    下位レイヤ(disk_initialize関数)の失敗。つまり、物理ドライブが動作可能な状態にない。
    FR_NO_FILE
    指定されたファイルが見つからなかった。
    FR_NO_PATH
    @@ -41,7 +42,8 @@
  • 空でないディレクトリまたはカレント ディレクトリを削除しようとした。
  • FA_READフラグを付けずに開いたファイルに対して読み出しを行った。
  • FA_WRITEフラグを付けずに開いたファイルに対して変更を加えようとした。
  • -
  • ボリュームまたは静的ディレクトリが満杯でオブジェクトの新規作成ができなかった。
  • +
  • ボリュームまたは静的ディレクトリ(FAT12/16のルート)が満杯でディレクトリ エントリの新規作成ができなかった。
  • +
  • ファイルに割り当てる連続領域が見つからなかった。
  • FR_EXIST
    @@ -50,8 +52,8 @@
    指定されたファイル オブジェクトやディレクトリ オブジェクトが無効、またはヌル ポインタが渡された。無効になる理由は次のことが考えられます。
    FR_WRITE_PROTECTED
    diff --git a/doc/ja/rename.html b/doc/ja/rename.html index 7ee32ea..fe1aa90 100644 --- a/doc/ja/rename.html +++ b/doc/ja/rename.html @@ -28,7 +28,7 @@ FRESULT f_rename (
    old_name
    変更対象のファイルまたはサブ ディレクトリのパス名を示すヌル文字'\0'終端の文字列へのポインタを指定します。
    new_name
    -
    新しいパス名を示すヌル文字'\0'終端の文字列へのポインタを指定します。既に存在するオブジェクトと同じ名前は使えません。また、ドライブ番号は指定しても無視され、old_nameで決められた論理ドライブ上のオブジェクトとして扱われます。
    +
    新しいパス名を示すヌル文字'\0'終端の文字列へのポインタを指定します。また、ドライブ番号は指定しても無視され、old_nameで決められたボリューム上のオブジェクトとして扱われます。これと同じパス名(old_nameは除く)のオブジェクトが存在すると、関数はFR_EXISTで失敗します。
    diff --git a/doc/res/fd.mp4 b/doc/res/fd.mp4 new file mode 100644 index 0000000..cc572b9 Binary files /dev/null and b/doc/res/fd.mp4 differ diff --git a/doc/res/rwtest1.png b/doc/res/rwtest1.png index af51c5f..bc03302 100644 Binary files a/doc/res/rwtest1.png and b/doc/res/rwtest1.png differ diff --git a/doc/updates.txt b/doc/updates.txt new file mode 100644 index 0000000..2de0651 --- /dev/null +++ b/doc/updates.txt @@ -0,0 +1,189 @@ +R0.12b (September 4, 2016) + Improved f_rename() to be able to rename objects with the same name but case. + Fixed an error in the case conversion teble of code page 866. (ff.c) + Fixed writing data is truncated at the file offset 4GiB on the exFAT volume. (appeared at R0.12) + Fixed creating a file in the root directory of exFAT volume can fail. (appeared at R0.12) + Fixed f_mkfs() creating exFAT volume with too small cluster size can collapse unallocated memory. (appeared at R0.12) + Fixed wrong object name can be returned when read directory at Unicode cfg. (appeared at R0.12) + Fixed large file allocation/removing on the exFAT volume collapses allocation bitmap. (appeared at R0.12) + Fixed some internal errors in f_expand() and f_lseek(). (appeared at R0.12) + +R0.12a (July 10, 2016) + Added support for creating exFAT volume with some changes of f_mkfs(). + Added a file open method FA_OPEN_APPEND. An f_lseek() following f_open() is no longer needed. + f_forward() is available regardless of _FS_TINY. + Fixed f_mkfs() creates wrong volume. (appeared at R0.12) + Fixed wrong memory read in create_name(). (appeared at R0.12) + Fixed compilation fails at some configurations, _USE_FASTSEEK and _USE_FORWARD. + +R0.12 (April 12, 2016) + Added support for exFAT file system. (_FS_EXFAT) + Added f_expand(). (_USE_EXPAND) + Changed some members in FINFO structure and behavior of f_readdir(). + Added an option _USE_CHMOD and removed an option _WORD_ACCESS. + Fixed errors in the case conversion teble of Unicode (cc*.c). + +R0.11a (September 5, 2015) + Fixed wrong media change can lead a deadlock at thread-safe configuration. + Added code page 771, 860, 861, 863, 864, 865 and 869. (_CODE_PAGE) + Removed some code pages actually not exist on the standard systems. (_CODE_PAGE) + Fixed errors in the case conversion teble of code page 437 and 850 (ff.c). + Fixed errors in the case conversion teble of Unicode (cc*.c). + +R0.11 (February 9, 2015) + Added f_findfirst() and f_findnext(). (_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) + +R0.10c (November 9, 2014) + 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(). (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.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 its lossy converted SFN. (appeared at R0.07) + +R0.10a (January 15, 2014) + Added arbitrary strings as drive number in the path name. (_STR_VOLUME_ID) + Added an option for 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 larger than 0. (appeared at R0.10) + Fixed f_close() invalidates the file object without volume lock. + Fixed volume lock is left acquired after return from f_closedir(). (appeared at R0.10) + Fixed creation of a directory entry with LFN fails on too many SFN collisions. (appeared at R0.07) + +R0.10 (October 2, 2013) + Added an option for character encoding on the file. (_STRF_ENCODE) + Added f_closedir(). + Added forced full FAT scan option for f_getfree(). (_FS_NOFSINFO) + Added forced mount option 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 result code on error. + +R0.09b (January 24, 2013) + Added f_getlabel() and f_setlabel(). (_USE_LABEL = 1) + +R0.09a (August 27, 2012) + Fixed assertion failure due to OS/2 EA on FAT12/16 volume. + Changed file functions reject null object pointer to avoid crash. + Changed option name _FS_SHARE to _FS_LOCK. + +R0.09 (September 6, 2011) + f_mkfs() supports multiple partition on a physical drive. + Added f_fdisk(). (_MULTI_PARTITION = 2) + +R0.08b (January 15, 2011) + Fast seek function 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 names. + +R0.08a (August 16, 2010) + Added f_getcwd(). (_FS_RPATH = 2) + Added sector erase function. (_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. + +R0.08 (May 15, 2010) + Added a memory configuration option. (_USE_LFN) + Added support of file lock. (_FS_SHARE) + Added fast seek function. (_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. + +R0.07e (November 3, 2009) + 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. + +R0.07c (Junuary 21, 2009) + Fixed f_unlink() may return FR_OK on error. + Fixed wrong cache control in f_lseek(). + Added support of relative path. + Added f_chdir(). + Added f_chdrive(). + Added proper case conversion to extended characters. + +R0.07a (April 14, 2009) + Separated out OS dependent code on re-entrant configuration. + Added multiple sector size support. + +R0.07 (April 1, 2009) + Merged Tiny-FatFs into 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. + +R0.06 (April 1, 2008) + Added f_forward. (Tiny-FatFs) + Added string functions: fgets, fputc, fputs and fprintf. + Improved performance of f_lseek on moving to the same or following cluster. + +R0.05a (February 3, 2008) + 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 left not flushed when create and close without write. + +R0.05 (August 26, 2007) + 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) + +R0.04b (May 5, 2007) + 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 (<= csize) collapses the file object. + +R0.04a (April 1, 2007) + Supported multiple partitions on a plysical drive. (FatFs) + Added minimization level 3. + Added a capability of extending file size to f_lseek. + Fixed an endian sensitive code in f_mkfs. (FatFs) + Fixed a problem corresponds to FAT32 support. (Tiny-FatFs) + +R0.04 (February 4, 2007) + Supported multiple drive system. (FatFs) + Changed some APIs for multiple drive system. + Added f_mkfs. (FatFs) + Added _USE_FAT32 option. (Tiny-FatFs) + +R0.03a (December 11, 2006) + Improved cluster scan algolithm to write files fast. + Fixed f_mkdir creates incorrect directory on FAT32. + +R0.03 (September 22, 2006) + Added f_rename. + Changed option _FS_MINIMUM to _FS_MINIMIZE. + +R0.02a (June 10, 2006) + Added a configuration option _FS_MINIMUM. + +R0.02 (Jun 01, 2006) + Added FAT12. + Removed unbuffered mode. + Fixed a problem on small (<32M) patition. + +R0.01 (April 29, 2006) + First release + +R0.00 (February 26, 2006) + Prototype (not released) + diff --git a/src/00history.txt b/src/00history.txt index 5d40fb6..ab22088 100644 --- a/src/00history.txt +++ b/src/00history.txt @@ -260,8 +260,20 @@ R0.12a (July 10, 2016) Added support for creating exFAT volume with some changes of f_mkfs(). Added a file open method FA_OPEN_APPEND. An f_lseek() following f_open() is no longer needed. f_forward() is available regardless of _FS_TINY. - Fixed f_mkfs() creates wrong volume. + Fixed f_mkfs() creates wrong volume. (appeared at R0.12) + Fixed wrong memory read in create_name(). (appeared at R0.12) Fixed compilation fails at some configurations, _USE_FASTSEEK and _USE_FORWARD. - Fixed wrong memory read in create_name(). + +R0.12b (September 04, 2016) + + Improved f_rename() to be able to rename objects with the same name but case. + Fixed an error in the case conversion teble of code page 866. (ff.c) + Fixed writing data is truncated at the file offset 4GiB on the exFAT volume. (appeared at R0.12) + Fixed creating a file in the root directory of exFAT volume can fail. (appeared at R0.12) + Fixed f_mkfs() creating exFAT volume with too small cluster size can collapse unallocated memory. (appeared at R0.12) + Fixed wrong object name can be returned when read directory at Unicode cfg. (appeared at R0.12) + Fixed large file allocation/removing on the exFAT volume collapses allocation bitmap. (appeared at R0.12) + Fixed some internal errors in f_expand() and f_lseek(). (appeared at R0.12) + diff --git a/src/diskio.c b/src/diskio.c index e7e786b..f611063 100644 --- a/src/diskio.c +++ b/src/diskio.c @@ -41,7 +41,7 @@ DSTATUS disk_status ( return stat; - case DEB_USB : + case DEV_USB : result = USB_disk_status(); // translate the reslut code here diff --git a/src/ff.c b/src/ff.c index e9771bb..61da21f 100644 --- a/src/ff.c +++ b/src/ff.c @@ -1,5 +1,5 @@ /*----------------------------------------------------------------------------/ -/ FatFs - Generic FAT file system module R0.12a / +/ FatFs - Generic FAT file system module R0.12b / /-----------------------------------------------------------------------------/ / / Copyright (C) 2016, ChaN, all right reserved. @@ -28,7 +28,7 @@ ---------------------------------------------------------------------------*/ -#if _FATFS != 80186 /* Revision ID */ +#if _FATFS != 68020 /* Revision ID */ #error Wrong include file (ff.h). #endif @@ -298,7 +298,7 @@ typedef struct { 0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, \ 0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ - 0x90,0x91,0x92,0x93,0x9d,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \ + 0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \ 0xF0,0xF0,0xF2,0xF2,0xF4,0xF4,0xF6,0xF6,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} #elif _CODE_PAGE == 869 /* Greek 2 */ @@ -396,7 +396,7 @@ typedef struct { #define BPB_NumFATs 16 /* Number of FATs (BYTE) */ #define BPB_RootEntCnt 17 /* Size of root directory area for FAT12/16 [entry] (WORD) */ #define BPB_TotSec16 19 /* Volume size (16-bit) [sector] (WORD) */ -#define BPB_Media 21 /* Media descriptor (BYTE) */ +#define BPB_Media 21 /* Media descriptor byte (BYTE) */ #define BPB_FATSz16 22 /* FAT size (16-bit) [sector] (WORD) */ #define BPB_SecPerTrk 24 /* Track size for int13h [sector] (WORD) */ #define BPB_NumHeads 26 /* Number of heads for int13h (WORD) */ @@ -409,6 +409,7 @@ typedef struct { #define BS_VolLab 43 /* Volume label string (8-byte) */ #define BS_FilSysType 54 /* File system type string (8-byte) */ #define BS_BootCode 62 /* Boot code (448-byte) */ +#define BS_55AA 510 /* Signature word (WORD) */ #define BPB_FATSz32 36 /* FAT32: FAT size [sector] (DWORD) */ #define BPB_ExtFlags32 40 /* FAT32: Extended flags (WORD) */ @@ -462,8 +463,6 @@ typedef struct { #define PTE_StLba 8 /* MBR PTE: Start in LBA */ #define PTE_SizLba 12 /* MBR PTE: Size in LBA */ -#define BS_55AA 510 /* Signature word (WORD) */ - #define DIR_Name 0 /* Short file name (11-byte) */ #define DIR_Attr 11 /* Attribute (BYTE) */ #define DIR_NTres 12 /* Lower case flag (BYTE) */ @@ -1141,7 +1140,7 @@ DWORD find_bitmap ( /* 0:No free cluster, 2..:Free cluster found, 0xFFFFFFFF:Dis 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; + if (move_window(fs, fs->database + val / 8 / SS(fs)) != FR_OK) return 0xFFFFFFFF; /* (assuming bitmap is located top of the cluster heap) */ i = val / 8 % SS(fs); bm = 1 << (val % 8); do { do { @@ -1180,7 +1179,7 @@ FRESULT change_bitmap ( clst -= 2; /* The first bit corresponds to cluster #2 */ - sect = fs->database + clst / 8 / SS(fs); /* Sector address */ + 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 */ for (;;) { @@ -1194,6 +1193,7 @@ FRESULT change_bitmap ( } while (bm <<= 1); /* Next bit */ bm = 1; } while (++i < SS(fs)); /* Next byte */ + i = 0; } } @@ -1263,7 +1263,7 @@ FRESULT remove_chain ( /* FR_OK(0):succeeded, !=0:error */ res = put_fat(fs, clst, 0); /* Mark the cluster 'free' on the FAT */ if (res != FR_OK) return res; } - if (fs->free_clst != 0xFFFFFFFF) { /* Update FSINFO */ + if (fs->free_clst < fs->n_fatent - 2) { /* Update FSINFO */ fs->free_clst++; fs->fsi_flag |= 1; } @@ -1320,7 +1320,7 @@ DWORD create_chain ( /* 0:No free cluster, 1:Internal error, 0xFFFFFFFF:Disk err if (clst == 0) { /* Create a new chain */ - scl = fs->last_clst; /* Get suggested cluster to start at */ + scl = fs->last_clst; /* Get suggested cluster to start from */ if (scl == 0 || scl >= fs->n_fatent) scl = 1; } else { /* Stretch current chain */ @@ -1332,7 +1332,7 @@ DWORD create_chain ( /* 0:No free cluster, 1:Internal error, 0xFFFFFFFF:Disk err } #if _FS_EXFAT - if (fs->fs_type == FS_EXFAT) { /* At the exFAT */ + if (fs->fs_type == FS_EXFAT) { /* On the exFAT volume */ ncl = find_bitmap(fs, scl, 1); /* Find a free cluster */ if (ncl == 0 || ncl == 0xFFFFFFFF) return ncl; /* No free cluster or hard error? */ res = change_bitmap(fs, ncl, 1, 1); /* Mark the cluster 'in use' */ @@ -1348,7 +1348,7 @@ DWORD create_chain ( /* 0:No free cluster, 1:Internal error, 0xFFFFFFFF:Disk err } } else #endif - { /* At the FAT12/16/32 */ + { /* On the FAT12/16/32 volume */ ncl = scl; /* Start cluster */ for (;;) { ncl++; /* Next cluster */ @@ -1774,7 +1774,7 @@ void gen_numname ( /* itoa (hexdecimal) */ i = 7; do { - c = (seq % 16) + '0'; + c = (BYTE)((seq % 16) + '0'); if (c > '9') c += 7; ns[i--] = c; seq /= 16; @@ -2104,7 +2104,7 @@ FRESULT dir_read ( c = dp->dir[DIR_Name]; /* Test for the entry type */ if (c == 0) { res = FR_NO_FILE; break; } /* Reached to end of the directory */ #if _FS_EXFAT - if (fs->fs_type == FS_EXFAT) { /* At the exFAT */ + if (fs->fs_type == FS_EXFAT) { /* On the exFAT volume */ if (_USE_LABEL && vol) { if (c == 0x83) break; /* Volume label entry? */ } else { @@ -2119,7 +2119,7 @@ FRESULT dir_read ( } } else #endif - { /* At the FAT12/16/32 */ + { /* On the FAT12/16/32 volume */ dp->obj.attr = a = dp->dir[DIR_Attr] & AM_MASK; /* Get attribute */ #if _USE_LFN != 0 /* LFN configuration */ if (c == DDEM || c == '.' || (int)((a & ~AM_ARC) == AM_VOL) != vol) { /* An entry without valid data */ @@ -2128,7 +2128,7 @@ FRESULT dir_read ( if (a == AM_LFN) { /* An LFN entry is found */ if (c & LLEF) { /* Is it start of an LFN sequence? */ sum = dp->dir[LDIR_Chksum]; - c &= ~LLEF; ord = c; + c &= (BYTE)~LLEF; ord = c; dp->blk_ofs = dp->dptr; } /* Check LFN validity and capture it */ @@ -2177,7 +2177,7 @@ FRESULT dir_find ( /* FR_OK(0):succeeded, !=0:error */ res = dir_sdi(dp, 0); /* Rewind directory object */ if (res != FR_OK) return res; #if _FS_EXFAT - if (fs->fs_type == FS_EXFAT) { /* At the exFAT */ + if (fs->fs_type == FS_EXFAT) { /* On the exFAT volume */ BYTE nc; UINT di, ni; WORD hash = xname_sum(fs->lfnbuf); /* Hash value of the name to find */ @@ -2193,7 +2193,7 @@ FRESULT dir_find ( /* FR_OK(0):succeeded, !=0:error */ return res; } #endif - /* At the FAT12/16/32 */ + /* On the FAT12/16/32 volume */ #if _USE_LFN != 0 ord = sum = 0xFF; dp->blk_ofs = 0xFFFFFFFF; /* Reset LFN sequence */ #endif @@ -2211,7 +2211,7 @@ FRESULT dir_find ( /* FR_OK(0):succeeded, !=0:error */ if (!(dp->fn[NSFLAG] & NS_NOLFN)) { if (c & LLEF) { /* Is it start of LFN sequence? */ sum = dp->dir[LDIR_Chksum]; - c &= ~LLEF; ord = c; /* LFN start order */ + c &= (BYTE)~LLEF; ord = c; /* LFN start order */ dp->blk_ofs = dp->dptr; /* Start offset of LFN */ } /* Check validity of the LFN entry and compare it with given name */ @@ -2257,7 +2257,7 @@ FRESULT dir_register ( /* FR_OK:succeeded, FR_DENIED:no free entry or too many S for (nlen = 0; fs->lfnbuf[nlen]; nlen++) ; /* Get lfn length */ #if _FS_EXFAT - if (fs->fs_type == FS_EXFAT) { /* At the exFAT */ + if (fs->fs_type == FS_EXFAT) { /* On the exFAT volume */ DIR dj; nent = (nlen + 14) / 15 + 2; /* Number of entries to allocate (85+C0+C1s) */ @@ -2265,7 +2265,7 @@ FRESULT dir_register ( /* FR_OK:succeeded, FR_DENIED:no free entry or too many S if (res != FR_OK) return res; dp->blk_ofs = dp->dptr - SZDIRE * (nent - 1); /* Set block position */ - if (dp->obj.stat & 4) { /* Has the sub-directory been stretched? */ + if (dp->obj.sclust != 0 && (dp->obj.stat & 4)) { /* Has the sub-directory been stretched? */ dp->obj.stat &= 3; dp->obj.objsize += (DWORD)fs->csize * SS(fs); /* Increase object size by cluster size */ res = fill_fat_chain(&dp->obj); /* Complement FAT chain if needed */ @@ -2283,7 +2283,7 @@ FRESULT dir_register ( /* FR_OK:succeeded, FR_DENIED:no free entry or too many S return FR_OK; } #endif - /* At the FAT12/16/32 */ + /* On the FAT12/16/32 volume */ mem_cpy(sn, dp->fn, 12); if (sn[NSFLAG] & NS_LOSS) { /* When LFN is out of 8.3 format, generate a numbered name */ dp->fn[NSFLAG] = NS_NOLFN; /* Find only SFN */ @@ -2360,9 +2360,9 @@ FRESULT dir_remove ( /* FR_OK:Succeeded, FR_DISK_ERR:A disk error */ res = move_window(fs, dp->sect); if (res != FR_OK) break; /* Mark an entry 'deleted' */ - if (_FS_EXFAT && fs->fs_type == FS_EXFAT) { /* At the exFAT */ + if (_FS_EXFAT && fs->fs_type == FS_EXFAT) { /* On the exFAT volume */ dp->dir[XDIR_Type] &= 0x7F; - } else { /* At the FAT12/16/32 */ + } else { /* On the FAT12/16/32 volume */ dp->dir[DIR_Name] = DDEM; } fs->wflag = 1; @@ -2412,12 +2412,12 @@ void get_fileinfo ( /* No return code */ #if _USE_LFN != 0 /* LFN configuration */ #if _FS_EXFAT - if (fs->fs_type == FS_EXFAT) { /* At the exFAT */ + if (fs->fs_type == FS_EXFAT) { /* On the exFAT volume */ get_xdir_info(fs->dirbuf, fno); return; } else #endif - { /* At the FAT12/16/32 */ + { /* On the FAT12/16/32 volume */ if (dp->blk_ofs != 0xFFFFFFFF) { /* Get LFN if available */ i = j = 0; while ((w = fs->lfnbuf[j++]) != 0) { /* Get an LFN character */ @@ -2429,7 +2429,7 @@ void get_fileinfo ( /* No return code */ } #endif if (i >= _MAX_LFN) { i = 0; break; } /* No LFN if buffer overflow */ - fno->fname[i++] = (char)w; + fno->fname[i++] = (TCHAR)w; } fno->fname[i] = 0; /* Terminate the LFN */ } @@ -2627,7 +2627,7 @@ FRESULT create_name ( /* FR_OK: successful, FR_INVALID_NAME: could not create */ if (si) cf |= NS_LOSS | NS_LFN; while (di && lfn[di - 1] != '.') di--; /* Find extension (di<=si: no extension) */ - b = i = 0; ni = 8; + i = b = 0; ni = 8; for (;;) { w = lfn[si++]; /* Get an LFN character */ if (!w) break; /* Break on end of the LFN */ @@ -2954,7 +2954,7 @@ FRESULT find_volume ( /* FR_OK(0): successful, !=0: any error occurred */ UINT i; - /* Get logical drive number from the path name */ + /* Get logical drive number */ *rfs = 0; vol = get_ldnumber(path); if (vol < 0) return FR_INVALID_DRIVE; @@ -2966,7 +2966,7 @@ FRESULT find_volume ( /* FR_OK(0): successful, !=0: any error occurred */ ENTER_FF(fs); /* Lock the volume */ *rfs = fs; /* Return pointer to the file system object */ - mode &= ~FA_READ; /* Desired access mode, write access or not */ + mode &= (BYTE)~FA_READ; /* Desired access mode, write access or not */ if (fs->fs_type) { /* If the volume has been mounted */ stat = disk_status(fs->drv); if (!(stat & STA_NOINIT)) { /* and the physical drive is kept initialized */ @@ -3044,7 +3044,7 @@ FRESULT find_volume ( /* FR_OK(0): successful, !=0: any error occurred */ fs->volbase = bsect; fs->database = bsect + ld_dword(fs->win + BPB_DataOfsEx); fs->fatbase = bsect + ld_dword(fs->win + BPB_FatOfsEx); - if (maxlba < fs->database + nclst * fs->csize) return FR_NO_FILESYSTEM; /* (Volume size must not be smaller than the size requiered) */ + 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) */ @@ -3161,15 +3161,14 @@ FRESULT find_volume ( /* FR_OK(0): successful, !=0: any error occurred */ static FRESULT validate ( /* Returns FR_OK or FR_INVALID_OBJECT */ - void* dfp, /* Pointer to the FIL/DIR object to check validity */ + _FDID* obj, /* Pointer to the _OBJ, the 1st member in the FIL/DIR object, to check validity */ FATFS** fs /* Pointer to pointer to the owner file system object to return */ ) { - _FDID *obj = (_FDID*)dfp; /* Assuming .obj in the FIL/DIR is the first member */ FRESULT res; - if (!dfp || !obj->fs || !obj->fs->fs_type || obj->fs->id != obj->id || (disk_status(obj->fs->drv) & STA_NOINIT)) { + if (!obj || !obj->fs || !obj->fs->fs_type || obj->fs->id != obj->id || (disk_status(obj->fs->drv) & STA_NOINIT)) { *fs = 0; /* The object is invalid */ res = FR_INVALID_OBJECT; } else { @@ -3207,6 +3206,7 @@ FRESULT f_mount ( const TCHAR *rp = path; + /* Get logical drive number */ vol = get_ldnumber(&rp); if (vol < 0) return FR_INVALID_DRIVE; cfs = FatFs[vol]; /* Pointer to fs object */ @@ -3260,7 +3260,7 @@ FRESULT f_open ( if (!fp) return FR_INVALID_OBJECT; - /* Get logical drive number */ + /* Get logical drive */ mode &= _FS_READONLY ? FA_READ : FA_READ | FA_WRITE | FA_CREATE_ALWAYS | FA_CREATE_NEW | FA_OPEN_ALWAYS | FA_OPEN_APPEND | FA_SEEKEND; res = find_volume(&path, &fs, mode); if (res == FR_OK) { @@ -3459,7 +3459,7 @@ FRESULT f_read ( *br = 0; /* Clear read byte counter */ - res = validate(fp, &fs); + res = validate(&fp->obj, &fs); /* Check validity of the file object */ if (res != FR_OK || (res = (FRESULT)fp->err) != FR_OK) LEAVE_FF(fs, res); /* Check validity */ if (!(fp->flag & FA_READ)) LEAVE_FF(fs, FR_DENIED); /* Check access mode */ remain = fp->obj.objsize - fp->fptr; @@ -3494,9 +3494,7 @@ FRESULT f_read ( if (csect + cc > fs->csize) { /* Clip at cluster boundary */ cc = fs->csize - csect; } - if (disk_read(fs->drv, rbuff, sect, cc) != RES_OK) { - ABORT(fs, FR_DISK_ERR); - } + if (disk_read(fs->drv, rbuff, sect, cc) != RES_OK) ABORT(fs, FR_DISK_ERR); #if !_FS_READONLY && _FS_MINIMIZE <= 2 /* Replace one of the read sectors with cached data if it contains a dirty sector */ #if _FS_TINY if (fs->wflag && fs->winsect - sect < cc) { @@ -3516,12 +3514,10 @@ FRESULT f_read ( #if !_FS_READONLY if (fp->flag & FA_DIRTY) { /* Write-back dirty sector cache */ if (disk_write(fs->drv, fp->buf, fp->sect, 1) != RES_OK) ABORT(fs, FR_DISK_ERR); - fp->flag &= ~FA_DIRTY; + fp->flag &= (BYTE)~FA_DIRTY; } #endif - if (disk_read(fs->drv, fp->buf, sect, 1) != RES_OK) { /* Fill sector cache */ - ABORT(fs, FR_DISK_ERR); - } + if (disk_read(fs->drv, fp->buf, sect, 1) != RES_OK) ABORT(fs, FR_DISK_ERR); /* Fill sector cache */ } #endif fp->sect = sect; @@ -3562,13 +3558,12 @@ FRESULT f_write ( *bw = 0; /* Clear write byte counter */ - res = validate(fp, &fs); + res = validate(&fp->obj, &fs); /* Check validity of the file object */ if (res != FR_OK || (res = (FRESULT)fp->err) != FR_OK) LEAVE_FF(fs, res); /* Check validity */ if (!(fp->flag & FA_WRITE)) LEAVE_FF(fs, FR_DENIED); /* Check access mode */ - /* Check fptr wrap-around (file size cannot exceed the limit on each FAT specs) */ - if ((_FS_EXFAT && fs->fs_type == FS_EXFAT && fp->fptr + btw < fp->fptr) - || (DWORD)fp->fptr + btw < (DWORD)fp->fptr) { + /* Check fptr wrap-around (file size cannot reach 4GiB on FATxx) */ + if ((!_FS_EXFAT || fs->fs_type != FS_EXFAT) && (DWORD)(fp->fptr + btw) < (DWORD)fp->fptr) { btw = (UINT)(0xFFFFFFFF - (DWORD)fp->fptr); } @@ -3603,7 +3598,7 @@ FRESULT f_write ( #else if (fp->flag & FA_DIRTY) { /* Write-back sector cache */ if (disk_write(fs->drv, fp->buf, fp->sect, 1) != RES_OK) ABORT(fs, FR_DISK_ERR); - fp->flag &= ~FA_DIRTY; + fp->flag &= (BYTE)~FA_DIRTY; } #endif sect = clust2sect(fs, fp->clust); /* Get current sector */ @@ -3614,9 +3609,7 @@ FRESULT f_write ( if (csect + cc > fs->csize) { /* Clip at cluster boundary */ cc = fs->csize - csect; } - if (disk_write(fs->drv, wbuff, sect, cc) != RES_OK) { - ABORT(fs, FR_DISK_ERR); - } + if (disk_write(fs->drv, wbuff, sect, cc) != RES_OK) ABORT(fs, FR_DISK_ERR); #if _FS_MINIMIZE <= 2 #if _FS_TINY if (fs->winsect - sect < cc) { /* Refill sector cache if it gets invalidated by the direct write */ @@ -3626,7 +3619,7 @@ FRESULT f_write ( #else if (fp->sect - sect < cc) { /* Refill sector cache if it gets invalidated by the direct write */ mem_cpy(fp->buf, wbuff + ((fp->sect - sect) * SS(fs)), SS(fs)); - fp->flag &= ~FA_DIRTY; + fp->flag &= (BYTE)~FA_DIRTY; } #endif #endif @@ -3634,16 +3627,15 @@ FRESULT f_write ( continue; } #if _FS_TINY - if (fp->fptr >= fp->obj.objsize) { /* Avoid silly cache filling at growing edge */ + if (fp->fptr >= fp->obj.objsize) { /* Avoid silly cache filling on the growing edge */ if (sync_window(fs) != FR_OK) ABORT(fs, FR_DISK_ERR); fs->winsect = sect; } #else - if (fp->sect != sect) { /* Fill sector cache with file data */ - if (fp->fptr < fp->obj.objsize && - disk_read(fs->drv, fp->buf, sect, 1) != RES_OK) { - ABORT(fs, FR_DISK_ERR); - } + if (fp->sect != sect && /* Fill sector cache with file data */ + fp->fptr < fp->obj.objsize && + disk_read(fs->drv, fp->buf, sect, 1) != RES_OK) { + ABORT(fs, FR_DISK_ERR); } #endif fp->sect = sect; @@ -3660,7 +3652,7 @@ FRESULT f_write ( #endif } - fp->flag |= FA_MODIFIED; /* Set file change flag */ + fp->flag |= FA_MODIFIED; /* Set file change flag */ LEAVE_FF(fs, FR_OK); } @@ -3683,13 +3675,13 @@ FRESULT f_sync ( DEF_NAMBUF - res = validate(fp, &fs); /* Check validity of the object */ + res = validate(&fp->obj, &fs); /* Check validity of the file object */ if (res == FR_OK) { if (fp->flag & FA_MODIFIED) { /* Is there any change to the file? */ #if !_FS_TINY if (fp->flag & FA_DIRTY) { /* Write-back cached data if needed */ if (disk_write(fs->drv, fp->buf, fp->sect, 1) != RES_OK) LEAVE_FF(fs, FR_DISK_ERR); - fp->flag &= ~FA_DIRTY; + fp->flag &= (BYTE)~FA_DIRTY; } #endif /* Update the directory entry */ @@ -3714,7 +3706,7 @@ FRESULT f_sync ( res = store_xdir(&dj); /* Restore it to the directory */ if (res == FR_OK) { res = sync_fs(fs); - fp->flag &= ~FA_MODIFIED; + fp->flag &= (BYTE)~FA_MODIFIED; } } FREE_NAMBUF(); @@ -3732,7 +3724,7 @@ FRESULT f_sync ( st_word(dir + DIR_LstAccDate, 0); fs->wflag = 1; res = sync_fs(fs); /* Restore it to the directory */ - fp->flag &= ~FA_MODIFIED; + fp->flag &= (BYTE)~FA_MODIFIED; } } } @@ -3762,7 +3754,7 @@ FRESULT f_close ( if (res == FR_OK) #endif { - res = validate(fp, &fs); /* Lock volume */ + res = validate(&fp->obj, &fs); /* Lock volume */ if (res == FR_OK) { #if _FS_LOCK != 0 res = dec_lock(fp->obj.lockid); /* Decrement file open counter */ @@ -3795,10 +3787,11 @@ FRESULT f_chdrive ( int vol; + /* Get logical drive number */ vol = get_ldnumber(&path); if (vol < 0) return FR_INVALID_DRIVE; - CurrVol = (BYTE)vol; + CurrVol = (BYTE)vol; /* Set it as current volume */ return FR_OK; } @@ -3814,7 +3807,7 @@ FRESULT f_chdir ( FATFS *fs; DEF_NAMBUF - /* Get logical drive number */ + /* Get logical drive */ res = find_volume(&path, &fs, 0); if (res == FR_OK) { dj.obj.fs = fs; @@ -3873,7 +3866,7 @@ FRESULT f_getcwd ( *buff = 0; - /* Get logical drive number */ + /* Get logical drive */ res = find_volume((const TCHAR**)&buff, &fs, 0); /* Get current volume */ if (res == FR_OK) { dj.obj.fs = fs; @@ -3950,7 +3943,7 @@ FRESULT f_lseek ( DWORD cl, pcl, ncl, tcl, dsc, tlen, ulen, *tbl; #endif - res = validate(fp, &fs); /* Check validity of the object */ + res = validate(&fp->obj, &fs); /* Check validity of the file object */ if (res != FR_OK || (res = (FRESULT)fp->err) != FR_OK) LEAVE_FF(fs, res); /* Check validity */ #if _USE_FASTSEEK if (fp->cltbl) { /* Fast seek */ @@ -3991,13 +3984,11 @@ FRESULT f_lseek ( #if !_FS_TINY #if !_FS_READONLY if (fp->flag & FA_DIRTY) { /* Write-back dirty sector cache */ - if (disk_write(fs->drv, fp->buf, fp->sect, 1) != RES_OK) ABORT(fp, FR_DISK_ERR); - fp->flag &= ~FA_DIRTY; + if (disk_write(fs->drv, fp->buf, fp->sect, 1) != RES_OK) ABORT(fs, FR_DISK_ERR); + fp->flag &= (BYTE)~FA_DIRTY; } #endif - if (disk_read(fs->drv, fp->buf, dsc, 1) != RES_OK) { /* Load current sector */ - ABORT(fs, FR_DISK_ERR); - } + if (disk_read(fs->drv, fp->buf, dsc, 1) != RES_OK) ABORT(fs, FR_DISK_ERR); /* Load current sector */ #endif fp->sect = dsc; } @@ -4008,6 +3999,9 @@ FRESULT f_lseek ( /* Normal Seek */ { +#if _FS_EXFAT + if (fs->fs_type != FS_EXFAT && ofs >= 0x100000000) ofs = 0xFFFFFFFF; /* Clip at 4GiB-1 if at FATxx */ +#endif if (ofs > fp->obj.objsize && (_FS_READONLY || !(fp->flag & FA_WRITE))) { /* In read-only mode, clip offset with the file size */ ofs = fp->obj.objsize; } @@ -4017,7 +4011,7 @@ FRESULT f_lseek ( bcs = (DWORD)fs->csize * SS(fs); /* Cluster size (byte) */ if (ifptr > 0 && (ofs - 1) / bcs >= (ifptr - 1) / bcs) { /* When seek to same or following cluster, */ - fp->fptr = (ifptr - 1) & ~(bcs - 1); /* start from the current cluster */ + fp->fptr = (ifptr - 1) & ~(FSIZE_t)(bcs - 1); /* start from the current cluster */ ofs -= fp->fptr; clst = fp->clust; } else { /* When seek to back cluster, */ @@ -4034,20 +4028,25 @@ FRESULT f_lseek ( } if (clst != 0) { while (ofs > bcs) { /* Cluster following loop */ + ofs -= bcs; fp->fptr += bcs; #if !_FS_READONLY if (fp->flag & FA_WRITE) { /* Check if in write mode or not */ - clst = create_chain(&fp->obj, clst); /* Force stretch if in write mode */ - if (clst == 0) { /* When disk gets full, clip file size */ - ofs = bcs; break; + if (_FS_EXFAT && fp->fptr > fp->obj.objsize) { /* No FAT chain object needs correct objsize to generate FAT value */ + fp->obj.objsize = fp->fptr; + fp->flag |= FA_MODIFIED; + } + clst = create_chain(&fp->obj, clst); /* Follow chain with forceed stretch */ + if (clst == 0) { /* Clip file size in case of disk full */ + ofs = 0; break; } } else #endif + { clst = get_fat(&fp->obj, clst); /* Follow cluster chain if not in write mode */ + } if (clst == 0xFFFFFFFF) ABORT(fs, FR_DISK_ERR); if (clst <= 1 || clst >= fs->n_fatent) ABORT(fs, FR_INT_ERR); fp->clust = clst; - fp->fptr += bcs; - ofs -= bcs; } fp->fptr += ofs; if (ofs % SS(fs)) { @@ -4057,26 +4056,22 @@ FRESULT f_lseek ( } } } + if (!_FS_READONLY && fp->fptr > fp->obj.objsize) { /* Set file change flag if the file size is extended */ + fp->obj.objsize = fp->fptr; + fp->flag |= FA_MODIFIED; + } if (fp->fptr % SS(fs) && nsect != fp->sect) { /* Fill sector cache if needed */ #if !_FS_TINY #if !_FS_READONLY if (fp->flag & FA_DIRTY) { /* Write-back dirty sector cache */ if (disk_write(fs->drv, fp->buf, fp->sect, 1) != RES_OK) ABORT(fs, FR_DISK_ERR); - fp->flag &= ~FA_DIRTY; + fp->flag &= (BYTE)~FA_DIRTY; } #endif - if (disk_read(fs->drv, fp->buf, nsect, 1) != RES_OK) { /* Fill sector cache */ - ABORT(fs, FR_DISK_ERR); - } + if (disk_read(fs->drv, fp->buf, nsect, 1) != RES_OK) ABORT(fs, FR_DISK_ERR); /* Fill sector cache */ #endif fp->sect = nsect; } -#if !_FS_READONLY - if (fp->fptr > fp->obj.objsize) { /* Set file change flag if the file size is extended */ - fp->obj.objsize = fp->fptr; - fp->flag |= FA_MODIFIED; - } -#endif } LEAVE_FF(fs, res); @@ -4102,7 +4097,7 @@ FRESULT f_opendir ( if (!dp) return FR_INVALID_OBJECT; - /* Get logical drive number */ + /* Get logical drive */ obj = &dp->obj; res = find_volume(&path, &fs, 0); if (res == FR_OK) { @@ -4167,7 +4162,7 @@ FRESULT f_closedir ( FATFS *fs; - res = validate(dp, &fs); + res = validate(&dp->obj, &fs); /* Check validity of the file object */ if (res == FR_OK) { #if _FS_LOCK != 0 if (dp->obj.lockid) { /* Decrement sub-directory open counter */ @@ -4202,7 +4197,7 @@ FRESULT f_readdir ( DEF_NAMBUF - res = validate(dp, &fs); /* Check validity of the object */ + res = validate(&dp->obj, &fs); /* Check validity of the directory object */ if (res == FR_OK) { if (!fno) { res = dir_sdi(dp, 0); /* Rewind the directory object */ @@ -4290,7 +4285,7 @@ FRESULT f_stat ( DEF_NAMBUF - /* Get logical drive number */ + /* Get logical drive */ res = find_volume(&path, &dj.obj.fs, 0); if (res == FR_OK) { INIT_NAMBUF(dj.obj.fs); @@ -4329,7 +4324,7 @@ FRESULT f_getfree ( _FDID obj; - /* Get logical drive number */ + /* Get logical drive */ res = find_volume(&path, &fs, 0); if (res == FR_OK) { *fatfs = fs; /* Return ptr to the fs object */ @@ -4411,8 +4406,8 @@ FRESULT f_truncate ( DWORD ncl; - res = validate(fp, &fs); /* Check validity of the object */ - if (res != FR_OK || (res = (FRESULT)fp->err) != FR_OK) LEAVE_FF(fs, res); /* Check validity */ + res = validate(&fp->obj, &fs); /* Check validity of the file object */ + if (res != FR_OK || (res = (FRESULT)fp->err) != FR_OK) LEAVE_FF(fs, res); if (!(fp->flag & FA_WRITE)) LEAVE_FF(fs, FR_DENIED); /* Check access mode */ if (fp->obj.objsize > fp->fptr) { @@ -4435,7 +4430,7 @@ FRESULT f_truncate ( if (disk_write(fs->drv, fp->buf, fp->sect, 1) != RES_OK) { res = FR_DISK_ERR; } else { - fp->flag &= ~FA_DIRTY; + fp->flag &= (BYTE)~FA_DIRTY; } } #endif @@ -4466,7 +4461,7 @@ FRESULT f_unlink ( DEF_NAMBUF - /* Get logical drive number */ + /* Get logical drive */ res = find_volume(&path, &fs, FA_WRITE); dj.obj.fs = fs; if (res == FR_OK) { @@ -4560,7 +4555,7 @@ FRESULT f_mkdir ( DEF_NAMBUF - /* Get logical drive number */ + /* Get logical drive */ res = find_volume(&path, &fs, FA_WRITE); dj.obj.fs = fs; if (res == FR_OK) { @@ -4654,7 +4649,7 @@ FRESULT f_rename ( get_ldnumber(&path_new); /* Ignore drive number of new name */ - res = find_volume(&path_old, &fs, FA_WRITE); /* Get logical drive number of the old object */ + res = find_volume(&path_old, &fs, FA_WRITE); /* Get logical drive of the old object */ if (res == FR_OK) { djo.obj.fs = fs; INIT_NAMBUF(fs); @@ -4671,10 +4666,12 @@ FRESULT f_rename ( mem_cpy(buf, fs->dirbuf, SZDIRE * 2); /* Save 85+C0 entry of old object */ mem_cpy(&djn, &djo, sizeof djo); - res = follow_path(&djn, path_new); /* Make sure if new object name is not in use */ - if (res == FR_OK) res = FR_EXIST; /* Is new name already in use? */ - if (res == FR_NO_FILE) { /* It is a valid path and no name collision */ - res = dir_register(&djn); /* Register the new entry */ + res = follow_path(&djn, path_new); /* Make sure if new object name is not in use */ + if (res == FR_OK) { /* Is new name already in use by any other object? */ + res = (djn.obj.sclust == djo.obj.sclust && djn.dptr == djo.dptr) ? FR_NO_FILE : FR_EXIST; + } + if (res == FR_NO_FILE) { /* It is a valid path and no name collision */ + res = dir_register(&djn); /* Register the new entry */ if (res == FR_OK) { nf = fs->dirbuf[XDIR_NumSec]; nn = fs->dirbuf[XDIR_NumName]; nh = ld_word(fs->dirbuf + XDIR_NameHash); @@ -4691,7 +4688,9 @@ FRESULT f_rename ( mem_cpy(buf, djo.dir + DIR_Attr, 21); /* Save information about the object except name */ mem_cpy(&djn, &djo, sizeof (DIR)); /* Duplicate the directory object */ res = follow_path(&djn, path_new); /* Make sure if new object name is not in use */ - if (res == FR_OK) res = FR_EXIST; /* Is new name already in use? */ + if (res == FR_OK) { /* Is new name already in use by any other object? */ + res = (djn.obj.sclust == djo.obj.sclust && djn.dptr == djo.dptr) ? FR_NO_FILE : FR_EXIST; + } if (res == FR_NO_FILE) { /* It is a valid path and no name collision */ res = dir_register(&djn); /* Register the new entry */ if (res == FR_OK) { @@ -4754,7 +4753,7 @@ FRESULT f_chmod ( DEF_NAMBUF - res = find_volume(&path, &fs, FA_WRITE); /* Get logical drive number */ + res = find_volume(&path, &fs, FA_WRITE); /* Get logical drive */ dj.obj.fs = fs; if (res == FR_OK) { INIT_NAMBUF(fs); @@ -4798,7 +4797,7 @@ FRESULT f_utime ( DEF_NAMBUF - res = find_volume(&path, &fs, FA_WRITE); /* Get logical drive number */ + res = find_volume(&path, &fs, FA_WRITE); /* Get logical drive */ dj.obj.fs = fs; if (res == FR_OK) { INIT_NAMBUF(fs); @@ -4846,7 +4845,7 @@ FRESULT f_getlabel ( WCHAR w; #endif - /* Get logical drive number */ + /* Get logical drive */ res = find_volume(&path, &fs, 0); /* Get volume label */ @@ -4934,7 +4933,7 @@ FRESULT f_setlabel ( static const char badchr[] = "\"*+,.:;<=>\?[]|\x7F"; - /* Get logical drive number */ + /* Get logical drive */ res = find_volume(&label, &fs, FA_WRITE); if (res != FR_OK) LEAVE_FF(fs, res); dj.obj.fs = fs; @@ -4943,7 +4942,7 @@ FRESULT f_setlabel ( for (slen = 0; (UINT)label[slen] >= ' '; slen++) ; /* Get name length */ #if _FS_EXFAT - if (fs->fs_type == FS_EXFAT) { /* At the exFAT */ + if (fs->fs_type == FS_EXFAT) { /* On the exFAT volume */ for (i = j = 0; i < slen; ) { /* Create volume label in directory form */ w = label[i++]; #if !_LFN_UNICODE @@ -4960,7 +4959,7 @@ FRESULT f_setlabel ( slen = j; } else #endif - { /* At the FAT12/16/32 */ + { /* On the FAT12/16/32 volume */ for ( ; slen && label[slen - 1] == ' '; slen--) ; /* Remove trailing spaces */ if (slen) { /* Is there a volume label to be set? */ dirvn[0] = 0; i = j = 0; /* Create volume label in directory form */ @@ -5001,7 +5000,7 @@ FRESULT f_setlabel ( res = dir_read(&dj, 1); /* Get volume label entry */ if (res == FR_OK) { if (_FS_EXFAT && fs->fs_type == FS_EXFAT) { - dj.dir[XDIR_NumLabel] = slen / 2; /* Change the volume label */ + dj.dir[XDIR_NumLabel] = (BYTE)(slen / 2); /* Change the volume label */ mem_cpy(dj.dir + XDIR_Label, dirvn, slen); } else { if (slen) { @@ -5021,7 +5020,7 @@ FRESULT f_setlabel ( mem_set(dj.dir, 0, SZDIRE); /* Clear the entry */ if (_FS_EXFAT && fs->fs_type == FS_EXFAT) { dj.dir[XDIR_Type] = 0x83; /* Create 83 entry */ - dj.dir[XDIR_NumLabel] = slen / 2; + dj.dir[XDIR_NumLabel] = (BYTE)(slen / 2); mem_cpy(dj.dir + XDIR_Label, dirvn, slen); } else { dj.dir[DIR_Attr] = AM_VOL; /* Create volume label entry */ @@ -5059,8 +5058,8 @@ FRESULT f_expand ( DWORD n, clst, stcl, scl, ncl, tcl, lclst; - res = validate(fp, &fs); /* Check validity of the object */ - if (res != FR_OK || (res = (FRESULT)fp->err) != FR_OK) LEAVE_FF(fs, res); /* Check validity */ + res = validate(&fp->obj, &fs); /* Check validity of the file object */ + if (res != FR_OK || (res = (FRESULT)fp->err) != FR_OK) LEAVE_FF(fs, res); if (fsz == 0 || fp->obj.objsize != 0 || !(fp->flag & FA_WRITE)) LEAVE_FF(fs, FR_DENIED); #if _FS_EXFAT if (fs->fs_type != FS_EXFAT && fsz >= 0x100000000) LEAVE_FF(fs, FR_DENIED); /* Check if in size limit */ @@ -5101,8 +5100,8 @@ FRESULT f_expand ( } if (res == FR_OK) { if (opt) { - for (clst = scl; tcl; clst++, tcl--) { /* Create a cluster chain on the FAT */ - res = put_fat(fs, clst, (tcl == 1) ? 0xFFFFFFFF : clst + 1); + for (clst = scl, n = tcl; n; clst++, n--) { /* Create a cluster chain on the FAT */ + res = put_fat(fs, clst, (n == 1) ? 0xFFFFFFFF : clst + 1); if (res != FR_OK) break; lclst = clst; } @@ -5112,12 +5111,18 @@ FRESULT f_expand ( } } - if (opt && res == FR_OK) { + if (res == FR_OK) { fs->last_clst = lclst; /* Set suggested start cluster to start next */ - fp->obj.sclust = scl; /* Update object allocation information */ - fp->obj.objsize = fsz; - if (_FS_EXFAT) fp->obj.stat = 2; /* Set status 'contiguous chain' */ - fp->flag |= FA_MODIFIED; + if (opt) { + fp->obj.sclust = scl; /* Update object allocation information */ + fp->obj.objsize = fsz; + if (_FS_EXFAT) fp->obj.stat = 2; /* Set status 'contiguous chain' */ + fp->flag |= FA_MODIFIED; + if (fs->free_clst < fs->n_fatent - 2) { /* Update FSINFO */ + fs->free_clst -= tcl; + fs->fsi_flag |= 1; + } + } } LEAVE_FF(fs, res); @@ -5148,8 +5153,8 @@ FRESULT f_forward ( *bf = 0; /* Clear transfer byte counter */ - res = validate(fp, &fs); /* Check validity of the object */ - if (res != FR_OK || (res = (FRESULT)fp->err) != FR_OK) LEAVE_FF(fs, res); /* Check validity */ + res = validate(&fp->obj, &fs); /* Check validity of the file object */ + if (res != FR_OK || (res = (FRESULT)fp->err) != FR_OK) LEAVE_FF(fs, res); if (!(fp->flag & FA_READ)) LEAVE_FF(fs, FR_DENIED); /* Check access mode */ remain = fp->obj.objsize - fp->fptr; @@ -5178,7 +5183,7 @@ FRESULT f_forward ( #if !_FS_READONLY if (fp->flag & FA_DIRTY) { /* Write-back dirty sector cache */ if (disk_write(fs->drv, fp->buf, fp->sect, 1) != RES_OK) ABORT(fs, FR_DISK_ERR); - fp->flag &= ~FA_DIRTY; + fp->flag &= (BYTE)~FA_DIRTY; } #endif if (disk_read(fs->drv, fp->buf, sect, 1) != RES_OK) ABORT(fs, FR_DISK_ERR); @@ -5213,14 +5218,14 @@ FRESULT f_mkfs ( { const UINT n_fats = 1; /* Number of FATs for FAT12/16/32 volume (1 or 2) */ const UINT n_rootdir = 512; /* Number of root directory entries for FAT12/16 volume */ - static const WORD cst[] = {1, 4, 16, 64, 256, 512, 0}; /* Cluster size boundary for FAT12/16 volume (4KS unit) */ - static const WORD cst32[] = {1, 2, 4, 8, 16, 32, 0}; /* Cluster size boundary for FAT32 volume (128KS unit) */ + static const WORD cst[] = {1, 4, 16, 64, 256, 512, 0}; /* Cluster size boundary for FAT12/16 volume (4Ks unit) */ + static const WORD cst32[] = {1, 2, 4, 8, 16, 32, 0}; /* Cluster size boundary for FAT32 volume (128Ks unit) */ BYTE fmt, sys, *buf, *pte, pdrv, part; WORD ss; - DWORD n, pau, n_clst, sz_blk, sect, szb_buf, sz_buf; + DWORD szb_buf, sz_buf, sz_blk, n_clst, pau, sect, nsect, n; DWORD b_vol, b_fat, b_data; /* Base LBA for volume, fat, data */ DWORD sz_vol, sz_rsv, sz_fat, sz_dir; /* Size for volume, fat, dir, data */ - UINT i, ns; + UINT i; int vol; DSTATUS stat; #if _USE_TRIM || _FS_EXFAT @@ -5233,34 +5238,33 @@ FRESULT f_mkfs ( if (vol < 0) return FR_INVALID_DRIVE; if (FatFs[vol]) FatFs[vol]->fs_type = 0; /* Clear mounted volume */ pdrv = LD2PD(vol); /* Physical drive */ - part = LD2PT(vol); /* Partition (0:create as new, 1-4:get by partition table) */ + part = LD2PT(vol); /* Partition (0:create as new, 1-4:get from partition table) */ /* Check physical drive status */ stat = disk_initialize(pdrv); if (stat & STA_NOINIT) return FR_NOT_READY; if (stat & STA_PROTECT) return FR_WRITE_PROTECTED; - if (disk_ioctl(pdrv, GET_BLOCK_SIZE, &sz_blk) != RES_OK || !sz_blk || sz_blk > 32768 || (sz_blk & (sz_blk - 1))) sz_blk = 1; + if (disk_ioctl(pdrv, GET_BLOCK_SIZE, &sz_blk) != RES_OK || !sz_blk || sz_blk > 32768 || (sz_blk & (sz_blk - 1))) sz_blk = 1; /* Erase block to align data area */ #if _MAX_SS != _MIN_SS /* Get sector size of the medium */ if (disk_ioctl(pdrv, GET_SECTOR_SIZE, &ss) != RES_OK) return FR_DISK_ERR; if (ss > _MAX_SS || ss < _MIN_SS || (ss & (ss - 1))) return FR_DISK_ERR; #else ss = _MAX_SS; #endif - if ((au != 0 && au < ss) || (au & (au - 1))) return FR_INVALID_PARAMETER; /* Check if au is valid */ - au /= ss; /* Cluster size in byte to in sector */ - if (au > 32768) return FR_INVALID_PARAMETER; + if ((au != 0 && au < ss) || au > 0x1000000 || (au & (au - 1))) return FR_INVALID_PARAMETER; /* Check if au is valid */ + au /= ss; /* Cluster size in unit of sector */ - /* Set size and pointer of the working buffer */ - buf = (BYTE*)work; /* Use given working buffer */ - if (len < ss) return FR_MKFS_ABORTED; - szb_buf = len & ~(ss - 1); /* Round-down by sector size [byte] */ - sz_buf = szb_buf / ss; /* Size of sector buffer [sector] */ + /* Get working buffer */ + buf = (BYTE*)work; /* Working buffer */ + sz_buf = len / ss; /* Size of working buffer (sector) */ + szb_buf = sz_buf * ss; /* Size of working buffer (byte) */ + if (!szb_buf) return FR_MKFS_ABORTED; /* Determine where the volume to be located (b_vol, sz_vol) */ if (_MULTI_PARTITION && part != 0) { /* Get partition information from partition table in the MBR */ if (disk_read(pdrv, buf, 0, 1) != RES_OK) return FR_DISK_ERR; /* Load MBR */ - if (ld_word(buf + BS_55AA) != 0xAA55) return FR_MKFS_ABORTED; /* Check MBR is valid */ + if (ld_word(buf + BS_55AA) != 0xAA55) return FR_MKFS_ABORTED; /* Check if MBR is valid */ pte = buf + (MBR_Table + (part - 1) * SZ_PTE); if (!pte[PTE_System]) return FR_MKFS_ABORTED; /* No partition? */ b_vol = ld_dword(pte + PTE_StLba); /* Get volume start sector */ @@ -5272,16 +5276,16 @@ FRESULT f_mkfs ( if (sz_vol < b_vol) return FR_MKFS_ABORTED; sz_vol -= b_vol; /* Volume size */ } - if (sz_vol < 128) return FR_MKFS_ABORTED; /* Check volume size (>=128s) */ + if (sz_vol < 128) return FR_MKFS_ABORTED; /* Check if volume size is >=128s */ - /* Pre-determine the FAT type by argument */ + /* Pre-determine the FAT type */ do { if (_FS_EXFAT && (opt & FM_EXFAT)) { /* exFAT possible? */ - if ((opt & FM_ANY) == FM_EXFAT || sz_vol >= 0x4000000 || au >= 256) { /* exFAT only, vol >= 64Ms or au >= 256s ? */ + if ((opt & FM_ANY) == FM_EXFAT || sz_vol >= 0x4000000 || au > 128) { /* exFAT only, vol >= 64Ms or au > 128s ? */ fmt = FS_EXFAT; break; } } - if (au >= 256) return FR_INVALID_PARAMETER; /* Too large au for FAT/FAT32 */ + if (au > 128) return FR_INVALID_PARAMETER; /* Too large au for FAT/FAT32 */ if (opt & FM_FAT32) { /* FAT32 possible? */ if ((opt & FM_ANY) == FM_FAT32 || !(opt & FM_FAT)) { /* FAT32 only or no-FAT? */ fmt = FS_FAT32; break; @@ -5293,7 +5297,7 @@ FRESULT f_mkfs ( #if _FS_EXFAT if (fmt == FS_EXFAT) { /* Create an exFAT volume */ - DWORD sum, szb_bit, szb_case; + DWORD szb_bit, szb_case, sum, nb, cl; WCHAR ch, si; UINT j, st; BYTE b; @@ -5306,20 +5310,19 @@ FRESULT f_mkfs ( /* Determine FAT location, data location and number of clusters */ if (!au) { /* au auto-selection */ au = 8; - if (sz_vol >= 0x80000) au = 64; /* >= 512KS */ - if (sz_vol >= 0x4000000) au = 256; /* >= 64MS */ + if (sz_vol >= 0x80000) au = 64; /* >= 512Ks */ + if (sz_vol >= 0x4000000) au = 256; /* >= 64Ms */ } b_fat = b_vol + 32; /* FAT start at offset 32 */ - sz_fat = ((sz_vol / au + 2) * 4 + ss - 1) / ss; /* Numbef of FAT sectors */ + 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) return FR_MKFS_ABORTED; /* Too small volume? */ - n_clst = (sz_vol - (b_data - b_vol)) / au; /* Nunber of clusters */ + n_clst = (sz_vol - (b_data - b_vol)) / au; /* Number of clusters */ if (n_clst <16) return FR_MKFS_ABORTED; /* Too few clusters? */ if (n_clst > MAX_EXFAT) return FR_MKFS_ABORTED; /* Too many clusters? */ - szb_bit = (n_clst + 7) / 8; /* Size of allocation bitmap */ - tbl[0] = (szb_bit + au * ss - 1) / (au * ss); /* Number of bitmap clusters */ - tbl[2] = 1; /* Number of rootdir clusters */ + szb_bit = (n_clst + 7) / 8; /* Size of allocation bitmap */ + tbl[0] = (szb_bit + au * ss - 1) / (au * ss); /* Number of allocation bitmap clusters */ /* Create a compressed up-case table */ sect = b_data + au * tbl[0]; /* Table start sector */ @@ -5350,43 +5353,49 @@ FRESULT f_mkfs ( sum = xsum32(buf[i + 1] = (BYTE)(ch >> 8), sum); i += 2; szb_case += 2; if (!si || i == szb_buf) { /* Write buffered data when buffer full or end of process */ - ns = (i + ss - 1) / ss; - if (disk_write(pdrv, buf, sect, ns) != RES_OK) return FR_DISK_ERR; - sect += ns; i = 0; + n = (i + ss - 1) / ss; + if (disk_write(pdrv, buf, sect, n) != RES_OK) return FR_DISK_ERR; + sect += n; i = 0; } } while (si); - tbl[1] = (szb_case + au * ss - 1) / (au * ss); /* Number of up-case clusters */ + tbl[1] = (szb_case + au * ss - 1) / (au * ss); /* Number of up-case table clusters */ + tbl[2] = 1; /* Number of root dir clusters */ /* Initialize the allocation bitmap */ - mem_set(buf, 0, szb_buf); /* Set in-use flags of bitmap, up-case and root dir */ - for (i = 0, n = tbl[0] + tbl[1] + tbl[2]; n >= 8; buf[i++] = 0xFF, n -= 8) ; - for (b = 1; n; buf[i] |= b, b <<= 1, n--) ; - sect = b_data; n = (szb_bit + ss - 1) / ss; /* Start of bitmap and number of the sectors */ - do { /* Fill allocation bitmap sectors */ - ns = (n > sz_buf) ? sz_buf : n; - if (disk_write(pdrv, buf, sect, ns) != RES_OK) return FR_DISK_ERR; - sect += ns; - mem_set(buf, 0, ss); - } while (n -= ns); + sect = b_data; nsect = (szb_bit + ss - 1) / ss; /* Start of bitmap and number of sectors */ + nb = tbl[0] + tbl[1] + tbl[2]; /* Number of clusters in-use by system */ + do { + mem_set(buf, 0, szb_buf); + for (i = 0; nb >= 8 && i < szb_buf; buf[i++] = 0xFF, nb -= 8) ; + for (b = 1; nb && i < szb_buf; buf[i] |= b, b <<= 1, nb--) ; + n = (nsect > sz_buf) ? sz_buf : nsect; /* Write the buffered data */ + if (disk_write(pdrv, buf, sect, n) != RES_OK) return FR_DISK_ERR; + sect += n; nsect -= n; + } while (nsect); /* Initialize the FAT */ - st_qword(buf, 0xFFFFFFFFFFFFFFF8); /* Entry 0 and 1 */ - for (j = 0, i = 2; j < 3; j++) { /* Set entries of bitmap, up-case and root dir */ - for (n = tbl[j]; n; n--) { - st_dword(buf + i * 4, (n >= 2) ? i + 1 : 0xFFFFFFFF); - i++; + sect = b_fat; nsect = sz_fat; /* Start of FAT and number of FAT sectors */ + j = nb = cl = 0; + do { + mem_set(buf, 0, szb_buf); i = 0; /* Clear work area and reset write index */ + if (cl == 0) { /* Set entry 0 and 1 */ + st_dword(buf + i, 0xFFFFFFF8); i += 4; cl++; + st_dword(buf + i, 0xFFFFFFFF); i += 4; cl++; } - } - sect = b_fat; n = sz_fat; /* Start of FAT and number of the sectors */ - do { /* Fill FAT sectors */ - ns = (n > sz_buf) ? sz_buf : n; - if (disk_write(pdrv, buf, sect, ns) != RES_OK) return FR_DISK_ERR; - sect += ns; - mem_set(buf, 0, ss); - } while (n -= ns); + do { /* Create chains of bitmap, up-case and root dir */ + while (nb && i < szb_buf) { /* Create a chain */ + st_dword(buf + i, (nb > 1) ? cl + 1 : 0xFFFFFFFF); + i += 4; cl++; nb--; + } + if (!nb && j < 3) nb = tbl[j++]; /* Next chain */ + } while (nb && i < szb_buf); + n = (nsect > sz_buf) ? sz_buf : nsect; /* Write the buffered data */ + if (disk_write(pdrv, buf, sect, n) != RES_OK) return FR_DISK_ERR; + sect += n; nsect -= n; + } while (nsect); /* Initialize the root directory */ - mem_set(buf, 0, ss); + mem_set(buf, 0, szb_buf); buf[SZDIRE * 0 + 0] = 0x83; /* 83 entry (volume label) */ buf[SZDIRE * 1 + 0] = 0x81; /* 81 entry (allocation bitmap) */ st_dword(buf + SZDIRE * 1 + 20, 2); @@ -5395,13 +5404,13 @@ FRESULT f_mkfs ( st_dword(buf + SZDIRE * 2 + 4, sum); st_dword(buf + SZDIRE * 2 + 20, 2 + tbl[0]); st_dword(buf + SZDIRE * 2 + 24, szb_case); - sect = b_data + au * (tbl[0] + tbl[1]); n = au; /* Start of directory and number of the sectors */ - do { /* Fill root direcotry sectors */ - ns = (n > sz_buf) ? sz_buf : n; - if (disk_write(pdrv, buf, sect, ns) != RES_OK) return FR_DISK_ERR; - sect += ns; + sect = b_data + au * (tbl[0] + tbl[1]); nsect = au; /* Start of the root directory and number of sectors */ + do { /* Fill root directory sectors */ + n = (nsect > sz_buf) ? sz_buf : nsect; + if (disk_write(pdrv, buf, sect, n) != RES_OK) return FR_DISK_ERR; mem_set(buf, 0, ss); - } while (n -= ns); + sect += n; nsect -= n; + } while (nsect); /* Create two set of the exFAT VBR blocks */ sect = b_vol; @@ -5447,7 +5456,7 @@ FRESULT f_mkfs ( } } else -#endif +#endif /* _FS_EXFAT */ { /* Create an FAT12/16/32 volume */ do { pau = au; @@ -5530,14 +5539,14 @@ FRESULT f_mkfs ( st_word(buf + BPB_BytsPerSec, ss); /* Sector size [byte] */ buf[BPB_SecPerClus] = (BYTE)pau; /* Cluster size [sector] */ st_word(buf + BPB_RsvdSecCnt, (WORD)sz_rsv); /* Size of reserved area */ - buf[BPB_NumFATs] = n_fats; /* Number of FATs */ + buf[BPB_NumFATs] = (BYTE)n_fats; /* Number of FATs */ st_word(buf + BPB_RootEntCnt, (WORD)((fmt == FS_FAT32) ? 0 : n_rootdir)); /* Number of root directory entries */ if (sz_vol < 0x10000) { st_word(buf + BPB_TotSec16, (WORD)sz_vol); /* Volume size in 16-bit LBA */ } else { - st_dword(buf + BPB_TotSec32, sz_vol); /* Volume size in 12-bit LBA */ + st_dword(buf + BPB_TotSec32, sz_vol); /* Volume size in 32-bit LBA */ } - buf[BPB_Media] = 0xF8; /* Media descriptor */ + buf[BPB_Media] = 0xF8; /* Media descriptor byte */ st_word(buf + BPB_SecPerTrk, 63); /* Number of sectors per track (for int13) */ st_word(buf + BPB_NumHeads, 255); /* Number of heads (for int13) */ st_dword(buf + BPB_HiddSec, b_vol); /* Volume offset in the physical drive [sector] */ @@ -5574,8 +5583,8 @@ FRESULT f_mkfs ( } /* Initialize FAT area */ - mem_set(buf, 0, szb_buf); - sect = b_fat; /* Start sector */ + mem_set(buf, 0, (UINT)szb_buf); + sect = b_fat; /* FAT start sector */ for (i = 0; i < n_fats; i++) { /* Initialize FATs each */ if (fmt == FS_FAT32) { st_dword(buf + 0, 0xFFFFFFF8); /* Entry 0 */ @@ -5584,22 +5593,22 @@ FRESULT f_mkfs ( } else { st_dword(buf + 0, (fmt == FS_FAT12) ? 0xFFFFF8 : 0xFFFFFFF8); /* Entry 0 and 1 */ } - n = sz_fat; /* Sector count of a FAT */ + nsect = sz_fat; /* Number of FAT sectors */ do { /* Fill FAT sectors */ - ns = (n > sz_buf) ? sz_buf : n; - if (disk_write(pdrv, buf, sect, ns) != RES_OK) return FR_DISK_ERR; - sect += ns; + n = (nsect > sz_buf) ? sz_buf : nsect; + if (disk_write(pdrv, buf, sect, (UINT)n) != RES_OK) return FR_DISK_ERR; mem_set(buf, 0, ss); - } while (n -= ns); + sect += n; nsect -= n; + } while (nsect); } /* Initialize root directory (fill with zero) */ - n = (fmt == FS_FAT32) ? pau : sz_dir; /* Sector count of root directory */ + nsect = (fmt == FS_FAT32) ? pau : sz_dir; /* Number of root directory sectors */ do { - ns = (n > sz_buf) ? sz_buf : n; - if (disk_write(pdrv, buf, sect, ns) != RES_OK) return FR_DISK_ERR; - sect += ns; - } while (n -= ns); + n = (nsect > sz_buf) ? sz_buf : nsect; + if (disk_write(pdrv, buf, sect, (UINT)n) != RES_OK) return FR_DISK_ERR; + sect += n; nsect -= n; + } while (nsect); } /* Determine system ID in the partition table */ diff --git a/src/ff.h b/src/ff.h index 26748b9..905dd66 100644 --- a/src/ff.h +++ b/src/ff.h @@ -1,5 +1,5 @@ /*----------------------------------------------------------------------------/ -/ FatFs - Generic FAT file system module R0.12a / +/ FatFs - Generic FAT file system module R0.12b / /-----------------------------------------------------------------------------/ / / Copyright (C) 2016, ChaN, all right reserved. @@ -19,7 +19,7 @@ #ifndef _FATFS -#define _FATFS 80186 /* Revision ID */ +#define _FATFS 68020 /* Revision ID */ #ifdef __cplusplus extern "C" { @@ -159,7 +159,7 @@ typedef struct { /* File object structure (FIL) */ typedef struct { - _FDID obj; /* Object identifier */ + _FDID obj; /* Object identifier (must be the 1st member to detect invalid object pointer) */ BYTE flag; /* File status flags */ BYTE err; /* Abort flag (error code) */ FSIZE_t fptr; /* File read/write pointer (Zeroed on file open) */ diff --git a/src/ffconf.h b/src/ffconf.h index d5533e5..ae552a2 100644 --- a/src/ffconf.h +++ b/src/ffconf.h @@ -2,7 +2,7 @@ / FatFs - FAT file system module configuration file /---------------------------------------------------------------------------*/ -#define _FFCONF 80186 /* Revision ID */ +#define _FFCONF 68020 /* Revision ID */ /*---------------------------------------------------------------------------/ / Function Configurations @@ -204,14 +204,14 @@ #define _FS_TINY 0 /* This option switches tiny buffer configuration. (0:Normal or 1:Tiny) -/ At the tiny configuration, size of the file object (FIL) is reduced _MAX_SS bytes. +/ At the tiny configuration, size of file object (FIL) is reduced _MAX_SS bytes. / Instead of private sector buffer eliminated from the file object, common sector / buffer in the file system object (FATFS) is used for the file data transfer. */ #define _FS_EXFAT 0 -/* This option switches support of exFAT file system in addition to the traditional -/ FAT file system. (0:Disable or 1:Enable) To enable exFAT, also LFN must be enabled. +/* This option switches support of exFAT file system. (0:Disable or 1:Enable) +/ When enable exFAT, also LFN needs to be enabled. (_USE_LFN >= 1) / Note that enabling exFAT discards C89 compatibility. */ @@ -259,7 +259,9 @@ / The _FS_TIMEOUT defines timeout period in unit of time tick. / The _SYNC_t defines O/S dependent sync object type. e.g. HANDLE, ID, OS_EVENT*, / SemaphoreHandle_t and etc.. A header file for O/S definitions needs to be -/ included somewhere in the scope of ff.c. */ +/ included somewhere in the scope of ff.h. */ + +/* #include // O/S definitions */ /*--- End of configuration options ---*/