33#if FF_DEFINED != 86631
34#error Wrong include file (ff.h).
39#define MAX_DIR 0x200000
40#define MAX_DIR_EX 0x10000000
41#define MAX_FAT12 0xFF5
42#define MAX_FAT16 0xFFF5
43#define MAX_FAT32 0x0FFFFFF5
44#define MAX_EXFAT 0x7FFFFFFD
48#define IsUpper(c) ((c) >= 'A' && (c) <= 'Z')
49#define IsLower(c) ((c) >= 'a' && (c) <= 'z')
50#define IsDigit(c) ((c) >= '0' && (c) <= '9')
51#define IsSeparator(c) ((c) == '/' || (c) == '\\')
52#define IsTerminator(c) ((UINT)(c) < (FF_USE_LFN ? ' ' : '!'))
53#define IsSurrogate(c) ((c) >= 0xD800 && (c) <= 0xDFFF)
54#define IsSurrogateH(c) ((c) >= 0xD800 && (c) <= 0xDBFF)
55#define IsSurrogateL(c) ((c) >= 0xDC00 && (c) <= 0xDFFF)
59#define FA_SEEKEND 0x20
60#define FA_MODIFIED 0x40
87#define ET_FILEDIR 0x85
89#define ET_FILENAME 0xC1
97#define BPB_BytsPerSec 11
98#define BPB_SecPerClus 13
99#define BPB_RsvdSecCnt 14
100#define BPB_NumFATs 16
101#define BPB_RootEntCnt 17
102#define BPB_TotSec16 19
104#define BPB_FATSz16 22
105#define BPB_SecPerTrk 24
106#define BPB_NumHeads 26
107#define BPB_HiddSec 28
108#define BPB_TotSec32 32
114#define BS_FilSysType 54
115#define BS_BootCode 62
118#define BPB_FATSz32 36
119#define BPB_ExtFlags32 40
120#define BPB_FSVer32 42
121#define BPB_RootClus32 44
122#define BPB_FSInfo32 48
123#define BPB_BkBootSec32 50
124#define BS_DrvNum32 64
126#define BS_BootSig32 66
128#define BS_VolLab32 71
129#define BS_FilSysType32 82
130#define BS_BootCode32 90
132#define BPB_ZeroedEx 11
133#define BPB_VolOfsEx 64
134#define BPB_TotSecEx 72
135#define BPB_FatOfsEx 80
136#define BPB_FatSzEx 84
137#define BPB_DataOfsEx 88
138#define BPB_NumClusEx 92
139#define BPB_RootClusEx 96
140#define BPB_VolIDEx 100
141#define BPB_FSVerEx 104
142#define BPB_VolFlagEx 106
143#define BPB_BytsPerSecEx 108
144#define BPB_SecPerClusEx 109
145#define BPB_NumFATsEx 110
146#define BPB_DrvNumEx 111
147#define BPB_PercInUseEx 112
148#define BPB_RsvdEx 113
149#define BS_BootCodeEx 120
154#define DIR_CrtTime10 13
155#define DIR_CrtTime 14
156#define DIR_LstAccDate 18
157#define DIR_FstClusHI 20
158#define DIR_ModTime 22
159#define DIR_FstClusLO 26
160#define DIR_FileSize 28
164#define LDIR_Chksum 13
165#define LDIR_FstClusLO 26
167#define XDIR_NumLabel 1
169#define XDIR_CaseSum 4
173#define XDIR_CrtTime 8
174#define XDIR_ModTime 12
175#define XDIR_AccTime 16
176#define XDIR_CrtTime10 20
177#define XDIR_ModTime10 21
181#define XDIR_GenFlags 33
182#define XDIR_NumName 35
183#define XDIR_NameHash 36
184#define XDIR_ValidFileSize 40
185#define XDIR_FstClus 52
186#define XDIR_FileSize 56
194#define FSI_StrucSig 484
195#define FSI_Free_Count 488
196#define FSI_Nxt_Free 492
215#define GPTH_CurLba 24
216#define GPTH_BakLba 32
217#define GPTH_FstLba 40
218#define GPTH_LstLba 48
219#define GPTH_DskGuid 56
222#define GPTH_PteSize 84
226#define GPTE_UpGuid 16
227#define GPTE_FstLba 32
228#define GPTE_LstLba 40
234#define ABORT(fs, res) { fp->err = (BYTE)(res); LEAVE_FF(fs, res); }
240#error Static LFN work area cannot be used in thread-safe configuration
242#define LEAVE_FF(fs, res) { unlock_fs(fs, res); return res; }
244#define LEAVE_FF(fs, res) return res
249#if FF_MULTI_PARTITION
250#define LD2PD(vol) VolToPart[vol].pd
251#define LD2PT(vol) VolToPart[vol].pt
253#define LD2PD(vol) (BYTE)(vol)
259#if (FF_MAX_SS < FF_MIN_SS) || (FF_MAX_SS != 512 && FF_MAX_SS != 1024 && FF_MAX_SS != 2048 && FF_MAX_SS != 4096) || (FF_MIN_SS != 512 && FF_MIN_SS != 1024 && FF_MIN_SS != 2048 && FF_MIN_SS != 4096)
260#error Wrong sector size configuration
262#if FF_MAX_SS == FF_MIN_SS
263#define SS(fs) ((UINT)FF_MAX_SS)
265#define SS(fs) ((fs)->ssize)
271#if FF_NORTC_YEAR < 1980 || FF_NORTC_YEAR > 2107 || FF_NORTC_MON < 1 || FF_NORTC_MON > 12 || FF_NORTC_MDAY < 1 || FF_NORTC_MDAY > 31
272#error Invalid FF_FS_NORTC settings
274#define GET_FATTIME() ((DWORD)(FF_NORTC_YEAR - 1980) << 25 | (DWORD)FF_NORTC_MON << 21 | (DWORD)FF_NORTC_MDAY << 16)
276#define GET_FATTIME() get_fattime()
283#error FF_FS_LOCK must be 0 at read-only configuration
295#define TBL_CT437 {0x80,0x9A,0x45,0x41,0x8E,0x41,0x8F,0x80,0x45,0x45,0x45,0x49,0x49,0x49,0x8E,0x8F, \
296 0x90,0x92,0x92,0x4F,0x99,0x4F,0x55,0x55,0x59,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \
297 0x41,0x49,0x4F,0x55,0xA5,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF, \
298 0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
299 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, \
300 0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
301 0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF, \
302 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
303#define TBL_CT720 {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F, \
304 0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \
305 0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF, \
306 0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
307 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, \
308 0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
309 0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF, \
310 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
311#define TBL_CT737 {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F, \
312 0x90,0x92,0x92,0x93,0x94,0x95,0x96,0x97,0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87, \
313 0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0xAA,0x92,0x93,0x94,0x95,0x96, \
314 0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
315 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, \
316 0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
317 0x97,0xEA,0xEB,0xEC,0xE4,0xED,0xEE,0xEF,0xF5,0xF0,0xEA,0xEB,0xEC,0xED,0xEE,0xEF, \
318 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
319#define TBL_CT771 {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F, \
320 0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \
321 0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F, \
322 0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
323 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, \
324 0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDC,0xDE,0xDE, \
325 0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \
326 0xF0,0xF0,0xF2,0xF2,0xF4,0xF4,0xF6,0xF6,0xF8,0xF8,0xFA,0xFA,0xFC,0xFC,0xFE,0xFF}
327#define TBL_CT775 {0x80,0x9A,0x91,0xA0,0x8E,0x95,0x8F,0x80,0xAD,0xED,0x8A,0x8A,0xA1,0x8D,0x8E,0x8F, \
328 0x90,0x92,0x92,0xE2,0x99,0x95,0x96,0x97,0x97,0x99,0x9A,0x9D,0x9C,0x9D,0x9E,0x9F, \
329 0xA0,0xA1,0xE0,0xA3,0xA3,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF, \
330 0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
331 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, \
332 0xB5,0xB6,0xB7,0xB8,0xBD,0xBE,0xC6,0xC7,0xA5,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
333 0xE0,0xE1,0xE2,0xE3,0xE5,0xE5,0xE6,0xE3,0xE8,0xE8,0xEA,0xEA,0xEE,0xED,0xEE,0xEF, \
334 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
335#define TBL_CT850 {0x43,0x55,0x45,0x41,0x41,0x41,0x41,0x43,0x45,0x45,0x45,0x49,0x49,0x49,0x41,0x41, \
336 0x45,0x92,0x92,0x4F,0x4F,0x4F,0x55,0x55,0x59,0x4F,0x55,0x4F,0x9C,0x4F,0x9E,0x9F, \
337 0x41,0x49,0x4F,0x55,0xA5,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF, \
338 0xB0,0xB1,0xB2,0xB3,0xB4,0x41,0x41,0x41,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
339 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0x41,0x41,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, \
340 0xD1,0xD1,0x45,0x45,0x45,0x49,0x49,0x49,0x49,0xD9,0xDA,0xDB,0xDC,0xDD,0x49,0xDF, \
341 0x4F,0xE1,0x4F,0x4F,0x4F,0x4F,0xE6,0xE8,0xE8,0x55,0x55,0x55,0x59,0x59,0xEE,0xEF, \
342 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
343#define TBL_CT852 {0x80,0x9A,0x90,0xB6,0x8E,0xDE,0x8F,0x80,0x9D,0xD3,0x8A,0x8A,0xD7,0x8D,0x8E,0x8F, \
344 0x90,0x91,0x91,0xE2,0x99,0x95,0x95,0x97,0x97,0x99,0x9A,0x9B,0x9B,0x9D,0x9E,0xAC, \
345 0xB5,0xD6,0xE0,0xE9,0xA4,0xA4,0xA6,0xA6,0xA8,0xA8,0xAA,0x8D,0xAC,0xB8,0xAE,0xAF, \
346 0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBD,0xBF, \
347 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC6,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, \
348 0xD1,0xD1,0xD2,0xD3,0xD2,0xD5,0xD6,0xD7,0xB7,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
349 0xE0,0xE1,0xE2,0xE3,0xE3,0xD5,0xE6,0xE6,0xE8,0xE9,0xE8,0xEB,0xED,0xED,0xDD,0xEF, \
350 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xEB,0xFC,0xFC,0xFE,0xFF}
351#define TBL_CT855 {0x81,0x81,0x83,0x83,0x85,0x85,0x87,0x87,0x89,0x89,0x8B,0x8B,0x8D,0x8D,0x8F,0x8F, \
352 0x91,0x91,0x93,0x93,0x95,0x95,0x97,0x97,0x99,0x99,0x9B,0x9B,0x9D,0x9D,0x9F,0x9F, \
353 0xA1,0xA1,0xA3,0xA3,0xA5,0xA5,0xA7,0xA7,0xA9,0xA9,0xAB,0xAB,0xAD,0xAD,0xAE,0xAF, \
354 0xB0,0xB1,0xB2,0xB3,0xB4,0xB6,0xB6,0xB8,0xB8,0xB9,0xBA,0xBB,0xBC,0xBE,0xBE,0xBF, \
355 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC7,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, \
356 0xD1,0xD1,0xD3,0xD3,0xD5,0xD5,0xD7,0xD7,0xDD,0xD9,0xDA,0xDB,0xDC,0xDD,0xE0,0xDF, \
357 0xE0,0xE2,0xE2,0xE4,0xE4,0xE6,0xE6,0xE8,0xE8,0xEA,0xEA,0xEC,0xEC,0xEE,0xEE,0xEF, \
358 0xF0,0xF2,0xF2,0xF4,0xF4,0xF6,0xF6,0xF8,0xF8,0xFA,0xFA,0xFC,0xFC,0xFD,0xFE,0xFF}
359#define TBL_CT857 {0x80,0x9A,0x90,0xB6,0x8E,0xB7,0x8F,0x80,0xD2,0xD3,0xD4,0xD8,0xD7,0x49,0x8E,0x8F, \
360 0x90,0x92,0x92,0xE2,0x99,0xE3,0xEA,0xEB,0x98,0x99,0x9A,0x9D,0x9C,0x9D,0x9E,0x9E, \
361 0xB5,0xD6,0xE0,0xE9,0xA5,0xA5,0xA6,0xA6,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF, \
362 0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
363 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC7,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, \
364 0xD0,0xD1,0xD2,0xD3,0xD4,0x49,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
365 0xE0,0xE1,0xE2,0xE3,0xE5,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xDE,0xED,0xEE,0xEF, \
366 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
367#define TBL_CT860 {0x80,0x9A,0x90,0x8F,0x8E,0x91,0x86,0x80,0x89,0x89,0x92,0x8B,0x8C,0x98,0x8E,0x8F, \
368 0x90,0x91,0x92,0x8C,0x99,0xA9,0x96,0x9D,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \
369 0x86,0x8B,0x9F,0x96,0xA5,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF, \
370 0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
371 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, \
372 0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
373 0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF, \
374 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
375#define TBL_CT861 {0x80,0x9A,0x90,0x41,0x8E,0x41,0x8F,0x80,0x45,0x45,0x45,0x8B,0x8B,0x8D,0x8E,0x8F, \
376 0x90,0x92,0x92,0x4F,0x99,0x8D,0x55,0x97,0x97,0x99,0x9A,0x9D,0x9C,0x9D,0x9E,0x9F, \
377 0xA4,0xA5,0xA6,0xA7,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF, \
378 0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
379 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, \
380 0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
381 0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF, \
382 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
383#define TBL_CT862 {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F, \
384 0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \
385 0x41,0x49,0x4F,0x55,0xA5,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF, \
386 0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
387 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, \
388 0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
389 0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF, \
390 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
391#define TBL_CT863 {0x43,0x55,0x45,0x41,0x41,0x41,0x86,0x43,0x45,0x45,0x45,0x49,0x49,0x8D,0x41,0x8F, \
392 0x45,0x45,0x45,0x4F,0x45,0x49,0x55,0x55,0x98,0x4F,0x55,0x9B,0x9C,0x55,0x55,0x9F, \
393 0xA0,0xA1,0x4F,0x55,0xA4,0xA5,0xA6,0xA7,0x49,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF, \
394 0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
395 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, \
396 0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
397 0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF, \
398 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
399#define TBL_CT864 {0x80,0x9A,0x45,0x41,0x8E,0x41,0x8F,0x80,0x45,0x45,0x45,0x49,0x49,0x49,0x8E,0x8F, \
400 0x90,0x92,0x92,0x4F,0x99,0x4F,0x55,0x55,0x59,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \
401 0x41,0x49,0x4F,0x55,0xA5,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF, \
402 0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
403 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, \
404 0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
405 0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF, \
406 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
407#define TBL_CT865 {0x80,0x9A,0x90,0x41,0x8E,0x41,0x8F,0x80,0x45,0x45,0x45,0x49,0x49,0x49,0x8E,0x8F, \
408 0x90,0x92,0x92,0x4F,0x99,0x4F,0x55,0x55,0x59,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \
409 0x41,0x49,0x4F,0x55,0xA5,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF, \
410 0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
411 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, \
412 0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
413 0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF, \
414 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
415#define TBL_CT866 {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F, \
416 0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \
417 0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F, \
418 0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
419 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, \
420 0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
421 0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \
422 0xF0,0xF0,0xF2,0xF2,0xF4,0xF4,0xF6,0xF6,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
423#define TBL_CT869 {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F, \
424 0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x86,0x9C,0x8D,0x8F,0x90, \
425 0x91,0x90,0x92,0x95,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF, \
426 0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
427 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, \
428 0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xA4,0xA5,0xA6,0xD9,0xDA,0xDB,0xDC,0xA7,0xA8,0xDF, \
429 0xA9,0xAA,0xAC,0xAD,0xB5,0xB6,0xB7,0xB8,0xBD,0xBE,0xC6,0xC7,0xCF,0xCF,0xD0,0xEF, \
430 0xF0,0xF1,0xD1,0xD2,0xD3,0xF5,0xD4,0xF7,0xF8,0xF9,0xD5,0x96,0x95,0x98,0xFE,0xFF}
435#define TBL_DC932 {0x81, 0x9F, 0xE0, 0xFC, 0x40, 0x7E, 0x80, 0xFC, 0x00, 0x00}
436#define TBL_DC936 {0x81, 0xFE, 0x00, 0x00, 0x40, 0x7E, 0x80, 0xFE, 0x00, 0x00}
437#define TBL_DC949 {0x81, 0xFE, 0x00, 0x00, 0x41, 0x5A, 0x61, 0x7A, 0x81, 0xFE}
438#define TBL_DC950 {0x81, 0xFE, 0x00, 0x00, 0x40, 0x7E, 0xA1, 0xFE, 0x00, 0x00}
442#define MERGE_2STR(a, b) a ## b
443#define MKCVTBL(hd, cp) MERGE_2STR(hd, cp)
461#if FF_VOLUMES < 1 || FF_VOLUMES > 10
462#error Wrong FF_VOLUMES setting
482#if FF_MIN_GPT > 0x100000000
483#error Wrong FF_MIN_GPT setting
485static const BYTE GUID_MS_Basic[16] = {0xA2,0xA0,0xD0,0xEB,0xE5,0xB9,0x33,0x44,0x87,0xC0,0x68,0xB6,0xB7,0x26,0x99,0xC7};
496#error LFN must be enabled when enable exFAT
499#define INIT_NAMBUF(fs)
501#define LEAVE_MKFS(res) return res
504#if FF_MAX_LFN < 12 || FF_MAX_LFN > 255
505#error Wrong setting of FF_MAX_LFN
507#if FF_LFN_BUF < FF_SFN_BUF || FF_SFN_BUF < 12
508#error Wrong setting of FF_LFN_BUF or FF_SFN_BUF
510#if FF_LFN_UNICODE < 0 || FF_LFN_UNICODE > 3
511#error Wrong setting of FF_LFN_UNICODE
513static const BYTE LfnOfs[] = {1,3,5,7,9,14,16,18,20,22,24,28,30};
514#define MAXDIRB(nc) ((nc + 44U) / 15 * SZDIRE)
522#define INIT_NAMBUF(fs)
524#define LEAVE_MKFS(res) return res
528#define DEF_NAMBUF WCHAR lbuf[FF_MAX_LFN+1]; BYTE dbuf[MAXDIRB(FF_MAX_LFN)];
529#define INIT_NAMBUF(fs) { (fs)->lfnbuf = lbuf; (fs)->dirbuf = dbuf; }
532#define DEF_NAMBUF WCHAR lbuf[FF_MAX_LFN+1];
533#define INIT_NAMBUF(fs) { (fs)->lfnbuf = lbuf; }
536#define LEAVE_MKFS(res) return res
540#define DEF_NAMBUF WCHAR *lfn;
541#define INIT_NAMBUF(fs) { lfn = ff_memalloc((FF_MAX_LFN+1)*2 + MAXDIRB(FF_MAX_LFN)); if (!lfn) LEAVE_FF(fs, FR_NOT_ENOUGH_CORE); (fs)->lfnbuf = lfn; (fs)->dirbuf = (BYTE*)(lfn+FF_MAX_LFN+1); }
542#define FREE_NAMBUF() ff_memfree(lfn)
544#define DEF_NAMBUF WCHAR *lfn;
545#define INIT_NAMBUF(fs) { lfn = ff_memalloc((FF_MAX_LFN+1)*2); if (!lfn) LEAVE_FF(fs, FR_NOT_ENOUGH_CORE); (fs)->lfnbuf = lfn; }
546#define FREE_NAMBUF() ff_memfree(lfn)
548#define LEAVE_MKFS(res) { if (!work) ff_memfree(buf); return res; }
549#define MAX_MALLOC 0x8000
552#error Wrong setting of FF_USE_LFN
564#define CODEPAGE CodePage
590#elif FF_CODE_PAGE < 900
591#define CODEPAGE FF_CODE_PAGE
595#define CODEPAGE FF_CODE_PAGE
619 rv = rv << 8 | ptr[0];
628 rv = rv << 8 | ptr[2];
629 rv = rv << 8 | ptr[1];
630 rv = rv << 8 | ptr[0];
635static QWORD ld_qword (
const BYTE* ptr)
640 rv = rv << 8 | ptr[6];
641 rv = rv << 8 | ptr[5];
642 rv = rv << 8 | ptr[4];
643 rv = rv << 8 | ptr[3];
644 rv = rv << 8 | ptr[2];
645 rv = rv << 8 | ptr[1];
646 rv = rv << 8 | ptr[0];
654 *ptr++ = (
BYTE)val; val >>= 8;
660 *ptr++ = (
BYTE)val; val >>= 8;
661 *ptr++ = (
BYTE)val; val >>= 8;
662 *ptr++ = (
BYTE)val; val >>= 8;
667static void st_qword (
BYTE* ptr, QWORD val)
669 *ptr++ = (
BYTE)val; val >>= 8;
670 *ptr++ = (
BYTE)val; val >>= 8;
671 *ptr++ = (
BYTE)val; val >>= 8;
672 *ptr++ = (
BYTE)val; val >>= 8;
673 *ptr++ = (
BYTE)val; val >>= 8;
674 *ptr++ = (
BYTE)val; val >>= 8;
675 *ptr++ = (
BYTE)val; val >>= 8;
691 if (DbcTbl &&
c >= DbcTbl[0]) {
692 if (
c <= DbcTbl[1])
return 1;
693 if (
c >= DbcTbl[2] &&
c <= DbcTbl[3])
return 1;
695#elif FF_CODE_PAGE >= 900
696 if (
c >= DbcTbl[0]) {
697 if (
c <= DbcTbl[1])
return 1;
698 if (
c >= DbcTbl[2] &&
c <= DbcTbl[3])
return 1;
701 if (
c != 0)
return 0;
711 if (DbcTbl &&
c >= DbcTbl[4]) {
712 if (
c <= DbcTbl[5])
return 1;
713 if (
c >= DbcTbl[6] &&
c <= DbcTbl[7])
return 1;
714 if (
c >= DbcTbl[8] &&
c <= DbcTbl[9])
return 1;
716#elif FF_CODE_PAGE >= 900
717 if (
c >= DbcTbl[4]) {
718 if (
c <= DbcTbl[5])
return 1;
719 if (
c >= DbcTbl[6] &&
c <= DbcTbl[7])
return 1;
720 if (
c >= DbcTbl[8] &&
c <= DbcTbl[9])
return 1;
723 if (
c != 0)
return 0;
737 const TCHAR *p = *str;
739#if FF_LFN_UNICODE == 1
749#elif FF_LFN_UNICODE == 2
755 if ((uc & 0xE0) == 0xC0) {
757 }
else if ((uc & 0xF0) == 0xE0) {
759 }
else if ((uc & 0xF8) == 0xF0) {
766 if ((
b & 0xC0) != 0x80)
return 0xFFFFFFFF;
767 uc = uc << 6 | (
b & 0x3F);
769 if (uc < 0x80 ||
IsSurrogate(uc) || uc >= 0x110000)
return 0xFFFFFFFF;
770 if (uc >= 0x010000) uc = 0xD800DC00 | ((uc - 0x10000) << 6 & 0x3FF0000) | (uc & 0x3FF);
773#elif FF_LFN_UNICODE == 3
775 if (uc >= 0x110000 ||
IsSurrogate(uc))
return 0xFFFFFFFF;
776 if (uc >= 0x010000) uc = 0xD800DC00 | ((uc - 0x10000) << 6 & 0x3FF0000) | (uc & 0x3FF);
790 if (wc == 0)
return 0xFFFFFFFF;
807#if FF_LFN_UNICODE == 1
810 hs = (
WCHAR)(chr >> 16);
822#elif FF_LFN_UNICODE == 2
826 if (szb < 1)
return 0;
831 if (szb < 2)
return 0;
832 *buf++ = (
TCHAR)(0xC0 | (chr >> 6 & 0x1F));
833 *buf++ = (
TCHAR)(0x80 | (chr >> 0 & 0x3F));
838 *buf++ = (
TCHAR)(0xE0 | (chr >> 12 & 0x0F));
839 *buf++ = (
TCHAR)(0x80 | (chr >> 6 & 0x3F));
840 *buf++ = (
TCHAR)(0x80 | (chr >> 0 & 0x3F));
844 if (szb < 4)
return 0;
845 hc = ((chr & 0xFFFF0000) - 0xD8000000) >> 6;
846 chr = (chr & 0xFFFF) - 0xDC00;
847 if (hc >= 0x100000 || chr >= 0x400)
return 0;
848 chr = (hc | chr) + 0x10000;
849 *buf++ = (
TCHAR)(0xF0 | (chr >> 18 & 0x07));
850 *buf++ = (
TCHAR)(0x80 | (chr >> 12 & 0x3F));
851 *buf++ = (
TCHAR)(0x80 | (chr >> 6 & 0x3F));
852 *buf++ = (
TCHAR)(0x80 | (chr >> 0 & 0x3F));
855#elif FF_LFN_UNICODE == 3
858 if (szb < 1)
return 0;
859 if (chr >= 0x10000) {
860 hc = ((chr & 0xFFFF0000) - 0xD8000000) >> 6;
861 chr = (chr & 0xFFFF) - 0xDC00;
862 if (hc >= 0x100000 || chr >= 0x400)
return 0;
863 chr = (hc | chr) + 0x10000;
873 if (szb < 2)
return 0;
874 *buf++ = (char)(wc >> 8);
878 if (wc == 0 || szb < 1)
return 0;
894 return ff_req_grant(fs->sobj);
898static void unlock_fs (
904 ff_rel_grant(fs->sobj);
976 if (acc >= 1 &&
Files[i].ctr)
return 0;
994 if (n == 0x100) n = 0;
1061 sect = (
LBA_t)0 - 1;
1089 memset(fs->
win, 0,
sizeof fs->
win);
1120 if (clst >= fs->
n_fatent - 2)
return 0;
1141 if (clst < 2 || clst >= fs->
n_fatent) {
1149 bc = (
UINT)clst; bc += bc / 2;
1151 wc = fs->
win[bc++ %
SS(fs)];
1153 wc |= fs->
win[bc %
SS(fs)] << 8;
1154 val = (clst & 1) ? (wc >> 4) : (wc & 0xFFF);
1172 if (obj->
stat == 2 && cofs <= clen) {
1173 val = (cofs == clen) ? 0x7FFFFFFF : clst + 1;
1176 if (obj->
stat == 3 && cofs < obj->n_cont) {
1180 if (obj->
stat != 2) {
1181 if (obj->n_frag != 0) {
1220 if (clst >= 2 && clst < fs->n_fatent) {
1223 bc = (
UINT)clst; bc += bc / 2;
1225 if (res !=
FR_OK)
break;
1226 p = fs->
win + bc++ %
SS(fs);
1227 *p = (clst & 1) ? ((*p & 0x0F) | ((
BYTE)val << 4)) : (
BYTE)val;
1230 if (res !=
FR_OK)
break;
1231 p = fs->
win + bc %
SS(fs);
1232 *p = (clst & 1) ? (
BYTE)(val >> 4) : ((*p & 0xF0) | ((
BYTE)(val >> 8) & 0x0F));
1238 if (res !=
FR_OK)
break;
1248 if (res !=
FR_OK)
break;
1250 val = (val & 0x0FFFFFFF) | (
ld_dword(fs->
win + clst * 4 %
SS(fs)) & 0xF0000000);
1265#if FF_FS_EXFAT && !FF_FS_READONLY
1274static DWORD find_bitmap (
1282 DWORD val, scl, ctr;
1286 if (clst >= fs->
n_fatent - 2) clst = 0;
1287 scl = val = clst; ctr = 0;
1290 i = val / 8 %
SS(fs); bm = 1 << (val % 8);
1293 bv = fs->
win[i] & bm; bm <<= 1;
1295 val = 0; bm = 0; i =
SS(fs);
1298 if (++ctr == ncl)
return scl + 2;
1302 if (val == clst)
return 0;
1305 }
while (++i <
SS(fs));
1327 sect = fs->bitbase + clst / 8 /
SS(fs);
1328 i = clst / 8 %
SS(fs);
1329 bm = 1 << (clst % 8);
1337 if (--ncl == 0)
return FR_OK;
1340 }
while (++i <
SS(fs));
1350static FRESULT fill_first_frag (
1358 if (obj->
stat == 3) {
1359 for (cl = obj->
sclust, n = obj->n_cont; n; cl++, n--) {
1361 if (res !=
FR_OK)
return res;
1373static FRESULT fill_last_frag (
1382 while (obj->n_frag > 0) {
1383 res =
put_fat(obj->
fs, lcl - obj->n_frag + 1, (obj->n_frag > 1) ? lcl - obj->n_frag + 2 : term);
1384 if (res !=
FR_OK)
return res;
1408#if FF_FS_EXFAT || FF_USE_TRIM
1409 DWORD scl = clst, ecl = clst;
1419 res =
put_fat(fs, pclst, 0xFFFFFFFF);
1420 if (res !=
FR_OK)
return res;
1426 if (nxt == 0)
break;
1431 if (res !=
FR_OK)
return res;
1437#if FF_FS_EXFAT || FF_USE_TRIM
1438 if (ecl + 1 == nxt) {
1443 res = change_bitmap(fs, scl, ecl - scl + 1, 0);
1444 if (res !=
FR_OK)
return res;
1456 }
while (clst < fs->n_fatent);
1464 if (obj->
stat == 0) {
1466 while (clst != pclst) {
1470 if (nxt != clst + 1)
break;
1473 if (clst == pclst) {
1477 if (obj->
stat == 3 && pclst >= obj->
sclust && pclst <= obj->sclust + obj->n_cont) {
1506 if (scl == 0 || scl >= fs->
n_fatent) scl = 1;
1510 if (cs < 2)
return 1;
1511 if (cs == 0xFFFFFFFF)
return cs;
1512 if (cs < fs->n_fatent)
return cs;
1519 ncl = find_bitmap(fs, scl, 1);
1520 if (ncl == 0 || ncl == 0xFFFFFFFF)
return ncl;
1521 res = change_bitmap(fs, ncl, 1, 1);
1527 if (obj->
stat == 2 && ncl != scl + 1) {
1528 obj->n_cont = scl - obj->
sclust;
1532 if (obj->
stat != 2) {
1533 if (ncl == clst + 1) {
1534 obj->n_frag = obj->n_frag ? obj->n_frag + 1 : 2;
1536 if (obj->n_frag == 0) obj->n_frag = 1;
1537 res = fill_last_frag(obj, clst, ncl);
1538 if (res ==
FR_OK) obj->n_frag = 1;
1549 if (cs == 1 || cs == 0xFFFFFFFF)
return cs;
1552 if (cs >= 2 && cs < fs->n_fatent) scl = cs;
1562 if (ncl > scl)
return 0;
1566 if (cs == 1 || cs == 0xFFFFFFFF)
return cs;
1567 if (ncl == scl)
return 0;
1570 res =
put_fat(fs, ncl, 0xFFFFFFFF);
1571 if (res ==
FR_OK && clst != 0) {
1597static DWORD clmt_clust (
1602 DWORD cl, ncl, *tbl;
1606 tbl =
fp->cltbl + 1;
1610 if (ncl == 0)
return 0;
1611 if (cl < ncl)
break;
1640 memset(fs->
win, 0,
sizeof fs->
win);
1645 memset(ibuf, 0, szb);
1652 ibuf = fs->
win; szb = 1;
1691 while (ofs >= csz) {
1701 dp->
sect += ofs /
SS(fs);
1702 dp->
dir = fs->
win + (ofs %
SS(fs));
1727 if (ofs %
SS(fs) == 0) {
1730 if (dp->
clust == 0) {
1736 if ((ofs /
SS(fs) & (fs->
csize - 1)) == 0) {
1752 if (!stretch) dp->
sect = 0;
1790 if (res !=
FR_OK)
break;
1796 if (++n == n_ent)
break;
1801 }
while (res ==
FR_OK);
1855 const WCHAR* lfnbuf,
1865 i = ((dir[
LDIR_Ord] & 0x3F) - 1) * 13;
1867 for (wc = 1, s = 0; s < 13; s++) {
1875 if (uc != 0xFFFF)
return 0;
1879 if ((dir[
LDIR_Ord] &
LLEF) && wc && lfnbuf[i])
return 0;
1885#if FF_FS_MINIMIZE <= 1 || FF_FS_RPATH >= 2 || FF_USE_LABEL || FF_FS_EXFAT
1901 i = ((dir[
LDIR_Ord] & ~LLEF) - 1) * 13;
1903 for (wc = 1, s = 0; s < 13; s++) {
1907 lfnbuf[i++] = wc = uc;
1909 if (uc != 0xFFFF)
return 0;
1947 if (wc != 0xFFFF) wc = lfn[i++];
1949 if (wc == 0) wc = 0xFFFF;
1951 if (wc == 0xFFFF || !lfn[i]) ord |=
LLEF;
1960#if FF_USE_LFN && !FF_FS_READONLY
1978 memcpy(dst, src, 11);
1984 for (i = 0; i < 16; i++) {
1985 sreg = (sreg << 1) + (wc & 1);
1987 if (sreg & 0x10000) sreg ^= 0x11021;
1996 c = (
BYTE)((seq % 16) +
'0'); seq /= 16;
1997 if (
c >
'9')
c += 7;
2003 for (j = 0; j < i && dst[j] !=
' '; j++) {
2005 if (j == i - 1)
break;
2010 dst[j++] = (i < 8) ? ns[i++] :
' ';
2030 sum = (sum >> 1) + (sum << 7) + *dir++;
2044static WORD xdir_sum (
2053 for (i = sum = 0; i < szblk; i++) {
2057 sum = ((sum & 1) ? 0x8000 : 0) + (sum >> 1) + dir[i];
2065static WORD xname_sum (
2073 while ((chr = *name++) != 0) {
2075 sum = ((sum & 1) ? 0x8000 : 0) + (sum >> 1) + (chr & 0xFF);
2076 sum = ((sum & 1) ? 0x8000 : 0) + (sum >> 1) + (chr >> 8);
2082#if !FF_FS_READONLY && FF_USE_MKFS
2083static DWORD xsum32 (
2088 sum = ((sum & 1) ? 0x80000000 : 0) + (sum >> 1) + dat;
2110 if (res !=
FR_OK)
return res;
2119 if (res !=
FR_OK)
return res;
2121 if (res !=
FR_OK)
return res;
2131 if (res !=
FR_OK)
return res;
2133 if (res !=
FR_OK)
return res;
2136 }
while ((i +=
SZDIRE) < sz_ent);
2150static void init_alloc_info (
2163#if !FF_FS_READONLY || FF_FS_RPATH != 0
2185 res = load_xdir(dp);
2211 while (res ==
FR_OK) {
2213 if (res !=
FR_OK)
break;
2216 if (--nent == 0)
break;
2229static void create_xdir (
2240 memset(dirb, 0, 2 *
SZDIRE);
2246 nlen = nc1 = 0; wc = 1;
2250 if (wc != 0 && (wc = lfn[nlen]) != 0) nlen++;
2253 }
while (i %
SZDIRE != 0);
2255 }
while (lfn[nlen]);
2267#if FF_FS_MINIMIZE <= 1 || FF_FS_RPATH >= 2 || FF_USE_LABEL || FF_FS_EXFAT
2272#define DIR_READ_FILE(dp) dir_read(dp, 0)
2273#define DIR_READ_LABEL(dp) dir_read(dp, 1)
2284 BYTE ord = 0xFF, sum = 0xFF;
2289 if (res !=
FR_OK)
break;
2301 res = load_xdir(dp);
2338 if (res !=
FR_OK)
break;
2365 if (res !=
FR_OK)
return res;
2377 for (nc = fs->dirbuf[
XDIR_NumName], di =
SZDIRE * 2, ni = 0; nc; nc--, di += 2, ni++) {
2378 if ((di %
SZDIRE) == 0) di += 2;
2381 if (nc == 0 && !fs->
lfnbuf[ni])
break;
2388 ord = sum = 0xFF; dp->
blk_ofs = 0xFFFFFFFF;
2392 if (res !=
FR_OK)
break;
2398 ord = 0xFF; dp->
blk_ofs = 0xFFFFFFFF;
2411 if (ord == 0 && sum ==
sum_sfn(dp->
dir))
break;
2413 ord = 0xFF; dp->
blk_ofs = 0xFFFFFFFF;
2421 }
while (res ==
FR_OK);
2446 for (len = 0; fs->
lfnbuf[len]; len++) ;
2450 n_ent = (len + 14) / 15 + 2;
2452 if (res !=
FR_OK)
return res;
2457 res = fill_first_frag(&dp->
obj);
2458 if (res !=
FR_OK)
return res;
2459 res = fill_last_frag(&dp->
obj, dp->
clust, 0xFFFFFFFF);
2460 if (res !=
FR_OK)
return res;
2464 res = load_obj_xdir(&dj, &dp->
obj);
2465 if (res !=
FR_OK)
return res;
2470 res = store_xdir(&dj);
2471 if (res !=
FR_OK)
return res;
2475 create_xdir(fs->dirbuf, fs->
lfnbuf);
2480 memcpy(sn, dp->
fn, 12);
2483 for (n = 1; n < 100; n++) {
2486 if (res !=
FR_OK)
break;
2494 n_ent = (sn[
NSFLAG] &
NS_LFN) ? (len + 12) / 13 + 1 : 1;
2496 if (res ==
FR_OK && --n_ent) {
2502 if (res !=
FR_OK)
break;
2506 }
while (res ==
FR_OK && --n_ent);
2535#if !FF_FS_READONLY && FF_FS_MINIMIZE == 0
2553 if (res !=
FR_OK)
break;
2560 if (dp->
dptr >= last)
break;
2562 }
while (res ==
FR_OK);
2581#if FF_FS_MINIMIZE <= 1 || FF_FS_RPATH >= 2
2603 if (dp->
sect == 0)
return;
2614 if ((si %
SZDIRE) == 0) si += 2;
2615 wc =
ld_word(fs->dirbuf + si); si += 2; nc++;
2620 if (nw == 0) { di = 0;
break; }
2624 if (hs != 0) di = 0;
2625 if (di == 0) fno->
fname[di++] =
'?';
2637 if (dp->
blk_ofs != 0xFFFFFFFF) {
2640 while (fs->
lfnbuf[si] != 0) {
2646 if (nw == 0) { di = 0;
break; }
2650 if (hs != 0) di = 0;
2658 if (wc ==
' ')
continue;
2661#if FF_LFN_UNICODE >= 1
2663 wc = wc << 8 | dp->
dir[si++];
2666 if (wc == 0) { di = 0;
break; }
2668 if (nw == 0) { di = 0;
break; }
2676 if (fno->
fname[0] == 0) {
2678 fno->
fname[di++] =
'?';
2682 if (wc ==
'.') lcf =
NS_EXT;
2695 if (
c ==
' ')
continue;
2697 if (si == 9) fno->
fname[di++] =
'.';
2713#if FF_USE_FIND && FF_FS_MINIMIZE <= 1
2718#define FIND_RECURS 4
2721static DWORD get_achar (
2728#if FF_USE_LFN && FF_LFN_UNICODE >= 1
2730 if (chr == 0xFFFFFFFF) chr = 0;
2734 chr = (
BYTE)*(*ptr)++;
2735 if (
IsLower(chr)) chr -= 0x20;
2736#if FF_CODE_PAGE == 0
2737 if (
ExCvt && chr >= 0x80) chr =
ExCvt[chr - 0x80];
2738#elif FF_CODE_PAGE < 900
2739 if (chr >= 0x80) chr =
ExCvt[chr - 0x80];
2741#if FF_CODE_PAGE == 0 || FF_CODE_PAGE >= 900
2752static int pattern_match (
2759 const TCHAR *pptr, *nptr;
2764 while ((skip & 0xFF) != 0) {
2765 if (!get_achar(&nam))
return 0;
2768 if (*pat == 0 && skip)
return 1;
2771 pptr = pat; nptr = nam;
2773 if (*pptr ==
'?' || *pptr ==
'*') {
2774 if (recur == 0)
return 0;
2777 if (*pptr++ ==
'?') sk++;
else sk |= 0x100;
2778 }
while (*pptr ==
'?' || *pptr ==
'*');
2779 if (pattern_match(pptr, nptr, sk, recur - 1))
return 1;
2780 nchr = *nptr;
break;
2782 pchr = get_achar(&pptr);
2783 nchr = get_achar(&nptr);
2784 if (pchr != nchr)
break;
2785 if (pchr == 0)
return 1;
2788 }
while (skip && nchr);
2819 if (uc >= 0x10000) lfn[di++] = (
WCHAR)(uc >> 16);
2822 if (wc < 0x80 && strchr(
"*:<>|\"\?\x7F", (
int)wc))
return FR_INVALID_NAME;
2836 if ((di == 1 && lfn[di - 1] ==
'.') ||
2837 (di == 2 && lfn[di - 1] ==
'.' && lfn[di - 2] ==
'.')) {
2839 for (i = 0; i < 11; i++) {
2840 dp->
fn[i] = (i < di) ?
'.' :
' ';
2848 if (wc !=
' ' && wc !=
'.')
break;
2855 for (si = 0; lfn[si] ==
' '; si++) ;
2857 while (di > 0 && lfn[di - 1] !=
'.') di--;
2859 memset(dp->
fn,
' ', 11);
2864 if (wc ==
' ' || (wc ==
'.' && si != di)) {
2869 if (i >= ni || si == di) {
2876 si = di; i = 8; ni = 11;
b <<= 2;
2882#if FF_CODE_PAGE == 0
2885 if (wc & 0x80) wc =
ExCvt[wc & 0x7F];
2889#elif FF_CODE_PAGE < 900
2891 if (wc & 0x80) wc =
ExCvt[wc & 0x7F];
2902 dp->
fn[i++] = (
BYTE)(wc >> 8);
2904 if (wc == 0 || strchr(
"+,;=[]", (
int)wc)) {
2920 if (ni == 8)
b <<= 2;
2921 if ((
b & 0x0C) == 0x0C || (
b & 0x03) == 0x03) cf |=
NS_LFN;
2938 p = *path; sfn = dp->
fn;
2939 memset(sfn,
' ', 11);
2945 if (
c !=
'.' || si >= 3)
break;
2956 if (
c <=
' ')
break;
2961 if (
c ==
'.' || i >= ni) {
2966#if FF_CODE_PAGE == 0
2967 if (
ExCvt &&
c >= 0x80) {
2970#elif FF_CODE_PAGE < 900
3028 dp->
obj.c_scl = fs->cdc_scl;
3029 dp->
obj.c_size = fs->cdc_size;
3030 dp->
obj.c_ofs = fs->cdc_ofs;
3031 res = load_obj_xdir(&dj, &dp->
obj);
3032 if (res !=
FR_OK)
return res;
3039 if ((
UINT)*path <
' ') {
3046 if (res !=
FR_OK)
break;
3052 if (!(ns &
NS_LAST))
continue;
3071 init_alloc_info(fs, &dp->
obj);
3094 const TCHAR *tp, *tt;
3104 if (!tp)
return vol;
3109 if (
IsDigit(*tp) && tp + 2 == tt) {
3112#if FF_STR_VOLUME_ID == 1
3116 sp = VolumeStr[i]; tp = *path;
3118 c = *sp++; tc = *tp++;
3121 }
while (
c && (
TCHAR)
c == tc);
3131#if FF_STR_VOLUME_ID == 2
3133 while (*(tp + 1) ==
'/') tp++;
3136 tt = tp; sp = VolumeStr[i];
3138 c = *sp++; tc = *(++tt);
3141 }
while (
c && (
TCHAR)
c == tc);
3178 for (
b = 1;
b;
b <<= 1) {
3179 crc ^= (
d &
b) ? 1 : 0;
3180 crc = (crc & 1) ? crc >> 1 ^ 0xEDB88320 : crc >> 1;
3188static int test_gpt_header (
3196 if (memcmp(gpth +
GPTH_Sign,
"EFI PART" "\0\0\1\0" "\x5C\0\0", 16))
return 0;
3197 for (i = 0, bcc = 0xFFFFFFFF; i < 92; i++) {
3198 bcc = crc32(bcc, i -
GPTH_Bcc < 4 ? 0 : gpth[i]);
3207#if !FF_FS_READONLY && FF_USE_MKFS
3210static DWORD make_rand (
3219 if (seed == 0) seed = 1;
3221 for (r = 0; r < 8; r++) seed = seed & 1 ? seed >> 1 ^ 0xA3000000 : seed >> 1;
3222 *buff++ = (
BYTE)seed;
3251 if (sign == 0xAA55 && !memcmp(fs->
win +
BS_JmpBoot,
"\xEB\x76\x90" "EXFAT ", 11))
return 1;
3254 if (
b == 0xEB ||
b == 0xE9 ||
b == 0xE8) {
3262 &&
b != 0 && (
b & (
b - 1)) == 0
3271 return sign == 0xAA55 ? 2 : 3;
3288 if (fmt != 2 && (fmt >= 3 || part == 0))
return fmt;
3294 DWORD n_ent, v_ent, ofs;
3298 if (!test_gpt_header(fs->
win))
return 3;
3301 for (v_ent = i = 0; i < n_ent; i++) {
3307 if (part == 0 && fmt <= 1)
return fmt;
3308 if (part != 0 && v_ent == part)
return fmt;
3315 for (i = 0; i < 4; i++) {
3318 i = part ? part - 1 : 0;
3320 fmt = mbr_pt[i] ?
check_fs(fs, mbr_pt[i]) : 3;
3321 }
while (part == 0 && fmt >= 2 && ++i < 4);
3341 DWORD tsect, sysect, fasize, nclst, szbfat;
3383#if FF_MAX_SS != FF_MIN_SS
3399 DWORD so, cv, bcl, i;
3449 if (cv == 0xFFFFFFFF)
break;
3485 nclst = (tsect - sysect) / fs->
csize;
3515#if (FF_FS_NOFSINFO & 3) != 3
3525#if (FF_FS_NOFSINFO & 1) == 0
3528#if (FF_FS_NOFSINFO & 2) == 0
3542 fs->dirbuf = DirBuf;
3571 if (lock_fs(obj->
fs)) {
3586 *rfs = (res ==
FR_OK) ? obj->
fs : 0;
3614 const TCHAR *rp = path;
3627 if (!ff_del_syncobj(cfs->sobj))
return FR_INT_ERR;
3640 if (opt == 0)
return FR_OK;
3663 DWORD cl, bcs, clst, tm;
3714 init_alloc_info(fs, &
fp->obj);
3716 memset(fs->dirbuf + 2, 0, 30);
3717 memset(fs->dirbuf + 38, 0, 26);
3721 res = store_xdir(&dj);
3722 if (res ==
FR_OK &&
fp->obj.sclust != 0) {
3763 fp->dir_ptr = dj.
dir;
3787 init_alloc_info(fs, &
fp->obj);
3805 memset(
fp->buf, 0,
sizeof fp->buf);
3808 fp->fptr =
fp->obj.objsize;
3810 clst =
fp->obj.sclust;
3811 for (ofs =
fp->obj.objsize; res ==
FR_OK && ofs > bcs; ofs -= bcs) {
3817 if (res ==
FR_OK && ofs %
SS(fs)) {
3838 if (res !=
FR_OK)
fp->obj.fs = 0;
3862 UINT rcnt, cc, csect;
3870 remain =
fp->obj.objsize -
fp->fptr;
3871 if (btr > remain) btr = (
UINT)remain;
3873 for ( ; btr > 0; btr -= rcnt, *br += rcnt, rbuff += rcnt,
fp->fptr += rcnt) {
3874 if (
fp->fptr %
SS(fs) == 0) {
3877 if (
fp->fptr == 0) {
3878 clst =
fp->obj.sclust;
3882 clst = clmt_clust(
fp,
fp->fptr);
3898 if (csect + cc > fs->
csize) {
3899 cc = fs->
csize - csect;
3902#if !FF_FS_READONLY && FF_FS_MINIMIZE <= 2
3905 memcpy(rbuff + ((fs->
winsect - sect) *
SS(fs)), fs->
win,
SS(fs));
3909 memcpy(rbuff + ((
fp->sect - sect) *
SS(fs)),
fp->buf,
SS(fs));
3917 if (
fp->sect != sect) {
3930 if (rcnt > btr) rcnt = btr;
3933 memcpy(rbuff, fs->
win +
fp->fptr %
SS(fs), rcnt);
3935 memcpy(rbuff,
fp->buf +
fp->fptr %
SS(fs), rcnt);
3961 UINT wcnt, cc, csect;
3962 const BYTE *wbuff = (
const BYTE*)buff;
3975 for ( ; btw > 0; btw -= wcnt, *bw += wcnt, wbuff += wcnt,
fp->fptr += wcnt,
fp->obj.objsize = (
fp->fptr >
fp->obj.objsize) ?
fp->fptr :
fp->obj.objsize) {
3976 if (
fp->fptr %
SS(fs) == 0) {
3979 if (
fp->fptr == 0) {
3980 clst =
fp->obj.sclust;
3987 clst = clmt_clust(
fp,
fp->fptr);
3994 if (clst == 0)
break;
3998 if (
fp->obj.sclust == 0)
fp->obj.sclust = clst;
4013 if (csect + cc > fs->
csize) {
4014 cc = fs->
csize - csect;
4017#if FF_FS_MINIMIZE <= 2
4019 if (fs->
winsect - sect < cc) {
4020 memcpy(fs->
win, wbuff + ((fs->
winsect - sect) *
SS(fs)),
SS(fs));
4024 if (
fp->sect - sect < cc) {
4025 memcpy(
fp->buf, wbuff + ((
fp->sect - sect) *
SS(fs)),
SS(fs));
4034 if (
fp->fptr >=
fp->obj.objsize) {
4039 if (
fp->sect != sect &&
4040 fp->fptr <
fp->obj.objsize &&
4048 if (wcnt > btw) wcnt = btw;
4051 memcpy(fs->
win +
fp->fptr %
SS(fs), wbuff, wcnt);
4054 memcpy(
fp->buf +
fp->fptr %
SS(fs), wbuff, wcnt);
4094 res = fill_first_frag(&
fp->obj);
4096 res = fill_last_frag(&
fp->obj,
fp->clust, 0xFFFFFFFF);
4103 res = load_obj_xdir(&dj, &
fp->
obj);
4113 res = store_xdir(&dj);
4168 if (res ==
FR_OK)
fp->obj.fs = 0;
4173 unlock_fs(fs,
FR_OK);
4209#if FF_STR_VOLUME_ID == 2
4229 fs->cdc_scl = dj.
obj.c_scl;
4230 fs->cdc_size = dj.
obj.c_size;
4231 fs->cdc_ofs = dj.
obj.c_ofs;
4254#if FF_STR_VOLUME_ID == 2
4301 if (res !=
FR_OK)
break;
4303 if (res !=
FR_OK)
break;
4306 if (res !=
FR_OK)
break;
4309 if (res !=
FR_OK)
break;
4312 }
while (res ==
FR_OK);
4314 if (res !=
FR_OK)
break;
4316 for (n = 0; fno.
fname[n]; n++) ;
4320 while (n) buff[--i] = fno.
fname[--n];
4325 if (i == len) buff[--i] =
'/';
4328#if FF_STR_VOLUME_ID >= 1
4329 for (n = 0, vp = (
const char*)VolumeStr[
CurrVol]; vp[n]; n++) ;
4332 for (vl = 0; vl < n; *tp++ = (
TCHAR)vp[vl], vl++) ;
4347 do *tp++ = buff[i++];
while (i < len);
4362#if FF_FS_MINIMIZE <= 2
4378 DWORD cl, pcl, ncl, tcl, tlen, ulen;
4385#if FF_FS_EXFAT && !FF_FS_READONLY
4387 res = fill_last_frag(&
fp->obj,
fp->clust, 0xFFFFFFFF);
4396 tlen = *tbl++; ulen = 2;
4397 cl =
fp->obj.sclust;
4401 tcl = cl; ncl = 0; ulen += 2;
4407 }
while (cl == pcl + 1);
4409 *tbl++ = ncl; *tbl++ = tcl;
4411 }
while (cl < fs->n_fatent);
4420 if (ofs >
fp->obj.objsize) ofs =
fp->obj.objsize;
4423 fp->clust = clmt_clust(
fp, ofs - 1);
4427 if (
fp->fptr %
SS(fs) && dsc !=
fp->sect) {
4450 ofs =
fp->obj.objsize;
4453 fp->fptr = nsect = 0;
4457 (ofs - 1) / bcs >= (ifptr - 1) / bcs) {
4458 fp->fptr = (ifptr - 1) & ~(
FSIZE_t)(bcs - 1);
4462 clst =
fp->obj.sclust;
4468 fp->obj.sclust = clst;
4475 ofs -= bcs;
fp->fptr += bcs;
4479 fp->obj.objsize =
fp->fptr;
4499 nsect += (
DWORD)(ofs /
SS(fs));
4504 fp->obj.objsize =
fp->fptr;
4507 if (
fp->fptr %
SS(fs) && nsect !=
fp->sect) {
4526#if FF_FS_MINIMIZE <= 1
4557 init_alloc_info(fs, &dp->
obj);
4614 unlock_fs(fs,
FR_OK);
4673 if (res !=
FR_OK || !fno || !fno->
fname[0])
break;
4674 if (pattern_match(dp->pat, fno->
fname, 0, FIND_RECURS))
break;
4675#if FF_USE_LFN && FF_USE_FIND == 2
4676 if (pattern_match(dp->pat, fno->
altname, 0, FIND_RECURS))
break;
4692 const TCHAR* pattern
4710#if FF_FS_MINIMIZE == 0
4758 DWORD nfree, clst, stat;
4775 clst = 2; obj.
fs = fs;
4778 if (stat == 0xFFFFFFFF) { res =
FR_DISK_ERR;
break; }
4780 if (stat == 0) nfree++;
4781 }
while (++clst < fs->n_fatent);
4794 if (res !=
FR_OK)
break;
4796 for (
b = 8, bm = fs->
win[i];
b && clst;
b--, clst--) {
4797 if (!(bm & 1)) nfree++;
4800 i = (i + 1) %
SS(fs);
4811 if (res !=
FR_OK)
break;
4817 if ((
ld_dword(fs->
win + i) & 0x0FFFFFFF) == 0) nfree++;
4855 if (
fp->fptr <
fp->obj.objsize) {
4856 if (
fp->fptr == 0) {
4864 if (res ==
FR_OK && ncl < fs->n_fatent) {
4868 fp->obj.objsize =
fp->fptr;
4930 init_alloc_info(fs, &obj);
4939 if (dclst == fs->
cdir) {
4963 if (res ==
FR_OK && dclst != 0) {
5041 res = store_xdir(&dj);
5071 const TCHAR* path_old,
5072 const TCHAR* path_new
5101 memcpy(buf, fs->dirbuf,
SZDIRE * 2);
5102 memcpy(&djn, &djo,
sizeof djo);
5112 memcpy(fs->dirbuf, buf,
SZDIRE * 2);
5117 res = store_xdir(&djn);
5124 memcpy(&djn, &djo,
sizeof (
DIR));
5133 memcpy(dir + 13, buf + 13,
SZDIRE - 13);
5145 if (res ==
FR_OK && dir[1] ==
'.') {
5175#if FF_USE_CHMOD && !FF_FS_READONLY
5203 res = store_xdir(&dj);
5248 res = store_xdir(&dj);
5290 if (res ==
FR_OK && label) {
5307 if (nw == 0) { di = 0;
break; }
5311 if (hs != 0) di = 0;
5319#if FF_USE_LFN && FF_LFN_UNICODE >= 1
5322 if (wc == 0) { di = 0;
break; }
5323 di +=
put_utf(wc, &label[di], 4);
5325 label[di++] = (
TCHAR)wc;
5331 }
while (label[--di] ==
' ');
5342 if (res ==
FR_OK && vsn) {
5381 static const char badchr[18] =
"+.,;=[]" "/*:<>|\\\"\?\x7F";
5392 memset(dirvn, 0, 22);
5394 while ((
UINT)*label >=
' ') {
5396 if (dc >= 0x10000) {
5397 if (dc == 0xFFFFFFFF || di >= 10) {
5403 if (dc == 0 || strchr(&badchr[7], (
int)dc) || di >= 11) {
5411 memset(dirvn,
' ', 11);
5413 while ((
UINT)*label >=
' ') {
5418 wc = (
BYTE)*label++;
5421#if FF_CODE_PAGE == 0
5422 if (
ExCvt && wc >= 0x80) wc =
ExCvt[wc - 0x80];
5423#elif FF_CODE_PAGE < 900
5424 if (wc >= 0x80) wc =
ExCvt[wc - 0x80];
5427 if (wc == 0 || strchr(&badchr[0], (
int)wc) || di >= (
UINT)((wc >= 0x100) ? 10 : 11)) {
5430 if (wc >= 0x100) dirvn[di++] = (
BYTE)(wc >> 8);
5431 dirvn[di++] = (
BYTE)wc;
5434 while (di && dirvn[di - 1] ==
' ') di--;
5448 memcpy(dj.
dir, dirvn, 11);
5468 memcpy(dj.
dir, dirvn, 11);
5486#if FF_USE_EXPAND && !FF_FS_READONLY
5499 DWORD n, clst, stcl, scl, ncl, tcl, lclst;
5509 tcl = (
DWORD)(fsz / n) + ((fsz & (n - 1)) ? 1 : 0);
5511 if (stcl < 2 || stcl >= fs->
n_fatent) stcl = 2;
5515 scl = find_bitmap(fs, stcl, tcl);
5520 res = change_bitmap(fs, scl, tcl, 1);
5521 lclst = scl + tcl - 1;
5529 scl = clst = stcl; ncl = 0;
5532 if (++clst >= fs->
n_fatent) clst = 2;
5534 if (n == 0xFFFFFFFF) { res =
FR_DISK_ERR;
break; }
5536 if (++ncl == tcl)
break;
5538 scl = clst; ncl = 0;
5540 if (clst == stcl) { res =
FR_DENIED;
break; }
5544 for (clst = scl, n = tcl; n; clst++, n--) {
5545 res =
put_fat(fs, clst, (n == 1) ? 0xFFFFFFFF : clst + 1);
5546 if (res !=
FR_OK)
break;
5558 fp->obj.sclust = scl;
5559 fp->obj.objsize = fsz;
5602 remain =
fp->obj.objsize -
fp->fptr;
5603 if (btf > remain) btf = (
UINT)remain;
5605 for ( ; btf > 0 && (*func)(0, 0);
fp->fptr += rcnt, *bf += rcnt, btf -= rcnt) {
5607 if (
fp->fptr %
SS(fs) == 0) {
5609 clst = (
fp->fptr == 0) ?
5623 if (
fp->sect != sect) {
5636 if (rcnt > btf) rcnt = btf;
5637 rcnt = (*func)(dbuf + ((
UINT)
fp->fptr %
SS(fs)), rcnt);
5647#if !FF_FS_READONLY && FF_USE_MKFS
5652#define N_SEC_TRACK 63
5653#define GPT_ALIGN 0x100000
5654#define GPT_ITEMS 128
5659static FRESULT create_partition (
5668 DWORD sz_drv32, nxt_alloc32, sz_part32;
5670 BYTE hd, n_hd, sc, n_sc;
5678 UINT sz_ptbl, pi, si, ofs;
5679 DWORD bcc, rnd, align;
5680 QWORD nxt_alloc, sz_part, sz_pool, top_bpt;
5681 static const BYTE gpt_mbr[16] = {0x00, 0x00, 0x02, 0x00, 0xEE, 0xFE, 0xFF, 0x00, 0x01, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF};
5683#if FF_MAX_SS != FF_MIN_SS
5690 align = GPT_ALIGN / ss;
5691 sz_ptbl = GPT_ITEMS *
SZ_GPTE / ss;
5692 top_bpt = sz_drv - sz_ptbl - 1;
5693 nxt_alloc = 2 + sz_ptbl;
5694 sz_pool = top_bpt - nxt_alloc;
5695 bcc = 0xFFFFFFFF; sz_part = 1;
5698 if (pi *
SZ_GPTE % ss == 0) memset(buf, 0, ss);
5700 nxt_alloc = (nxt_alloc + align - 1) & ((QWORD)0 - align);
5701 sz_part = plst[si++];
5702 if (sz_part <= 100) {
5703 sz_part = sz_pool * sz_part / 100;
5704 sz_part = (sz_part + align - 1) & ((QWORD)0 - align);
5706 if (nxt_alloc + sz_part > top_bpt) {
5707 sz_part = (nxt_alloc < top_bpt) ? top_bpt - nxt_alloc : 0;
5712 memcpy(buf + ofs +
GPTE_PtGuid, GUID_MS_Basic, 16);
5713 rnd = make_rand(rnd, buf + ofs +
GPTE_UpGuid, 16);
5715 st_qword(buf + ofs +
GPTE_LstLba, nxt_alloc + sz_part - 1);
5716 nxt_alloc += sz_part;
5718 if ((pi + 1) *
SZ_GPTE % ss == 0) {
5719 for (i = 0; i < ss; bcc = crc32(bcc, buf[i++])) ;
5723 }
while (++pi < GPT_ITEMS);
5727 memcpy(buf +
GPTH_Sign,
"EFI PART" "\0\0\1\0" "\x5C\0\0", 16);
5737 for (i = 0, bcc= 0xFFFFFFFF; i < 92; bcc = crc32(bcc, buf[i++])) ;
5746 for (i = 0, bcc= 0xFFFFFFFF; i < 92; bcc = crc32(bcc, buf[i++])) ;
5759 sz_drv32 = (
DWORD)sz_drv;
5761 for (n_hd = 8; n_hd != 0 && sz_drv32 / n_hd / n_sc > 1024; n_hd *= 2) ;
5762 if (n_hd == 0) n_hd = 255;
5766 for (i = 0, nxt_alloc32 = n_sc; i < 4 && nxt_alloc32 != 0 && nxt_alloc32 < sz_drv32; i++, nxt_alloc32 += sz_part32) {
5767 sz_part32 = (
DWORD)plst[i];
5768 if (sz_part32 <= 100) sz_part32 = (sz_part32 == 100) ? sz_drv32 : sz_drv32 / 100 * sz_part32;
5769 if (nxt_alloc32 + sz_part32 > sz_drv32 || nxt_alloc32 + sz_part32 < nxt_alloc32) sz_part32 = sz_drv32 - nxt_alloc32;
5770 if (sz_part32 == 0)
break;
5776 cy = (
UINT)(nxt_alloc32 / n_sc / n_hd);
5777 hd = (
BYTE)(nxt_alloc32 / n_sc % n_hd);
5778 sc = (
BYTE)(nxt_alloc32 % n_sc + 1);
5783 cy = (
UINT)((nxt_alloc32 + sz_part32 - 1) / n_sc / n_hd);
5784 hd = (
BYTE)((nxt_alloc32 + sz_part32 - 1) / n_sc % n_hd);
5785 sc = (
BYTE)((nxt_alloc32 + sz_part32 - 1) % n_sc + 1);
5809 static const WORD cst[] = {1, 4, 16, 64, 256, 512, 0};
5810 static const WORD cst32[] = {1, 2, 4, 8, 16, 32, 0};
5812 BYTE fsopt, fsty, sys, *buf, *pte, pdrv, ipart;
5814 DWORD sz_buf, sz_blk, n_clst, pau, nsect, n, vsn;
5815 LBA_t sz_vol, b_vol, b_fat, b_data;
5817 DWORD sz_rsv, sz_fat, sz_dir, sz_au;
5818 UINT n_fat, n_root, i;
5830 if (!opt) opt = &defopt;
5836 sz_blk = opt->
align;
5838 if (sz_blk == 0 || sz_blk > 0x8000 || (sz_blk & (sz_blk - 1))) sz_blk = 1;
5839#if FF_MAX_SS != FF_MIN_SS
5880 if (!memcmp(buf + ofs +
GPTE_PtGuid, GUID_MS_Basic, 16) && ++i == ipart) {
5882 sz_vol = ld_qword(buf + ofs +
GPTE_LstLba) - b_vol + 1;
5885 n_ent--; ofs = (ofs +
SZ_GPTE) % ss;
5904 b_vol = GPT_ALIGN / ss; sz_vol -= b_vol + GPT_ITEMS *
SZ_GPTE / ss + 1;
5908 if (sz_vol > N_SEC_TRACK) {
5909 b_vol = N_SEC_TRACK; sz_vol -= b_vol;
5920 if ((fsopt &
FM_ANY) ==
FM_EXFAT || sz_vol >= 0x4000000 || sz_au > 128) {
5927 if (sz_au > 128) sz_au = 128;
5941 DWORD szb_bit, szb_case, sum, nbit, clu, clen[3];
5947 lba[0] = b_vol; lba[1] = b_vol + sz_vol - 1;
5953 if (sz_vol >= 0x80000) sz_au = 64;
5954 if (sz_vol >= 0x4000000) sz_au = 256;
5957 sz_fat = (
DWORD)((sz_vol / sz_au + 2) * 4 + ss - 1) / ss;
5958 b_data = (b_fat + sz_fat + sz_blk - 1) & ~((
LBA_t)sz_blk - 1);
5960 n_clst = (
DWORD)(sz_vol - (b_data - b_vol)) / sz_au;
5964 szb_bit = (n_clst + 7) / 8;
5965 clen[0] = (szb_bit + sz_au * ss - 1) / (sz_au * ss);
5968 sect = b_data + sz_au * clen[0];
5970 st = 0; si = 0; i = 0; j = 0; szb_case = 0;
5980 ch = 0xFFFF; st = 2;
break;
5986 if (--j == 0) st = 0;
5993 sum = xsum32(buf[i + 0] = (
BYTE)ch, sum);
5994 sum = xsum32(buf[i + 1] = (
BYTE)(ch >> 8), sum);
5995 i += 2; szb_case += 2;
5996 if (si == 0 || i == sz_buf * ss) {
5997 n = (i + ss - 1) / ss;
6002 clen[1] = (szb_case + sz_au * ss - 1) / (sz_au * ss);
6006 sect = b_data; nsect = (szb_bit + ss - 1) / ss;
6007 nbit = clen[0] + clen[1] + clen[2];
6009 memset(buf, 0, sz_buf * ss);
6010 for (i = 0; nbit != 0 && i / 8 < sz_buf * ss; buf[i / 8] |= 1 << (i % 8), i++, nbit--) ;
6011 n = (nsect > sz_buf) ? sz_buf : nsect;
6013 sect += n; nsect -= n;
6017 sect = b_fat; nsect = sz_fat;
6020 memset(buf, 0, sz_buf * ss); i = 0;
6022 st_dword(buf + i, 0xFFFFFFF8); i += 4; clu++;
6023 st_dword(buf + i, 0xFFFFFFFF); i += 4; clu++;
6026 while (nbit != 0 && i < sz_buf * ss) {
6027 st_dword(buf + i, (nbit > 1) ? clu + 1 : 0xFFFFFFFF);
6028 i += 4; clu++; nbit--;
6030 if (nbit == 0 && j < 3) nbit = clen[j++];
6031 }
while (nbit != 0 && i < sz_buf * ss);
6032 n = (nsect > sz_buf) ? sz_buf : nsect;
6034 sect += n; nsect -= n;
6038 memset(buf, 0, sz_buf * ss);
6047 sect = b_data + sz_au * (clen[0] + clen[1]); nsect = sz_au;
6049 n = (nsect > sz_buf) ? sz_buf : nsect;
6052 sect += n; nsect -= n;
6057 for (n = 0; n < 2; n++) {
6060 memcpy(buf +
BS_JmpBoot,
"\xEB\x76\x90" "EXFAT ", 11);
6076 for (i = sum = 0; i < ss; i++) {
6082 st_word(buf + ss - 2, 0xAA55);
6083 for (j = 1; j < 9; j++) {
6084 for (i = 0; i < ss; sum = xsum32(buf[i++], sum)) ;
6089 for ( ; j < 11; j++) {
6090 for (i = 0; i < ss; sum = xsum32(buf[i++], sum)) ;
6094 for (i = 0; i < ss; i += 4)
st_dword(buf + i, sum);
6106 n = (
DWORD)sz_vol / 0x20000;
6107 for (i = 0, pau = 1; cst32[i] && cst32[i] <= n; i++, pau <<= 1) ;
6109 n_clst = (
DWORD)sz_vol / pau;
6110 sz_fat = (n_clst * 4 + 8 + ss - 1) / ss;
6116 n = (
DWORD)sz_vol / 0x1000;
6117 for (i = 0, pau = 1; cst[i] && cst[i] <= n; i++, pau <<= 1) ;
6119 n_clst = (
DWORD)sz_vol / pau;
6124 n = (n_clst * 3 + 1) / 2 + 3;
6126 sz_fat = (n + ss - 1) / ss;
6130 b_fat = b_vol + sz_rsv;
6131 b_data = b_fat + sz_fat * n_fat + sz_dir;
6134 n = (
DWORD)(((b_data + sz_blk - 1) & ~(sz_blk - 1)) - b_data);
6136 sz_rsv += n; b_fat += n;
6139 n--; sz_rsv++; b_fat++;
6141 sz_fat += n / n_fat;
6146 n_clst = ((
DWORD)sz_vol - sz_rsv - sz_fat * n_fat - sz_dir) / pau;
6149 if (sz_au == 0 && (sz_au = pau / 2) != 0)
continue;
6155 if (sz_au == 0 && (pau * 2) <= 64) {
6156 sz_au = pau * 2;
continue;
6161 if (sz_au == 0 && (sz_au = pau * 2) <= 128)
continue;
6165 if (sz_au == 0 && (sz_au = pau * 2) <= 128)
continue;
6176 lba[0] = b_vol; lba[1] = b_vol + sz_vol - 1;
6181 memcpy(buf +
BS_JmpBoot,
"\xEB\xFE\x90" "MSDOS5.0", 11);
6187 if (sz_vol < 0x10000) {
6204 memcpy(buf +
BS_VolLab32,
"NO NAME " "FAT32 ", 19);
6210 memcpy(buf +
BS_VolLab,
"NO NAME " "FAT ", 19);
6229 memset(buf, 0, sz_buf * ss);
6231 for (i = 0; i < n_fat; i++) {
6241 n = (nsect > sz_buf) ? sz_buf : nsect;
6244 sect += n; nsect -= n;
6249 nsect = (fsty ==
FS_FAT32) ? pau : sz_dir;
6251 n = (nsect > sz_buf) ? sz_buf : nsect;
6253 sect += n; nsect -= n;
6266 if (sz_vol >= 0x10000) {
6269 sys = (fsty ==
FS_FAT16) ? 0x04 : 0x01;
6276 if (!
FF_LBA64 || !(fsopt & 0x80)) {
6284 lba[0] = sz_vol; lba[1] = 0;
6285 fr = create_partition(pdrv, lba, sys, buf);
6298#if FF_MULTI_PARTITION
6321 LEAVE_MKFS(create_partition(pdrv, ptbl, 0x07, buf));
6331#if FF_USE_LFN && FF_LFN_UNICODE && (FF_STRF_ENCODE < 0 || FF_STRF_ENCODE > 3)
6332#error Wrong FF_STRF_ENCODE setting
6349#if FF_USE_LFN && FF_LFN_UNICODE && FF_STRF_ENCODE <= 2
6352#if FF_USE_LFN && FF_LFN_UNICODE && FF_STRF_ENCODE == 3
6356#if FF_USE_LFN && FF_LFN_UNICODE
6362#if FF_STRF_ENCODE == 0
6368 if (rc != 1 || !
dbc_2nd(s[0]))
continue;
6369 wc = wc << 8 | s[0];
6372 if (dc == 0)
continue;
6373#elif FF_STRF_ENCODE == 1 || FF_STRF_ENCODE == 2
6383 dc = ((dc & 0x3FF) + 0x40) << 10 | (wc & 0x3FF);
6391 if ((dc & 0xE0) == 0xC0) { dc &= 0x1F; ct = 1; }
6392 if ((dc & 0xF0) == 0xE0) { dc &= 0x0F; ct = 2; }
6393 if ((dc & 0xF8) == 0xF0) { dc &= 0x07; ct = 3; }
6394 if (ct == 0)
continue;
6396 if (rc != ct)
break;
6399 if ((s[rc] & 0xC0) != 0x80)
break;
6400 dc = dc << 6 | (s[rc] & 0x3F);
6401 }
while (++rc < ct);
6402 if (rc != ct || dc < 0x80 ||
IsSurrogate(dc) || dc >= 0x110000)
continue;
6408#if FF_LFN_UNICODE == 1 || FF_LFN_UNICODE == 3
6410 *p++ = (
TCHAR)(0xD800 | ((dc >> 10) - 0x40)); nc++;
6411 dc = 0xDC00 | (dc & 0x3FF);
6413 *p++ = (
TCHAR)dc; nc++;
6414 if (dc ==
'\n')
break;
6415#elif FF_LFN_UNICODE == 2
6419 if (dc ==
'\n')
break;
6422 *p++ = (
TCHAR)(0xC0 | (dc >> 6 & 0x1F));
6423 *p++ = (
TCHAR)(0x80 | (dc >> 0 & 0x3F));
6427 *p++ = (
TCHAR)(0xE0 | (dc >> 12 & 0x0F));
6428 *p++ = (
TCHAR)(0x80 | (dc >> 6 & 0x3F));
6429 *p++ = (
TCHAR)(0x80 | (dc >> 0 & 0x3F));
6432 *p++ = (
TCHAR)(0xF0 | (dc >> 18 & 0x07));
6433 *p++ = (
TCHAR)(0x80 | (dc >> 12 & 0x3F));
6434 *p++ = (
TCHAR)(0x80 | (dc >> 6 & 0x3F));
6435 *p++ = (
TCHAR)(0x80 | (dc >> 0 & 0x3F));
6450 *p++ = (
TCHAR)dc; nc++;
6451 if (dc ==
'\n')
break;
6456 return nc ? buff : 0;
6464#define SZ_PUTC_BUF 64
6465#define SZ_NUM_BUF 32
6476#if FF_USE_LFN && FF_LFN_UNICODE == 1
6478#elif FF_USE_LFN && FF_LFN_UNICODE == 2
6492#if FF_USE_LFN && FF_LFN_UNICODE
6494#if FF_LFN_UNICODE == 2
6508#if FF_USE_LFN && FF_LFN_UNICODE
6509#if FF_LFN_UNICODE == 1
6513 hs = pb->hs; pb->hs = 0;
6520#elif FF_LFN_UNICODE == 2
6523 pb->bs[pb->wi = 0] = (
BYTE)
c;
6524 if ((
BYTE)
c < 0x80)
break;
6525 if (((
BYTE)
c & 0xE0) == 0xC0) pb->ct = 1;
6526 if (((
BYTE)
c & 0xF0) == 0xE0) pb->ct = 2;
6527 if (((
BYTE)
c & 0xF1) == 0xF0) pb->ct = 3;
6530 if (((
BYTE)
c & 0xC0) != 0x80) {
6531 pb->ct = 0;
continue;
6533 pb->bs[++pb->wi] = (
BYTE)
c;
6534 if (--pb->ct == 0)
break;
6538 tp = (
const TCHAR*)pb->bs;
6540 if (dc == 0xFFFFFFFF)
return;
6542 hs = (
WCHAR)(dc >> 16);
6543#elif FF_LFN_UNICODE == 3
6546 hs = (
WCHAR)(0xD800 | ((
c >> 10) - 0x40));
6547 wc = 0xDC00 | (
c & 0x3FF);
6555#if FF_STRF_ENCODE == 1
6563#elif FF_STRF_ENCODE == 2
6565 pb->
buf[i++] = (
BYTE)(hs >> 8);
6569 pb->
buf[i++] = (
BYTE)(wc >> 8);
6571#elif FF_STRF_ENCODE == 3
6574 hs = (hs & 0x3FF) + 0x40;
6575 pb->
buf[i++] = (
BYTE)(0xF0 | hs >> 8);
6576 pb->
buf[i++] = (
BYTE)(0x80 | (hs >> 2 & 0x3F));
6577 pb->
buf[i++] = (
BYTE)(0x80 | (hs & 3) << 4 | (wc >> 6 & 0x0F));
6578 pb->
buf[i++] = (
BYTE)(0x80 | (wc & 0x3F));
6585 pb->
buf[i++] = (
BYTE)(0xC0 | wc >> 6);
6588 pb->
buf[i++] = (
BYTE)(0xE0 | wc >> 12);
6589 pb->
buf[i++] = (
BYTE)(0x80 | (wc >> 6 & 0x3F));
6591 pb->
buf[i++] = (
BYTE)(0x80 | (wc & 0x3F));
6595 if (hs != 0)
return;
6597 if (wc == 0)
return;
6599 pb->
buf[i++] = (
BYTE)(wc >> 8); nc++;
6608 if (i >= (
int)(
sizeof pb->
buf) - 4) {
6610 i = (n == (
UINT)i) ? 0 : -1;
6634 memset(pb, 0,
sizeof (
putbuff));
6669 while (*str)
putc_bfd(&pb, *str++);
6679#if FF_PRINT_FLOAT && FF_INTDEF == 2
6682static int ilog10 (
double n)
6688 n /= 100000; rv += 5;
6695 n *= 100000; rv -= 5;
6704static double i10x (
int n)
6710 rv *= 100000; n -= 5;
6717 rv /= 100000; n += 5;
6744 if (prec < 0) prec = 6;
6746 val = 0 - val; sign =
'-';
6754 val += i10x(0 - prec) / 2;
6760 val += i10x(ilog10(val) - prec) / 2;
6765 if (
e < -99)
e = -99;
6772 if (sign ==
'-') *buf++ = sign;
6774 if (m == -1) *buf++ = ds;
6776 d = (int)(val / w); val -=
d * w;
6777 *buf++ = (char)(
'0' +
d);
6778 }
while (--m >= -prec);
6782 e = 0 -
e; *buf++ =
'-';
6786 *buf++ = (char)(
'0' +
e / 10);
6787 *buf++ = (char)(
'0' +
e % 10);
6792 if (sign) *buf++ = sign;
6793 do *buf++ = *er++;
while (*er);
6811#if FF_PRINT_LLI && FF_INTDEF == 2
6832 f = w = 0; pad =
' '; prec = -1;
6835 pad =
'0'; tc = *fmt++;
6836 }
else if (tc ==
'-') {
6840 w = va_arg(arp,
int);
6844 w = w * 10 + tc -
'0';
6851 prec = va_arg(arp,
int);
6856 prec = prec * 10 + tc -
'0';
6862 f |= 4; tc = *fmt++;
6863#if FF_PRINT_LLI && FF_INTDEF == 2
6865 f |= 8; tc = *fmt++;
6885 tp = va_arg(arp,
TCHAR*);
6887 for (j = 0; tp[j]; j++) ;
6888 if (prec >= 0 && j > (
UINT)prec) j = prec;
6889 for ( ; !(
f & 2) && j < w; j++)
putc_bfd(&pb, pad);
6890 while (*tp && prec--)
putc_bfd(&pb, *tp++);
6891 while (j++ < w)
putc_bfd(&pb,
' ');
6893#if FF_PRINT_FLOAT && FF_INTDEF == 2
6897 ftoa(str, va_arg(arp,
double), prec, tc);
6898 for (j = strlen(str); !(
f & 2) && j < w; j++)
putc_bfd(&pb, pad);
6899 for (i = 0; str[i];
putc_bfd(&pb, str[i++])) ;
6900 while (j++ < w)
putc_bfd(&pb,
' ');
6908#if FF_PRINT_LLI && FF_INTDEF == 2
6910 v = (QWORD)va_arg(arp, LONGLONG);
6913 v = (tc ==
'd') ? (QWORD)(LONGLONG)va_arg(arp,
long) : (QWORD)va_arg(arp,
unsigned long);
6915 v = (tc ==
'd') ? (QWORD)(LONGLONG)va_arg(arp,
int) : (QWORD)va_arg(arp,
unsigned int);
6918 if (tc ==
'd' && (v & 0x8000000000000000)) {
6923 v = (
DWORD)va_arg(arp,
long);
6925 v = (tc ==
'd') ? (
DWORD)(long)va_arg(arp,
int) : (
DWORD)va_arg(arp,
unsigned int);
6927 if (tc ==
'd' && (v & 0x80000000)) {
6933 d = (char)(v % r); v /= r;
6934 if (
d > 9)
d += (tc ==
'x') ? 0x27 : 0x07;
6937 if (
f & 1) str[i++] =
'-';
6939 for (j = i; !(
f & 2) && j < w; j++)
putc_bfd(&pb, pad);
6941 while (j++ < w)
putc_bfd(&pb,
' ');
6954#if FF_CODE_PAGE == 0
6963 static const WORD validcp[22] = { 437, 720, 737, 771, 775, 850, 852, 855, 857, 860, 861, 862, 863, 864, 865, 866, 869, 932, 936, 949, 950, 0};
6964 static const BYTE*
const tables[22] = {Ct437, Ct720, Ct737, Ct771, Ct775, Ct850, Ct852, Ct855, Ct857, Ct860, Ct861, Ct862, Ct863, Ct864, Ct865, Ct866, Ct869, Dc932, Dc936, Dc949, Dc950, 0};
6968 for (i = 0; validcp[i] != 0 && validcp[i] != cp; i++) ;
DRESULT disk_read(BYTE pdrv, BYTE *buff, LBA_t sector, UINT count)
DSTATUS disk_initialize(BYTE pdrv)
DSTATUS disk_status(BYTE pdrv)
DRESULT disk_ioctl(BYTE pdrv, BYTE cmd, void *buff)
DRESULT disk_write(BYTE pdrv, const BYTE *buff, LBA_t sector, UINT count)
static void gen_numname(BYTE *dst, const BYTE *src, const WCHAR *lfn, UINT seq)
static UINT put_utf(DWORD chr, TCHAR *buf, UINT szb)
static FATFS * FatFs[FF_VOLUMES]
FRESULT f_getfree(const TCHAR *path, DWORD *nclst, FATFS **fatfs)
static FRESULT dir_alloc(DIR *dp, UINT n_ent)
static UINT inc_lock(DIR *dp, int acc)
FRESULT f_chdrive(const TCHAR *path)
static FRESULT create_name(DIR *dp, const TCHAR **path)
FRESULT f_mount(FATFS *fs, const TCHAR *path, BYTE opt)
static void putc_bfd(putbuff *pb, TCHAR c)
FRESULT f_unlink(const TCHAR *path)
static int pick_lfn(WCHAR *lfnbuf, BYTE *dir)
static void get_fileinfo(DIR *dp, FILINFO *fno)
static void st_word(BYTE *ptr, WORD val)
static int dbc_1st(BYTE c)
static FRESULT dir_next(DIR *dp, int stretch)
static DWORD create_chain(FFOBJID *obj, DWORD clst)
static FRESULT move_window(FATFS *fs, LBA_t sect)
static FRESULT mount_volume(const TCHAR **path, FATFS **rfs, BYTE mode)
static void st_clust(FATFS *fs, BYTE *dir, DWORD cl)
static FRESULT dir_read(DIR *dp, int vol)
static const BYTE LfnOfs[]
static FRESULT put_fat(FATFS *fs, DWORD clst, DWORD val)
int f_printf(FIL *fp, const TCHAR *fmt,...)
TCHAR * f_gets(TCHAR *buff, int len, FIL *fp)
FRESULT f_mkdir(const TCHAR *path)
static int putc_flush(putbuff *pb)
static LBA_t clst2sect(FATFS *fs, DWORD clst)
FRESULT f_chdir(const TCHAR *path)
#define XDIR_ValidFileSize
static FRESULT sync_window(FATFS *fs)
static DWORD get_fat(FFOBJID *obj, DWORD clst)
FRESULT f_truncate(FIL *fp)
static BYTE sum_sfn(const BYTE *dir)
static FRESULT dir_remove(DIR *dp)
FRESULT f_lseek(FIL *fp, FSIZE_t ofs)
#define DIR_READ_FILE(dp)
#define LEAVE_FF(fs, res)
static UINT check_fs(FATFS *fs, LBA_t sect)
static int get_ldnumber(const TCHAR **path)
static void put_lfn(const WCHAR *lfn, BYTE *dir, BYTE ord, BYTE sum)
int f_puts(const TCHAR *str, FIL *fp)
static void clear_lock(FATFS *fs)
static DWORD ld_dword(const BYTE *ptr)
static int cmp_lfn(const WCHAR *lfnbuf, BYTE *dir)
FRESULT f_rename(const TCHAR *path_old, const TCHAR *path_new)
static DWORD tchar2uni(const TCHAR **str)
static FRESULT dir_register(DIR *dp)
FRESULT f_readdir(DIR *dp, FILINFO *fno)
FRESULT f_closedir(DIR *dp)
FRESULT f_opendir(DIR *dp, const TCHAR *path)
static int enq_lock(void)
FRESULT f_stat(const TCHAR *path, FILINFO *fno)
static FRESULT dir_find(DIR *dp)
FRESULT f_read(FIL *fp, void *buff, UINT btr, UINT *br)
static FRESULT dir_sdi(DIR *dp, DWORD ofs)
static DWORD ld_clust(FATFS *fs, const BYTE *dir)
int f_putc(TCHAR c, FIL *fp)
static FRESULT dir_clear(FATFS *fs, DWORD clst)
static FRESULT validate(FFOBJID *obj, FATFS **rfs)
static const BYTE ExCvt[]
static FILESEM Files[FF_FS_LOCK]
FRESULT f_write(FIL *fp, const void *buff, UINT btw, UINT *bw)
static FRESULT dec_lock(UINT i)
static FRESULT sync_fs(FATFS *fs)
static int dbc_2nd(BYTE c)
static FRESULT chk_lock(DIR *dp, int acc)
FRESULT f_open(FIL *fp, const TCHAR *path, BYTE mode)
static FRESULT follow_path(DIR *dp, const TCHAR *path)
static UINT find_volume(FATFS *fs, UINT part)
static void st_dword(BYTE *ptr, DWORD val)
static void putc_init(putbuff *pb, FIL *fp)
static FRESULT remove_chain(FFOBJID *obj, DWORD clst, DWORD pclst)
static WORD ld_word(const BYTE *ptr)
#define DIR_READ_LABEL(dp)
FRESULT f_findnext(DIR *dp, FILINFO *fno)
FRESULT f_expand(FIL *fp, FSIZE_t fsz, BYTE opt)
WCHAR ff_oem2uni(WCHAR oem, WORD cp)
FRESULT f_forward(FIL *fp, UINT(*func)(const BYTE *, UINT), UINT btf, UINT *bf)
FRESULT f_findfirst(DIR *dp, FILINFO *fno, const TCHAR *path, const TCHAR *pattern)
FRESULT f_fdisk(BYTE pdrv, const LBA_t ptbl[], void *work)
WCHAR ff_uni2oem(DWORD uni, WORD cp)
FRESULT f_mkfs(const TCHAR *path, const MKFS_PARM *opt, void *work, UINT len)
FRESULT f_chmod(const TCHAR *path, BYTE attr, BYTE mask)
FRESULT f_setlabel(const TCHAR *label)
FRESULT f_utime(const TCHAR *path, const FILINFO *fno)
void ff_memfree(void *mblock)
FRESULT f_getlabel(const TCHAR *path, TCHAR *label, DWORD *vsn)
DWORD ff_wtoupper(DWORD uni)
FRESULT f_getcwd(TCHAR *buff, UINT len)
void * ff_memalloc(UINT msize)
#define FF_MULTI_PARTITION
TCHAR fname[FF_LFN_BUF+1]
TCHAR altname[FF_SFN_BUF+1]