From 9acb379950c8de5a5b565221ac97ad09f026d7e9 Mon Sep 17 00:00:00 2001 From: Christopher Williams Date: Wed, 11 Mar 2015 10:25:52 -0700 Subject: [PATCH] FatFs R0.11, released Febrary 9, 2015 --- README.md | 18 +- doc/00index_e.html | 102 ++++--- doc/00index_j.html | 103 ++++--- doc/css_e.css | 1 + doc/css_j.css | 3 +- doc/en/appnote.html | 208 +++++++------ doc/en/chdir.html | 2 +- doc/en/chdrive.html | 2 +- doc/en/chmod.html | 2 +- doc/en/close.html | 2 +- doc/en/closedir.html | 2 +- doc/en/dinit.html | 4 +- doc/en/dioctl.html | 10 +- doc/en/dread.html | 6 +- 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 | 21 +- doc/en/findfirst.html | 119 ++++++++ doc/en/findnext.html | 69 +++++ doc/en/forward.html | 4 +- doc/en/getcwd.html | 2 +- doc/en/getfree.html | 2 +- doc/en/gets.html | 6 +- doc/en/lseek.html | 6 +- doc/en/mkdir.html | 2 +- doc/en/mkfs.html | 17 +- doc/en/mount.html | 12 +- doc/en/open.html | 6 +- doc/en/opendir.html | 2 +- doc/en/printf.html | 6 +- doc/en/putc.html | 10 +- doc/en/puts.html | 10 +- doc/en/rc.html | 8 +- doc/en/readdir.html | 8 +- 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 | 4 +- doc/en/tell.html | 2 +- doc/en/truncate.html | 2 +- doc/en/unlink.html | 2 +- doc/en/utime.html | 2 +- doc/img/app3.c | 2 +- doc/img/f6.png | Bin 1436 -> 1464 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 | 146 +++++---- doc/ja/dinit.html | 4 +- doc/ja/dioctl.html | 10 +- doc/ja/dread.html | 8 +- doc/ja/dstat.html | 2 +- doc/ja/dwrite.html | 6 +- doc/ja/eof.html | 2 +- doc/ja/error.html | 2 +- doc/ja/filename.html | 23 +- doc/ja/findfirst.html | 119 ++++++++ doc/ja/findnext.html | 69 +++++ doc/ja/forward.html | 2 +- doc/ja/gets.html | 4 +- doc/ja/lseek.html | 6 +- 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 | 4 +- doc/ja/readdir.html | 8 +- 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 | 4 +- doc/ja/unlink.html | 9 +- src/00readme.txt | 166 +---------- src/diskio.c | 12 +- src/ff.c | 673 ++++++++++++++++++++++-------------------- src/ff.h | 35 ++- src/ffconf.h | 76 +++-- src/history.txt | 180 +++++++++++ src/option/unicode.c | 2 +- 95 files changed, 1494 insertions(+), 1031 deletions(-) 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/findfirst.html create mode 100644 doc/ja/findnext.html create mode 100644 src/history.txt diff --git a/README.md b/README.md index da158ed..c584ada 100644 --- a/README.md +++ b/README.md @@ -7,15 +7,15 @@ systems", by ChaN. See http://elm-chan.org/fsw/ff/00index_e.html. License ======= -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. +FatFs module is a free software that opened under license policy of +following conditions. -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. +Copyright (C) 2015, ChaN, all right reserved. +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. diff --git a/doc/00index_e.html b/doc/00index_e.html index 9dc9d8e..d1e3e23 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

-

いずれも書き込み中や操作の対象でないファイルには影響はありません。これらのクリチカル セクションは、ファイルを書き込みモードで開いている時間を最小限にするか、f_sync()を適宜使用することで図5のようにリスクを最小化することができます。

+

いずれも書き込み中や操作の対象でないファイルには影響はありません。これらのクリチカル セクションは、ファイルを書き込みモードで開いている時間を最小限にするか、f_sync関数を適宜使用することで図5のようにリスクを最小化することができます。

-
+

APIの拡張的使用例

FatFs APIの拡張的使用例です。有用なコードがあった場合は、随時追加していきます。。

    @@ -256,25 +240,27 @@ _FS_LOCK 0 (Disable file lock control)
-
+

FatFsのライセンスについて

-

