From 80543174b157ae2b16c45ef4ab617126fa4c7433 Mon Sep 17 00:00:00 2001 From: savelij13 Date: Thu, 11 Sep 2025 10:06:37 +0300 Subject: [PATCH] fatfs v0.11 February 09, 2015: - Added f_findfirst(), f_findnext() and f_findclose(). (_USE_FIND) - Fixed f_unlink() does not remove cluster chain of the file. (appeared at R0.10c) - Fixed _FS_NORTC option does not work properly. (appeared at R0.10c) --- doc/00index_e.html | 102 ++++--- doc/00index_j.html | 103 ++++--- doc/css_e.css | 1 + doc/css_j.css | 3 +- doc/en/appnote.html | 224 +++++++------- doc/en/chdir.html | 2 +- doc/en/chdrive.html | 2 +- doc/en/chmod.html | 2 +- doc/en/close.html | 3 +- doc/en/closedir.html | 2 +- doc/en/config.html | 215 +++++++++++++ doc/en/dinit.html | 4 +- doc/en/dioctl.html | 10 +- doc/en/dread.html | 8 +- doc/en/dstat.html | 2 +- doc/en/dwrite.html | 4 +- doc/en/eof.html | 2 +- doc/en/fattime.html | 6 +- doc/en/fdisk.html | 2 +- doc/en/filename.html | 34 ++- doc/en/findfirst.html | 119 ++++++++ doc/en/findnext.html | 69 +++++ doc/en/forward.html | 5 +- doc/en/getcwd.html | 4 +- doc/en/getfree.html | 4 +- doc/en/gets.html | 6 +- doc/en/lseek.html | 11 +- doc/en/mkdir.html | 2 +- doc/en/mkfs.html | 19 +- doc/en/mount.html | 18 +- doc/en/open.html | 10 +- doc/en/opendir.html | 4 +- doc/en/printf.html | 6 +- doc/en/putc.html | 10 +- doc/en/puts.html | 10 +- doc/en/rc.html | 29 +- doc/en/read.html | 1 - doc/en/readdir.html | 9 +- doc/en/rename.html | 2 +- doc/en/sdir.html | 5 +- doc/en/setlabel.html | 5 +- doc/en/sfatfs.html | 22 +- doc/en/sfile.html | 12 +- doc/en/sfileinfo.html | 6 +- doc/en/size.html | 2 +- doc/en/stat.html | 2 +- doc/en/sync.html | 5 +- doc/en/tell.html | 2 +- doc/en/truncate.html | 3 +- doc/en/unlink.html | 2 +- doc/en/utime.html | 2 +- doc/en/write.html | 1 - doc/img/app3.c | 2 +- doc/img/app4.c | 2 +- doc/img/f6.png | Bin 1436 -> 1464 bytes doc/img/funcs.png | Bin 14357 -> 19491 bytes doc/img/layers.png | Bin 2401 -> 5521 bytes doc/img/layers1.png | Bin 0 -> 3843 bytes doc/img/layers2.png | Bin 0 -> 3741 bytes doc/ja/appnote.html | 173 +++++------ doc/ja/close.html | 1 - doc/ja/config.html | 216 +++++++++++++ doc/ja/dinit.html | 4 +- doc/ja/dioctl.html | 12 +- doc/ja/dread.html | 12 +- doc/ja/dstat.html | 2 +- doc/ja/dwrite.html | 10 +- doc/ja/eof.html | 2 +- doc/ja/error.html | 2 +- doc/ja/fattime.html | 2 +- doc/ja/filename.html | 32 +- doc/ja/findfirst.html | 119 ++++++++ doc/ja/findnext.html | 68 +++++ doc/ja/forward.html | 3 +- doc/ja/getfree.html | 2 +- doc/ja/gets.html | 4 +- doc/ja/lseek.html | 11 +- doc/ja/mkdir.html | 4 +- doc/ja/mkfs.html | 19 +- doc/ja/mount.html | 4 +- doc/ja/open.html | 6 +- doc/ja/opendir.html | 5 +- doc/ja/printf.html | 4 +- doc/ja/putc.html | 4 +- doc/ja/puts.html | 4 +- doc/ja/rc.html | 27 +- doc/ja/read.html | 1 - doc/ja/readdir.html | 9 +- doc/ja/rename.html | 2 +- doc/ja/sdir.html | 9 +- doc/ja/setlabel.html | 3 +- doc/ja/sfatfs.html | 12 +- doc/ja/sfile.html | 6 +- doc/ja/sfileinfo.html | 8 +- doc/ja/size.html | 2 +- doc/ja/sync.html | 5 +- doc/ja/truncate.html | 1 - doc/ja/unlink.html | 9 +- doc/ja/write.html | 1 - src/00readme.txt | 166 +--------- src/diskio.c | 12 +- src/ff.c | 682 ++++++++++++++++++++++-------------------- src/ff.h | 35 ++- src/ffconf.h | 99 +++--- src/history.txt | 180 +++++++++++ src/option/unicode.c | 2 +- 106 files changed, 2024 insertions(+), 1114 deletions(-) create mode 100644 doc/en/config.html create mode 100644 doc/en/findfirst.html create mode 100644 doc/en/findnext.html create mode 100644 doc/img/layers1.png create mode 100644 doc/img/layers2.png create mode 100644 doc/ja/config.html create mode 100644 doc/ja/findfirst.html create mode 100644 doc/ja/findnext.html create mode 100644 src/history.txt diff --git a/doc/00index_e.html b/doc/00index_e.html index ac547a8..69d2352 100644 --- a/doc/00index_e.html +++ b/doc/00index_e.html @@ -19,7 +19,7 @@
layer -

FatFs is a generic FAT file system module for small embedded systems. The FatFs module is written in compliance with ANSI C (C89) and completely separated from the disk I/O layer. Therefore it is independent of the platform. It can be incorporated into small microcontrollers with limited resource, such as 8051, PIC, AVR, ARM, Z80, 78K and etc. Also Petit FatFs module for tiny microcontrollers is available here↗.

+

FatFs is a generic FAT file system module for small embedded systems. The FatFs module is written in compliance with ANSI C (C89) and completely separated from the disk I/O layer. Therefore it is independent of the platform. It can be incorporated into small microcontrollers with limited resource, such as 8051, PIC, AVR, ARM, Z80, 78K and etc. Also Petit FatFs module for tiny microcontrollers is available here.

Features

解説

-

buffに指定されるアドレスは常にワード アライメントされているとは限りません。詳細は、disk_read()の解説を参照してください。

+

buffに指定されるアドレスは常にワード アライメントされているとは限りません。これについては、disk_read関数の解説を参照してください。

一般的に、複数セクタの転送要求は、デバイスに対して可能な限りマルチ セクタ転送しなければなりません。複数のシングル セクタ書き込みに分解された場合、スループットが著しく低下することがあります。

-

FatFsはディスク関数が遅延書き込み機能を持つことも想定しています。この関数から戻るとき、デバイスが書き込み中とかキャッシュに書き込まれただけなど、必ずしもメディアへの書き込みが完了している必要はありません。ただし、buffのデータは、この関数から戻ると無効となります。書き込み完了の要求は、disk_ioctl()CTRL_SYNCコマンドによって行われます。このような遅延書き込み機能が実装された場合、スループットをさらに向上させることができます。

+

FatFsはディスク制御レイヤが遅延書き込み機能を持つことも想定しています。この関数から戻るとき、デバイスが書き込みを実行中だったり単にライトバック キャッシュに書き込まれただけなど、必ずしもメディアへの書き込みが完了している必要はありません。ただし、buffのデータは、この関数から戻ると無効となります。書き込み完了の要求は、disk_ioctl関数のCTRL_SYNCコマンドによって行われます。このような遅延書き込み機能が実装された場合、書き込みスループットを向上させることができます。

アプリケーションからはこの関数を呼び出してはなりません。さもないと、FATボリュームが破壊される可能性があります。