ソース ファイルのヘッダにライセンス条件が記述されているので、利用の際はそれに従うこと。英語を読めない方のために以下に日本語訳を示しておきます。

-
/*----------------------------------------------------------------------------/
-/  FatFs - FAT file system module  R0.10b                   (C)ChaN, 2014
+

ソース ファイルにライセンス条件が記述されているので、利用の際はそれに従うこと。原文は英語ですが、参考までに以下に日本語訳を示しておきます。

+
+/*----------------------------------------------------------------------------/
+/  FatFs - FAT file system module  R0.11                 (C)ChaN, 2015
 /-----------------------------------------------------------------------------/
-/ FatFsモジュールは、小規模な組み込みシステム向けの汎用FATファイルシステム 
-/ モジュールです。これはフリー ソフトウェアとして、教育・研究・開発のために
-/ 以下のライセンス ポリシーの下で公開されています。
+/ FatFsモジュールはフリーソフトウェアで、次に示す条件の下に公開されています。
 /
-/  Copyright (C) 2014, ChaN, all right reserved.
+/ Copyright (C) 2015, ChaN, all right reserved.
 /
-/ * FatFsモジュールはフリー ソフトウェアであり、また無保証です。
-/ * 用途に制限はありません。あなたの責任の下において、個人的・非営利的な
-/   ものから商用製品の開発に及ぶ目的に使用・改変・再配布することができます。
-/ * ソース コードを再配布するときは、上記の著作権表示を保持しなければなりません。
-/
-/-----------------------------------------------------------------------------/
-

要するにFatFsはタダで自由に使えるということです。ソース コードを再配布するときは、このブロックをそのまま保持しておくこと。このようにFatFsはBSDライクなライセンスとしていますが、一つ大きな違いがあります。特に組み込み用途での利用価値を高めるため、バイナリ形式(ソース コードを含まない形式全て)での再配布については、条件は設けていません。その場合は、FatFsおよびそのライセンス文書についてはドキュメントに明記してもしなくてもかまいません。これは、一条項BSDライセンスと等価ということです。もちろんGNU GPLプロジェクトとも共存可能です。何らかの変更を加えて再配布する際は、矛盾しない他のライセンス(GNU GPLや修正BSDライセンスなど)に変更することも可能です。

+/ 1. ソースコードで再配布するときは、その中に上記の著作権表示、この条文、および +/ 次の免責事項を保持すること +/ +/ このソフトウェアは、著作権者らおよびコントリビューターらによって現状のまま +/ 提供されており、いかなる保証もありません。 +/ 著作権者もコントリビューターも、このソフトウェアの使用により発生するいかなる +/ 損害についても、責任を負いません。 +/----------------------------------------------------------------------------*/ +
+

このようにFatFsはBSDライクなライセンスとしていますが、一つ大きな違いがあります。FatFsは主に組み込み向けとして開発されたため、バイナリ形式(ソース コードを含まない形式全て)での再配布については、商用での使いやすさを考慮して配布時の条件を設けていません。つまり、バイナリ配布の場合は、FatFsおよびそのライセンス文書についてドキュメントに明記してもしなくてもかまいません。これは、一条項BSDライセンスと等価ということです。もちろん、GNU GPLなどほとんど全てのオープン ソース ライセンスの下のプロジェクトにおいて共存可能です。FatFsに何らかの修正や拡張を加えてソース コードで再配布する場合は、矛盾しない他のオープン ソース ライセンス(GNU GPLや修正BSDライセンスなど)に変更することも可能です。

戻る

diff --git a/doc/ja/dinit.html b/doc/ja/dinit.html index 6329150..73b171f 100644 --- a/doc/ja/dinit.html +++ b/doc/ja/dinit.html @@ -32,13 +32,13 @@ DSTATUS disk_initialize (

戻り値

-

この関数は戻り値としてディスク ステータスを返します。ディスク ステータスの詳細に関してはdisk_status()を参照してください。

+

この関数は戻り値としてディスク ステータスを返します。ディスク ステータスの詳細に関してはdisk_status関数を参照してください。

解説

ストレージ デバイスを初期化し、データの読み書きなど全ての動作が可能な状態にします。関数が成功すると、戻り値のSTA_NOINITフラグがクリアされます。

-

アプリケーションからはこの関数を呼び出してはなりません。さもないと、FATボリュームが破壊される可能性があります。エラー等により再初期化が必要なときは、f_mount()を使用してください。FatFsモジュールは、自動マウント動作により、必要に応じてこの関数を呼び出します。

+

アプリケーションからはこの関数を呼び出してはなりません。さもないと、FATボリュームが破壊される可能性があります。エラー等により再初期化が必要なときは、f_mount関数を使用してください。FatFsモジュールは、自動マウント動作により、必要に応じてこの関数を呼び出します。

戻る

diff --git a/doc/ja/dioctl.html b/doc/ja/dioctl.html index 120d798..32d8704 100644 --- a/doc/ja/dioctl.html +++ b/doc/ja/dioctl.html @@ -27,7 +27,7 @@ DRESULT disk_ioctl (

引数

pdrv
-
対象のデバイスを示す物理ドライブ番号(0-9)が指定されます。
+
対象のデバイスを識別する物理ドライブ番号(0-9)が指定されます。
cmd
制御コマンド コードが指定されます。
buff
@@ -55,10 +55,10 @@ DRESULT disk_ioctl ( - - + + - +
標準ioctlコマンド
コマンド解説
CTRL_SYNCデバイスのデータ書き込み処理を完了させます。ドライバがライト バック キャッシュなどを持っている場合は、書き込まれていないデータを即時書き込みます。メディア上への書き込みがそれぞれdisk_write()の中で完了する場合は、このコマンドに対してすることはありません。
GET_SECTOR_COUNT総セクタ数の取得。buffの指すDWORD型変数にドライブ上の総セクタ数を返します。f_mkfs()およびf_fdisk()内から呼び出され、作成するボリュームのサイズを決定するために使用されます。
CTRL_SYNCデバイスのデータ書き込み処理を完了させます。ドライバがライト バック キャッシュなどを持っている場合は、書き込まれていないデータを即時書き込みます。メディア上への書き込みがそれぞれdisk_write関数の中で完了する場合は、このコマンドに対してすることはありません。
GET_SECTOR_COUNT総セクタ数の取得。buffの指すDWORD型変数にドライブ上の総セクタ数を返します。f_mkfs, f_fdisk関数内から呼び出され、作成するボリュームのサイズを決定するために使用されます。
GET_SECTOR_SIZEセクタ サイズの取得。buffの指すWORD型変数にドライブのセクタ サイズを返します。有効値は512、1024、2048または4096です。セクタ サイズが固定(_MAX_SS ==_MIN_SS)のときはこのコマンドは使われることはなく、デバイスは常にそのセクタ サイズで動作しなければなりません。
GET_BLOCK_SIZE消去ブロック サイズの取得。buffの指すDWORD型変数にフラッシュ メモリの消去ブロック サイズ(セクタ単位)を返します。1から32768の範囲で2の累乗の値でなければなりません。ブロック サイズ不明またはフラッシュ メモリ以外のデバイスでは1を返します。f_mkfs()内でのみ使用され、作成されるボリュームのデータ領域はこの境界にアライメントされます。
GET_BLOCK_SIZE消去ブロック サイズの取得。buffの指すDWORD型変数にフラッシュ メモリの消去ブロック サイズ(セクタ単位)を返します。1から32768の範囲で2の累乗の値でなければなりません。ブロック サイズ不明またはフラッシュ メモリ以外のデバイスでは1を返します。f_mkfs関数内でのみ使用され、作成されるボリュームのデータ領域はこの境界にアライメントされます。
CTRL_TRIM不必要セクタの通知。buffの指すDWORD型配列には不必要になった領域 {開始セクタ,終了セクタ} を指定して呼び出されます。TRIM機能が有効(_USE_TRIM == 1)で、クラスタが解放されるとき、およびフォーマット時に呼び出されます。これは、ATAコマンド セットのTrimコマンドと等価で、この機能をサポートしないデバイスは何もする必要はありません。また、戻り値はチェックされず、結果によってFatFsの動作が影響を受けることはありません。
@@ -68,7 +68,7 @@ DRESULT disk_ioctl ( コマンド解説 CTRL_FORMATメディアの物理フォーマットを行います。buffはNULLでないとき、進行表示のためのコールバック関数のアドレスを示します。 CTRL_POWER_IDLEデバイスをアイドル状態にします。通常の読み書き要求でアクティブ状態に戻るなら、STA_NOINITフラグをセットする必要はありません。 -CTRL_POWER_OFFデバイスをシャットダウン状態にします。STA_NOINITはセットされます。デバイスはdisk_initialize()でアクティブ状態に戻ります。 +CTRL_POWER_OFFデバイスをシャットダウン状態にします。STA_NOINITはセットされます。デバイスはdisk_initialize関数でアクティブ状態に戻ります。 CTRL_LOCKユーザによるメディアの取り出しを禁止します。 CTRL_UNLOCKユーザによるメディアの取り出しを許可します。 CTRL_EJECTメディアを排出します。完了後、STA_NOINITSTA_NODISKフラグはセットされます。 diff --git a/doc/ja/dread.html b/doc/ja/dread.html index 2dac64e..3487ada 100644 --- a/doc/ja/dread.html +++ b/doc/ja/dread.html @@ -28,7 +28,7 @@ DRESULT disk_read (

引数

pdrv
-
対象のデバイスを示す物理ドライブ番号(0-9)が指定されます。シングル ドライブ システムでは、常に0が指定されます。
+
対象のデバイスを識別する物理ドライブ番号(0-9)が指定されます。シングル ドライブ システムでは、常に0が指定されます。
buff
ストレージ デバイスから読み出したデータを格納するバイト配列が指定されます。
sector
@@ -56,12 +56,12 @@ DRESULT disk_read (

解説

-

ストレージ デバイスに対するデータの読み書きは、セクタ単位で行われます。FatFsでは512~4096バイトのセクタ サイズをサポートします。固定セクタ サイズ構成(_MIN_SS == MAX_SS)のときは、暗黙的にそのセクタ サイズで動作しなければなりません。可変セクタ サイズ構成(_MIN_SS < MAX_SS)

のときは、初期化後disk_ioctl()でセクタ サイズを問い合わせてくるので、それに対して正しい値を返す必要があります。 +

ストレージ デバイスに対するデータの読み書きは、セクタ単位で行われます。FatFsでは512~4096バイトのセクタ サイズをサポートします。固定セクタ サイズ構成(_MIN_SS == MAX_SS)のときは、暗黙的にそのセクタ サイズで動作しなければなりません。可変セクタ サイズ構成(_MIN_SS < MAX_SS)のときは、disk_initialize関数に続いてdisk_ioctl関数でセクタ サイズを問い合わせてくるので、それに対して正しい値を返す必要があります。

buffBYTE型なので、指定されるアドレスは常にワード アライメントされているとは限りません。非アライメント アドレスへの転送は、直接転送において発生することがあります。もしも、ハードウェア上の制約でそのような転送が不可能なときは、この関数内で二段転送するなどして解決するか、または別の方法で対応しなければなりません。次にいくつかの対応方法を示します(いずれか一つでOK)。

  • この関数内で解決する - 推奨
  • -
  • f_read()において、セクタ全体を含む転送を避ける - 直接転送が発生しない
  • -
  • f_read(fp, buff, btr, &br)において、(((UINT)buff & 3) == (f_tell(fp) & 3))を満足させる - buffのワード アライメントが保証される
  • +
  • 全てのf_read関数において、セクタ全体を含む転送を避ける - 直接転送が発生しない
  • +
  • f_read(fp, buff, btr, &br)関数において、(((UINT)buff & 3) == (f_tell(fp) & 3))を満足させる - buffのワード アライメントが保証される

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

diff --git a/doc/ja/dstat.html b/doc/ja/dstat.html index 6a30944..f965649 100644 --- a/doc/ja/dstat.html +++ b/doc/ja/dstat.html @@ -35,7 +35,7 @@ DSTATUS disk_status (

現在のストレージ デバイスの状態を次のフラグの組み合わせ値で返します。

STA_NOINIT
-
デバイスが初期化されていないことを示すフラグ。システム リセットやメディアの取り外し等でセットされ、disk_initialize()の正常終了でクリア、失敗でセットされます。メディア交換は非同期に発生するイベントなので、過去にメディア交換があった場合もこのフラグに反映させる必要があります。FatFsモジュールは、このフラグを参照してマウント動作が必要かどうかを判断します。
+
デバイスが初期化されていないことを示すフラグ。システム リセットやメディアの取り外し等でセットされ、disk_initialize関数の正常終了でクリア、失敗でセットされます。メディア交換は非同期に発生するイベントなので、過去にメディア交換があった場合もこのフラグに反映させる必要があります。FatFsモジュールは、このフラグを参照してマウント動作が必要かどうかを判断します。
STA_NODISK
メディアが存在しないことを示すフラグ。メディアが取り外されている間はセットされ、セットされている間はクリアされます。固定ディスクでは常にクリアします。なお、このフラグはFatFsモジュールでは参照されません。
STA_PROTECT
diff --git a/doc/ja/dwrite.html b/doc/ja/dwrite.html index 15d4ead..1fd8567 100644 --- a/doc/ja/dwrite.html +++ b/doc/ja/dwrite.html @@ -28,7 +28,7 @@ DRESULT disk_write (

引数

pdrv
-
対象のデバイスを示す物理ドライブ番号(0-9)が指定されます。
+
対象のデバイスを識別する物理ドライブ番号(0-9)が指定されます。
buff
ストレージ デバイスに書き込むセクタ データが格納されたバイト配列が指定されます。バイト数は、セクタ サイズ*countとなります。
sector
@@ -58,9 +58,9 @@ DRESULT disk_write (

解説

-

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 b9098b3..40e9d63 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 bb01d80..2a9f2ab 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/filename.html b/doc/ja/filename.html index 524566c..fed7af8 100644 --- a/doc/ja/filename.html +++ b/doc/ja/filename.html @@ -11,14 +11,14 @@

パス名のフォーマット

-
+

ファイル ディレクトリ名

-

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

+

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

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

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関数で設定された値となります。

@@ -36,10 +36,16 @@

また、_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,8 +53,7 @@
 
-


-
+

ボリューム管理

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

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

diff --git a/doc/ja/findfirst.html b/doc/ja/findfirst.html new file mode 100644 index 0000000..e806dba --- /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..8da1ce9 --- /dev/null +++ b/doc/ja/findnext.html @@ -0,0 +1,69 @@ + + + + + + + + +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 e9212ce..0b1255a 100644 --- a/doc/ja/forward.html +++ b/doc/ja/forward.html @@ -114,7 +114,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/gets.html b/doc/ja/gets.html index 74e0b22..45cafb3 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 88e1ab2..9098afb 100644 --- a/doc/ja/lseek.html +++ b/doc/ja/lseek.html @@ -49,13 +49,13 @@ 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となります。

+

_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となります。

diff --git a/doc/ja/mkdir.html b/doc/ja/mkdir.html index 63da707..5e92469 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 19b4341..ba83fcf 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 d465edb..783b535 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 c308398..016341d 100644 --- a/doc/ja/open.html +++ b/doc/ja/open.html @@ -37,7 +37,7 @@ FRESULT f_open (
- +
パス名の例_FS_RPATH == 0_FS_RPATH == 1
file.txtドライブ0のルート ディレクトリ下のファイルカレント ドライブのカレント ディレクトリ下のファイル
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 ae40984..15009b9 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 4de1da2..439146d 100644 --- a/doc/ja/printf.html +++ b/doc/ja/printf.html @@ -45,7 +45,7 @@ int f_printf (

解説

-

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

+

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

diff --git a/doc/ja/sfatfs.html b/doc/ja/sfatfs.html index 93b9e7c..fd7405d 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 5da60f9..f5f7025 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 a9167f1..108e332 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 d75ffc3..5762f7a 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 4b594d6..906b59e 100644 --- a/doc/ja/sync.html +++ b/doc/ja/sync.html @@ -45,8 +45,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/unlink.html b/doc/ja/unlink.html index 3ae691a..d9b631b 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/src/00readme.txt b/src/00readme.txt index b30f7d3..70994ed 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 169ae95..82200ad 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 733025c..e4199c3 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 @@ -471,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) */ @@ -485,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 */ @@ -517,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 @@ -525,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 @@ -830,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); @@ -877,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; @@ -932,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; @@ -1159,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 */ @@ -1171,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; } @@ -1192,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 */ @@ -1206,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 */ @@ -1240,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; } @@ -1269,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 */ @@ -1297,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; } @@ -1312,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 @@ -1338,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 */ @@ -1351,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 */ @@ -1373,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 */ @@ -1382,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; } @@ -1407,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; @@ -1416,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 */ } @@ -1440,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++) { @@ -1534,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 */ @@ -1591,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 */ @@ -1609,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 */ @@ -1687,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 */ @@ -1722,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 */ @@ -1736,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; } } @@ -1762,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 */ @@ -1787,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; @@ -1815,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 */ @@ -1849,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 */ @@ -1863,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) ? '.' : ' '; @@ -1873,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--; } @@ -1915,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 { @@ -1936,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 */ @@ -1998,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? */ @@ -2015,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) */ @@ -2104,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 */ @@ -2116,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; @@ -2135,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 @@ -2190,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 */ @@ -2237,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 */ @@ -2256,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 */ @@ -2272,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) */ @@ -2298,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) */ @@ -2317,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 } } @@ -2444,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; @@ -2473,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 @@ -2495,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; @@ -2549,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 @@ -2818,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); @@ -2904,7 +2872,7 @@ FRESULT f_chdir ( { FRESULT res; DIR dj; - DEF_NAMEBUF; + DEFINE_NAMEBUF; /* Get logical drive number */ @@ -2942,7 +2910,7 @@ FRESULT f_getcwd ( DWORD ccl; TCHAR *tp; FILINFO fno; - DEF_NAMEBUF; + DEFINE_NAMEBUF; *buff = 0; @@ -3020,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 */ @@ -3029,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 */ @@ -3086,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) @@ -3179,7 +3147,7 @@ FRESULT f_opendir ( { FRESULT res; FATFS* fs; - DEF_NAMEBUF; + DEFINE_NAMEBUF; if (!dp) return FR_INVALID_OBJECT; @@ -3266,7 +3234,7 @@ FRESULT f_readdir ( ) { FRESULT res; - DEF_NAMEBUF; + DEFINE_NAMEBUF; res = validate(dp); /* Check validity of the object */ @@ -3297,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 */ @@ -3309,7 +3329,7 @@ FRESULT f_stat ( { FRESULT res; DIR dj; - DEF_NAMEBUF; + DEFINE_NAMEBUF; /* Get logical drive number */ @@ -3468,7 +3488,7 @@ FRESULT f_unlink ( DIR dj, sdj; BYTE *dir; DWORD dclst = 0; - DEF_NAMEBUF; + DEFINE_NAMEBUF; /* Get logical drive number */ @@ -3491,21 +3511,20 @@ FRESULT f_unlink ( } if (res == FR_OK) { dclst = ld_clust(dj.fs, dir); - if (dir[DIR_Attr] & AM_DIR) { /* Is it a sub-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) */ } } } @@ -3538,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 */ @@ -3561,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; @@ -3585,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); @@ -3606,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 */ @@ -3630,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); } @@ -3656,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 */ @@ -3674,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 */ @@ -3682,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; @@ -3707,8 +3726,8 @@ FRESULT f_rename ( if (res == FR_OK) res = sync_fs(djo.fs); } - } /* End of critical section */ + } } } } @@ -3733,7 +3752,7 @@ FRESULT f_utime ( FRESULT res; DIR dj; BYTE *dir; - DEF_NAMEBUF; + DEFINE_NAMEBUF; /* Get logical drive number */ @@ -3749,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); } @@ -3767,6 +3786,7 @@ FRESULT f_utime ( + #if _USE_LABEL /*-----------------------------------------------------------------------*/ /* Get volume label */ @@ -3781,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 */ @@ -3794,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++] : ' '; @@ -3856,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 { @@ -3882,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 */ @@ -3894,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); @@ -3906,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); } @@ -3989,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) */ @@ -4011,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 */ @@ -4034,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) @@ -4072,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 */ @@ -4119,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 */ @@ -4128,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; @@ -4142,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 */ @@ -4187,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; @@ -4212,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); } @@ -4221,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; @@ -4237,7 +4261,7 @@ FRESULT f_mkfs ( #if _MULTI_PARTITION /*-----------------------------------------------------------------------*/ -/* Divide Physical Drive */ +/* Create partition table on the physical drive */ /*-----------------------------------------------------------------------*/ FRESULT f_fdisk ( @@ -4385,6 +4409,7 @@ TCHAR* f_gets ( + #if !_FS_READONLY #include /*-----------------------------------------------------------------------*/ diff --git a/src/ff.h b/src/ff.h index 5eaad5f..28537b6 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 f968d7e..4dc4beb 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 diff --git a/src/history.txt b/src/history.txt new file mode 100644 index 0000000..b00f58c --- /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 22e0320..170e2e0 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