diff --git a/doc/ja/eof.html b/doc/ja/eof.html index 4f6e923..33d08b9 100644 --- a/doc/ja/eof.html +++ b/doc/ja/eof.html @@ -39,7 +39,7 @@ int f_eof (

解説

-

f_eof関数は、現リビジョンではマクロとして実装されています。

+

この関数は、現リビジョンではマクロとして実装されています。

 #define f_eof(fp) ((int)((fp)->fptr == (fp)->fsize))
 
diff --git a/doc/ja/error.html b/doc/ja/error.html index 0283be1..e2f08d0 100644 --- a/doc/ja/error.html +++ b/doc/ja/error.html @@ -39,7 +39,7 @@ int f_error (

解説

-

f_error関数は、現リビジョンではマクロとして実装されています。

+

この関数は、現リビジョンではマクロとして実装されています。

 #define f_error(fp) ((fp)->err)
 
diff --git a/doc/ja/fattime.html b/doc/ja/fattime.html index 98e9485..0b8f5ff 100644 --- a/doc/ja/fattime.html +++ b/doc/ja/fattime.html @@ -48,7 +48,7 @@ DWORD get_fattime (void);

対応情報

-

リード オンリー構成(_FS_READONLY == 1)ではこの関数は必要とされません。

+

リード オンリー構成(_FS_READONLY == 1)または、非RTCサポート構成(_RTC_NOUSE == 1)ではこの関数は必要とされません。

diff --git a/doc/ja/filename.html b/doc/ja/filename.html index 6acb61f..8b651dd 100644 --- a/doc/ja/filename.html +++ b/doc/ja/filename.html @@ -11,16 +11,16 @@

パス名のフォーマット

-
+

ファイル ディレクトリ名

-

FatFsモジュールでのファイル、ディレクトリ、ドライブの指定方法はDOS/Windows APIとほぼ同じです。パス名のフォーマットは次の通りです。

+

FatFsモジュールでは、パス名によるファイル、ディレクトリ、ドライブの指定方法はDOS/Windows APIとほぼ同じです。パス名のフォーマットは次の通りです。

"[論理ドライブ番号:][/]ディレクトリ名/ファイル名"
-

FatFsモジュールは長いファイル名(LFN)および8.3形式ファイル名(SFN)に対応しています。LFNは、(_USE_LFN > 0)のとき使用可能になります。ディレクトリ セパレータにはDOS/Windows APIと同じく'/''\'を使用します。連続したセパレータは無視され1個として扱われます。唯一の違いは、論理ドライブの指定だけです。論理ドライブ番号は、'0''9'の一文字の数字とコロンで指定し、省略した場合はデフォルト ドライブ(0またはカレント ドライブ)が選択されます。

+

FatFsモジュールは長いファイル名(LFN)および8.3形式ファイル名(SFN)に対応しています。LFNは、(_USE_LFN > 0)のとき使用可能になります。ディレクトリ セパレータにはDOS/Windows APIと同じく'/''\'を使用します。連続したセパレータは無視され1個として扱われます。唯一の違いは、論理ドライブの指定だけです。論理ドライブ番号は、'0''9'の一文字の数字とコロンで指定し、省略した場合はデフォルト ドライブ(0またはカレント ドライブ)が選択されます。

ヌル文字や制御文字('\0''\x1F')は、パス名の終端として認識されます。パス名に先行あるいは中に含まれるスペースは、LFN構成では名前の一部として有効ですが、非LFN構成ではスペースはパス名の終端として認識されます。

-

標準構成(_FS_RPATH == 0)のときは、全てのオブジェクトがルート ディレクトリから辿る絶対パスで指定されます。OS指向なカレント ディレクトリという概念は無く、またドット ディレクトリ("."や"..")は使用できません。パス名先頭のセパレータは無視されます。デフォルト ドライブ番号は常に0になります。

-

相対パスを有効(_FS_RPATH == 1)にしたときは、先行するセパレータの有無によって検索開始ディレクトリが変わり、セパレータがある場合はルート ディレクトリから、無い場合はf_chdir()で設定されるカレント ディレクトリからになります。またパス名にドット ディレクトリが使用できます。デフォルト ドライブ番号はf_chdrive()で設定された値となります。

+

標準構成(_FS_RPATH == 0)のときは、全てのオブジェクトがルート ディレクトリから辿る絶対パスで指定されます。OS指向なカレント ディレクトリという概念は無く、またドット ディレクトリ(".""..")は使用できません。パス名先頭のセパレータは無視されます。デフォルト ドライブ番号は常に0になります。

+

相対パスを有効(_FS_RPATH >= 1)にしたときは、先行するセパレータの有無によって検索開始ディレクトリが変わり、セパレータがある場合はルート ディレクトリから、無い場合はf_chdir関数で設定されるカレント ディレクトリからになります。またパス名にドット ディレクトリが使用できます。デフォルト ドライブ番号はf_chdrive関数で設定された値となります。

- + @@ -33,13 +33,19 @@
パス名の例_FS_RPATH == 0_FS_RPATH == 1
パス名の例_FS_RPATH == 0_FS_RPATH >= 1
file.txtドライブ0のルート ディレクトリ下のファイルカレント ドライブのカレント ディレクトリ下のファイル
/file.txtドライブ0のルート ディレクトリ下のファイルカレント ドライブのルート ディレクトリ下のファイル
ドライブ0のルート ディレクトリカレント ドライブのカレント ディレクトリ
dir1/..無効カレント ディレクトリ
/..無効ルート ディレクトリ(その上は辿れない)
-

また、_STR_VOLUME_IDオプションを有効にすることでドライブ番号の識別には数字のほか、"sd:file1.txt""ram:swapfile.dat"のように、任意の文字列を使用することも可能になります。

+

また、_STR_VOLUME_IDオプションを有効にすることでドライブ番号の識別には数字のほか、"sd:file1.txt""ram:swapfile.dat"のように、任意の文字列を使用することも可能になります。

-


-
+
+

使用可能な文字と大文字小文字の識別

+

FATファイル システムでファイル名に使用可能な文字は、0~9 A~Z ! # $ % & ' ( ) - @ ^ _ ` { } ~および拡張文字(\x80\xFF)となっています。LFN拡張ではこれらに加え、+ , ; = [ ]およびスペースが使用可能になり、スペースとピリオドはファイル名の末尾を除く任意の位置に挿入できます。

+

FATファイル システムでは、パス名についてケース インセンシティブです。たとえば、file.txt, File.Txt, FILE.TXTの3つの名前は同じ物として扱われます。これは、ASCII文字だけでなく拡張文字についても適用されます。ファイルが作成される際、SFNエントリには全て大文字に変換された名前が記録されます。LFN対応システムでは、LFNエントリには大文字変換されない名前が記録されます。

+

古い日本語MS-DOSでは拡張文字(いわゆる全角文字)についてはケース センシティブでした。FatFsモジュールではこれにしたがい、非LFN構成で文字コードにDBCSが選択されたときに限り、拡張文字に対して大文字変換を行わずにSFNエントリに記録および検索されます(日本語MSDOS仕様)。LFN構成では拡張文字についても大文字変換を行います(WindowsNT仕様)。このため、非LFN構成で全角小文字を含む名前でファイルを作成すると、Windowsでそのファイルを開けなくなるなどの互換性問題を起こすので、それらのシステムで相互利用するボリューム上ではDBCS拡張文字の使用は避けるべきです。

+
+ +

Unicode API

-

ファイル関数の入出力のうちファイル名やパス名を指定する引数の型は、TCHARで定義されていますが、これは通常はcharのエリアスになっています。そして、_CODE_PAGEで指定されるANSI/OEMコード(SBCSまたはDBCS)の文字列として扱われます。ファイル名入出力をUnicodeとする構成(_LFN_UNICODE == 1)にしたときは、TCHARはワイド文字(WCHAR, unsigned short)に切り替わり、パス名の入出力にUnicodeを使用するようになります。これによりLFN規格に完全対応となり、ANSI/OEMコードにない文字(たとえば ✝☪✡☸☭など)も使用できます。この設定は文字列入出力関数のデータ型とファイル上のエンコーディングにも影響を与えます。リテラル文字列を定義するとき、次に示すように_T(s)および_TEXT(s)マクロを使ってANSI/OEMとUnicodeを自動切り替えすることができます。

+

ファイル関数の入出力のうちファイル名やパス名を指定する引数の型は、TCHARで定義されていますが、これは通常はcharのエリアスになっています。そして、_CODE_PAGEで指定されるANSI/OEMコード(SBCSまたはDBCS)の文字列として扱われます。ファイル名入出力をUnicodeとする構成(_LFN_UNICODE == 1)にしたときは、TCHARはワイド文字(WCHAR, unsigned short)に切り替わり、パス名の入出力にUnicodeを使用するようになります。これによりLFN規格に完全対応となり、ファイル名としてANSI/OEMコードにない文字(たとえば ✝☪✡☸☭など)も使用できます。この設定は文字列入出力関数においては、データ型とファイル上のエンコーディングに影響を与えます。リテラル文字列を定義するとき、次に示すように_T(s)および_TEXT(s)マクロを使ってANSI/OEMとUnicodeを自動切り替えすることができます。

  f_open(fp, "filename.txt", FA_READ);      /* ANSI/OEM専用コード */
  f_open(fp, L"filename.txt", FA_READ);     /* Unicode専用コード */
@@ -47,11 +53,10 @@
 
-


-
+

ボリューム管理

デフォルトの構成では、それぞれの論理ドライブは同じ番号の物理ドライブに1:1で結びつけられていて、自動検出機能によりその物理ドライブ上の一つのFATボリュームがマウントされます。FATボリュームの検出は、セクタ0、第一区画~第四区画の順に行われます。

-

_MULTI_PARTITIONに1を指定すると、それぞれの論理ドライブに対して個別に物理ドライブ番号と区画を指定できるようになります。この構成では、論理ドライブと区画の対応を解決するためのテーブルを次に示すように定義する必要があります。

+

_MULTI_PARTITIONに1を指定すると、それぞれの論理ドライブに対して個別に物理ドライブ番号と区画を指定できるようになります。この構成では、論理ドライブと区画の対応を解決するためのテーブルを次に示すように定義する必要があります。

 例:論理ドライブ0~2を物理ドライブ0(非リムーバブル)の3つの基本区画に割り当て、
    論理ドライブ3を物理ドライブ1(リムーバブル)に割り当てる場合。
@@ -72,5 +77,6 @@ PARTITION VolToPart[] = {
 
 
+

戻る

diff --git a/doc/ja/findfirst.html b/doc/ja/findfirst.html new file mode 100644 index 0000000..c1815cb --- /dev/null +++ b/doc/ja/findfirst.html @@ -0,0 +1,119 @@ + + + + + + + + +FatFs - f_findfirst + + + + +
+

f_findfirst

+

ディレクトリ内のオブジェクトの検索を開始します。

+
+FRESULT f_findfirst (
+  DIR* dp,              /* [OUT] ディレクトリ オブジェクト構造体へのポインタ */
+  FILINFO* fno,         /* [OUT] ファイル情報構造体へのポインタ */
+  const TCHAR* path,    /* [IN] ディレクトリ名へのポインタ */
+  const TCHAR* pattern  /* [IN] マッチ パターン文字列へのポインタ */
+);
+
+
+ +
+

引数

+
+
dp
+
空のディレクトリ オブジェクト構造体へのポインタを指定します。
+
fno
+
最初にマッチしたディレクトリ項目を格納するファイル情報構造体へのポインタを指定します。
+
path
+
オープンするディレクトリのパス名を示すヌル文字'\0'終端の文字列へのポインタを指定します。
+
pattern
+
検索する名前を示すヌル文字'\0'終端の文字列へのポインタを指定します。この文字列は、続くf_findnext関数でも参照されるため、一連の処理が終了するまで有効でなければなりません。
+
+
+ + + + + +
+

解説

+

pathで指定されるディレクトリを開き、そのディレクトリ内の項目の検索を開始します。正常終了すると、ディレクトリ オブジェクト構造体が作成され、最初に検索名文字列に名前がマッチした項目の情報がfnoの指定するファイル情報構造体にストアされます。名前のマッチする項目が見つからなかった場合は、fno->fname[]にヌル文字列が返されます。ファイル情報構造体の使い方については、f_readdir関数を参照してください。

+

マッチ パターン文字列は、ワイルドカード文字(?*)を含むことができます。?は任意の1文字に、*は0文字以上の任意の文字列にマッチします。LFN構成では、SFNとLFN(あれば)の両方に対してテストを行います。現リビジョンではパターン マッチングにおいて次の点で標準システムとは異なる動作となります。

+
    +
  • "*.*"は拡張子なしの名前にマッチしない。(標準システムでは全ての名前にマッチ)
  • +
  • ピリオドで終わるパターンは、どの名前にもマッチしない。(標準システムでは拡張子無しの名前にマッチ)
  • +
  • DBCS拡張文字については、LFN構成でも非Unicode API構成ではケース センシティブとなる。
  • +
+
+ + +
+

対応情報

+

この関数は、f_opendir関数およびf_readdir関数のラッパー関数です。_USE_FIND == 1で、かつ_FS_MINIMIZE <= 1のとき使用可能になります。

+
+ + +
+

使用例

+
+/* ディレクトリ内のオブジェクトの検索と表示 */
+
+void find_image (void)
+{
+    FRESULT fr;     /* 戻り値 */
+    DIR dj;         /* ディレクトリ オブジェクト */
+    FILINFO fno;    /* ファイル情報構造体 */
+#if _USE_LFN
+    char lfn[_MAX_LFN + 1];
+    fno.lfname = lfn;
+    fno.lfsize = sizeof lfn;
+#endif
+
+    fr = f_findfirst(&dj, &fno, "", "dsc*.jpg");  /* "dsc"で始まるJPEGファイルを検索 */
+
+    while (fr == FR_OK && fno.fname[0]) {         /* 見つかる間繰り返し */
+#if _USE_LFN
+        printf("%s  %s\n", fno.fname, fno.lfname);/* 見つけた項目の名前を表示 */
+#else
+        printf("%s\n", fno.fname);
+#endif
+        fr = f_findnext(&dj, &fno);               /* 次を検索 */
+    }
+    f_closedir(&dj);
+}
+
+
+ + + + +

戻る

+ + diff --git a/doc/ja/findnext.html b/doc/ja/findnext.html new file mode 100644 index 0000000..07cd756 --- /dev/null +++ b/doc/ja/findnext.html @@ -0,0 +1,68 @@ + + + + + + + + +FatFs - f_findnext + + + + +
+

f_findnext

+

次にマッチするオブジェクトを検索します。

+
+FRESULT f_findnext (
+  DIR* dp,              /* [IN] ディレクトリ構造体へのポインタ */
+  FILINFO* fno          /* [OUT] ファイル情報構造体へのポインタ */
+);
+
+
+ +
+

引数

+
+
dp
+
f_findfirst関数で作成された有効なディレクトリ構造体へのポインタを指定します。
+
fno
+
マッチしたディレクトリ項目を格納するファイル情報構造体へのポインタを指定します。
+
+
+ + + + + +
+

解説

+

次に名前のマッチするディレクトリ項目を検索し、見つかった項目をファイル情報構造体にストアします。名前のマッチする項目が見つからずディレクトリの最後まで達した場合は、fno->fname[]にヌル文字列が返されます。

+
+ + +
+

対応情報

+

この関数は、f_readdir関数のラッパー関数です。_USE_FIND == 1で、かつ_FS_MINIMIZE <= 1のとき使用可能になります。

+
+ + + + +

戻る

+ + diff --git a/doc/ja/forward.html b/doc/ja/forward.html index 19261da..81356eb 100644 --- a/doc/ja/forward.html +++ b/doc/ja/forward.html @@ -45,7 +45,6 @@ FRESULT f_forward ( FR_OK, FR_DISK_ERR, FR_INT_ERR, -FR_NOT_READY, FR_DENIED, FR_INVALID_OBJECT, FR_TIMEOUT @@ -114,7 +113,7 @@ FRESULT play_file ( if (rc) return rc; /* 全てのデータが転送されるかエラーが発生するまで続ける */ - while (rc == FR_OK && fil.fptr < fil.fsize) { + while (rc == FR_OK && !f_eof(&fil)) { /* ほかの処理... */ diff --git a/doc/ja/getfree.html b/doc/ja/getfree.html index ef93133..b523bae 100644 --- a/doc/ja/getfree.html +++ b/doc/ja/getfree.html @@ -53,7 +53,7 @@ FRESULT f_getfree (

解説

-

論理ドライブ上の空き領域のサイズをクラスタ単位で取得します。返されたファイル システム オブジェクトのcsizeメンバがクラスタあたりのセクタ数を示しているので、これを元にセクタ単位の空きサイズが計算できます。FAT32ボリュームにおいては、FSINFOの情報が実際の空きクラスタ数と同期していない場合、不正確な値を返す可能性があります。この問題を避けるため、_FS_NOFSINFOオプションでマウント後の初回は必ずフルFATスキャンをするように構成することもできます。

+

論理ドライブ上の空き領域のサイズをクラスタ単位で取得します。返されたファイル システム オブジェクトのcsizeメンバがクラスタあたりのセクタ数を示しているので、これを元にセクタ単位の空きサイズが計算できます。FAT32ボリュームにおいては、FSINFOの情報が実際の空きクラスタ数と同期していない場合、不正確な値を返す可能性があります。この問題を避けるため、_FS_NOFSINFOオプションでマウント後の初回は必ずフルFATスキャンをするように構成することもできます。

diff --git a/doc/ja/gets.html b/doc/ja/gets.html index 9b2189e..e57f7e8 100644 --- a/doc/ja/gets.html +++ b/doc/ja/gets.html @@ -44,14 +44,14 @@ TCHAR* f_gets (

解説

-

この関数はf_read()のラッパー関数です。読み出し動作は、最初の'\n'を読み込むか、ファイル終端に達するか、len - 1文字を読み出すまで続きます。読み込まれた文字列の終端には'\0'が付加されます。既にファイル終端で1文字も読み込まれなかったとき、または何らかのエラーが発生したときは関数は失敗しヌル ポインタを返します。ファイル終端かエラーかはf_eof(),f_error()マクロで調べられます。

+

読み出し動作は、最初の'\n'を読み込むか、ファイル終端に達するか、len - 1文字を読み出すまで続きます。読み込まれた文字列の終端には'\0'が付加されます。既にファイル終端で1文字も読み込まれなかったとき、または何らかのエラーが発生したときは関数は失敗しヌル ポインタを返します。ファイル終端かエラーかはf_eof/f_error関数で調べられます。

Unicode API構成(_LFN_UNICODE == 1)が選択されているときは、buffはUTF-16文字列になりますが、ファイル上のエンコードは、_STRF_ENCODEオプションで選択できます。それ以外の時は無変換(1バイト/1文字)で読み出します。

対応情報

-

_USE_STRFUNCが1または2のとき使用可能です。2のときは、ファイルに含まれる'\r'が取り除かれてバッファに読み込まれます。

+

この関数はf_read関数のラッパー関数です。_USE_STRFUNCが1または2のとき使用可能です。2のときは、ファイルに含まれる'\r'が取り除かれてバッファに読み込まれます。

diff --git a/doc/ja/lseek.html b/doc/ja/lseek.html index 37f8d91..380aecb 100644 --- a/doc/ja/lseek.html +++ b/doc/ja/lseek.html @@ -39,7 +39,6 @@ FRESULT f_lseek ( FR_OK, FR_DISK_ERR, FR_INT_ERR, -FR_NOT_READY, FR_INVALID_OBJECT, FR_TIMEOUT, FR_NOT_ENOUGH_CORE @@ -49,19 +48,19 @@ FRESULT f_lseek (

解説

-

ファイルのリード/ライト ポインタ(次に読み出し・書き込みされるバイトのオフセット)を移動します。オフセットの原点はファイル先頭です。書き込みモードでファイル サイズより大きな値を指定すると、そこまでファイル サイズが拡張され、拡張された部分のデータは未定義となります。データを遅延無く高速に書き込みたいときは、予めこの関数で必要なサイズまでファイル サイズを拡張しておくと良いでしょう。f_lseek()が正常終了したあとは、リード/ライト ポインタが正しく移動したかチェックするべきです。リード/ライト ポインタが指定より小さいときは、次の原因が考えられます。

+

ファイルのリード/ライト ポインタ(次に読み出し・書き込みされるバイトのオフセット)を移動します。オフセットの原点はファイル先頭です。書き込みモードでファイル サイズより大きな値を指定すると、そこまでファイル サイズが拡張され、拡張された部分のデータは未定義となります。データを遅延無く高速に書き込みたいときは、予めこの関数で必要なサイズまでファイル サイズを拡張しておくと良いでしょう。f_lseek関数が正常終了したあとは、リード/ライト ポインタが正しく移動したかチェックするべきです。リード/ライト ポインタが指定より小さいときは、次の原因が考えられます。

  • 非書き込みモードまたは高速シーク モードのため、ファイル サイズでクリップされた。
  • ファイル拡張中にディスクが満杯になった。
-

_USE_FASTSEEKが1で、且つファイル オブジェクトのcltblメンバがNULL以外(f_open()でNULLに設定される)のとき、高速シーク モードになります。これはファイルのクラスタ配置情報(CLMT)をメモリ上に保持しておくことにより、FATにアクセスすることなく後方シークやロング シークを高速に行う機能です。高速シーク モードは、f_read()/f_wtite()の動作にも適用されます。高速シーク モードではf_wtite()/f_lseek()によるファイル サイズの拡張はできません。

-

高速シーク動作を行う前に、CLMTを作成しておく必要があります。これを作成するには、まずCLMT格納バッファ(DWORD型配列)を準備し、cltblメンバにそのポインタをセットします。そして、配列の先頭要素にその配列のサイズ(要素数)を入れ、f_lseek()ofsCREATE_LINKMAPを指定して呼び出します。関数が成功するとCLMTが作成され、以降のf_read()/f_write()/f_lseek()ではFATへのアクセスは発生しません。FR_NOT_ENOUGH_COREで失敗したときは配列サイズが不足で、先頭要素には実際に必要となる要素数が返されます。必要な要素数は、(ファイルの分割数 + 1) * 2 です。たとえば、ファイルが5つのフラグメントに分断されているときに必要な要素数は、12となります。

+

高速シーク モードは、ファイルのクラスタ配置情報(CLMT)をメモリ上に保持しておくことにより、FATにアクセスすることなく後方シークやロング シークを高速に行う機能で、シーク動作のほかf_read/f_wtite関数の動作にも適用されます。高速シーク モードではf_wtite/f_lseek関数によるファイル サイズの拡張はできません。

+

高速シーク モードは、ファイル オブジェクトのメンバcltbl(f_open関数でNULLになる)にNULL以外を設定したとき有効になるので、まずCLMTを作成しておく必要があります。これを作成するには、まずCLMT格納バッファ(DWORD型配列)を準備し、cltblにそのポインタをセットします。そして、配列の先頭要素にその配列のサイズ(要素数)を入れ、f_lseek関数をofsCREATE_LINKMAPを指定して呼び出します。関数が成功するとCLMTが作成され、以降のf_read/f_write/f_lseek関数ではFATへのアクセスは発生しません。CLMTの先頭要素には実際に使用した(または必要となる)要素数が返されます。使用される要素数は、(ファイルの分割数 + 1) * 2 です。たとえば、ファイルが5つのフラグメントに分断されているときは、12要素が使用されます。FR_NOT_ENOUGH_COREで失敗したときは、配列サイズが不足です。

対応情報

-

_FS_MINIMIZE < 3のとき使用可能です。

+

_FS_MINIMIZE < 3のとき使用可能です。高速シーク モードを利用するときは、_USE_FASTSEEK == 1である必要があります。

@@ -107,6 +106,8 @@ FRESULT f_lseek ( DWORD clmt[SZ_TBL]; /* リンク マップ テーブル格納バッファ */ + res = f_open(fp, fname, FA_READ | FA_WRITE); /* ファイルを開く */ + res = f_lseek(fp, ofs1); /* 通常シーク (オープン時、cltblはNULLに初期化される) */ fp->cltbl = clmt; /* 高速シーク機能の有効化 */ diff --git a/doc/ja/mkdir.html b/doc/ja/mkdir.html index c39b843..eb301f5 100644 --- a/doc/ja/mkdir.html +++ b/doc/ja/mkdir.html @@ -13,7 +13,7 @@

f_mkdir

-

ディレクトリを作成します。

+

サブ ディレクトリを作成します。

 FRESULT f_mkdir (
   const TCHAR* path /* [IN] 作成するディレクトリ名へのポインタ */
@@ -53,7 +53,7 @@ FRESULT f_mkdir (
 
 

解説

-

空のディレクトリを作成します。

+

空のサブ ディレクトリを作成します。ディレクトリを削除するときはf_unlink関数を使用してください。

diff --git a/doc/ja/mkfs.html b/doc/ja/mkfs.html index c1c63ee..9430e85 100644 --- a/doc/ja/mkfs.html +++ b/doc/ja/mkfs.html @@ -13,7 +13,7 @@

f_mkfs

-

論理ドライブ上にFATボリュームを作成(フォーマット)します。

+

論理ドライブ上にFATボリュームを作成します。

 FRESULT f_mkfs (
   const TCHAR* path, /* [IN] 論理ドライブ番号 */
@@ -27,7 +27,7 @@ FRESULT f_mkfs (
 

引数

path
-
フォーマット対象の論理ドライブを示すパス名を示すヌル文字'\0'終端の文字列へのポインタを指定します。ドライブ番号を含まない場合は、カレント ドライブを意味します。
+
対象の論理ドライブを示すパス名を示すヌル文字'\0'終端の文字列へのポインタを指定します。ドライブ番号を含まない場合は、カレント ドライブを意味します。
sfd
パーテーション形式。(0(FDISK) または 1(SFD))
au
@@ -49,8 +49,8 @@ FRESULT f_mkfs (

説明

-

物理ドライブ上にFATボリュームを作成します。FDISK形式が指定された場合は、物理ドライブ全体を占める基本区画(パーテーション)が作成され、その中にFATボリュームが作成されます。SFD形式では、FATボリュームが物理ドライブの先頭セクタからベタで作成されます。

-

フォーマットする論理ドライブがマルチ パーテーション機能(_MULTI_PARTITION)によって特定の区画(1~4)に結び付けられている場合は、その区画の中にFATボリュームが作成されます。sfdは無視され、また対応する物理ドライブはこれに先立ち、f_fdisk()または他のツールで適切に区画設定されている必要があります。

+

物理ドライブ上にFATボリュームを作成(フォーマット)します。FDISK形式が指定された場合は、物理ドライブ全体を占める基本区画(パーテーション)が作成され、その中にFATボリュームが作成されます。SFD形式では、FATボリュームが物理ドライブの先頭セクタからベタで作成されます。

+

マルチ パーテーション機能(_MULTI_PARTITION)が有効で、かつフォーマット対象の論理ドライブが特定の区画(1~4)に結び付けられている場合は、その区画の中にFATボリュームが作成されます。sfdは無視され、その物理ドライブはこれに先立ち、f_fdisk関数または他のツールで適切に区画設定されている必要があります。

パーテーション形式には、FDISK形式とSFD形式の二通りあります。FDISK形式は、ハードディスク、MMC、SDC、CFC、U Diskなどで標準的に使用されます。FDISK形式では一台の物理ドライブ上に一つまたは複数の区画を作成することができます。区画管理情報はMBR(物理ドライブの先頭セクタ)に記録されます。SFD形式は単に何の分割も行わない形式で、ボリュームは物理ドライブの先頭セクタから開始します。SFD形式は、フロッピー ディスク、マイクロドライブ、光学ディスク、およびその他スーパー フロッピー メディアで標準的に使用されています。

FATタイプ(FAT12/FAT16/FAT32)は、そのボリューム上のクラスタ数によってのみ決定される決まり[FAT仕様書より]になっていて、それ以外の要因はありません。したがって、どのFATタイプになるかはボリューム サイズとクラスタ サイズに依存します。クラスタ サイズは大きくするほど性能が上がります。

クラスタ数がFATタイプの境界に近くなるときは、FR_MKFS_ABORTEDで関数が失敗する可能性があります。

@@ -66,7 +66,7 @@ FRESULT f_mkfs (

使用例

-/* Format the default drive */
+/* Format default drive and create a file */
 int main (void)
 {
     FATFS fs;      /* File system object (volume work area) */
@@ -75,7 +75,7 @@ int main (void)
     UINT bw;       /* Bytes written */
 
 
-    /* Register work area */
+    /* Register work area (do not care about error) */
     f_mount(&fs, "", 0);
 
     /* Create FAT volume with default cluster size */
@@ -83,19 +83,18 @@ int main (void)
     if (res) ...
 
     /* Create a file as new */
-    res = f_open(&fil, "hello.txt", FA_CREATE_NEW | FA_WRITE);
+    res = f_open(&fil, "hello.txt", FA_CREATE_NEW | FA_WRITE);
     if (res) ...
 
     /* Write a message */
-    f_write(&fil, "Hello, World!\r\n", 15, &bw);
+    f_write(&fil, "Hello, World!\r\n", 15, &bw);
     if (bw != 15) ...
 
     /* Close the file */
-    f_close(&fil);
+    f_close(&fil);
 
     /* Unregister work area */
     f_mount(0, "", 0);
-
 
diff --git a/doc/ja/mount.html b/doc/ja/mount.html index 3e3296e..4e9768d 100644 --- a/doc/ja/mount.html +++ b/doc/ja/mount.html @@ -58,11 +58,11 @@ FRESULT f_mount (

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

    -
  • ファイル システム オブジェクトがクリア(無効)状態(f_mount()の実行による)
  • +
  • ファイル システム オブジェクトがクリア(無効)状態(f_mount関数の実行による)
  • 物理ドライブが未初期化状態(システム リセットやメディアの交換による)

optに1を指定すると、ファイル システムオブジェクトの登録に続きマウント動作が行われます。メディアが無いなどの理由でマウント動作に失敗すると対応するエラーを返しファイル システム オブジェクト無効状態のままになりますが、登録自体は有効なので続いてボリュームへのアクセスがあれば再びマウント動作が実行されます。

-

下位レイヤの実装上メディア交換の検出がサポートされない(disk_status()に反映されない)ときは、アプリケーションはメディア交換の後この関数でファイル システム オブジェクトを明示的にクリアし、マウント動作が正常に行えるようにする必要があります。

+

下位レイヤの実装上メディア交換の検出がサポートされない(disk_status関数に反映されない)ときは、アプリケーションはメディア交換の後この関数でファイル システム オブジェクトを明示的にクリアし、マウント動作が正常に行えるようにする必要があります。

diff --git a/doc/ja/open.html b/doc/ja/open.html index 97ac80e..b650064 100644 --- a/doc/ja/open.html +++ b/doc/ja/open.html @@ -37,7 +37,7 @@ FRESULT f_open ( FA_READ読み出しモードで開きます。読み書きする場合はFA_WRITEと共に指定します。 FA_WRITE書き込みモードで開きます。読み書きする場合はFA_READと共に指定します。 FA_OPEN_EXISTING既存のファイルを開きます。ファイルが無いときはエラーになります。(デフォルト) -FA_OPEN_ALWAYS既存のファイルを開きます。ファイルが無いときはファイルを作成します。追記の場合は、この方法でオープンした後、f_lseek()でファイルの最後尾に移動してください。 +FA_OPEN_ALWAYS既存のファイルを開きます。ファイルが無いときはファイルを作成します。追記の場合は、この方法でオープンした後、f_lseek関数でファイルの最後尾に移動してください。 FA_CREATE_NEWファイルを作成します。同名のファイルがある場合は、FR_EXISTで失敗します。 FA_CREATE_ALWAYSファイルを作成します。同名のファイルがある場合は、サイズを0にしてから開きます。 @@ -73,9 +73,9 @@ FRESULT f_open (

解説

-

既存のファイルを開いたり、新しいファイルを作成します。関数が成功するとファイル オブジェクトが作成され、以降そのファイルに対するアクセスに使用します。ファイルを閉じるときは、f_close()を使用します。何らかの変更が行われたファイルがその後正しく閉じられなかった場合、そのファイルが破損する場合があります。

+

既存のファイルを開いたり、新しいファイルを作成します。関数が成功するとファイル オブジェクトが作成され、以降そのファイルに対するアクセスに使用します。ファイルを閉じるときは、f_close関数を使用します。何らかの変更が行われたファイルがその後正しく閉じられなかった場合、そのファイルが破損する場合があります。

既に開かれているファイルを開く必要がある場合は、多重アクセス制御を参照してください。しかし、一つのファイルに対する書き込みモードを含む重複オープンは常に禁止です。

-

ファイル アクセスを開始する前に、f_mount()を使ってそれぞれの論理ドライブにワーク エリア(ファイル システム オブジェクト)を与える必要があります。この初期化の後、その論理ドライブに対して全てのファイル関数が使えるようになります。

+

ファイル アクセスを開始する前に、f_mount関数を使ってそれぞれの論理ドライブにワーク エリア(ファイル システム オブジェクト)を与える必要があります。この初期化の後、その論理ドライブに対して全てのファイル関数が使えるようになります。

diff --git a/doc/ja/opendir.html b/doc/ja/opendir.html index 411c79f..166ee7d 100644 --- a/doc/ja/opendir.html +++ b/doc/ja/opendir.html @@ -28,7 +28,7 @@ FRESULT f_opendir (
dp
空のディレクトリ オブジェクト構造体へのポインタを指定します。
path
-
オープンするディレクトリのパス名を示すヌル文字'\0'終端の文字列へのポインタを指定します。
+
開くディレクトリのパス名を示すヌル文字'\0'終端の文字列へのポインタを指定します。
@@ -50,13 +50,12 @@ FRESULT f_opendir ( FR_NOT_ENOUGH_CORE, FR_TOO_MANY_OPEN_FILES

-

解説

-

ディレクトリを開きます。正常終了したら、作成されたDIR構造体を使ってこのディレクトリの項目を順次読み出せます。

+

ディレクトリを開きます。正常終了したら、作成されたディレクトリ オブジェクト構造体を使ってこのディレクトリの項目を順次読み出せます。

diff --git a/doc/ja/printf.html b/doc/ja/printf.html index 9676fad..6534c84 100644 --- a/doc/ja/printf.html +++ b/doc/ja/printf.html @@ -45,7 +45,7 @@ int f_printf (

解説

-

この関数は、f_putc()およびf_puts()のラッパー関数です。書式制御機能はC標準ライブラリのサブセットとなっていて、書式制御文字は次に示すものが使用可能です。

+

書式制御機能はC標準ライブラリのサブセットとなっていて、書式制御文字は次に示すものが使用可能です。

  • タイプ: c C s S d D u U x X b B
  • 精度指定: l L
  • @@ -56,7 +56,7 @@ int f_printf (

    対応情報

    -

    _FS_READONLY == 0で、且つ_USE_STRFUNCが1または2のとき使用可能になります。2の時は、出力に含まれる'\n''\r'+'\n'に展開されてファイルに書き込まれます。

    +

    この関数は、f_putc関数およびf_puts関数のラッパー関数です。_FS_READONLY == 0で、且つ_USE_STRFUNCが1または2のとき使用可能になります。2の時は、出力に含まれる'\n''\r'+'\n'に展開されてファイルに書き込まれます。

    APIにUnicodeが選択(_LFN_UNICODEが1)されているときは、fmtはUnicode文字列になりますが、ファイル上のエンコードは、_STRF_ENCODEオプションで選択できます。それ以外の時は無変換(1バイト/1文字)で書き込みます。

    diff --git a/doc/ja/putc.html b/doc/ja/putc.html index b30d10a..57af633 100644 --- a/doc/ja/putc.html +++ b/doc/ja/putc.html @@ -42,13 +42,13 @@ int f_putc (

    解説

    -

    1文字をファイルに書き込みます。この関数はf_write()のラッパー関数です。

    +

    1文字をファイルに書き込みます。

    対応情報

    -

    _FS_READONLY == 0で、且つ_USE_STRFUNCが 1または 2のとき使用可能です。2を指定すると、'\n''\r'+'\n'に展開されてファイルに書き込まれます。

    +

    この関数はf_write関数のラッパー関数です。_FS_READONLY == 0で、且つ_USE_STRFUNCが 1または 2のとき使用可能です。2を指定すると、'\n''\r'+'\n'に展開されてファイルに書き込まれます。

    diff --git a/doc/ja/puts.html b/doc/ja/puts.html index 9292017..4e4ed9e 100644 --- a/doc/ja/puts.html +++ b/doc/ja/puts.html @@ -42,13 +42,13 @@ int f_puts (

    解説

    -

    文字列をファイルに書き込みます。この関数はf_write()のラッパー関数です。

    +

    文字列をファイルに書き込みます。

    対応情報

    -

    _FS_READONLY == 0で、且つ_USE_STRFUNCが1または2のとき使用可能です。2を指定すると、文字列に含まれる'\n''\r'+'\n'に展開されてファイルに書き込まれます。

    +

    この関数はf_write関数のラッパー関数です。_FS_READONLY == 0で、且つ_USE_STRFUNCが1または2のとき使用可能です。2を指定すると、文字列に含まれる'\n''\r'+'\n'に展開されてファイルに書き込まれます。

    diff --git a/doc/ja/rc.html b/doc/ja/rc.html index 40cc9c9..f3007db 100644 --- a/doc/ja/rc.html +++ b/doc/ja/rc.html @@ -17,7 +17,7 @@
    FR_OK (0)
    関数は成功した。
    FR_DISK_ERR
    -
    下位レイヤ(disk_read(), disk_write(), disk_ioctl()関数)で回復不能なエラーが発生した。
    ※開かれたファイルの操作においてこのエラーが発生すると、そのファイル オブジェクトはアボート状態となり、クローズ以外のの操作ができなくなります。
    +
    下位レイヤ(disk_read/disk_write/disk_ioctl関数)で回復不能なエラーが発生した。
    ※開かれたファイルの操作においてこのエラーが発生すると、そのファイル オブジェクトはアボート状態となり、クローズ以外のの操作ができなくなります。
    FR_INT_ERR
    内部処理の健全性に異常が検出された。原因としては次のようなことが考えられます。
      @@ -26,7 +26,7 @@
    ※開かれたファイルの操作においてこのエラーが発生すると、そのファイル オブジェクトはアボート状態となり、クローズ以外の操作ができなくなります。
    FR_NOT_READY
    -
    物理ドライブが動作可能な状態にない。または、ドライブの初期化に失敗した。
    +
    disk_initialize関数の失敗。物理ドライブが動作可能な状態にない。
    FR_NO_FILE
    指定されたファイルが見つからなかった。
    FR_NO_PATH
    @@ -47,39 +47,46 @@
    FR_EXIST
    新しく作成しようとしたオブジェクトと同じ名前のオブジェクトが既に存在する。
    FR_INVALID_OBJECT
    -
    指定されたファイル オブジェクトやディレクトリ オブジェクトが無効(オープンされていない、既に閉じられた、破損しているなど)、またはヌル ポインタが渡された。また、開かれたままのオブジェクトは、それの属するボリュームのマウント動作により無効となります。
    +
    指定されたファイル オブジェクトやディレクトリ オブジェクトが無効、またはヌル ポインタが渡された。無効になる理由は次のことが考えられます。 +
      +
    • オープンされていない、既に閉じられた、破損しているなど。
    • +
    • それの属するボリュームのマウント動作があった。ボリューム上で開かれたオブジェクトは全て無効化される。
    • +
    • 関連する物理ドライブがメディアの取り外しで動作不可能になっている。
    • +
    +
    FR_WRITE_PROTECTED
    物理ドライブが書き込み禁止状態のとき、書き込みを伴う操作を行おうとした。
    FR_INVALID_DRIVE
    -
    パス名中に指定されたドライブ番号が無効、またはパス名にヌル ポインタが渡された。(関連オプション: _VOLUMES)
    +
    パス名中に指定されたドライブ番号が無効、またはパス名にヌル ポインタが渡された。(関連オプション: _VOLUMES)
    FR_NOT_ENABLED
    そのボリュームの操作に必要なワーク エリア(ファイル システム オブジェクト構造体)が与えられていない。
    FR_NO_FILESYSTEM
    物理ドライブ上に有効なFATボリュームが見つからなかった。
    FR_MKFS_ABORTED
    -
    f_mkfs()の処理が開始前に中断された。原因としては次のようなことが考えられます。 +
    f_mkfs関数の処理が開始前に中断された。原因としては次のようなことが考えられます。
    • ボリュームが小さすぎる。
    • FATタイプの計算に矛盾が見つかった。クラスタ数がFATタイプの境界付近になるときに発生する場合があります。
    • -
    • その論理ドライブに対応する区画が見つからなかった。(関連オプション: _MULTI_PARTITION)
    • +
    • その論理ドライブに対応する区画が見つからなかった。(関連オプション: _MULTI_PARTITION)
    FR_TIMEOUT
    -
    再入制御による待ち時間が定義された時間を越えたため、関数は実行されなかった。(関連オプション: _TIMEOUT)
    +
    再入制御による待ち時間が定義された時間を越えたため、関数は実行されなかった。(関連オプション: _TIMEOUT)
    FR_LOCKED
    -
    多重アクセス排他機能により、そのファイルやディレクトリに対して行おうとしたアクセスが拒否された。(関連オプション: _FS_LOCK)
    +
    多重アクセス排他機能により、そのファイルやディレクトリに対して行おうとしたアクセスが拒否された。(関連オプション: _FS_LOCK)
    FR_NOT_ENOUGH_CORE
    メモリ不足による失敗。原因としては次のようなことが考えられます。
      -
    • LFN操作バッファの動的確保に失敗した。(関連オプション: _USE_LFN)
    • +
    • LFN操作バッファの動的確保に失敗した。(関連オプション: _USE_LFN)
    • 与えられた配列のサイズが実際に必要なサイズに対して不足している。
    FR_TOO_MANY_OPEN_FILES
    -
    同時オープン可能なファイル数を越えてファイルを開こうとした。(関連オプション: _FS_LOCK)
    +
    同時オープン可能なファイル数を越えてファイルを開こうとした。(関連オプション: _FS_LOCK)
    FR_INVALID_PARAMETER
    与えられたパラメータが無効または矛盾している。
    +

    戻る

    diff --git a/doc/ja/read.html b/doc/ja/read.html index 7056dfb..b73a5d9 100644 --- a/doc/ja/read.html +++ b/doc/ja/read.html @@ -45,7 +45,6 @@ FRESULT f_read ( FR_OK, FR_DISK_ERR, FR_INT_ERR, -FR_NOT_READY, FR_DENIED, FR_INVALID_OBJECT, FR_TIMEOUT diff --git a/doc/ja/readdir.html b/doc/ja/readdir.html index f5f9378..d2b83a7 100644 --- a/doc/ja/readdir.html +++ b/doc/ja/readdir.html @@ -26,7 +26,7 @@ FRESULT f_readdir (

    引数

    dp
    -
    有効なディレクトリ オブジェクト構造体へのポインタを指定します。
    +
    f_opendir関数で作成された有効なディレクトリ オブジェクトへのポインタを指定します。
    fno
    読み出したディレクトリ項目を格納するファイル情報構造体へのポインタを指定します。
    @@ -39,7 +39,6 @@ FRESULT f_readdir ( FR_OK, FR_DISK_ERR, FR_INT_ERR, -FR_NOT_READY, FR_INVALID_OBJECT, FR_TIMEOUT, FR_NOT_ENOUGH_CORE @@ -49,15 +48,15 @@ FRESULT f_readdir (

    解説

    -

    ディレクトリの項目(ファイルとディレクトリ)を順次読み出します。この関数を繰り返し実行することによりそのディレクトリの全ての項目を読み出すことができます。得られるファイル情報の詳細については FILINFO構造体を参照してください。全ての項目が読み出され、読み出す項目がもう無いときは、fname[]メンバにヌル文字列が返されます。fnoにヌル ポインタを指定すると、そのディレクトリのリード インデックスを先頭に巻き戻します。また、この関数は次に示すように関連する構成オプションにより動作が変わります。

    -

    ドット エントリ("."、"..")は、相対パスが有効なとき(_FS_RPATH >= 1)にのみ出力に現れます。

    +

    ディレクトリの項目(ファイルとディレクトリ)を順次読み出します。この関数を繰り返し実行することによりそのディレクトリの全ての項目を読み出すことができます。得られるファイル情報の詳細については FILINFO構造体を参照してください。全ての項目が読み出され、読み出す項目がもう無いときは、fno->fname[]にヌル文字列が返されます。fnoにヌル ポインタを指定すると、そのディレクトリのリード インデックスを先頭に巻き戻します。また、この関数は次に示すように関連する構成オプションにより動作が変わります。

    +

    ドット エントリ(".""..")は、相対パスが有効なとき(_FS_RPATH >= 1)にのみ出力に現れます。

    LFN機能が有効な時は、この関数の呼び出しに先立ってFILINFO構造体のlfnamelfsizeが有効な値で初期化されていなければなりません。lfnameはLFNを格納するバッファで、lfsizeはそのバッファの要素数です。LFNを読み出す必要がないときは、lfnameにヌル ポインタをセットしてください。次の条件に一つでも該当する場合は、LFN格納バッファにヌル文字列が返されます。

    • ディレクトリ項目にLFN情報が存在しない。
    • LFNの長さに対してLFN格納バッファまたはLFN操作バッファのサイズが不十分。
    • LFNに現在のOEMコードに存在しない文字が含まれている。(非Unicode構成のとき)
    -

    また、ディレクトリ項目にLFN情報が存在しない場合は、fname[]に英小文字が含まれる場合があります。

    +

    また、そのディレクトリ項目にLFN情報が存在しない場合は、fname[]に英小文字が含まれる場合があります。

    diff --git a/doc/ja/rename.html b/doc/ja/rename.html index d60653a..5d35f73 100644 --- a/doc/ja/rename.html +++ b/doc/ja/rename.html @@ -56,7 +56,7 @@ FRESULT f_rename (

    解説

    -

    ファイルまたはサブ ディレクトリの名前を変更します。また、同時に別のディレクトリへの移動も可能ですが、異なるドライブへの移動はできません。開かれているオブジェクトに対して使用してはなりません

    +

    ファイルまたはサブ ディレクトリの名前を変更します。また、同時に別のディレクトリへの移動も可能ですが、異なるドライブ間の移動はできません。開かれているオブジェクトに対する使用は不正な操作となり、FAT構造が破壊される可能性があります。多重アクセス制御が有効のときは安全に拒否されます。

    diff --git a/doc/ja/sdir.html b/doc/ja/sdir.html index d2e53ef..c9eec4c 100644 --- a/doc/ja/sdir.html +++ b/doc/ja/sdir.html @@ -13,7 +13,7 @@

    DIR

    -

    DIR構造体は、f_opendir(), f_readdir()のワーク エリアとして使用されます。アプリケーションは、この構造体のメンバを書き換えてはなりません。

    +

    DIR構造体は、f_opendir/f_readdir/f_findfirst/f_findnext関数のワーク エリアとして使用されます。アプリケーションは、この構造体のメンバを書き換えてはなりません。

     typedef struct {
         FATFS*  fs;        /* 親ファイル システム オブジェクトへのポインタ */
    @@ -22,15 +22,18 @@
         DWORD   sclust;    /* テーブル開始クラスタ (0:ルート) */
         DWORD   clust;     /* 現在のクラスタ番号 */
         DWORD   sect;      /* 現在のセクタ番号 */
    -    BYTE*   dir;       /* 現在のSFNエントリへのポインタ */
    +    BYTE*   dir;       /* 現在のSFNエントリ(Win[]内)へのポインタ */
         BYTE*   fn;        /* SFNバッファへのポインタ (in/out) {file[8],ext[3],status[1]} */
     #if _FS_LOCK
    -    UINT    lockid;    /* ロックID */
    +    UINT    lockid;    /* サブ ディレクトリ ロックID (0:ルート) */
     #endif
     #if _USE_LFN
         WCHAR*  lfn;       /* LFNバッファへのポインタ (in/out) */
         WORD    lfn_idx;   /* LFNエントリの先頭インデックス (0xFFFF:無効) */
     #endif
    +#if _USE_FIND
    +    const TCHAR*  pat; /* マッチング パターンへのポインタ */
    +#endif
     } DIR;
     
    diff --git a/doc/ja/setlabel.html b/doc/ja/setlabel.html index 9b8e64c..3ad63e0 100644 --- a/doc/ja/setlabel.html +++ b/doc/ja/setlabel.html @@ -51,10 +51,11 @@ FRESULT f_setlabel (

    解説

    文字列の先頭にドライブ番号を含む場合は、その論理ドライブに対して設定されます。含まない場合は、デフォルト ドライブに設定されます。ボリューム ラベルを削除するときは、ヌル文字列を指定します。ボリューム ラベルのフォーマットは、ファイル名(SFN)とほぼ同じですが、次の点が異なります。

      -
    • ローカル文字コード換算で11バイト以下。LFN拡張は適用されません。
    • +
    • OEMコード換算で11バイト以下。ボリューム ラベルにはLFN拡張は適用されません。
    • ピリオドを含むことはできない。
    • 任意の位置にスペースを置くことができる。ただし、最後尾となるスペースは除去される。
    +

    【補足】 標準システム(Windows)では\xE5で始まるボーリューム ラベル(CP932なら「薔薇」など)の扱いに問題があります。このため、この関数ではそのような名前は無効として処理しています。

diff --git a/doc/ja/sfatfs.html b/doc/ja/sfatfs.html index e35a596..5ca0dfb 100644 --- a/doc/ja/sfatfs.html +++ b/doc/ja/sfatfs.html @@ -13,16 +13,16 @@

FATFS

-

FATFS構造体(ファイル システム オブジェクト)は、個々の論理ドライブのダイナミック ワーク エリアを保持し、f_mount()でFatFsモジュールに登録されます。初期化が行われるタイミングは、f_mount()(強制マウント指定)の実行またはメディア交換の後の最初のファイル アクセスの時です。アプリケーションは、この構造体のメンバを書き換えてはなりません。

+

FATFS構造体(ファイル システム オブジェクト)は、個々の論理ドライブのダイナミック ワーク エリアを保持し、f_mount関数でFatFsモジュールに登録されます。初期化が行われるタイミングは、f_mount関数(強制マウント指定)の実行またはメディア交換の後の最初のファイル アクセスの時です。アプリケーションは、この構造体のメンバを書き換えてはなりません。

 typedef struct {
-    BYTE    fs_type;      /* FATタイプ */
+    BYTE    fs_type;      /* FATタイプ (0:無効, FS_FAT12, FS_FAT16 or FS_FAT32) */
     BYTE    drv;          /* 物理ドライブ番号 */
-    BYTE    csize;        /* クラスタ当たりのセクタ数 (1,2,4,8,...,128)*/
+    BYTE    csize;        /* クラスタ当たりのセクタ数 (1,2,4,8,...,128) */
     BYTE    n_fats;       /* FATの多重化数 (1,2) */
     BYTE    wflag;        /* win[]ダーティ フラグ */
-    BYTE    fsi_flag;     /* FSINFOフラグ (b7:Disabled, b0:Dirty)*/
+    BYTE    fsi_flag;     /* FSINFOフラグ (b7:Disabled, b0:Dirty) */
     WORD    id;           /* ファイル システム マウントID */
     WORD    n_rootdir;    /* ルート ディレクトリのエントリ数 (FAT12/16) */
 #if _MAX_SS != _MIN_SS
@@ -36,13 +36,13 @@
     DWORD   free_clust;   /* FSINFO: 空きクラスタ数 */
 #endif
 #if _FS_RPATH
-    DWORD   cdir;         /* カレント ディレクトリのクラスタ (0:ルート) */
+    DWORD   cdir;         /* カレント ディレクトリのクラスタ番号 (0:ルート) */
 #endif
     DWORD   n_fatent;     /* FATエントリ数 (総クラスタ数 + 2) */
     DWORD   fsize;        /* FAT 1個のセクタ数 */
     DWORD   volbase;      /* ボリューム開始セクタ */
     DWORD   fatbase;      /* FAT領域開始セクタ */
-    DWORD   dirbase;      /* ルート ディレクトリ領域開始セクタ(クラスタ) */
+    DWORD   dirbase;      /* ルート ディレクトリ領域開始(セクタ|クラスタ) */
     DWORD   database;     /* データ領域開始セクタ */
     DWORD   winsect;      /* win[]に現れているセクタ番号 */
     BYTE    win[_MAX_SS]; /* ディスク アクセス ウィンドウ */
diff --git a/doc/ja/sfile.html b/doc/ja/sfile.html
index 4ffe340..6122647 100644
--- a/doc/ja/sfile.html
+++ b/doc/ja/sfile.html
@@ -13,7 +13,7 @@
 
 

FIL

-

FIL構造体(ファイル オブジェクト)は、f_open()で初期化され、以後そのファイルの状態を保持します。また、f_close()でファイルが閉じられると無効化されます。アプリケーションは、この構造体のメンバを書き換えてはなりません(cltblは例外)。非タイニー構成(_FS_TINY == 0)では、内部に_MAX_SSバイトのセクタ バッファが確保されるので、そのサイズには注意が必要です。

+

FIL構造体(ファイル オブジェクト)は、f_open関数で初期化され、以後そのファイルの状態を保持します。また、f_close関数でファイルが閉じられると無効化されます。アプリケーションは、この構造体のメンバを書き換えてはなりません(cltblは例外)。非タイニー構成(_FS_TINY == 0)では、内部に_MAX_SSバイトのセクタ バッファが確保されるので、そのサイズには注意が必要です。

 typedef struct {
@@ -24,7 +24,7 @@
     DWORD   fptr;         /* ファイル読み書きポインタ (ファイル先頭からのバイト オフセット) */
     DWORD   fsize;        /* ファイル サイズ(バイト単位) */
     DWORD   sclust;       /* ファイル開始クラスタ番号 (0:割り当て無し) */
-    DWORD   clust;        /* 現在のクラスタ */
+    DWORD   clust;        /* 現在のクラスタ (fptrが0のときは無効、fptrがクラスタ境界上のときは前のクラスタ) */
     DWORD   dsect;        /* 現在のデータ セクタ */
 #if !_FS_READONLY
     DWORD   dir_sect;     /* このファイルのディレクトリ エントリのあるセクタ */
@@ -37,7 +37,7 @@
     UINT    lockid;       /* ファイル ロックID */
 #endif
 #if !_FS_TINY
-    BYTE    buf[_MAX_SS]; /* ファイル プライベート データ転送バッファ */
+    BYTE    buf[_MAX_SS]; /* ファイル プライベート データ転送バッファ (fptrがセクタ境界上にない時は常に有効だが、fptrがセクタ境界上のときは無効な場合がある) */
 #endif
 } FIL;
 
diff --git a/doc/ja/sfileinfo.html b/doc/ja/sfileinfo.html index 84cc36e..129de54 100644 --- a/doc/ja/sfileinfo.html +++ b/doc/ja/sfileinfo.html @@ -13,7 +13,7 @@

FILINFO

-

FILINFO構造体は、f_stat(), f_readdir()で返されるファイル情報を保持します。

+

FILINFO構造体は、f_stat/f_readdir/f_findfirst/f_findnext関数で返されるオブジェクトに関する情報を保持します。

 typedef struct {
     DWORD fsize;     /* ファイル サイズ */
@@ -58,11 +58,11 @@
 
fattrib
属性フラグが格納されます。フラグはAM_DIR, AM_RDO, AM_HID, AM_SYS, AM_ARCの組み合わせとなります。
fname[]
-
8.3形式の名前が'\0'で終わる文字列として格納されます。非LFN構成のときは、常に大文字で返されます。LFN構成のときは短い名前が返されますが、ASCII英字が小文字になる場合があります。
+
8.3形式の名前(SFN)が'\0'で終わる文字列として格納されます。非LFN構成のときは、常に大文字で返されます。LFN構成のときは、文字列に含まれるASCII英字が小文字になる場合があります。
lfname
-
返される長いファイル名を格納するバッファへのポインタ。この構造体を使用する前にアプリケーションにより初期化されなければなりません。このメンバにNULLが設定されるとLFNは返されません。非LFN構成のときはこのメンバは存在しません。
+
長いファイル名(LFN)を格納するバッファへのポインタ。このメンバは、この構造体を使用する前にアプリケーションにより初期化されなければなりません。NULLが設定されるとLFNは返されません。非LFN構成のときはこのメンバは存在しません。
lfsize
-
長いファイル名を格納するバッファのサイズ(要素数)。この構造体を使用する前にアプリケーションにより初期化されなければなりません。非LFN構成のときはこのメンバは存在しません。
+
長いファイル名を格納するバッファのサイズ(要素数)。このメンバは、この構造体を使用する前にアプリケーションにより初期化されなければなりません。非LFN構成のときはこのメンバは存在しません。

戻る

diff --git a/doc/ja/size.html b/doc/ja/size.html index 2ffcca3..5771273 100644 --- a/doc/ja/size.html +++ b/doc/ja/size.html @@ -39,7 +39,7 @@ DWORD f_size (

解説

-

f_size関数は、現リビジョンではマクロとして実装されています。

+

この関数は、現リビジョンではマクロとして実装されています。

 #define f_size(fp) ((fp)->fsize)
 
diff --git a/doc/ja/sync.html b/doc/ja/sync.html index 579c66e..fb6f336 100644 --- a/doc/ja/sync.html +++ b/doc/ja/sync.html @@ -36,7 +36,6 @@ FRESULT f_sync ( FR_OK, FR_DISK_ERR, FR_INT_ERR, -FR_NOT_READY, FR_INVALID_OBJECT, FR_TIMEOUT

@@ -45,8 +44,8 @@ FRESULT f_sync (

解説

-

この関数はf_close()と同じ処理を実行しますが、ファイルは引き続き開かれたままになり、読み書きを続行できます。ロギングなど、書き込みモードで長時間ファイルが開かれているアプリケーションにおいて、定期的または区切りの良いところでこの関数を使用することにより、不意の電源断やメディアの取り外しにより失われるデータを最小にすることができます。この背景については、アプリケーション ノートも参照してください。

-

実際のところ、f_close()内ではこの関数を呼び出した後ファイル オブジェクトを無効化しているだけなので、f_close()直前にf_sync()を置くことは無意味です。

+

この関数はf_close関数と同じ処理を実行しますが、ファイルは引き続き開かれたままになり、読み書きを続行できます。ロギングなど、書き込みモードで長時間ファイルが開かれているアプリケーションにおいて、定期的または区切りの良いところでこの関数を使用することにより、不意の電源断やメディアの取り外しにより失われるデータを最小にすることができます。この背景については、アプリケーション ノートも参照してください。

+

実際のところ、f_close関数内ではこの関数を呼び出した後ファイル オブジェクトを無効化しているだけなので、f_close関数の直前にf_sync関数を置くことは無意味です。

diff --git a/doc/ja/truncate.html b/doc/ja/truncate.html index 7b26ec5..6302ee5 100644 --- a/doc/ja/truncate.html +++ b/doc/ja/truncate.html @@ -36,7 +36,6 @@ FRESULT f_truncate ( FR_OK, FR_DISK_ERR, FR_INT_ERR, -FR_NOT_READY, FR_DENIED, FR_INVALID_OBJECT, FR_TIMEOUT diff --git a/doc/ja/unlink.html b/doc/ja/unlink.html index fdba631..f75f3fc 100644 --- a/doc/ja/unlink.html +++ b/doc/ja/unlink.html @@ -54,13 +54,12 @@ FRESULT f_unlink (

解説

-

削除対象のオブジェクトが次の条件に当てはまる場合、そのアクセスは拒否され関数は失敗します。 +

削除対象のオブジェクトが次の条件に当てはまる場合、そのアクセスは拒否(FR_DENIED)され関数は失敗します。

    -
  • リード オンリー属性(AM_RDO)を持っている場合は、拒否(FR_DENIED)される。
  • -
  • 空でないサブ ディレクトリまたはカレント ディレクトリである場合は、拒否(FR_DENIED)される。
  • -
  • 開かれているファイルまたはサブ ディレクトリである場合は、多重アクセス制御が有効なら安全に拒否(FR_LOCKED)されますが、そうでないときは不正な操作となり、FAT構造が破壊される可能性があります。
  • +
  • リード オンリー属性(AM_RDO)を持っている場合。
  • +
  • 空でないサブ ディレクトリまたはカレント ディレクトリである場合。
  • +
  • 開かれているオブジェクトである場合。多重アクセス制御が有効のときは安全に拒否されるが、そうでないときは不正な操作となりFAT構造が破壊される可能性がある。
-

diff --git a/doc/ja/write.html b/doc/ja/write.html index c0230c9..7783e95 100644 --- a/doc/ja/write.html +++ b/doc/ja/write.html @@ -45,7 +45,6 @@ FRESULT f_write ( FR_OK, FR_DISK_ERR, FR_INT_ERR, -FR_NOT_READY, FR_DENIED, FR_INVALID_OBJECT, FR_TIMEOUT diff --git a/src/00readme.txt b/src/00readme.txt index bab981a..c46ac5f 100644 --- a/src/00readme.txt +++ b/src/00readme.txt @@ -1,163 +1,21 @@ -FatFs Module Source Files R0.10c (C)ChaN, 2014 +FatFs Module Source Files R0.11 FILES - ffconf.h Configuration file for FatFs module. - ff.h Common include file for FatFs and application module. - ff.c FatFs module. - diskio.h Common include file for FatFs and disk I/O module. - diskio.c An example of glue function to attach existing disk I/O module to FatFs. - integer.h Integer type definitions for FatFs. - option Optional external functions. + 00readme.txt This file. + history.txt Revision history. + ffconf.h Configuration file for FatFs module. + ff.h Common include file for FatFs and application module. + ff.c FatFs module. + diskio.h Common include file for FatFs and disk I/O module. + diskio.c An example of glue function to attach existing disk I/O module to FatFs. + integer.h Integer type definitions for FatFs. + option Optional external functions. + Low level disk I/O module is not included in this archive because the FatFs module is only a generic file system layer and not depend on any specific storage device. You have to provide a low level disk I/O module that written - to control your storage device. + to control the target storage device. - - -AGREEMENTS - - FatFs module is an open source software to implement FAT file system to - small embedded systems. This is a free software and is opened for education, - research and commercial developments under license policy of following trems. - - Copyright (C) 2014, ChaN, all right reserved. - - * The FatFs module is a free software and there is NO WARRANTY. - * No restriction on use. You can use, modify and redistribute it for - personal, non-profit or commercial product UNDER YOUR RESPONSIBILITY. - * Redistributions of source code must retain the above copyright notice. - - - -REVISION HISTORY - - Feb 26, 2006 R0.00 Prototype - - Apr 29, 2006 R0.01 First release. - - Jun 01, 2006 R0.02 Added FAT12. - Removed unbuffered mode. - Fixed a problem on small (<32M) patition. - - Jun 10, 2006 R0.02a Added a configuration option _FS_MINIMUM. - - Sep 22, 2006 R0.03 Added f_rename. - Changed option _FS_MINIMUM to _FS_MINIMIZE. - - Dec 11, 2006 R0.03a Improved cluster scan algolithm to write files fast. - Fixed f_mkdir creates incorrect directory on FAT32. - - Feb 04, 2007 R0.04 Supported multiple drive system. (FatFs) - Changed some APIs for multiple drive system. - Added f_mkfs. (FatFs) - Added _USE_FAT32 option. (Tiny-FatFs) - - Apr 01, 2007 R0.04a Supported multiple partitions on a plysical drive. (FatFs) - Fixed an endian sensitive code in f_mkfs. (FatFs) - Added a capability of extending the file size to f_lseek. - Added minimization level 3. - Fixed a problem that can collapse a sector when recreate an - existing file in any sub-directory at non FAT32 cfg. (Tiny-FatFs) - - May 05, 2007 R0.04b Added _USE_NTFLAG option. - Added FSInfo support. - Fixed some problems corresponds to FAT32. (Tiny-FatFs) - Fixed DBCS name can result FR_INVALID_NAME. - Fixed short seek (0 < ofs <= csize) collapses the file object. - - Aug 25, 2007 R0.05 Changed arguments of f_read, f_write. - Changed arguments of f_mkfs. (FatFs) - Fixed f_mkfs on FAT32 creates incorrect FSInfo. (FatFs) - Fixed f_mkdir on FAT32 creates incorrect directory. (FatFs) - - Feb 03, 2008 R0.05a Added f_truncate(). - Added f_utime(). - Fixed off by one error at FAT sub-type determination. - Fixed btr in f_read() can be mistruncated. - Fixed cached sector is not flushed when create and close without write. - - Apr 01, 2008 R0.06 Added f_forward(). (Tiny-FatFs) - Added string functions: fputc(), fputs(), fprintf() and fgets(). - Improved performance of f_lseek() on move to the same or following cluster. - - Apr 01, 2009, R0.07 Merged Tiny-FatFs as a buffer configuration option. - Added long file name support. - Added multiple code page support. - Added re-entrancy for multitask operation. - Added auto cluster size selection to f_mkfs(). - Added rewind option to f_readdir(). - Changed result code of critical errors. - Renamed string functions to avoid name collision. - - Apr 14, 2009, R0.07a Separated out OS dependent code on reentrant cfg. - Added multiple sector size support. - - Jun 21, 2009, R0.07c Fixed f_unlink() may return FR_OK on error. - Fixed wrong cache control in f_lseek(). - Added relative path feature. - Added f_chdir(). - Added f_chdrive(). - Added proper case conversion for extended characters. - - Nov 03, 2009 R0.07e Separated out configuration options from ff.h to ffconf.h. - Added a configuration option, _LFN_UNICODE. - Fixed f_unlink() fails to remove a sub-dir on _FS_RPATH. - Fixed name matching error on the 13 char boundary. - Changed f_readdir() to return the SFN with always upper case on non-LFN cfg. - - May 15, 2010, R0.08 Added a memory configuration option. (_USE_LFN) - Added file lock feature. (_FS_SHARE) - Added fast seek feature. (_USE_FASTSEEK) - Changed some types on the API, XCHAR->TCHAR. - Changed fname member in the FILINFO structure on Unicode cfg. - String functions support UTF-8 encoding files on Unicode cfg. - - Aug 16,'10 R0.08a Added f_getcwd(). (_FS_RPATH = 2) - Added sector erase feature. (_USE_ERASE) - Moved file lock semaphore table from fs object to the bss. - Fixed a wrong directory entry is created on non-LFN cfg when the given name contains ';'. - Fixed f_mkfs() creates wrong FAT32 volume. - - Jan 15,'11 R0.08b Fast seek feature is also applied to f_read() and f_write(). - f_lseek() reports required table size on creating CLMP. - Extended format syntax of f_printf function. - Ignores duplicated directory separators in given path names. - - Sep 06,'11 R0.09 f_mkfs() supports multiple partition to finish the multiple partition feature. - Added f_fdisk(). (_MULTI_PARTITION = 2) - - Aug 27,'12 R0.09a Fixed assertion failure due to OS/2 EA on FAT12/16. - Changed f_open() and f_opendir() reject null object pointer to avoid crash. - Changed option name _FS_SHARE to _FS_LOCK. - - Jan 23,'13 R0.09b Added f_getlabel() and f_setlabel(). (_USE_LABEL) - - Oct 02,'13 R0.10 Added selection of character encoding on the file. (_STRF_ENCODE) - Added f_closedir(). - Added forced full FAT scan for f_getfree(). (_FS_NOFSINFO) - Added forced mount feature with changes of f_mount(). - Improved behavior of volume auto detection. - Improved write throughput of f_puts() and f_printf(). - Changed argument of f_chdrive(), f_mkfs(), disk_read() and disk_write(). - Fixed f_write() can be truncated when the file size is close to 4GB. - Fixed f_open(), f_mkdir() and f_setlabel() can return incorrect error code. - - Jan 15,'14 R0.10a Added arbitrary strings as drive number in the path name. (_STR_VOLUME_ID) - Added a configuration option of minimum sector size. (_MIN_SS) - 2nd argument of f_rename() can have a drive number and it will be ignored. - Fixed f_mount() with forced mount fails when drive number is >= 1. - Fixed f_close() invalidates the file object without volume lock. - Fixed f_closedir() returns but the volume lock is left acquired. - Fixed creation of an entry with LFN fails on too many SFN collisions. - - Mar 19,'14 R0.10b Fixed a hard error in the disk I/O layer can collapse the directory entry. - Fixed LFN entry is not deleted on delete/rename an object with lossy converted SFN. - - Nov 09,'14 R0.10c Added a configuration option for the platforms without RTC. (_FS_NORTC) - Fixed volume label created by Mac OS X cannot be retrieved with f_getlabel(). - Fixed a potential problem of FAT access that can appear on disk error. - Fixed null pointer dereference on attempting to delete the root direcotry. diff --git a/src/diskio.c b/src/diskio.c index 2ed3859..bd3ca33 100644 --- a/src/diskio.c +++ b/src/diskio.c @@ -8,14 +8,14 @@ /*-----------------------------------------------------------------------*/ #include "diskio.h" /* FatFs lower layer API */ -#include "usbdisk.h" /* Example: USB drive control */ -#include "atadrive.h" /* Example: ATA drive control */ -#include "sdcard.h" /* Example: MMC/SDC contorl */ +#include "usbdisk.h" /* Example: Header file of existing USB MSD control module */ +#include "atadrive.h" /* Example: Header file of existing ATA harddisk control module */ +#include "sdcard.h" /* Example: Header file of existing MMC/SDC contorl module */ /* Definitions of physical drive number for each drive */ -#define ATA 0 /* Example: Map ATA drive to drive number 0 */ -#define MMC 1 /* Example: Map MMC/SD card to drive number 1 */ -#define USB 2 /* Example: Map USB drive to drive number 2 */ +#define ATA 0 /* Example: Map ATA harddisk to physical drive 0 */ +#define MMC 1 /* Example: Map MMC/SD card to physical drive 1 */ +#define USB 2 /* Example: Map USB MSD to physical drive 2 */ /*-----------------------------------------------------------------------*/ diff --git a/src/ff.c b/src/ff.c index 89cef49..30d2e71 100644 --- a/src/ff.c +++ b/src/ff.c @@ -1,137 +1,32 @@ /*----------------------------------------------------------------------------/ -/ FatFs - FAT file system module R0.10c (C)ChaN, 2014 +/ FatFs - FAT file system module R0.11 (C)ChaN, 2015 /-----------------------------------------------------------------------------/ -/ FatFs module is a generic FAT file system module for small embedded systems. -/ This is a free software that opened for education, research and commercial -/ developments under license policy of following terms. +/ FatFs module is a free software that opened under license policy of +/ following conditions. / -/ Copyright (C) 2014, ChaN, all right reserved. +/ Copyright (C) 2015, ChaN, all right reserved. / -/ * The FatFs module is a free software and there is NO WARRANTY. -/ * No restriction on use. You can use, modify and redistribute it for -/ personal, non-profit or commercial products UNDER YOUR RESPONSIBILITY. -/ * Redistributions of source code must retain the above copyright notice. +/ 1. Redistributions of source code must retain the above copyright notice, +/ this condition and the following disclaimer. / -/-----------------------------------------------------------------------------/ -/ Feb 26,'06 R0.00 Prototype. -/ -/ Apr 29,'06 R0.01 First stable version. -/ -/ Jun 01,'06 R0.02 Added FAT12 support. -/ Removed unbuffered mode. -/ Fixed a problem on small (<32M) partition. -/ Jun 10,'06 R0.02a Added a configuration option (_FS_MINIMUM). -/ -/ Sep 22,'06 R0.03 Added f_rename(). -/ Changed option _FS_MINIMUM to _FS_MINIMIZE. -/ Dec 11,'06 R0.03a Improved cluster scan algorithm to write files fast. -/ Fixed f_mkdir() creates incorrect directory on FAT32. -/ -/ Feb 04,'07 R0.04 Supported multiple drive system. -/ Changed some interfaces for multiple drive system. -/ Changed f_mountdrv() to f_mount(). -/ Added f_mkfs(). -/ Apr 01,'07 R0.04a Supported multiple partitions on a physical drive. -/ Added a capability of extending file size to f_lseek(). -/ Added minimization level 3. -/ Fixed an endian sensitive code in f_mkfs(). -/ May 05,'07 R0.04b Added a configuration option _USE_NTFLAG. -/ Added FSINFO support. -/ Fixed DBCS name can result FR_INVALID_NAME. -/ Fixed short seek (<= csize) collapses the file object. -/ -/ Aug 25,'07 R0.05 Changed arguments of f_read(), f_write() and f_mkfs(). -/ Fixed f_mkfs() on FAT32 creates incorrect FSINFO. -/ Fixed f_mkdir() on FAT32 creates incorrect directory. -/ Feb 03,'08 R0.05a Added f_truncate() and f_utime(). -/ Fixed off by one error at FAT sub-type determination. -/ Fixed btr in f_read() can be mistruncated. -/ Fixed cached sector is not flushed when create and close without write. -/ -/ Apr 01,'08 R0.06 Added fputc(), fputs(), fprintf() and fgets(). -/ Improved performance of f_lseek() on moving to the same or following cluster. -/ -/ Apr 01,'09 R0.07 Merged Tiny-FatFs as a configuration option. (_FS_TINY) -/ Added long file name feature. -/ Added multiple code page feature. -/ Added re-entrancy for multitask operation. -/ Added auto cluster size selection to f_mkfs(). -/ Added rewind option to f_readdir(). -/ Changed result code of critical errors. -/ Renamed string functions to avoid name collision. -/ Apr 14,'09 R0.07a Separated out OS dependent code on reentrant cfg. -/ Added multiple sector size feature. -/ Jun 21,'09 R0.07c Fixed f_unlink() can return FR_OK on error. -/ Fixed wrong cache control in f_lseek(). -/ Added relative path feature. -/ Added f_chdir() and f_chdrive(). -/ Added proper case conversion to extended character. -/ Nov 03,'09 R0.07e Separated out configuration options from ff.h to ffconf.h. -/ Fixed f_unlink() fails to remove a sub-directory on _FS_RPATH. -/ Fixed name matching error on the 13 character boundary. -/ Added a configuration option, _LFN_UNICODE. -/ Changed f_readdir() to return the SFN with always upper case on non-LFN cfg. -/ -/ May 15,'10 R0.08 Added a memory configuration option. (_USE_LFN = 3) -/ Added file lock feature. (_FS_SHARE) -/ Added fast seek feature. (_USE_FASTSEEK) -/ Changed some types on the API, XCHAR->TCHAR. -/ Changed .fname in the FILINFO structure on Unicode cfg. -/ String functions support UTF-8 encoding files on Unicode cfg. -/ Aug 16,'10 R0.08a Added f_getcwd(). -/ Added sector erase feature. (_USE_ERASE) -/ Moved file lock semaphore table from fs object to the bss. -/ Fixed a wrong directory entry is created on non-LFN cfg when the given name contains ';'. -/ Fixed f_mkfs() creates wrong FAT32 volume. -/ Jan 15,'11 R0.08b Fast seek feature is also applied to f_read() and f_write(). -/ f_lseek() reports required table size on creating CLMP. -/ Extended format syntax of f_printf(). -/ Ignores duplicated directory separators in given path name. -/ -/ Sep 06,'11 R0.09 f_mkfs() supports multiple partition to complete the multiple partition feature. -/ Added f_fdisk(). -/ Aug 27,'12 R0.09a Changed f_open() and f_opendir() reject null object pointer to avoid crash. -/ Changed option name _FS_SHARE to _FS_LOCK. -/ Fixed assertion failure due to OS/2 EA on FAT12/16 volume. -/ Jan 24,'13 R0.09b Added f_setlabel() and f_getlabel(). -/ -/ Oct 02,'13 R0.10 Added selection of character encoding on the file. (_STRF_ENCODE) -/ Added f_closedir(). -/ Added forced full FAT scan for f_getfree(). (_FS_NOFSINFO) -/ Added forced mount feature with changes of f_mount(). -/ Improved behavior of volume auto detection. -/ Improved write throughput of f_puts() and f_printf(). -/ Changed argument of f_chdrive(), f_mkfs(), disk_read() and disk_write(). -/ Fixed f_write() can be truncated when the file size is close to 4GB. -/ Fixed f_open(), f_mkdir() and f_setlabel() can return incorrect error code. -/ Jan 15,'14 R0.10a Added arbitrary strings as drive number in the path name. (_STR_VOLUME_ID) -/ Added a configuration option of minimum sector size. (_MIN_SS) -/ 2nd argument of f_rename() can have a drive number and it will be ignored. -/ Fixed f_mount() with forced mount fails when drive number is >= 1. -/ Fixed f_close() invalidates the file object without volume lock. -/ Fixed f_closedir() returns but the volume lock is left acquired. -/ Fixed creation of an entry with LFN fails on too many SFN collisions. -/ May 19,'14 R0.10b Fixed a hard error in the disk I/O layer can collapse the directory entry. -/ Fixed LFN entry is not deleted on delete/rename an object with lossy converted SFN. -/ Nov 09,'14 R0.10c Added a configuration option for the platforms without RTC. (_FS_NORTC) -/ Fixed volume label created by Mac OS X cannot be retrieved with f_getlabel(). -/ Fixed a potential problem of FAT access that can appear on disk error. -/ Fixed null pointer dereference on attempting to delete the root direcotry. -/---------------------------------------------------------------------------*/ +/ This software is provided by the copyright holder and contributors "AS IS" +/ and any warranties related to this software are DISCLAIMED. +/ The copyright owner or contributors be NOT LIABLE for any damages caused +/ by use of this software. +/----------------------------------------------------------------------------*/ + #include "ff.h" /* Declarations of FatFs API */ #include "diskio.h" /* Declarations of disk I/O functions */ - - /*-------------------------------------------------------------------------- Module Private Definitions ---------------------------------------------------------------------------*/ -#if _FATFS != 80376 /* Revision ID */ +#if _FATFS != 32020 /* Revision ID */ #error Wrong include file (ff.h). #endif @@ -163,8 +58,11 @@ /* Timestamp feature */ -#if _FS_NORTC -#define GET_FATTIME() ((DWORD)_NORTC_YEAR << 25 | (DWORD)_NORTC_MON << 21 | (DWORD)_NORTC_MDAY << 16) +#if _FS_NORTC == 1 +#if _NORTC_YEAR < 1980 || _NORTC_YEAR > 2107 || _NORTC_MON < 1 || _NORTC_MON > 12 || _NORTC_MDAY < 1 || _NORTC_MDAY > 31 +#error Invalid _FS_NORTC settings +#endif +#define GET_FATTIME() ((DWORD)(_NORTC_YEAR - 1980) << 25 | (DWORD)_NORTC_MON << 21 | (DWORD)_NORTC_MDAY << 16) #else #define GET_FATTIME() get_fattime() #endif @@ -468,7 +366,7 @@ typedef struct { #define DIR_Name 0 /* Short file name (11) */ #define DIR_Attr 11 /* Attribute (1) */ -#define DIR_NTres 12 /* NT flag (1) */ +#define DIR_NTres 12 /* Lower case flag (1) */ #define DIR_CrtTimeTenth 13 /* Created time sub-second (1) */ #define DIR_CrtTime 14 /* Created time (2) */ #define DIR_CrtDate 16 /* Created date (2) */ @@ -482,11 +380,11 @@ typedef struct { #define LDIR_Attr 11 /* LFN attribute (1) */ #define LDIR_Type 12 /* LFN type (1) */ #define LDIR_Chksum 13 /* Sum of corresponding SFN entry */ -#define LDIR_FstClusLO 26 /* Filled by zero (0) */ -#define SZ_DIR 32 /* Size of a directory entry */ -#define LLE 0x40 /* Last long entry flag in LDIR_Ord */ -#define DDE 0xE5 /* Deleted directory entry mark in DIR_Name[0] */ -#define NDDE 0x05 /* Replacement of the character collides with DDE */ +#define LDIR_FstClusLO 26 /* Must be zero (0) */ +#define SZ_DIRE 32 /* Size of a directory entry */ +#define LLEF 0x40 /* Last long entry flag in LDIR_Ord */ +#define DDEM 0xE5 /* Deleted directory entry mark at DIR_Name[0] */ +#define RDDEM 0x05 /* Replacement of the character collides with DDEM */ @@ -514,7 +412,7 @@ static FILESEM Files[_FS_LOCK]; /* Open object lock semaphores */ #endif #if _USE_LFN == 0 /* Non LFN feature */ -#define DEF_NAMEBUF BYTE sfn[12] +#define DEFINE_NAMEBUF BYTE sfn[12] #define INIT_BUF(dobj) (dobj).fn = sfn #define FREE_BUF() #else @@ -522,16 +420,16 @@ static FILESEM Files[_FS_LOCK]; /* Open object lock semaphores */ #error Wrong _MAX_LFN setting #endif #if _USE_LFN == 1 /* LFN feature with static working buffer */ -static WCHAR LfnBuf[_MAX_LFN+1]; -#define DEF_NAMEBUF BYTE sfn[12] +static WCHAR LfnBuf[_MAX_LFN + 1]; +#define DEFINE_NAMEBUF BYTE sfn[12] #define INIT_BUF(dobj) { (dobj).fn = sfn; (dobj).lfn = LfnBuf; } #define FREE_BUF() #elif _USE_LFN == 2 /* LFN feature with dynamic working buffer on the stack */ -#define DEF_NAMEBUF BYTE sfn[12]; WCHAR lbuf[_MAX_LFN+1] +#define DEFINE_NAMEBUF BYTE sfn[12]; WCHAR lbuf[_MAX_LFN + 1] #define INIT_BUF(dobj) { (dobj).fn = sfn; (dobj).lfn = lbuf; } #define FREE_BUF() #elif _USE_LFN == 3 /* LFN feature with dynamic working buffer on the heap */ -#define DEF_NAMEBUF BYTE sfn[12]; WCHAR *lfn +#define DEFINE_NAMEBUF BYTE sfn[12]; WCHAR *lfn #define INIT_BUF(dobj) { lfn = ff_memalloc((_MAX_LFN + 1) * 2); if (!lfn) LEAVE_FF((dobj).fs, FR_NOT_ENOUGH_CORE); (dobj).lfn = lfn; (dobj).fn = sfn; } #define FREE_BUF() ff_memfree(lfn) #else @@ -827,11 +725,11 @@ FRESULT sync_fs ( /* FR_OK: successful, FR_DISK_ERR: failed */ if (fs->fs_type == FS_FAT32 && fs->fsi_flag == 1) { /* Create FSINFO structure */ mem_set(fs->win, 0, SS(fs)); - ST_WORD(fs->win+BS_55AA, 0xAA55); - ST_DWORD(fs->win+FSI_LeadSig, 0x41615252); - ST_DWORD(fs->win+FSI_StrucSig, 0x61417272); - ST_DWORD(fs->win+FSI_Free_Count, fs->free_clust); - ST_DWORD(fs->win+FSI_Nxt_Free, fs->last_clust); + ST_WORD(fs->win + BS_55AA, 0xAA55); + ST_DWORD(fs->win + FSI_LeadSig, 0x41615252); + ST_DWORD(fs->win + FSI_StrucSig, 0x61417272); + ST_DWORD(fs->win + FSI_Free_Count, fs->free_clust); + ST_DWORD(fs->win + FSI_Nxt_Free, fs->last_clust); /* Write it into the FSINFO sector */ fs->winsect = fs->volbase + 1; disk_write(fs->drv, fs->win, fs->winsect, 1); @@ -874,7 +772,7 @@ DWORD clust2sect ( /* !=0: Sector number, 0: Failed - invalid cluster# */ DWORD get_fat ( /* 0xFFFFFFFF:Disk error, 1:Internal error, 2..0x0FFFFFFF:Cluster status */ FATFS* fs, /* File system object */ - DWORD clst /* FAT item index (cluster#) to get the value */ + DWORD clst /* FAT index number (cluster number) to get the value */ ) { UINT wc, bc; @@ -929,8 +827,8 @@ DWORD get_fat ( /* 0xFFFFFFFF:Disk error, 1:Internal error, 2..0x0FFFFFFF:Cluste #if !_FS_READONLY FRESULT put_fat ( FATFS* fs, /* File system object */ - DWORD clst, /* FAT item index (cluster#) to be set */ - DWORD val /* New value to mark the cluster */ + DWORD clst, /* FAT index number (cluster number) to be changed */ + DWORD val /* New value to be set to the entry */ ) { UINT bc; @@ -1156,7 +1054,7 @@ FRESULT dir_sdi ( sect = dp->fs->dirbase; } else { /* Dynamic table (root-directory in FAT32 or sub-directory) */ - ic = SS(dp->fs) / SZ_DIR * dp->fs->csize; /* Entries per cluster */ + ic = SS(dp->fs) / SZ_DIRE * dp->fs->csize; /* Entries per cluster */ while (idx >= ic) { /* Follow cluster chain */ clst = get_fat(dp->fs, clst); /* Get next cluster */ if (clst == 0xFFFFFFFF) return FR_DISK_ERR; /* Disk error */ @@ -1168,8 +1066,8 @@ FRESULT dir_sdi ( } dp->clust = clst; /* Current cluster# */ if (!sect) return FR_INT_ERR; - dp->sect = sect + idx / (SS(dp->fs) / SZ_DIR); /* Sector# of the directory entry */ - dp->dir = dp->fs->win + (idx % (SS(dp->fs) / SZ_DIR)) * SZ_DIR; /* Ptr to the entry in the sector */ + dp->sect = sect + idx / (SS(dp->fs) / SZ_DIRE); /* Sector# of the directory entry */ + dp->dir = dp->fs->win + (idx % (SS(dp->fs) / SZ_DIRE)) * SZ_DIRE; /* Ptr to the entry in the sector */ return FR_OK; } @@ -1189,13 +1087,16 @@ FRESULT dir_next ( /* FR_OK:Succeeded, FR_NO_FILE:End of table, FR_DENIED:Could { DWORD clst; UINT i; +#if !_FS_READONLY + UINT c; +#endif i = dp->index + 1; if (!(i & 0xFFFF) || !dp->sect) /* Report EOT when index has reached 65535 */ return FR_NO_FILE; - if (!(i % (SS(dp->fs) / SZ_DIR))) { /* Sector changed? */ + if (!(i % (SS(dp->fs) / SZ_DIRE))) { /* Sector changed? */ dp->sect++; /* Next sector */ if (!dp->clust) { /* Static table */ @@ -1203,13 +1104,12 @@ FRESULT dir_next ( /* FR_OK:Succeeded, FR_NO_FILE:End of table, FR_DENIED:Could return FR_NO_FILE; } else { /* Dynamic table */ - if (((i / (SS(dp->fs) / SZ_DIR)) & (dp->fs->csize - 1)) == 0) { /* Cluster changed? */ + if (((i / (SS(dp->fs) / SZ_DIRE)) & (dp->fs->csize - 1)) == 0) { /* Cluster changed? */ clst = get_fat(dp->fs, dp->clust); /* Get next cluster */ if (clst <= 1) return FR_INT_ERR; if (clst == 0xFFFFFFFF) return FR_DISK_ERR; if (clst >= dp->fs->n_fatent) { /* If it reached end of dynamic table, */ #if !_FS_READONLY - UINT c; if (!stretch) return FR_NO_FILE; /* If do not stretch, report EOT */ clst = create_chain(dp->fs, dp->clust); /* Stretch cluster chain */ if (clst == 0) return FR_DENIED; /* No free cluster */ @@ -1237,7 +1137,7 @@ FRESULT dir_next ( /* FR_OK:Succeeded, FR_NO_FILE:End of table, FR_DENIED:Could } dp->index = (WORD)i; /* Current index */ - dp->dir = dp->fs->win + (i % (SS(dp->fs) / SZ_DIR)) * SZ_DIR; /* Current entry in the window */ + dp->dir = dp->fs->win + (i % (SS(dp->fs) / SZ_DIRE)) * SZ_DIRE; /* Current entry in the window */ return FR_OK; } @@ -1266,7 +1166,7 @@ FRESULT dir_alloc ( do { res = move_window(dp->fs, dp->sect); if (res != FR_OK) break; - if (dp->dir[0] == DDE || dp->dir[0] == 0) { /* Is it a free entry? */ + if (dp->dir[0] == DDEM || dp->dir[0] == 0) { /* Is it a free entry? */ if (++n == nent) break; /* A block of contiguous free entries is found */ } else { n = 0; /* Not a blank entry. Restart to search */ @@ -1294,9 +1194,9 @@ DWORD ld_clust ( { DWORD cl; - cl = LD_WORD(dir+DIR_FstClusLO); + cl = LD_WORD(dir + DIR_FstClusLO); if (fs->fs_type == FS_FAT32) - cl |= (DWORD)LD_WORD(dir+DIR_FstClusHI) << 16; + cl |= (DWORD)LD_WORD(dir + DIR_FstClusHI) << 16; return cl; } @@ -1309,8 +1209,8 @@ void st_clust ( DWORD cl /* Value to be set */ ) { - ST_WORD(dir+DIR_FstClusLO, cl); - ST_WORD(dir+DIR_FstClusHI, cl >> 16); + ST_WORD(dir + DIR_FstClusLO, cl); + ST_WORD(dir + DIR_FstClusHI, cl >> 16); } #endif @@ -1335,10 +1235,10 @@ int cmp_lfn ( /* 1:Matched, 0:Not matched */ WCHAR wc, uc; - i = ((dir[LDIR_Ord] & ~LLE) - 1) * 13; /* Get offset in the LFN buffer */ + i = ((dir[LDIR_Ord] & ~LLEF) - 1) * 13; /* Get offset in the LFN buffer */ s = 0; wc = 1; do { - uc = LD_WORD(dir+LfnOfs[s]); /* Pick an LFN character from the entry */ + uc = LD_WORD(dir + LfnOfs[s]); /* Pick an LFN character from the entry */ if (wc) { /* Last character has not been processed */ wc = ff_wtoupper(uc); /* Convert it to upper case */ if (i >= _MAX_LFN || wc != ff_wtoupper(lfnbuf[i++])) /* Compare it */ @@ -1348,7 +1248,7 @@ int cmp_lfn ( /* 1:Matched, 0:Not matched */ } } while (++s < 13); /* Repeat until all characters in the entry are checked */ - if ((dir[LDIR_Ord] & LLE) && wc && lfnbuf[i]) /* Last segment matched but different length */ + if ((dir[LDIR_Ord] & LLEF) && wc && lfnbuf[i]) /* Last segment matched but different length */ return 0; return 1; /* The part of LFN matched */ @@ -1370,7 +1270,7 @@ int pick_lfn ( /* 1:Succeeded, 0:Buffer overflow */ s = 0; wc = 1; do { - uc = LD_WORD(dir+LfnOfs[s]); /* Pick an LFN character from the entry */ + uc = LD_WORD(dir + LfnOfs[s]); /* Pick an LFN character from the entry */ if (wc) { /* Last character has not been processed */ if (i >= _MAX_LFN) return 0; /* Buffer overflow? */ lfnbuf[i++] = wc = uc; /* Store it */ @@ -1379,7 +1279,7 @@ int pick_lfn ( /* 1:Succeeded, 0:Buffer overflow */ } } while (++s < 13); /* Read all character in the entry */ - if (dir[LDIR_Ord] & LLE) { /* Put terminator if it is the last LFN part */ + if (dir[LDIR_Ord] & LLEF) { /* Put terminator if it is the last LFN part */ if (i >= _MAX_LFN) return 0; /* Buffer overflow? */ lfnbuf[i] = 0; } @@ -1404,7 +1304,7 @@ void fit_lfn ( dir[LDIR_Chksum] = sum; /* Set check sum */ dir[LDIR_Attr] = AM_LFN; /* Set attribute. LFN entry */ dir[LDIR_Type] = 0; - ST_WORD(dir+LDIR_FstClusLO, 0); + ST_WORD(dir + LDIR_FstClusLO, 0); i = (ord - 1) * 13; /* Get offset in the LFN buffer */ s = wc = 0; @@ -1413,7 +1313,7 @@ void fit_lfn ( ST_WORD(dir+LfnOfs[s], wc); /* Put it */ if (!wc) wc = 0xFFFF; /* Padding characters following last character */ } while (++s < 13); - if (wc == 0xFFFF || !lfnbuf[i]) ord |= LLE; /* Bottom LFN part is the start of LFN sequence */ + if (wc == 0xFFFF || !lfnbuf[i]) ord |= LLEF; /* Bottom LFN part is the start of LFN sequence */ dir[LDIR_Ord] = ord; /* Set the LFN order */ } @@ -1437,14 +1337,14 @@ void gen_numname ( { BYTE ns[8], c; UINT i, j; + WCHAR wc; + DWORD sr; mem_cpy(dst, src, 11); if (seq > 5) { /* On many collisions, generate a hash number instead of sequential number */ - WCHAR wc; - DWORD sr = seq; - + sr = seq; while (*lfn) { /* Create a CRC */ wc = *lfn++; for (i = 0; i < 16; i++) { @@ -1531,14 +1431,14 @@ FRESULT dir_find ( if (c == 0) { res = FR_NO_FILE; break; } /* Reached to end of table */ #if _USE_LFN /* LFN configuration */ a = dir[DIR_Attr] & AM_MASK; - if (c == DDE || ((a & AM_VOL) && a != AM_LFN)) { /* An entry without valid data */ + if (c == DDEM || ((a & AM_VOL) && a != AM_LFN)) { /* An entry without valid data */ ord = 0xFF; dp->lfn_idx = 0xFFFF; /* Reset LFN sequence */ } else { if (a == AM_LFN) { /* An LFN entry is found */ if (dp->lfn) { - if (c & LLE) { /* Is it start of LFN sequence? */ + if (c & LLEF) { /* Is it start of LFN sequence? */ sum = dir[LDIR_Chksum]; - c &= ~LLE; ord = c; /* LFN start order */ + c &= ~LLEF; ord = c; /* LFN start order */ dp->lfn_idx = dp->index; /* Start index of LFN */ } /* Check validity of the LFN entry and compare it with given name */ @@ -1588,13 +1488,13 @@ FRESULT dir_read ( if (c == 0) { res = FR_NO_FILE; break; } /* Reached to end of table */ a = dir[DIR_Attr] & AM_MASK; #if _USE_LFN /* LFN configuration */ - if (c == DDE || (!_FS_RPATH && c == '.') || (int)((a & ~AM_ARC) == AM_VOL) != vol) { /* An entry without valid data */ + if (c == DDEM || (!_FS_RPATH && c == '.') || (int)((a & ~AM_ARC) == AM_VOL) != vol) { /* An entry without valid data */ ord = 0xFF; } else { if (a == AM_LFN) { /* An LFN entry is found */ - if (c & LLE) { /* Is it start of LFN sequence? */ + if (c & LLEF) { /* Is it start of LFN sequence? */ sum = dir[LDIR_Chksum]; - c &= ~LLE; ord = c; + c &= ~LLEF; ord = c; dp->lfn_idx = dp->index; } /* Check LFN validity and capture it */ @@ -1606,7 +1506,7 @@ FRESULT dir_read ( } } #else /* Non LFN configuration */ - if (c != DDE && (_FS_RPATH || c != '.') && a != AM_LFN && (int)((a & ~AM_ARC) == AM_VOL) == vol) /* Is it a valid entry? */ + if (c != DDEM && (_FS_RPATH || c != '.') && a != AM_LFN && (int)((a & ~AM_ARC) == AM_VOL) == vol) /* Is it a valid entry? */ break; #endif res = dir_next(dp, 0); /* Next entry */ @@ -1684,7 +1584,7 @@ FRESULT dir_register ( /* FR_OK:Successful, FR_DENIED:No free entry or too many if (res == FR_OK) { /* Set SFN entry */ res = move_window(dp->fs, dp->sect); if (res == FR_OK) { - mem_set(dp->dir, 0, SZ_DIR); /* Clean the entry */ + mem_set(dp->dir, 0, SZ_DIRE); /* Clean the entry */ mem_cpy(dp->dir, dp->fn, 11); /* Put SFN */ #if _USE_LFN dp->dir[DIR_NTres] = dp->fn[NSFLAG] & (NS_BODY | NS_EXT); /* Put NT flag */ @@ -1719,8 +1619,8 @@ FRESULT dir_remove ( /* FR_OK: Successful, FR_DISK_ERR: A disk error */ do { res = move_window(dp->fs, dp->sect); if (res != FR_OK) break; - mem_set(dp->dir, 0, SZ_DIR); /* Clear and mark the entry "deleted" */ - *dp->dir = DDE; + mem_set(dp->dir, 0, SZ_DIRE); /* Clear and mark the entry "deleted" */ + *dp->dir = DDEM; dp->fs->wflag = 1; if (dp->index >= i) break; /* When reached SFN, all entries of the object has been deleted. */ res = dir_next(dp, 0); /* Next entry */ @@ -1733,8 +1633,8 @@ FRESULT dir_remove ( /* FR_OK: Successful, FR_DISK_ERR: A disk error */ if (res == FR_OK) { res = move_window(dp->fs, dp->sect); if (res == FR_OK) { - mem_set(dp->dir, 0, SZ_DIR); /* Clear and mark the entry "deleted" */ - *dp->dir = DDE; + mem_set(dp->dir, 0, SZ_DIRE); /* Clear and mark the entry "deleted" */ + *dp->dir = DDEM; dp->fs->wflag = 1; } } @@ -1759,18 +1659,20 @@ void get_fileinfo ( /* No return code */ { UINT i; TCHAR *p, c; - + BYTE *dir; +#if _USE_LFN + WCHAR w, *lfn; +#endif p = fno->fname; if (dp->sect) { /* Get SFN */ - BYTE *dir = dp->dir; - + dir = dp->dir; i = 0; while (i < 11) { /* Copy name body and extension */ c = (TCHAR)dir[i++]; - if (c == ' ') continue; /* Skip padding spaces */ - if (c == NDDE) c = (TCHAR)DDE; /* Restore replaced DDE character */ - if (i == 9) *p++ = '.'; /* Insert a . if extension is exist */ + if (c == ' ') continue; /* Skip padding spaces */ + if (c == RDDEM) c = (TCHAR)DDEM; /* Restore replaced DDEM character */ + if (i == 9) *p++ = '.'; /* Insert a . if extension is exist */ #if _USE_LFN if (IsUpper(c) && (dir[DIR_NTres] & (i >= 9 ? NS_EXT : NS_BODY))) c += 0x20; /* To lower */ @@ -1784,16 +1686,14 @@ void get_fileinfo ( /* No return code */ *p++ = c; } fno->fattrib = dir[DIR_Attr]; /* Attribute */ - fno->fsize = LD_DWORD(dir+DIR_FileSize); /* Size */ - fno->fdate = LD_WORD(dir+DIR_WrtDate); /* Date */ - fno->ftime = LD_WORD(dir+DIR_WrtTime); /* Time */ + fno->fsize = LD_DWORD(dir + DIR_FileSize); /* Size */ + fno->fdate = LD_WORD(dir + DIR_WrtDate); /* Date */ + fno->ftime = LD_WORD(dir + DIR_WrtTime); /* Time */ } *p = 0; /* Terminate SFN string by a \0 */ #if _USE_LFN if (fno->lfname) { - WCHAR w, *lfn; - i = 0; p = fno->lfname; if (dp->sect && fno->lfsize && dp->lfn_idx != 0xFFFF) { /* Get LFN if available */ lfn = dp->lfn; @@ -1812,7 +1712,77 @@ void get_fileinfo ( /* No return code */ } #endif } -#endif /* _FS_MINIMIZE <= 1 || _FS_RPATH >= 2*/ +#endif /* _FS_MINIMIZE <= 1 || _FS_RPATH >= 2 */ + + + + +/*-----------------------------------------------------------------------*/ +/* Pattern matching */ +/*-----------------------------------------------------------------------*/ +#if _USE_FIND && _FS_MINIMIZE <= 1 +static +WCHAR get_achar ( /* Get a character and advances ptr 1 or 2 */ + const TCHAR** ptr /* Pointer to pointer to the SBCS/DBCS/Unicode string */ +) +{ + WCHAR chr; + +#if !_LFN_UNICODE + chr = (BYTE)*(*ptr)++; /* Get a byte */ + if (IsLower(chr)) chr -= 0x20; /* To upper ASCII char */ + if (IsDBCS1(chr) && IsDBCS2(**ptr)) /* Get DBC 2nd byte if needed */ + chr = chr << 8 | (BYTE)*(*ptr)++; +#ifdef _EXCVT + if (chr >= 0x80) chr = ExCvt[chr - 0x80]; /* To upper SBCS extended char */ +#endif +#else + chr = ff_wtoupper(*(*ptr)++); /* Get a word and to upper */ +#endif + return chr; +} + + +static +int pattern_matching ( /* Return value: 0:mismatched, 1:matched */ + const TCHAR* pat, /* Matching pattern */ + const TCHAR* nam, /* String to be tested */ + int skip, /* Number of pre-skip chars (number of ?s) */ + int inf /* Infinite search (* specified) */ +) +{ + const TCHAR *pp, *np; + WCHAR pc, nc; + int nm, nx; + + + while (skip--) { /* Pre-skip name chars */ + if (!get_achar(&nam)) return 0; /* Branch mismatched if less name chars */ + } + if (!*pat && inf) return 1; /* (short circuit) */ + + do { + pp = pat; np = nam; /* Top of pattern and name to match */ + for (;;) { + if (*pp == '?' || *pp == '*') { /* Wildcard? */ + nm = nx = 0; + do { /* Analyze the wildcard chars */ + if (*pp++ == '?') nm++; else nx = 1; + } while (*pp == '?' || *pp == '*'); + if (pattern_matching(pp, np, nm, nx)) return 1; /* Test new branch (recurs upto number of wildcard blocks in the pattern) */ + nc = *np; break; /* Branch mismatched */ + } + pc = get_achar(&pp); /* Get a pattern char */ + nc = get_achar(&np); /* Get a name char */ + if (pc != nc) break; /* Branch mismatched? */ + if (!pc) return 1; /* Branch matched? (matched at end of both strings) */ + } + get_achar(&nam); /* nam++ */ + } while (inf && nc); /* Retry until end of name if infinite search is specified */ + + return 0; +} +#endif /* _USE_FIND && _FS_MINIMIZE <= 1 */ @@ -1846,9 +1816,9 @@ FRESULT create_name ( w &= 0xFF; if (IsDBCS1(w)) { /* Check if it is a DBC 1st byte (always false on SBCS cfg) */ b = (BYTE)p[si++]; /* Get 2nd byte */ + w = (w << 8) + b; /* Create a DBC */ if (!IsDBCS2(b)) return FR_INVALID_NAME; /* Reject invalid sequence */ - w = (w << 8) + b; /* Create a DBC */ } w = ff_convert(w, 1); /* Convert ANSI/OEM to Unicode */ if (!w) return FR_INVALID_NAME; /* Reject invalid code */ @@ -1860,8 +1830,8 @@ FRESULT create_name ( *path = &p[si]; /* Return pointer to the next segment */ cf = (w < ' ') ? NS_LAST : 0; /* Set last segment flag if end of path */ #if _FS_RPATH - if ((di == 1 && lfn[di-1] == '.') || /* Is this a dot entry? */ - (di == 2 && lfn[di-1] == '.' && lfn[di-2] == '.')) { + if ((di == 1 && lfn[di - 1] == '.') || /* Is this a dot entry? */ + (di == 2 && lfn[di - 1] == '.' && lfn[di - 2] == '.')) { lfn[di] = 0; for (i = 0; i < 11; i++) dp->fn[i] = (i < di) ? '.' : ' '; @@ -1870,7 +1840,7 @@ FRESULT create_name ( } #endif while (di) { /* Strip trailing spaces and dots */ - w = lfn[di-1]; + w = lfn[di - 1]; if (w != ' ' && w != '.') break; di--; } @@ -1912,12 +1882,12 @@ FRESULT create_name ( cf |= NS_LFN; /* Force create LFN entry */ } - if (_DF1S && w >= 0x100) { /* Double byte character (always false on SBCS cfg) */ + if (_DF1S && w >= 0x100) { /* DBC (always false at SBCS cfg) */ if (i >= ni - 1) { cf |= NS_LOSS | NS_LFN; i = ni; continue; } dp->fn[i++] = (BYTE)(w >> 8); - } else { /* Single byte character */ + } else { /* SBC */ if (!w || chk_chr("+,;=[]", w)) { /* Replace illegal characters for SFN */ w = '_'; cf |= NS_LOSS | NS_LFN;/* Lossy conversion */ } else { @@ -1933,7 +1903,7 @@ FRESULT create_name ( dp->fn[i++] = (BYTE)w; } - if (dp->fn[0] == DDE) dp->fn[0] = NDDE; /* If the first character collides with deleted mark, replace it with 0x05 */ + if (dp->fn[0] == DDEM) dp->fn[0] = RDDEM; /* If the first character collides with deleted mark, replace it with RDDEM */ if (ni == 8) b <<= 2; if ((b & 0x0C) == 0x0C || (b & 0x03) == 0x03) /* Create LFN entry when there are composite capitals */ @@ -1995,7 +1965,7 @@ FRESULT create_name ( return FR_INVALID_NAME; sfn[i++] = c; sfn[i++] = d; - } else { /* Single byte code */ + } else { /* SBC */ if (chk_chr("\"*+,:;<=>\?[]|\x7F", c)) /* Reject illegal chrs for SFN */ return FR_INVALID_NAME; if (IsUpper(c)) { /* ASCII large capital? */ @@ -2012,7 +1982,7 @@ FRESULT create_name ( c = (c <= ' ') ? NS_LAST : 0; /* Set last segment flag if end of path */ if (!i) return FR_INVALID_NAME; /* Reject nul string */ - if (sfn[0] == DDE) sfn[0] = NDDE; /* When first character collides with DDE, replace it with 0x05 */ + if (sfn[0] == DDEM) sfn[0] = RDDEM; /* When first character collides with DDEM, replace it with RDDEM */ if (ni == 8) b <<= 2; if ((b & 0x03) == 0x01) c |= NS_EXT; /* NT flag (Name extension has only small capital) */ @@ -2101,6 +2071,12 @@ int get_ldnumber ( /* Returns logical drive number (-1:invalid drive) */ const TCHAR *tp, *tt; UINT i; int vol = -1; +#if _STR_VOLUME_ID /* Find string drive id */ + static const char* const str[] = {_VOLUME_STRS}; + const char *sp; + char c; + TCHAR tc; +#endif if (*path) { /* If the pointer is not a null */ @@ -2113,13 +2089,9 @@ int get_ldnumber ( /* Returns logical drive number (-1:invalid drive) */ vol = (int)i; *path = ++tt; } - } else { /* No numeric drive number */ -#if _STR_VOLUME_ID /* Find string drive id */ - static const char* const str[] = {_VOLUME_STRS}; - const char *sp; - char c; - TCHAR tc; - + } +#if _STR_VOLUME_ID + else { /* No numeric drive number, find string drive id */ i = 0; tt++; do { sp = str[i]; tp = *path; @@ -2132,8 +2104,8 @@ int get_ldnumber ( /* Returns logical drive number (-1:invalid drive) */ vol = (int)i; *path = tt; } -#endif } +#endif return vol; } #if _FS_RPATH && _VOLUMES >= 2 @@ -2187,12 +2159,13 @@ FRESULT find_volume ( /* FR_OK(0): successful, !=0: any error occurred */ BYTE wmode /* !=0: Check write protection for write access */ ) { - BYTE fmt; + BYTE fmt, *pt; int vol; DSTATUS stat; - DWORD bsect, fasize, tsect, sysect, nclst, szbfat; + DWORD bsect, fasize, tsect, sysect, nclst, szbfat, br[4]; WORD nrsv; FATFS *fs; + UINT i; /* Get logical drive number from the path name */ @@ -2234,11 +2207,8 @@ FRESULT find_volume ( /* FR_OK(0): successful, !=0: any error occurred */ bsect = 0; fmt = check_fs(fs, bsect); /* Load sector 0 and check if it is an FAT boot sector as SFD */ if (fmt == 1 || (!fmt && (LD2PT(vol)))) { /* Not an FAT boot sector or forced partition number */ - UINT i; - DWORD br[4]; - for (i = 0; i < 4; i++) { /* Get partition offset */ - BYTE *pt = fs->win+MBR_Table + i * SZ_PTE; + pt = fs->win + MBR_Table + i * SZ_PTE; br[i] = pt[4] ? LD_DWORD(&pt[8]) : 0; } i = LD2PT(vol); /* Partition number: 0:auto, 1-4:forced */ @@ -2253,11 +2223,11 @@ FRESULT find_volume ( /* FR_OK(0): successful, !=0: any error occurred */ /* An FAT volume is found. Following code initializes the file system object */ - if (LD_WORD(fs->win+BPB_BytsPerSec) != SS(fs)) /* (BPB_BytsPerSec must be equal to the physical sector size) */ + if (LD_WORD(fs->win + BPB_BytsPerSec) != SS(fs)) /* (BPB_BytsPerSec must be equal to the physical sector size) */ return FR_NO_FILESYSTEM; - fasize = LD_WORD(fs->win+BPB_FATSz16); /* Number of sectors per FAT */ - if (!fasize) fasize = LD_DWORD(fs->win+BPB_FATSz32); + fasize = LD_WORD(fs->win + BPB_FATSz16); /* Number of sectors per FAT */ + if (!fasize) fasize = LD_DWORD(fs->win + BPB_FATSz32); fs->fsize = fasize; fs->n_fats = fs->win[BPB_NumFATs]; /* Number of FAT copies */ @@ -2269,18 +2239,18 @@ FRESULT find_volume ( /* FR_OK(0): successful, !=0: any error occurred */ if (!fs->csize || (fs->csize & (fs->csize - 1))) /* (Must be power of 2) */ return FR_NO_FILESYSTEM; - fs->n_rootdir = LD_WORD(fs->win+BPB_RootEntCnt); /* Number of root directory entries */ - if (fs->n_rootdir % (SS(fs) / SZ_DIR)) /* (Must be sector aligned) */ + fs->n_rootdir = LD_WORD(fs->win + BPB_RootEntCnt); /* Number of root directory entries */ + if (fs->n_rootdir % (SS(fs) / SZ_DIRE)) /* (Must be sector aligned) */ return FR_NO_FILESYSTEM; - tsect = LD_WORD(fs->win+BPB_TotSec16); /* Number of sectors on the volume */ - if (!tsect) tsect = LD_DWORD(fs->win+BPB_TotSec32); + tsect = LD_WORD(fs->win + BPB_TotSec16); /* Number of sectors on the volume */ + if (!tsect) tsect = LD_DWORD(fs->win + BPB_TotSec32); - nrsv = LD_WORD(fs->win+BPB_RsvdSecCnt); /* Number of reserved sectors */ + nrsv = LD_WORD(fs->win + BPB_RsvdSecCnt); /* Number of reserved sectors */ if (!nrsv) return FR_NO_FILESYSTEM; /* (Must not be 0) */ /* Determine the FAT sub type */ - sysect = nrsv + fasize + fs->n_rootdir / (SS(fs) / SZ_DIR); /* RSV+FAT+DIR */ + sysect = nrsv + fasize + fs->n_rootdir / (SS(fs) / SZ_DIRE); /* RSV + FAT + DIR */ if (tsect < sysect) return FR_NO_FILESYSTEM; /* (Invalid volume size) */ nclst = (tsect - sysect) / fs->csize; /* Number of clusters */ if (!nclst) return FR_NO_FILESYSTEM; /* (Invalid volume size) */ @@ -2295,7 +2265,7 @@ FRESULT find_volume ( /* FR_OK(0): successful, !=0: any error occurred */ fs->database = bsect + sysect; /* Data start sector */ if (fmt == FS_FAT32) { if (fs->n_rootdir) return FR_NO_FILESYSTEM; /* (BPB_RootEntCnt must be 0) */ - fs->dirbase = LD_DWORD(fs->win+BPB_RootClus); /* Root directory start cluster */ + fs->dirbase = LD_DWORD(fs->win + BPB_RootClus); /* Root directory start cluster */ szbfat = fs->n_fatent * 4; /* (Needed FAT size) */ } else { if (!fs->n_rootdir) return FR_NO_FILESYSTEM; /* (BPB_RootEntCnt must not be 0) */ @@ -2314,19 +2284,19 @@ FRESULT find_volume ( /* FR_OK(0): successful, !=0: any error occurred */ fs->fsi_flag = 0x80; #if (_FS_NOFSINFO & 3) != 3 if (fmt == FS_FAT32 /* Enable FSINFO only if FAT32 and BPB_FSInfo is 1 */ - && LD_WORD(fs->win+BPB_FSInfo) == 1 + && LD_WORD(fs->win + BPB_FSInfo) == 1 && move_window(fs, bsect + 1) == FR_OK) { fs->fsi_flag = 0; - if (LD_WORD(fs->win+BS_55AA) == 0xAA55 /* Load FSINFO data if available */ - && LD_DWORD(fs->win+FSI_LeadSig) == 0x41615252 - && LD_DWORD(fs->win+FSI_StrucSig) == 0x61417272) + if (LD_WORD(fs->win + BS_55AA) == 0xAA55 /* Load FSINFO data if available */ + && LD_DWORD(fs->win + FSI_LeadSig) == 0x41615252 + && LD_DWORD(fs->win + FSI_StrucSig) == 0x61417272) { #if (_FS_NOFSINFO & 1) == 0 - fs->free_clust = LD_DWORD(fs->win+FSI_Free_Count); + fs->free_clust = LD_DWORD(fs->win + FSI_Free_Count); #endif #if (_FS_NOFSINFO & 2) == 0 - fs->last_clust = LD_DWORD(fs->win+FSI_Nxt_Free); + fs->last_clust = LD_DWORD(fs->win + FSI_Nxt_Free); #endif } } @@ -2441,7 +2411,10 @@ FRESULT f_open ( FRESULT res; DIR dj; BYTE *dir; - DEF_NAMEBUF; + DEFINE_NAMEBUF; +#if !_FS_READONLY + DWORD dw, cl; +#endif if (!fp) return FR_INVALID_OBJECT; @@ -2470,8 +2443,6 @@ FRESULT f_open ( } /* Create or Open a file */ if (mode & (FA_CREATE_ALWAYS | FA_OPEN_ALWAYS | FA_CREATE_NEW)) { - DWORD dw, cl; - if (res != FR_OK) { /* No file, create new */ if (res == FR_NO_FILE) /* There is no file to open, create a new entry */ #if _FS_LOCK @@ -2492,9 +2463,9 @@ FRESULT f_open ( } if (res == FR_OK && (mode & FA_CREATE_ALWAYS)) { /* Truncate it if overwrite mode */ dw = GET_FATTIME(); /* Created time */ - ST_DWORD(dir+DIR_CrtTime, dw); + ST_DWORD(dir + DIR_CrtTime, dw); dir[DIR_Attr] = 0; /* Reset attribute */ - ST_DWORD(dir+DIR_FileSize, 0); /* size = 0 */ + ST_DWORD(dir + DIR_FileSize, 0);/* size = 0 */ cl = ld_clust(dj.fs, dir); /* Get start cluster */ st_clust(dir, 0); /* cluster = 0 */ dj.fs->wflag = 1; @@ -2546,7 +2517,7 @@ FRESULT f_open ( fp->flag = mode; /* File access mode */ fp->err = 0; /* Clear error flag */ fp->sclust = ld_clust(dj.fs, dir); /* File start cluster */ - fp->fsize = LD_DWORD(dir+DIR_FileSize); /* File size */ + fp->fsize = LD_DWORD(dir + DIR_FileSize); /* File size */ fp->fptr = 0; /* File pointer */ fp->dsect = 0; #if _USE_FASTSEEK @@ -2815,11 +2786,11 @@ FRESULT f_sync ( if (res == FR_OK) { dir = fp->dir_ptr; dir[DIR_Attr] |= AM_ARC; /* Set archive bit */ - ST_DWORD(dir+DIR_FileSize, fp->fsize); /* Update file size */ + ST_DWORD(dir + DIR_FileSize, fp->fsize); /* Update file size */ st_clust(dir, fp->sclust); /* Update start cluster */ tm = GET_FATTIME(); /* Update updated time */ - ST_DWORD(dir+DIR_WrtTime, tm); - ST_WORD(dir+DIR_LstAccDate, 0); + ST_DWORD(dir + DIR_WrtTime, tm); + ST_WORD(dir + DIR_LstAccDate, 0); fp->flag &= ~FA__WRITTEN; fp->fs->wflag = 1; res = sync_fs(fp->fs); @@ -2901,7 +2872,7 @@ FRESULT f_chdir ( { FRESULT res; DIR dj; - DEF_NAMEBUF; + DEFINE_NAMEBUF; /* Get logical drive number */ @@ -2939,7 +2910,7 @@ FRESULT f_getcwd ( DWORD ccl; TCHAR *tp; FILINFO fno; - DEF_NAMEBUF; + DEFINE_NAMEBUF; *buff = 0; @@ -3017,6 +2988,10 @@ FRESULT f_lseek ( ) { FRESULT res; + DWORD clst, bcs, nsect, ifptr; +#if _USE_FASTSEEK + DWORD cl, pcl, ncl, tcl, dsc, tlen, ulen, *tbl; +#endif res = validate(fp); /* Check validity of the object */ @@ -3026,8 +3001,6 @@ FRESULT f_lseek ( #if _USE_FASTSEEK if (fp->cltbl) { /* Fast seek */ - DWORD cl, pcl, ncl, tcl, dsc, tlen, ulen, *tbl; - if (ofs == CREATE_LINKMAP) { /* Create CLMT */ tbl = fp->cltbl; tlen = *tbl++; ulen = 2; /* Given table size and required table size */ @@ -3083,8 +3056,6 @@ FRESULT f_lseek ( /* Normal Seek */ { - DWORD clst, bcs, nsect, ifptr; - if (ofs > fp->fsize /* In read-only mode, clip offset with the file size */ #if !_FS_READONLY && !(fp->flag & FA_WRITE) @@ -3176,7 +3147,7 @@ FRESULT f_opendir ( { FRESULT res; FATFS* fs; - DEF_NAMEBUF; + DEFINE_NAMEBUF; if (!dp) return FR_INVALID_OBJECT; @@ -3263,7 +3234,7 @@ FRESULT f_readdir ( ) { FRESULT res; - DEF_NAMEBUF; + DEFINE_NAMEBUF; res = validate(dp); /* Check validity of the object */ @@ -3294,6 +3265,58 @@ FRESULT f_readdir ( +#if _USE_FIND +/*-----------------------------------------------------------------------*/ +/* Find next file */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_findnext ( + DIR* dp, /* Pointer to the open directory object */ + FILINFO* fno /* Pointer to the file information structure */ +) +{ + FRESULT res; + + + for (;;) { + res = f_readdir(dp, fno); /* Get a directory item */ + if (res != FR_OK || !fno || !fno->fname[0]) break; /* Terminate if any error or end of directory */ +#if _USE_LFN + if (fno->lfname && pattern_matching(dp->pat, fno->lfname, 0, 0)) break; /* Test for LFN if exist */ +#endif + if (pattern_matching(dp->pat, fno->fname, 0, 0)) break; /* Test for SFN */ + } + return res; + +} + + + +/*-----------------------------------------------------------------------*/ +/* Find first file */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_findfirst ( + DIR* dp, /* Pointer to the blank directory object */ + FILINFO* fno, /* Pointer to the file information structure */ + const TCHAR* path, /* Pointer to the directory to open */ + const TCHAR* pattern /* Pointer to the matching pattern */ +) +{ + FRESULT res; + + + dp->pat = pattern; /* Save pointer to pattern string */ + res = f_opendir(dp, path); /* Open the target directory */ + if (res == FR_OK) + res = f_findnext(dp, fno); /* Find the first item */ + return res; +} + +#endif /* _USE_FIND */ + + + #if _FS_MINIMIZE == 0 /*-----------------------------------------------------------------------*/ /* Get File Status */ @@ -3306,7 +3329,7 @@ FRESULT f_stat ( { FRESULT res; DIR dj; - DEF_NAMEBUF; + DEFINE_NAMEBUF; /* Get logical drive number */ @@ -3465,7 +3488,7 @@ FRESULT f_unlink ( DIR dj, sdj; BYTE *dir; DWORD dclst = 0; - DEF_NAMEBUF; + DEFINE_NAMEBUF; /* Get logical drive number */ @@ -3486,22 +3509,23 @@ FRESULT f_unlink ( if (dir[DIR_Attr] & AM_RDO) res = FR_DENIED; /* Cannot remove R/O object */ } - if (res == FR_OK && (dir[DIR_Attr] & AM_DIR)) { /* Is it a sub-dir? */ + if (res == FR_OK) { dclst = ld_clust(dj.fs, dir); - if (!dclst) { - res = FR_INT_ERR; - } else { /* Make sure the sub-directory is empty */ - mem_cpy(&sdj, &dj, sizeof (DIR)); - sdj.sclust = dclst; - res = dir_sdi(&sdj, 2); /* Exclude dot entries */ - if (res == FR_OK) { - res = dir_read(&sdj, 0); /* Read an item */ - if (res == FR_OK /* Not empty directory */ + if (dclst && (dir[DIR_Attr] & AM_DIR)) { /* Is it a sub-directory ? */ #if _FS_RPATH - || dclst == dj.fs->cdir /* or current directory */ + if (dclst == dj.fs->cdir) { /* Is it the current directory? */ + res = FR_DENIED; + } else #endif - ) res = FR_DENIED; - if (res == FR_NO_FILE) res = FR_OK; /* It is empty */ + { + mem_cpy(&sdj, &dj, sizeof (DIR)); /* Open the sub-directory */ + sdj.sclust = dclst; + res = dir_sdi(&sdj, 2); + if (res == FR_OK) { + res = dir_read(&sdj, 0); /* Read an item (excluding dot entries) */ + if (res == FR_OK) res = FR_DENIED; /* Not empty? (cannot remove) */ + if (res == FR_NO_FILE) res = FR_OK; /* Empty? (can remove) */ + } } } } @@ -3533,7 +3557,7 @@ FRESULT f_mkdir ( DIR dj; BYTE *dir, n; DWORD dsc, dcl, pcl, tm = GET_FATTIME(); - DEF_NAMEBUF; + DEFINE_NAMEBUF; /* Get logical drive number */ @@ -3556,16 +3580,16 @@ FRESULT f_mkdir ( dsc = clust2sect(dj.fs, dcl); dir = dj.fs->win; mem_set(dir, 0, SS(dj.fs)); - mem_set(dir+DIR_Name, ' ', 11); /* Create "." entry */ + mem_set(dir + DIR_Name, ' ', 11); /* Create "." entry */ dir[DIR_Name] = '.'; dir[DIR_Attr] = AM_DIR; - ST_DWORD(dir+DIR_WrtTime, tm); + ST_DWORD(dir + DIR_WrtTime, tm); st_clust(dir, dcl); - mem_cpy(dir+SZ_DIR, dir, SZ_DIR); /* Create ".." entry */ - dir[SZ_DIR+1] = '.'; pcl = dj.sclust; + mem_cpy(dir + SZ_DIRE, dir, SZ_DIRE); /* Create ".." entry */ + dir[SZ_DIRE + 1] = '.'; pcl = dj.sclust; if (dj.fs->fs_type == FS_FAT32 && pcl == dj.fs->dirbase) pcl = 0; - st_clust(dir+SZ_DIR, pcl); + st_clust(dir + SZ_DIRE, pcl); for (n = dj.fs->csize; n; n--) { /* Write dot entries and clear following sectors */ dj.fs->winsect = dsc++; dj.fs->wflag = 1; @@ -3580,7 +3604,7 @@ FRESULT f_mkdir ( } else { dir = dj.dir; dir[DIR_Attr] = AM_DIR; /* Attribute */ - ST_DWORD(dir+DIR_WrtTime, tm); /* Created time */ + ST_DWORD(dir + DIR_WrtTime, tm); /* Created time */ st_clust(dir, dcl); /* Table start cluster */ dj.fs->wflag = 1; res = sync_fs(dj.fs); @@ -3601,14 +3625,14 @@ FRESULT f_mkdir ( FRESULT f_chmod ( const TCHAR* path, /* Pointer to the file path */ - BYTE value, /* Attribute bits */ + BYTE attr, /* Attribute bits */ BYTE mask /* Attribute mask to change */ ) { FRESULT res; DIR dj; BYTE *dir; - DEF_NAMEBUF; + DEFINE_NAMEBUF; /* Get logical drive number */ @@ -3625,7 +3649,7 @@ FRESULT f_chmod ( res = FR_INVALID_NAME; } else { /* File or sub directory */ mask &= AM_RDO|AM_HID|AM_SYS|AM_ARC; /* Valid attribute mask */ - dir[DIR_Attr] = (value & mask) | (dir[DIR_Attr] & (BYTE)~mask); /* Apply attribute change */ + dir[DIR_Attr] = (attr & mask) | (dir[DIR_Attr] & (BYTE)~mask); /* Apply attribute change */ dj.fs->wflag = 1; res = sync_fs(dj.fs); } @@ -3651,7 +3675,7 @@ FRESULT f_rename ( DIR djo, djn; BYTE buf[21], *dir; DWORD dw; - DEF_NAMEBUF; + DEFINE_NAMEBUF; /* Get logical drive number of the source object */ @@ -3669,7 +3693,7 @@ FRESULT f_rename ( if (!djo.dir) { /* Is root dir? */ res = FR_NO_FILE; } else { - mem_cpy(buf, djo.dir+DIR_Attr, 21); /* Save the object information except name */ + mem_cpy(buf, djo.dir + DIR_Attr, 21); /* Save information about object except name */ mem_cpy(&djn, &djo, sizeof (DIR)); /* Duplicate the directory object */ if (get_ldnumber(&path_new) >= 0) /* Snip drive number off and ignore it */ res = follow_path(&djn, path_new); /* and make sure if new object name is not conflicting */ @@ -3677,20 +3701,20 @@ FRESULT f_rename ( res = FR_INVALID_DRIVE; if (res == FR_OK) res = FR_EXIST; /* The new object name is already existing */ if (res == FR_NO_FILE) { /* It is a valid path and no name collision */ -/* Start of critical section that any interruption can cause a cross-link */ res = dir_register(&djn); /* Register the new entry */ if (res == FR_OK) { - dir = djn.dir; /* Copy object information except name */ - mem_cpy(dir+13, buf+2, 19); +/* Start of critical section where any interruption can cause a cross-link */ + dir = djn.dir; /* Copy information about object except name */ + mem_cpy(dir + 13, buf + 2, 19); dir[DIR_Attr] = buf[0] | AM_ARC; djo.fs->wflag = 1; - if ((dir[DIR_Attr] & AM_DIR) && djo.sclust != djn.sclust) { /* Update .. entry in the directory if needed */ + if ((dir[DIR_Attr] & AM_DIR) && djo.sclust != djn.sclust) { /* Update .. entry in the sub-directory if needed */ dw = clust2sect(djo.fs, ld_clust(djo.fs, dir)); if (!dw) { res = FR_INT_ERR; } else { res = move_window(djo.fs, dw); - dir = djo.fs->win+SZ_DIR; /* .. entry */ + dir = djo.fs->win + SZ_DIRE * 1; /* Ptr to .. entry */ if (res == FR_OK && dir[1] == '.') { st_clust(dir, djn.sclust); djo.fs->wflag = 1; @@ -3702,8 +3726,8 @@ FRESULT f_rename ( if (res == FR_OK) res = sync_fs(djo.fs); } - } /* End of critical section */ + } } } } @@ -3728,7 +3752,7 @@ FRESULT f_utime ( FRESULT res; DIR dj; BYTE *dir; - DEF_NAMEBUF; + DEFINE_NAMEBUF; /* Get logical drive number */ @@ -3744,8 +3768,8 @@ FRESULT f_utime ( if (!dir) { /* Root directory */ res = FR_INVALID_NAME; } else { /* File or sub-directory */ - ST_WORD(dir+DIR_WrtTime, fno->ftime); - ST_WORD(dir+DIR_WrtDate, fno->fdate); + ST_WORD(dir + DIR_WrtTime, fno->ftime); + ST_WORD(dir + DIR_WrtDate, fno->fdate); dj.fs->wflag = 1; res = sync_fs(dj.fs); } @@ -3762,6 +3786,7 @@ FRESULT f_utime ( + #if _USE_LABEL /*-----------------------------------------------------------------------*/ /* Get volume label */ @@ -3776,6 +3801,9 @@ FRESULT f_getlabel ( FRESULT res; DIR dj; UINT i, j; +#if _USE_LFN && _LFN_UNICODE + WCHAR w; +#endif /* Get logical drive number */ @@ -3789,7 +3817,6 @@ FRESULT f_getlabel ( res = dir_read(&dj, 1); /* Get an entry with AM_VOL */ if (res == FR_OK) { /* A volume label is exist */ #if _USE_LFN && _LFN_UNICODE - WCHAR w; i = j = 0; do { w = (i < 11) ? dj.dir[i++] : ' '; @@ -3851,7 +3878,7 @@ FRESULT f_setlabel ( /* Create a volume label in directory form */ vn[0] = 0; for (sl = 0; label[sl]; sl++) ; /* Get name length */ - for ( ; sl && label[sl-1] == ' '; sl--) ; /* Remove trailing spaces */ + for ( ; sl && label[sl - 1] == ' '; sl--) ; /* Remove trailing spaces */ if (sl) { /* Create volume label in directory form */ i = j = 0; do { @@ -3877,7 +3904,8 @@ FRESULT f_setlabel ( if (w >= 0x100) vn[j++] = (BYTE)(w >> 8); vn[j++] = (BYTE)w; } while (i < sl); - while (j < 11) vn[j++] = ' '; + while (j < 11) vn[j++] = ' '; /* Fill remaining name field */ + if (vn[0] == DDEM) LEAVE_FF(dj.fs, FR_INVALID_NAME); /* Reject illegal name (heading DDEM) */ } /* Set volume label */ @@ -3889,9 +3917,9 @@ FRESULT f_setlabel ( if (vn[0]) { mem_cpy(dj.dir, vn, 11); /* Change the volume label name */ tm = GET_FATTIME(); - ST_DWORD(dj.dir+DIR_WrtTime, tm); + ST_DWORD(dj.dir + DIR_WrtTime, tm); } else { - dj.dir[0] = DDE; /* Remove the volume label */ + dj.dir[0] = DDEM; /* Remove the volume label */ } dj.fs->wflag = 1; res = sync_fs(dj.fs); @@ -3901,11 +3929,11 @@ FRESULT f_setlabel ( if (vn[0]) { /* Create volume label as new */ res = dir_alloc(&dj, 1); /* Allocate an entry for volume label */ if (res == FR_OK) { - mem_set(dj.dir, 0, SZ_DIR); /* Set volume label */ + mem_set(dj.dir, 0, SZ_DIRE); /* Set volume label */ mem_cpy(dj.dir, vn, 11); dj.dir[DIR_Attr] = AM_VOL; tm = GET_FATTIME(); - ST_DWORD(dj.dir+DIR_WrtTime, tm); + ST_DWORD(dj.dir + DIR_WrtTime, tm); dj.fs->wflag = 1; res = sync_fs(dj.fs); } @@ -3984,7 +4012,7 @@ FRESULT f_forward ( #if _USE_MKFS && !_FS_READONLY /*-----------------------------------------------------------------------*/ -/* Create File System on the Drive */ +/* Create file system on the logical drive */ /*-----------------------------------------------------------------------*/ #define N_ROOTDIR 512 /* Number of root directory entries for FAT12/16 */ #define N_FATS 1 /* Number of FATs (1 or 2) */ @@ -4006,6 +4034,9 @@ FRESULT f_mkfs ( DWORD n_vol, n_rsv, n_fat, n_dir; /* Size */ FATFS *fs; DSTATUS stat; +#if _USE_TRIM + DWORD eb[2]; +#endif /* Check mounted drive and clear work area */ @@ -4029,11 +4060,11 @@ FRESULT f_mkfs ( if (_MULTI_PARTITION && part) { /* Get partition information from partition table in the MBR */ if (disk_read(pdrv, fs->win, 0, 1) != RES_OK) return FR_DISK_ERR; - if (LD_WORD(fs->win+BS_55AA) != 0xAA55) return FR_MKFS_ABORTED; + if (LD_WORD(fs->win + BS_55AA) != 0xAA55) return FR_MKFS_ABORTED; tbl = &fs->win[MBR_Table + (part - 1) * SZ_PTE]; if (!tbl[4]) return FR_MKFS_ABORTED; /* No partition? */ - b_vol = LD_DWORD(tbl+8); /* Volume start sector */ - n_vol = LD_DWORD(tbl+12); /* Volume size */ + b_vol = LD_DWORD(tbl + 8); /* Volume start sector */ + n_vol = LD_DWORD(tbl + 12); /* Volume size */ } else { /* Create a partition in this function */ if (disk_ioctl(pdrv, GET_SECTOR_COUNT, &n_vol) != RES_OK || n_vol < 128) @@ -4067,7 +4098,7 @@ FRESULT f_mkfs ( n_fat = (fmt == FS_FAT12) ? (n_clst * 3 + 1) / 2 + 3 : (n_clst * 2) + 4; n_fat = (n_fat + SS(fs) - 1) / SS(fs); n_rsv = 1; - n_dir = (DWORD)N_ROOTDIR * SZ_DIR / SS(fs); + n_dir = (DWORD)N_ROOTDIR * SZ_DIRE / SS(fs); } b_fat = b_vol + n_rsv; /* FAT area start sector */ b_dir = b_fat + n_fat * N_FATS; /* Directory area start sector */ @@ -4114,7 +4145,7 @@ FRESULT f_mkfs ( md = 0xF0; } else { /* Create partition table (FDISK) */ mem_set(fs->win, 0, SS(fs)); - tbl = fs->win+MBR_Table; /* Create partition table for single partition in the drive */ + tbl = fs->win + MBR_Table; /* Create partition table for single partition in the drive */ tbl[1] = 1; /* Partition start head */ tbl[2] = 1; /* Partition start sector */ tbl[3] = 0; /* Partition start cylinder */ @@ -4123,9 +4154,9 @@ FRESULT f_mkfs ( n = (b_vol + n_vol) / 63 / 255; tbl[6] = (BYTE)(n >> 2 | 63); /* Partition end sector */ tbl[7] = (BYTE)n; /* End cylinder */ - ST_DWORD(tbl+8, 63); /* Partition start in LBA */ - ST_DWORD(tbl+12, n_vol); /* Partition size in LBA */ - ST_WORD(fs->win+BS_55AA, 0xAA55); /* MBR signature */ + ST_DWORD(tbl + 8, 63); /* Partition start in LBA */ + ST_DWORD(tbl + 12, n_vol); /* Partition size in LBA */ + ST_WORD(fs->win + BS_55AA, 0xAA55); /* MBR signature */ if (disk_write(pdrv, fs->win, 0, 1) != RES_OK) /* Write it to the MBR */ return FR_DISK_ERR; md = 0xF8; @@ -4137,42 +4168,42 @@ FRESULT f_mkfs ( mem_set(tbl, 0, SS(fs)); mem_cpy(tbl, "\xEB\xFE\x90" "MSDOS5.0", 11);/* Boot jump code, OEM name */ i = SS(fs); /* Sector size */ - ST_WORD(tbl+BPB_BytsPerSec, i); + ST_WORD(tbl + BPB_BytsPerSec, i); tbl[BPB_SecPerClus] = (BYTE)au; /* Sectors per cluster */ - ST_WORD(tbl+BPB_RsvdSecCnt, n_rsv); /* Reserved sectors */ + ST_WORD(tbl + BPB_RsvdSecCnt, n_rsv); /* Reserved sectors */ tbl[BPB_NumFATs] = N_FATS; /* Number of FATs */ i = (fmt == FS_FAT32) ? 0 : N_ROOTDIR; /* Number of root directory entries */ - ST_WORD(tbl+BPB_RootEntCnt, i); + ST_WORD(tbl + BPB_RootEntCnt, i); if (n_vol < 0x10000) { /* Number of total sectors */ - ST_WORD(tbl+BPB_TotSec16, n_vol); + ST_WORD(tbl + BPB_TotSec16, n_vol); } else { - ST_DWORD(tbl+BPB_TotSec32, n_vol); + ST_DWORD(tbl + BPB_TotSec32, n_vol); } tbl[BPB_Media] = md; /* Media descriptor */ - ST_WORD(tbl+BPB_SecPerTrk, 63); /* Number of sectors per track */ - ST_WORD(tbl+BPB_NumHeads, 255); /* Number of heads */ - ST_DWORD(tbl+BPB_HiddSec, b_vol); /* Hidden sectors */ + ST_WORD(tbl + BPB_SecPerTrk, 63); /* Number of sectors per track */ + ST_WORD(tbl + BPB_NumHeads, 255); /* Number of heads */ + ST_DWORD(tbl + BPB_HiddSec, b_vol); /* Hidden sectors */ n = GET_FATTIME(); /* Use current time as VSN */ if (fmt == FS_FAT32) { - ST_DWORD(tbl+BS_VolID32, n); /* VSN */ - ST_DWORD(tbl+BPB_FATSz32, n_fat); /* Number of sectors per FAT */ - ST_DWORD(tbl+BPB_RootClus, 2); /* Root directory start cluster (2) */ - ST_WORD(tbl+BPB_FSInfo, 1); /* FSINFO record offset (VBR+1) */ - ST_WORD(tbl+BPB_BkBootSec, 6); /* Backup boot record offset (VBR+6) */ + ST_DWORD(tbl + BS_VolID32, n); /* VSN */ + ST_DWORD(tbl + BPB_FATSz32, n_fat); /* Number of sectors per FAT */ + ST_DWORD(tbl + BPB_RootClus, 2); /* Root directory start cluster (2) */ + ST_WORD(tbl + BPB_FSInfo, 1); /* FSINFO record offset (VBR + 1) */ + ST_WORD(tbl + BPB_BkBootSec, 6); /* Backup boot record offset (VBR + 6) */ tbl[BS_DrvNum32] = 0x80; /* Drive number */ tbl[BS_BootSig32] = 0x29; /* Extended boot signature */ - mem_cpy(tbl+BS_VolLab32, "NO NAME " "FAT32 ", 19); /* Volume label, FAT signature */ + mem_cpy(tbl + BS_VolLab32, "NO NAME " "FAT32 ", 19); /* Volume label, FAT signature */ } else { - ST_DWORD(tbl+BS_VolID, n); /* VSN */ - ST_WORD(tbl+BPB_FATSz16, n_fat); /* Number of sectors per FAT */ + ST_DWORD(tbl + BS_VolID, n); /* VSN */ + ST_WORD(tbl + BPB_FATSz16, n_fat); /* Number of sectors per FAT */ tbl[BS_DrvNum] = 0x80; /* Drive number */ tbl[BS_BootSig] = 0x29; /* Extended boot signature */ - mem_cpy(tbl+BS_VolLab, "NO NAME " "FAT ", 19); /* Volume label, FAT signature */ + mem_cpy(tbl + BS_VolLab, "NO NAME " "FAT ", 19); /* Volume label, FAT signature */ } - ST_WORD(tbl+BS_55AA, 0xAA55); /* Signature (Offset is fixed here regardless of sector size) */ + ST_WORD(tbl + BS_55AA, 0xAA55); /* Signature (Offset is fixed here regardless of sector size) */ if (disk_write(pdrv, tbl, b_vol, 1) != RES_OK) /* Write it to the VBR sector */ return FR_DISK_ERR; - if (fmt == FS_FAT32) /* Write backup VBR if needed (VBR+6) */ + if (fmt == FS_FAT32) /* Write backup VBR if needed (VBR + 6) */ disk_write(pdrv, tbl, b_vol + 6, 1); /* Initialize FAT area */ @@ -4182,12 +4213,12 @@ FRESULT f_mkfs ( n = md; /* Media descriptor byte */ if (fmt != FS_FAT32) { n |= (fmt == FS_FAT12) ? 0x00FFFF00 : 0xFFFFFF00; - ST_DWORD(tbl+0, n); /* Reserve cluster #0-1 (FAT12/16) */ + ST_DWORD(tbl + 0, n); /* Reserve cluster #0-1 (FAT12/16) */ } else { n |= 0xFFFFFF00; - ST_DWORD(tbl+0, n); /* Reserve cluster #0-1 (FAT32) */ - ST_DWORD(tbl+4, 0xFFFFFFFF); - ST_DWORD(tbl+8, 0x0FFFFFFF); /* Reserve cluster #2 for root directory */ + ST_DWORD(tbl + 0, n); /* Reserve cluster #0-1 (FAT32) */ + ST_DWORD(tbl + 4, 0xFFFFFFFF); + ST_DWORD(tbl + 8, 0x0FFFFFFF); /* Reserve cluster #2 for root directory */ } if (disk_write(pdrv, tbl, wsect++, 1) != RES_OK) return FR_DISK_ERR; @@ -4207,8 +4238,6 @@ FRESULT f_mkfs ( #if _USE_TRIM /* Erase data area if needed */ { - DWORD eb[2]; - eb[0] = wsect; eb[1] = wsect + (n_clst - ((fmt == FS_FAT32) ? 1 : 0)) * au - 1; disk_ioctl(pdrv, CTRL_TRIM, eb); } @@ -4216,13 +4245,13 @@ FRESULT f_mkfs ( /* Create FSINFO if needed */ if (fmt == FS_FAT32) { - ST_DWORD(tbl+FSI_LeadSig, 0x41615252); - ST_DWORD(tbl+FSI_StrucSig, 0x61417272); - ST_DWORD(tbl+FSI_Free_Count, n_clst - 1); /* Number of free clusters */ - ST_DWORD(tbl+FSI_Nxt_Free, 2); /* Last allocated cluster# */ - ST_WORD(tbl+BS_55AA, 0xAA55); - disk_write(pdrv, tbl, b_vol + 1, 1); /* Write original (VBR+1) */ - disk_write(pdrv, tbl, b_vol + 7, 1); /* Write backup (VBR+7) */ + ST_DWORD(tbl + FSI_LeadSig, 0x41615252); + ST_DWORD(tbl + FSI_StrucSig, 0x61417272); + ST_DWORD(tbl + FSI_Free_Count, n_clst - 1); /* Number of free clusters */ + ST_DWORD(tbl + FSI_Nxt_Free, 2); /* Last allocated cluster# */ + ST_WORD(tbl + BS_55AA, 0xAA55); + disk_write(pdrv, tbl, b_vol + 1, 1); /* Write original (VBR + 1) */ + disk_write(pdrv, tbl, b_vol + 7, 1); /* Write backup (VBR + 7) */ } return (disk_ioctl(pdrv, CTRL_SYNC, 0) == RES_OK) ? FR_OK : FR_DISK_ERR; @@ -4232,7 +4261,7 @@ FRESULT f_mkfs ( #if _MULTI_PARTITION /*-----------------------------------------------------------------------*/ -/* Divide Physical Drive */ +/* Create partition table on the physical drive */ /*-----------------------------------------------------------------------*/ FRESULT f_fdisk ( @@ -4380,6 +4409,7 @@ TCHAR* f_gets ( + #if !_FS_READONLY #include /*-----------------------------------------------------------------------*/ diff --git a/src/ff.h b/src/ff.h index 5ee7262..22f1810 100644 --- a/src/ff.h +++ b/src/ff.h @@ -1,21 +1,23 @@ /*---------------------------------------------------------------------------/ -/ FatFs - FAT file system module include file R0.10c (C)ChaN, 2014 +/ FatFs - FAT file system module include R0.11 (C)ChaN, 2015 /----------------------------------------------------------------------------/ -/ FatFs module is a generic FAT file system module for small embedded systems. -/ This is a free software that opened for education, research and commercial -/ developments under license policy of following terms. +/ FatFs module is a free software that opened under license policy of +/ following conditions. / -/ Copyright (C) 2014, ChaN, all right reserved. +/ Copyright (C) 2015, ChaN, all right reserved. / -/ * The FatFs module is a free software and there is NO WARRANTY. -/ * No restriction on use. You can use, modify and redistribute it for -/ personal, non-profit or commercial product UNDER YOUR RESPONSIBILITY. -/ * Redistributions of source code must retain the above copyright notice. +/ 1. Redistributions of source code must retain the above copyright notice, +/ this condition and the following disclaimer. / -/----------------------------------------------------------------------------*/ +/ This software is provided by the copyright holder and contributors "AS IS" +/ and any warranties related to this software are DISCLAIMED. +/ The copyright owner or contributors be NOT LIABLE for any damages caused +/ by use of this software. +/---------------------------------------------------------------------------*/ + #ifndef _FATFS -#define _FATFS 80376 /* Revision ID */ +#define _FATFS 32020 /* Revision ID */ #ifdef __cplusplus extern "C" { @@ -154,11 +156,14 @@ typedef struct { WCHAR* lfn; /* Pointer to the LFN working buffer */ WORD lfn_idx; /* Last matched LFN index number (0xFFFF:No LFN) */ #endif +#if _USE_FIND + const TCHAR* pat; /* Pointer to the name matching pattern */ +#endif } DIR; -/* File status structure (FILINFO) */ +/* File information structure (FILINFO) */ typedef struct { DWORD fsize; /* File size */ @@ -215,11 +220,13 @@ FRESULT f_sync (FIL* fp); /* Flush cached data of a writing file */ FRESULT f_opendir (DIR* dp, const TCHAR* path); /* Open a directory */ FRESULT f_closedir (DIR* dp); /* Close an open directory */ FRESULT f_readdir (DIR* dp, FILINFO* fno); /* Read a directory item */ +FRESULT f_findfirst (DIR* dp, FILINFO* fno, const TCHAR* path, const TCHAR* pattern); /* Find first file */ +FRESULT f_findnext (DIR* dp, FILINFO* fno); /* Find next file */ FRESULT f_mkdir (const TCHAR* path); /* Create a sub directory */ FRESULT f_unlink (const TCHAR* path); /* Delete an existing file or directory */ FRESULT f_rename (const TCHAR* path_old, const TCHAR* path_new); /* Rename/Move a file or directory */ FRESULT f_stat (const TCHAR* path, FILINFO* fno); /* Get file status */ -FRESULT f_chmod (const TCHAR* path, BYTE value, BYTE mask); /* Change attribute of the file/dir */ +FRESULT f_chmod (const TCHAR* path, BYTE attr, BYTE mask); /* Change attribute of the file/dir */ FRESULT f_utime (const TCHAR* path, const FILINFO* fno); /* Change times-tamp of the file/dir */ FRESULT f_chdir (const TCHAR* path); /* Change current directory */ FRESULT f_chdrive (const TCHAR* path); /* Change current drive */ @@ -239,6 +246,8 @@ TCHAR* f_gets (TCHAR* buff, int len, FIL* fp); /* Get a string from the fil #define f_error(fp) ((fp)->err) #define f_tell(fp) ((fp)->fptr) #define f_size(fp) ((fp)->fsize) +#define f_rewind(fp) f_lseek((fp), 0) +#define f_rewinddir(dp) f_readdir((dp), 0) #ifndef EOF #define EOF (-1) diff --git a/src/ffconf.h b/src/ffconf.h index 34d3f55..7ac4f44 100644 --- a/src/ffconf.h +++ b/src/ffconf.h @@ -1,8 +1,8 @@ /*---------------------------------------------------------------------------/ -/ FatFs - FAT file system module configuration file R0.10c (C)ChaN, 2014 +/ FatFs - FAT file system module configuration file R0.11 (C)ChaN, 2015 /---------------------------------------------------------------------------*/ -#define _FFCONF 80376 /* Revision ID */ +#define _FFCONF 32020 /* Revision ID */ /*---------------------------------------------------------------------------/ / Functions and Buffer Configurations @@ -18,13 +18,13 @@ #define _FS_READONLY 0 /* This option switches read-only configuration. (0:Read/Write or 1:Read-only) -/ Read-only configuration removes basic writing API functions, f_write(), -/ f_sync(), f_unlink(), f_mkdir(), f_chmod(), f_rename(), f_truncate(), -/ f_getfree() and optional writing functions as well. */ +/ Read-only configuration removes writing API functions, f_write(), f_sync(), +/ f_unlink(), f_mkdir(), f_chmod(), f_rename(), f_truncate(), f_getfree() +/ and optional writing functions as well. */ #define _FS_MINIMIZE 0 -/* This option defines minimization level to remove some API functions. +/* This option defines minimization level to remove some basic API functions. / / 0: All basic functions are enabled. / 1: f_stat(), f_getfree(), f_unlink(), f_mkdir(), f_chmod(), f_utime(), @@ -42,9 +42,13 @@ / 2: Enable with LF-CRLF conversion. */ +#define _USE_FIND 0 +/* This option switches filtered directory read feature and related functions, +/ f_findfirst() and f_findnext(). (0:Disable or 1:Enable) */ + + #define _USE_MKFS 0 -/* This option switches f_mkfs() function. (0:Disable or 1:Enable) -/ To enable it, also _FS_READONLY need to be set to 0. */ +/* This option switches f_mkfs() function. (0:Disable or 1:Enable) */ #define _USE_FASTSEEK 0 @@ -57,8 +61,8 @@ #define _USE_FORWARD 0 -/* This option switches f_forward() function. (0:Disable or 1:Enable) */ -/* To enable it, also _FS_TINY need to be set to 1. */ +/* This option switches f_forward() function. (0:Disable or 1:Enable) +/ To enable it, also _FS_TINY need to be set to 1. */ /*---------------------------------------------------------------------------/ @@ -69,32 +73,24 @@ /* This option specifies the OEM code page to be used on the target system. / Incorrect setting of the code page can cause a file open failure. / -/ 932 - Japanese Shift_JIS (DBCS, OEM, Windows) -/ 936 - Simplified Chinese GBK (DBCS, OEM, Windows) -/ 949 - Korean (DBCS, OEM, Windows) -/ 950 - Traditional Chinese Big5 (DBCS, OEM, Windows) -/ 1250 - Central Europe (Windows) -/ 1251 - Cyrillic (Windows) -/ 1252 - Latin 1 (Windows) -/ 1253 - Greek (Windows) -/ 1254 - Turkish (Windows) -/ 1255 - Hebrew (Windows) -/ 1256 - Arabic (Windows) -/ 1257 - Baltic (Windows) -/ 1258 - Vietnam (OEM, Windows) -/ 437 - U.S. (OEM) -/ 720 - Arabic (OEM) -/ 737 - Greek (OEM) -/ 775 - Baltic (OEM) -/ 850 - Multilingual Latin 1 (OEM) -/ 858 - Multilingual Latin 1 + Euro (OEM) -/ 852 - Latin 2 (OEM) -/ 855 - Cyrillic (OEM) -/ 866 - Russian (OEM) -/ 857 - Turkish (OEM) -/ 862 - Hebrew (OEM) -/ 874 - Thai (OEM, Windows) -/ 1 - ASCII (No extended character. Valid for only non-LFN configuration.) */ +/ 1 - ASCII (No extended character. Non-LFN cfg. only) +/ 437 - U.S. +/ 720 - Arabic +/ 737 - Greek +/ 775 - Baltic +/ 850 - Multilingual Latin 1 +/ 852 - Latin 2 +/ 855 - Cyrillic +/ 857 - Turkish +/ 858 - Multilingual Latin 1 + Euro +/ 862 - Hebrew +/ 866 - Russian +/ 874 - Thai +/ 932 - Japanese Shift_JIS (DBCS) +/ 936 - Simplified Chinese GBK (DBCS) +/ 949 - Korean (DBCS) +/ 950 - Traditional Chinese Big5 (DBCS) +*/ #define _USE_LFN 0 @@ -163,7 +159,7 @@ / number is bound to the same physical drive number and only an FAT volume found on / the physical drive will be mounted. When multi-partition feature is enabled (1), / each logical drive number is bound to arbitrary physical drive and partition -/ listed in the VolToPart[]. Also f_fdisk() funciton will be enabled. */ +/ listed in the VolToPart[]. Also f_fdisk() funciton will be available. */ #define _MIN_SS 512 @@ -200,9 +196,9 @@ /---------------------------------------------------------------------------*/ #define _FS_NORTC 0 -#define _NORTC_MON 11 -#define _NORTC_MDAY 9 -#define _NORTC_YEAR 2014 +#define _NORTC_MON 2 +#define _NORTC_MDAY 1 +#define _NORTC_YEAR 2015 /* The _FS_NORTC option switches timestamp feature. If the system does not have / an RTC function or valid timestamp is not needed, set _FS_NORTC to 1 to disable / the timestamp feature. All objects modified by FatFs will have a fixed timestamp @@ -242,7 +238,8 @@ / / 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.. */ +/ SemaphoreHandle_t and etc.. A header file for O/S definitions needs to be +/ included somewhere in the scope of ff.c. */ #define _WORD_ACCESS 0 @@ -258,13 +255,17 @@ / If it is the case, _WORD_ACCESS can also be set to 1 to reduce code size. / Following table shows allowable settings of some processor types. / -/ ARM7TDMI 0 ColdFire 0 V850E 0 -/ Cortex-M3 0 Z80 0/1 V850ES 0/1 -/ Cortex-M0 0 x86 0/1 TLCS-870 0/1 -/ AVR 0/1 RX600(LE) 0/1 TLCS-900 0/1 -/ AVR32 0 RL78 0 R32C 0 -/ PIC18 0/1 SH-2 0 M16C 0/1 -/ PIC24 0 H8S 0 MSP430 0 -/ PIC32 0 H8/300H 0 8051 0/1 +/ ARM7TDMI 0 *2 ColdFire 0 *1 V850E 0 *2 +/ Cortex-M3 0 *3 Z80 0/1 V850ES 0/1 +/ Cortex-M0 0 *2 x86 0/1 TLCS-870 0/1 +/ AVR 0/1 RX600(LE) 0/1 TLCS-900 0/1 +/ AVR32 0 *1 RL78 0 *2 R32C 0 *2 +/ PIC18 0/1 SH-2 0 *1 M16C 0/1 +/ PIC24 0 *2 H8S 0 *1 MSP430 0 *2 +/ PIC32 0 *1 H8/300H 0 *1 8051 0/1 +/ +/ *1:Big-endian. +/ *2:Unaligned memory access is not supported. +/ *3:Some compilers generate LDM/STM for mem_cpy function. */ diff --git a/src/history.txt b/src/history.txt new file mode 100644 index 0000000..b101820 --- /dev/null +++ b/src/history.txt @@ -0,0 +1,180 @@ +---------------------------------------------------------------------------- + Revision history of FatFs module +---------------------------------------------------------------------------- + +R0.00 (February 26, 2006) + Prototype. + + +R0.01 (April 29, 2006) + First stable version. + + +R0.02 (June 01, 2006) + Added FAT12 support. + Removed unbuffered mode. + Fixed a problem on small (<32M) partition. + + +R0.02a (June 10, 2006) + Added a configuration option (_FS_MINIMUM). + + +R0.03 (September 22, 2006) + Added f_rename(). + Changed option _FS_MINIMUM to _FS_MINIMIZE. + + +R0.03a (December 11, 2006) + Improved cluster scan algorithm to write files fast. + Fixed f_mkdir() creates incorrect directory on FAT32. + + +R0.04 (February 04, 2007) + Added f_mkfs(). + Supported multiple drive system. + Changed some interfaces for multiple drive system. + Changed f_mountdrv() to f_mount(). + + +R0.04a (April 01, 2007) + Supported multiple partitions on a physical drive. + Added a capability of extending file size to f_lseek(). + Added minimization level 3. + Fixed an endian sensitive code in f_mkfs(). + + +R0.04b (May 05, 2007) + Added a configuration option _USE_NTFLAG. + Added FSINFO support. + Fixed DBCS name can result FR_INVALID_NAME. + Fixed short seek (<= csize) collapses the file object. + + +R0.05 (August 25, 2007) + Changed arguments of f_read(), f_write() and f_mkfs(). + Fixed f_mkfs() on FAT32 creates incorrect FSINFO. + Fixed f_mkdir() on FAT32 creates incorrect directory. + + +R0.05a (February 03, 2008) + Added f_truncate() and f_utime(). + Fixed off by one error at FAT sub-type determination. + Fixed btr in f_read() can be mistruncated. + Fixed cached sector is not flushed when create and close without write. + + +R0.06 (April 01, 2008) + Added fputc(), fputs(), fprintf() and fgets(). + Improved performance of f_lseek() on moving to the same or following cluster. + + +R0.07 (April 01, 2009) + Merged Tiny-FatFs as a configuration option. (_FS_TINY) + Added long file name feature. (_USE_LFN) + Added multiple code page feature. (_CODE_PAGE) + Added re-entrancy for multitask operation. (_FS_REENTRANT) + Added auto cluster size selection to f_mkfs(). + Added rewind option to f_readdir(). + Changed result code of critical errors. + Renamed string functions to avoid name collision. + + +R0.07a (April 14, 2009) + Septemberarated out OS dependent code on reentrant cfg. + Added multiple sector size feature. + + +R0.07c (June 21, 2009) + Fixed f_unlink() can return FR_OK on error. + Fixed wrong cache control in f_lseek(). + Added relative path feature. + Added f_chdir() and f_chdrive(). + Added proper case conversion to extended character. + + +R0.07e (November 03, 2009) + Septemberarated out configuration options from ff.h to ffconf.h. + Fixed f_unlink() fails to remove a sub-directory on _FS_RPATH. + Fixed name matching error on the 13 character boundary. + Added a configuration option, _LFN_UNICODE. + Changed f_readdir() to return the SFN with always upper case on non-LFN cfg. + + +R0.08 (May 15, 2010) + Added a memory configuration option. (_USE_LFN = 3) + Added file lock feature. (_FS_SHARE) + Added fast seek feature. (_USE_FASTSEEK) + Changed some types on the API, XCHAR->TCHAR. + Changed .fname in the FILINFO structure on Unicode cfg. + String functions support UTF-8 encoding files on Unicode cfg. + + +R0.08a (August 16, 2010) + Added f_getcwd(). (_FS_RPATH = 2) + Added sector erase feature. (_USE_ERASE) + Moved file lock semaphore table from fs object to the bss. + Fixed f_mkfs() creates wrong FAT32 volume. + + +R0.08b (January 15, 2011) + Fast seek feature is also applied to f_read() and f_write(). + f_lseek() reports required table size on creating CLMP. + Extended format syntax of f_printf(). + Ignores duplicated directory separators in given path name. + + +R0.09 (September 06, 2011) + f_mkfs() supports multiple partition to complete the multiple partition feature. + Added f_fdisk(). + + +R0.09a (August 27, 2012) + Changed f_open() and f_opendir() reject null object pointer to avoid crash. + Changed option name _FS_SHARE to _FS_LOCK. + Fixed assertion failure due to OS/2 EA on FAT12/16 volume. + + +R0.09b (January 24, 2013) + Added f_setlabel() and f_getlabel(). + + +R0.10 (October 02, 2013) + Added selection of character encoding on the file. (_STRF_ENCODE) + Added f_closedir(). + Added forced full FAT scan for f_getfree(). (_FS_NOFSINFO) + Added forced mount feature with changes of f_mount(). + Improved behavior of volume auto detection. + Improved write throughput of f_puts() and f_printf(). + Changed argument of f_chdrive(), f_mkfs(), disk_read() and disk_write(). + Fixed f_write() can be truncated when the file size is close to 4GB. + Fixed f_open(), f_mkdir() and f_setlabel() can return incorrect error code. + + +R0.10a (January 15, 2014) + Added arbitrary strings as drive number in the path name. (_STR_VOLUME_ID) + Added a configuration option of minimum sector size. (_MIN_SS) + 2nd argument of f_rename() can have a drive number and it will be ignored. + Fixed f_mount() with forced mount fails when drive number is >= 1. (appeared at R0.10) + Fixed f_close() invalidates the file object without volume lock. + Fixed f_closedir() returns but the volume lock is left acquired. (appeared at R0.10) + Fixed creation of an entry with LFN fails on too many SFN collisions. (appeared at R0.07) + + +R0.10b (May 19, 2014) + Fixed a hard error in the disk I/O layer can collapse the directory entry. + Fixed LFN entry is not deleted on delete/rename an object with lossy converted SFN. (appeared at R0.07) + + +R0.10c (November 09, 2014) + Added a configuration option for the platforms without RTC. (_FS_NORTC) + Changed option name _USE_ERASE to _USE_TRIM. + Fixed volume label created by Mac OS X cannot be retrieved with f_getlabel(). (appeared at R0.09b) + Fixed a potential problem of FAT access that can appear on disk error. + Fixed null pointer dereference on attempting to delete the root direcotry. (appeared at R0.08) + + +R0.11 (February 09, 2015) + Added f_findfirst(), f_findnext() and f_findclose(). (_USE_FIND) + Fixed f_unlink() does not remove cluster chain of the file. (appeared at R0.10c) + Fixed _FS_NORTC option does not work properly. (appeared at R0.10c) diff --git a/src/option/unicode.c b/src/option/unicode.c index 8b41fc2..0afe13e 100644 --- a/src/option/unicode.c +++ b/src/option/unicode.c @@ -10,7 +10,7 @@ #include "cc949.c" #elif _CODE_PAGE == 950 /* Traditional Chinese Big5 */ #include "cc950.c" -#else /* Small character-set */ +#else /* Single Byte Character-Set */ #include "ccsbcs.c" #endif