ReactOS 0.4.16-dev-319-g6cf4263
ff.h File Reference
#include <typedefs.h>
#include "ffconf.h"
Include dependency graph for ff.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Classes

struct  FATFS
 
struct  FIL
 
struct  DIR
 
struct  FILINFO
 

Macros

#define _FATFS   64180 /* Revision ID */
 
#define LD2PD(vol)   (BYTE)(vol) /* Each logical drive is bound to the same physical drive number */
 
#define LD2PT(vol)   0 /* Find first valid partition or in SFD */
 
#define _T(x)   x
 
#define _TEXT(x)   x
 
#define f_eof(fp)   ((int)((fp)->fptr == (fp)->fsize))
 
#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)
 
#define EOF   (-1)
 
#define FA_READ   0x01
 
#define FA_OPEN_EXISTING   0x00
 
#define FA_WRITE   0x02
 
#define FA_CREATE_NEW   0x04
 
#define FA_CREATE_ALWAYS   0x08
 
#define FA_OPEN_ALWAYS   0x10
 
#define FA__WRITTEN   0x20
 
#define FA__DIRTY   0x40
 
#define FS_FAT12   1
 
#define FS_FAT16   2
 
#define FS_FAT32   3
 
#define AM_RDO   0x01 /* Read only */
 
#define AM_HID   0x02 /* Hidden */
 
#define AM_SYS   0x04 /* System */
 
#define AM_VOL   0x08 /* Volume label */
 
#define AM_LFN   0x0F /* LFN entry */
 
#define AM_DIR   0x10 /* Directory */
 
#define AM_ARC   0x20 /* Archive */
 
#define AM_MASK   0x3F /* Mask of defined bits */
 
#define CREATE_LINKMAP   0xFFFFFFFF
 
#define LD_WORD(ptr)   (WORD)(((WORD)*((BYTE*)(ptr)+1)<<8)|(WORD)*(BYTE*)(ptr))
 
#define LD_DWORD(ptr)   (DWORD)(((DWORD)*((BYTE*)(ptr)+3)<<24)|((DWORD)*((BYTE*)(ptr)+2)<<16)|((WORD)*((BYTE*)(ptr)+1)<<8)|*(BYTE*)(ptr))
 
#define ST_WORD(ptr, val)   *(BYTE*)(ptr)=(BYTE)(val); *((BYTE*)(ptr)+1)=(BYTE)((WORD)(val)>>8)
 
#define ST_DWORD(ptr, val)   *(BYTE*)(ptr)=(BYTE)(val); *((BYTE*)(ptr)+1)=(BYTE)((WORD)(val)>>8); *((BYTE*)(ptr)+2)=(BYTE)((DWORD)(val)>>16); *((BYTE*)(ptr)+3)=(BYTE)((DWORD)(val)>>24)
 

Typedefs

typedef char TCHAR
 

Enumerations

enum  FRESULT {
  FR_OK = 0 , FR_DISK_ERR , FR_INT_ERR , FR_NOT_READY ,
  FR_NO_FILE , FR_NO_PATH , FR_INVALID_NAME , FR_DENIED ,
  FR_EXIST , FR_INVALID_OBJECT , FR_WRITE_PROTECTED , FR_INVALID_DRIVE ,
  FR_NOT_ENABLED , FR_NO_FILESYSTEM , FR_MKFS_ABORTED , FR_TIMEOUT ,
  FR_LOCKED , FR_NOT_ENOUGH_CORE , FR_TOO_MANY_OPEN_FILES , FR_INVALID_PARAMETER
}
 

Functions

FRESULT f_open (FIL *fp, const TCHAR *path, BYTE mode)
 
FRESULT f_close (FIL *fp)
 
FRESULT f_read (FIL *fp, void *buff, UINT btr, UINT *br)
 
FRESULT f_write (FIL *fp, const void *buff, UINT btw, UINT *bw)
 
FRESULT f_forward (FIL *fp, UINT(*func)(const BYTE *, UINT), UINT btf, UINT *bf)
 
FRESULT f_lseek (FIL *fp, DWORD ofs)
 
FRESULT f_truncate (FIL *fp)
 
FRESULT f_sync (FIL *fp)
 
FRESULT f_opendir (DIR *dp, const TCHAR *path)
 
FRESULT f_closedir (DIR *dp)
 
FRESULT f_readdir (DIR *dp, FILINFO *fno)
 
FRESULT f_findfirst (DIR *dp, FILINFO *fno, const TCHAR *path, const TCHAR *pattern)
 
FRESULT f_findnext (DIR *dp, FILINFO *fno)
 
FRESULT f_mkdir (const TCHAR *path)
 
FRESULT f_unlink (const TCHAR *path)
 
FRESULT f_rename (const TCHAR *path_old, const TCHAR *path_new)
 
FRESULT f_stat (const TCHAR *path, FILINFO *fno)
 
FRESULT f_chmod (const TCHAR *path, BYTE attr, BYTE mask)
 
FRESULT f_utime (const TCHAR *path, const FILINFO *fno)
 
FRESULT f_chdir (const TCHAR *path)
 
FRESULT f_chdrive (const TCHAR *path)
 
FRESULT f_getcwd (TCHAR *buff, UINT len)
 
FRESULT f_getfree (const TCHAR *path, DWORD *nclst, FATFS **fatfs)
 
FRESULT f_getlabel (const TCHAR *path, TCHAR *label, DWORD *vsn)
 
FRESULT f_setlabel (const TCHAR *label)
 
FRESULT f_mount (FATFS *fs, const TCHAR *path, BYTE opt)
 
FRESULT f_mkfs (const TCHAR *path, BYTE sfd, UINT au)
 
FRESULT f_fdisk (BYTE pdrv, const DWORD szt[], void *work)
 
int f_putc (TCHAR c, FIL *fp)
 
int f_puts (const TCHAR *str, FIL *cp)
 
int f_printf (FIL *fp, const TCHAR *str,...)
 
TCHARf_gets (TCHAR *buff, int len, FIL *fp)
 
DWORD get_fattime (void)
 
WCHAR ff_convert (WCHAR chr, UINT dir)
 
WCHAR ff_wtoupper (WCHAR chr)
 

Macro Definition Documentation

◆ _FATFS

#define _FATFS   64180 /* Revision ID */

Definition at line 20 of file ff.h.

◆ _T

#define _T (   x)    x

Definition at line 68 of file ff.h.

◆ _TEXT

#define _TEXT (   x)    x

Definition at line 69 of file ff.h.

◆ AM_ARC

#define AM_ARC   0x20 /* Archive */

Definition at line 322 of file ff.h.

◆ AM_DIR

#define AM_DIR   0x10 /* Directory */

Definition at line 321 of file ff.h.

◆ AM_HID

#define AM_HID   0x02 /* Hidden */

Definition at line 317 of file ff.h.

◆ AM_LFN

#define AM_LFN   0x0F /* LFN entry */

Definition at line 320 of file ff.h.

◆ AM_MASK

#define AM_MASK   0x3F /* Mask of defined bits */

Definition at line 323 of file ff.h.

◆ AM_RDO

#define AM_RDO   0x01 /* Read only */

Definition at line 316 of file ff.h.

◆ AM_SYS

#define AM_SYS   0x04 /* System */

Definition at line 318 of file ff.h.

◆ AM_VOL

#define AM_VOL   0x08 /* Volume label */

Definition at line 319 of file ff.h.

◆ CREATE_LINKMAP

#define CREATE_LINKMAP   0xFFFFFFFF

Definition at line 327 of file ff.h.

◆ EOF

#define EOF   (-1)

Definition at line 253 of file ff.h.

◆ f_eof

#define f_eof (   fp)    ((int)((fp)->fptr == (fp)->fsize))

Definition at line 245 of file ff.h.

◆ f_error

#define f_error (   fp)    ((fp)->err)

Definition at line 246 of file ff.h.

◆ f_rewind

#define f_rewind (   fp)    f_lseek((fp), 0)

Definition at line 249 of file ff.h.

◆ f_rewinddir

#define f_rewinddir (   dp)    f_readdir((dp), 0)

Definition at line 250 of file ff.h.

◆ f_size

#define f_size (   fp)    ((fp)->fsize)

Definition at line 248 of file ff.h.

◆ f_tell

#define f_tell (   fp)    ((fp)->fptr)

Definition at line 247 of file ff.h.

◆ FA__DIRTY

#define FA__DIRTY   0x40

Definition at line 303 of file ff.h.

◆ FA__WRITTEN

#define FA__WRITTEN   0x20

Definition at line 302 of file ff.h.

◆ FA_CREATE_ALWAYS

#define FA_CREATE_ALWAYS   0x08

Definition at line 300 of file ff.h.

◆ FA_CREATE_NEW

#define FA_CREATE_NEW   0x04

Definition at line 299 of file ff.h.

◆ FA_OPEN_ALWAYS

#define FA_OPEN_ALWAYS   0x10

Definition at line 301 of file ff.h.

◆ FA_OPEN_EXISTING

#define FA_OPEN_EXISTING   0x00

Definition at line 295 of file ff.h.

◆ FA_READ

#define FA_READ   0x01

Definition at line 294 of file ff.h.

◆ FA_WRITE

#define FA_WRITE   0x02

Definition at line 298 of file ff.h.

◆ FS_FAT12

#define FS_FAT12   1

Definition at line 309 of file ff.h.

◆ FS_FAT16

#define FS_FAT16   2

Definition at line 310 of file ff.h.

◆ FS_FAT32

#define FS_FAT32   3

Definition at line 311 of file ff.h.

◆ LD2PD

#define LD2PD (   vol)    (BYTE)(vol) /* Each logical drive is bound to the same physical drive number */

Definition at line 46 of file ff.h.

◆ LD2PT

#define LD2PT (   vol)    0 /* Find first valid partition or in SFD */

Definition at line 47 of file ff.h.

◆ LD_DWORD

#define LD_DWORD (   ptr)    (DWORD)(((DWORD)*((BYTE*)(ptr)+3)<<24)|((DWORD)*((BYTE*)(ptr)+2)<<16)|((WORD)*((BYTE*)(ptr)+1)<<8)|*(BYTE*)(ptr))

Definition at line 341 of file ff.h.

◆ LD_WORD

#define LD_WORD (   ptr)    (WORD)(((WORD)*((BYTE*)(ptr)+1)<<8)|(WORD)*(BYTE*)(ptr))

Definition at line 340 of file ff.h.

◆ ST_DWORD

#define ST_DWORD (   ptr,
  val 
)    *(BYTE*)(ptr)=(BYTE)(val); *((BYTE*)(ptr)+1)=(BYTE)((WORD)(val)>>8); *((BYTE*)(ptr)+2)=(BYTE)((DWORD)(val)>>16); *((BYTE*)(ptr)+3)=(BYTE)((DWORD)(val)>>24)

Definition at line 343 of file ff.h.

◆ ST_WORD

#define ST_WORD (   ptr,
  val 
)    *(BYTE*)(ptr)=(BYTE)(val); *((BYTE*)(ptr)+1)=(BYTE)((WORD)(val)>>8)

Definition at line 342 of file ff.h.

Typedef Documentation

◆ TCHAR

typedef char TCHAR

Definition at line 67 of file ff.h.

Enumeration Type Documentation

◆ FRESULT

Enumerator
FR_OK 
FR_DISK_ERR 
FR_INT_ERR 
FR_NOT_READY 
FR_NO_FILE 
FR_NO_PATH 
FR_INVALID_NAME 
FR_DENIED 
FR_EXIST 
FR_INVALID_OBJECT 
FR_WRITE_PROTECTED 
FR_INVALID_DRIVE 
FR_NOT_ENABLED 
FR_NO_FILESYSTEM 
FR_MKFS_ABORTED 
FR_TIMEOUT 
FR_LOCKED 
FR_NOT_ENOUGH_CORE 
FR_TOO_MANY_OPEN_FILES 
FR_INVALID_PARAMETER 

Definition at line 184 of file ff.h.

184 {
185 FR_OK = 0, /* (0) Succeeded */
186 FR_DISK_ERR, /* (1) A hard error occurred in the low level disk I/O layer */
187 FR_INT_ERR, /* (2) Assertion failed */
188 FR_NOT_READY, /* (3) The physical drive cannot work */
189 FR_NO_FILE, /* (4) Could not find the file */
190 FR_NO_PATH, /* (5) Could not find the path */
191 FR_INVALID_NAME, /* (6) The path name format is invalid */
192 FR_DENIED, /* (7) Access denied due to prohibited access or directory full */
193 FR_EXIST, /* (8) Access denied due to prohibited access */
194 FR_INVALID_OBJECT, /* (9) The file/directory object is invalid */
195 FR_WRITE_PROTECTED, /* (10) The physical drive is write protected */
196 FR_INVALID_DRIVE, /* (11) The logical drive number is invalid */
197 FR_NOT_ENABLED, /* (12) The volume has no work area */
198 FR_NO_FILESYSTEM, /* (13) There is no valid FAT volume */
199 FR_MKFS_ABORTED, /* (14) The f_mkfs() aborted due to any parameter error */
200 FR_TIMEOUT, /* (15) Could not get a grant to access the volume within defined period */
201 FR_LOCKED, /* (16) The operation is rejected according to the file sharing policy */
202 FR_NOT_ENOUGH_CORE, /* (17) LFN working buffer could not be allocated */
203 FR_TOO_MANY_OPEN_FILES, /* (18) Number of open files > _FS_LOCK */
204 FR_INVALID_PARAMETER /* (19) Given parameter is invalid */
205} FRESULT;
FRESULT
Definition: ff.h:184
@ FR_NO_FILESYSTEM
Definition: ff.h:198
@ FR_EXIST
Definition: ff.h:193
@ FR_INVALID_PARAMETER
Definition: ff.h:204
@ FR_INVALID_OBJECT
Definition: ff.h:194
@ FR_TIMEOUT
Definition: ff.h:200
@ FR_INVALID_DRIVE
Definition: ff.h:196
@ FR_MKFS_ABORTED
Definition: ff.h:199
@ FR_TOO_MANY_OPEN_FILES
Definition: ff.h:203
@ FR_OK
Definition: ff.h:185
@ FR_LOCKED
Definition: ff.h:201
@ FR_INVALID_NAME
Definition: ff.h:191
@ FR_DENIED
Definition: ff.h:192
@ FR_NO_FILE
Definition: ff.h:189
@ FR_DISK_ERR
Definition: ff.h:186
@ FR_INT_ERR
Definition: ff.h:187
@ FR_WRITE_PROTECTED
Definition: ff.h:195
@ FR_NOT_READY
Definition: ff.h:188
@ FR_NO_PATH
Definition: ff.h:190
@ FR_NOT_ENOUGH_CORE
Definition: ff.h:202
@ FR_NOT_ENABLED
Definition: ff.h:197

Function Documentation

◆ f_chdir()

FRESULT f_chdir ( const TCHAR path)

◆ f_chdrive()

FRESULT f_chdrive ( const TCHAR path)

◆ f_chmod()

FRESULT f_chmod ( const TCHAR path,
BYTE  attr,
BYTE  mask 
)

Definition at line 3671 of file ff.c.

3676{
3677 FRESULT res;
3678 DIR dj;
3679 BYTE *dir;
3681
3682
3683 res = find_volume(&dj.fs, &path, 1); /* Get logical drive number */
3684 if (res == FR_OK) {
3685 INIT_BUF(dj);
3686 res = follow_path(&dj, path); /* Follow the file path */
3687 FREE_BUF();
3688 if (_FS_RPATH && res == FR_OK && (dj.fn[NSFLAG] & NS_DOT))
3690 if (res == FR_OK) {
3691 dir = dj.dir;
3692 if (!dir) { /* Is it a root directory? */
3694 } else { /* File or sub directory */
3695 mask &= AM_RDO|AM_HID|AM_SYS|AM_ARC; /* Valid attribute mask */
3696 dir[DIR_Attr] = (attr & mask) | (dir[DIR_Attr] & (BYTE)~mask); /* Apply attribute change */
3697 dj.fs->wflag = 1;
3698 res = sync_fs(dj.fs);
3699 }
3700 }
3701 }
3702
3703 LEAVE_FF(dj.fs, res);
3704}
unsigned int dir
Definition: maze.c:112
#define NS_DOT
Definition: ff.c:357
static FRESULT find_volume(FATFS **rfs, const TCHAR **path, BYTE wmode)
Definition: ff.c:2203
#define DEFINE_NAMEBUF
Definition: ff.c:473
#define LEAVE_FF(fs, res)
Definition: ff.c:43
#define INIT_BUF(dobj)
Definition: ff.c:474
#define FREE_BUF()
Definition: ff.c:475
#define NSFLAG
Definition: ff.c:351
#define DIR_Attr
Definition: ff.c:410
static FRESULT sync_fs(FATFS *fs)
Definition: ff.c:760
static FRESULT follow_path(DIR *dp, const TCHAR *path)
Definition: ff.c:2052
#define AM_SYS
Definition: ff.h:318
#define AM_HID
Definition: ff.h:317
#define AM_RDO
Definition: ff.h:316
#define AM_ARC
Definition: ff.h:322
#define _FS_RPATH
Definition: ffconf.h:127
GLuint res
Definition: glext.h:9613
GLenum GLint GLuint mask
Definition: glext.h:6028
Definition: dirent.h:40
FATFS * fs
Definition: ff.h:144
BYTE * fn
Definition: ff.h:151
BYTE * dir
Definition: ff.h:150
BYTE wflag
Definition: ff.h:83
Definition: cookie.c:202
unsigned char BYTE
Definition: xxhash.c:193

◆ f_close()

FRESULT f_close ( FIL fp)

Definition at line 2857 of file ff.c.

2860{
2861 FRESULT res;
2862
2863
2864#if !_FS_READONLY
2865 res = f_sync(fp); /* Flush cached data */
2866 if (res == FR_OK)
2867#endif
2868 {
2869 res = validate(fp); /* Lock volume */
2870 if (res == FR_OK) {
2871#if _FS_REENTRANT
2872 FATFS *fs = fp->fs;
2873#endif
2874#if _FS_LOCK
2875 res = dec_lock(fp->lockid); /* Decrement file open counter */
2876 if (res == FR_OK)
2877#endif
2878 fp->fs = 0; /* Invalidate file object */
2879#if _FS_REENTRANT
2880 unlock_fs(fs, FR_OK); /* Unlock volume */
2881#endif
2882 }
2883 }
2884 return res;
2885}
static FRESULT validate(void *obj)
Definition: ff.c:2372
FRESULT f_sync(FIL *fp)
Definition: ff.c:2809
Definition: ff.h:78
FATFS * fs
Definition: ff.h:115
Definition: ffs.h:70

Referenced by main().

◆ f_closedir()

FRESULT f_closedir ( DIR dp)

Definition at line 3243 of file ff.c.

3246{
3247 FRESULT res;
3248
3249
3250 res = validate(dp);
3251 if (res == FR_OK) {
3252#if _FS_REENTRANT
3253 FATFS *fs = dp->fs;
3254#endif
3255#if _FS_LOCK
3256 if (dp->lockid) /* Decrement sub-directory open counter */
3257 res = dec_lock(dp->lockid);
3258 if (res == FR_OK)
3259#endif
3260 dp->fs = 0; /* Invalidate directory object */
3261#if _FS_REENTRANT
3262 unlock_fs(fs, FR_OK); /* Unlock volume */
3263#endif
3264 }
3265 return res;
3266}

◆ f_fdisk()

FRESULT f_fdisk ( BYTE  pdrv,
const DWORD  szt[],
void work 
)

◆ f_findfirst()

FRESULT f_findfirst ( DIR dp,
FILINFO fno,
const TCHAR path,
const TCHAR pattern 
)

◆ f_findnext()

FRESULT f_findnext ( DIR dp,
FILINFO fno 
)

◆ f_forward()

FRESULT f_forward ( FIL fp,
UINT(*)(const BYTE *, UINT func,
UINT  btf,
UINT bf 
)

◆ f_getcwd()

FRESULT f_getcwd ( TCHAR buff,
UINT  len 
)

◆ f_getfree()

FRESULT f_getfree ( const TCHAR path,
DWORD nclst,
FATFS **  fatfs 
)

Definition at line 3404 of file ff.c.

3409{
3410 FRESULT res;
3411 FATFS *fs;
3412 DWORD nfree, clst, sect, stat;
3413 UINT i;
3414 BYTE fat, *p;
3415
3416
3417 /* Get logical drive number */
3418 res = find_volume(fatfs, &path, 0);
3419 fs = *fatfs;
3420 if (res == FR_OK) {
3421 /* If free_clust is valid, return it without full cluster scan */
3422 if (fs->free_clust <= fs->n_fatent - 2) {
3423 *nclst = fs->free_clust;
3424 } else {
3425 /* Get number of free clusters */
3426 fat = fs->fs_type;
3427 nfree = 0;
3428 if (fat == FS_FAT12) { /* Sector unalighed entries: Search FAT via regular routine. */
3429 clst = 2;
3430 do {
3431 stat = get_fat(fs, clst);
3432 if (stat == 0xFFFFFFFF) { res = FR_DISK_ERR; break; }
3433 if (stat == 1) { res = FR_INT_ERR; break; }
3434 if (stat == 0) nfree++;
3435 } while (++clst < fs->n_fatent);
3436 } else { /* Sector alighed entries: Accelerate the FAT search. */
3437 clst = fs->n_fatent; sect = fs->fatbase;
3438 i = 0; p = 0;
3439 do {
3440 if (!i) {
3441 res = move_window(fs, sect++);
3442 if (res != FR_OK) break;
3443 p = fs->win;
3444 i = SS(fs);
3445 }
3446 if (fat == FS_FAT16) {
3447 if (LD_WORD(p) == 0) nfree++;
3448 p += 2; i -= 2;
3449 } else {
3450 if ((LD_DWORD(p) & 0x0FFFFFFF) == 0) nfree++;
3451 p += 4; i -= 4;
3452 }
3453 } while (--clst);
3454 }
3455 fs->free_clust = nfree; /* free_clust is valid */
3456 fs->fsi_flag |= 1; /* FSInfo is to be updated */
3457 *nclst = nfree; /* Return the free clusters */
3458 }
3459 }
3460 LEAVE_FF(fs, res);
3461}
#define stat
Definition: acwin.h:99
#define SS(fs)
Definition: ff.c:54
DWORD get_fat(FATFS *fs, DWORD clst)
Definition: ff.c:818
static FRESULT move_window(FATFS *fs, DWORD sector)
Definition: ff.c:729
#define LD_WORD(ptr)
Definition: ff.h:340
#define LD_DWORD(ptr)
Definition: ff.h:341
#define FS_FAT16
Definition: ff.h:310
#define FS_FAT12
Definition: ff.h:309
unsigned long DWORD
Definition: ntddk_ex.h:95
GLfloat GLfloat p
Definition: glext.h:8902
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define fs
Definition: i386-dis.c:444
static unsigned char * fat
Definition: mkdosfs.c:542
unsigned int UINT
Definition: ndis.h:50
Definition: stat.h:55

◆ f_getlabel()

FRESULT f_getlabel ( const TCHAR path,
TCHAR label,
DWORD vsn 
)

Definition at line 3839 of file ff.c.

3844{
3845 FRESULT res;
3846 DIR dj;
3847 UINT i, j;
3848#if _USE_LFN && _LFN_UNICODE
3849 WCHAR w;
3850#endif
3851
3852
3853 /* Get logical drive number */
3854 res = find_volume(&dj.fs, &path, 0);
3855
3856 /* Get volume label */
3857 if (res == FR_OK && label) {
3858 dj.sclust = 0; /* Open root directory */
3859 res = dir_sdi(&dj, 0);
3860 if (res == FR_OK) {
3861 res = dir_read(&dj, 1); /* Get an entry with AM_VOL */
3862 if (res == FR_OK) { /* A volume label is exist */
3863#if _USE_LFN && _LFN_UNICODE
3864 i = j = 0;
3865 do {
3866 w = (i < 11) ? dj.dir[i++] : ' ';
3867 if (IsDBCS1(w) && i < 11 && IsDBCS2(dj.dir[i]))
3868 w = w << 8 | dj.dir[i++];
3869 label[j++] = ff_convert(w, 1); /* OEM -> Unicode */
3870 } while (j < 11);
3871#else
3872 mem_cpy(label, dj.dir, 11);
3873#endif
3874 j = 11;
3875 do {
3876 label[j] = 0;
3877 if (!j) break;
3878 } while (label[--j] == ' ');
3879 }
3880 if (res == FR_NO_FILE) { /* No label, return nul string */
3881 label[0] = 0;
3882 res = FR_OK;
3883 }
3884 }
3885 }
3886
3887 /* Get volume serial number */
3888 if (res == FR_OK && vsn) {
3889 res = move_window(dj.fs, dj.fs->volbase);
3890 if (res == FR_OK) {
3891 i = dj.fs->fs_type == FS_FAT32 ? BS_VolID32 : BS_VolID;
3892 *vsn = LD_DWORD(&dj.fs->win[i]);
3893 }
3894 }
3895
3896 LEAVE_FF(dj.fs, res);
3897}
static FRESULT dir_sdi(DIR *dp, UINT idx)
Definition: ff.c:1080
#define BS_VolID
Definition: ff.c:386
static FRESULT dir_read(DIR *dp, int vol)
Definition: ff.c:1519
#define IsDBCS1(c)
Definition: ff.c:344
#define IsDBCS2(c)
Definition: ff.c:345
static void mem_cpy(void *dst, const void *src, UINT cnt)
Definition: ff.c:507
#define BS_VolID32
Definition: ff.c:398
#define FS_FAT32
Definition: ff.h:311
WCHAR ff_convert(WCHAR chr, UINT dir)
Definition: ccsbcs.c:275
GLubyte GLubyte GLubyte GLubyte w
Definition: glext.h:6102
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
if(dx< 0)
Definition: linetemp.h:194
static const WCHAR label[]
Definition: itemdlg.c:1546
DWORD sclust
Definition: ff.h:147
BYTE win[_MAX_SS]
Definition: ff.h:107
DWORD volbase
Definition: ff.h:102
BYTE fs_type
Definition: ff.h:79
__wchar_t WCHAR
Definition: xmlstorage.h:180

◆ f_gets()

TCHAR * f_gets ( TCHAR buff,
int  len,
FIL fp 
)

◆ f_lseek()

FRESULT f_lseek ( FIL fp,
DWORD  ofs 
)

Definition at line 3029 of file ff.c.

3033{
3034 FRESULT res;
3035 DWORD clst, bcs, nsect, ifptr;
3036#if _USE_FASTSEEK
3037 DWORD cl, pcl, ncl, tcl, dsc, tlen, ulen, *tbl;
3038#endif
3039
3040
3041 res = validate(fp); /* Check validity of the object */
3042 if (res != FR_OK) LEAVE_FF(fp->fs, res);
3043 if (fp->err) /* Check error */
3044 LEAVE_FF(fp->fs, (FRESULT)fp->err);
3045
3046#if _USE_FASTSEEK
3047 if (fp->cltbl) { /* Fast seek */
3048 if (ofs == CREATE_LINKMAP) { /* Create CLMT */
3049 tbl = fp->cltbl;
3050 tlen = *tbl++; ulen = 2; /* Given table size and required table size */
3051 cl = fp->sclust; /* Top of the chain */
3052 if (cl) {
3053 do {
3054 /* Get a fragment */
3055 tcl = cl; ncl = 0; ulen += 2; /* Top, length and used items */
3056 do {
3057 pcl = cl; ncl++;
3058 cl = get_fat(fp->fs, cl);
3059 if (cl <= 1) ABORT(fp->fs, FR_INT_ERR);
3060 if (cl == 0xFFFFFFFF) ABORT(fp->fs, FR_DISK_ERR);
3061 } while (cl == pcl + 1);
3062 if (ulen <= tlen) { /* Store the length and top of the fragment */
3063 *tbl++ = ncl; *tbl++ = tcl;
3064 }
3065 } while (cl < fp->fs->n_fatent); /* Repeat until end of chain */
3066 }
3067 *fp->cltbl = ulen; /* Number of items used */
3068 if (ulen <= tlen)
3069 *tbl = 0; /* Terminate table */
3070 else
3071 res = FR_NOT_ENOUGH_CORE; /* Given table size is smaller than required */
3072
3073 } else { /* Fast seek */
3074 if (ofs > fp->fsize) /* Clip offset at the file size */
3075 ofs = fp->fsize;
3076 fp->fptr = ofs; /* Set file pointer */
3077 if (ofs) {
3078 fp->clust = clmt_clust(fp, ofs - 1);
3079 dsc = clust2sect(fp->fs, fp->clust);
3080 if (!dsc) ABORT(fp->fs, FR_INT_ERR);
3081 dsc += (ofs - 1) / SS(fp->fs) & (fp->fs->csize - 1);
3082 if (fp->fptr % SS(fp->fs) && dsc != fp->dsect) { /* Refill sector cache if needed */
3083#if !_FS_TINY
3084#if !_FS_READONLY
3085 if (fp->flag & FA__DIRTY) { /* Write-back dirty sector cache */
3086 if (disk_write(fp->fs->drv, fp->buf, fp->dsect, 1) != RES_OK)
3087 ABORT(fp->fs, FR_DISK_ERR);
3088 fp->flag &= ~FA__DIRTY;
3089 }
3090#endif
3091 if (disk_read(fp->fs->drv, fp->buf, dsc, 1) != RES_OK) /* Load current sector */
3092 ABORT(fp->fs, FR_DISK_ERR);
3093#endif
3094 fp->dsect = dsc;
3095 }
3096 }
3097 }
3098 } else
3099#endif
3100
3101 /* Normal Seek */
3102 {
3103 if (ofs > fp->fsize /* In read-only mode, clip offset with the file size */
3104#if !_FS_READONLY
3105 && !(fp->flag & FA_WRITE)
3106#endif
3107 ) ofs = fp->fsize;
3108
3109 ifptr = fp->fptr;
3110 fp->fptr = nsect = 0;
3111 if (ofs) {
3112 bcs = (DWORD)fp->fs->csize * SS(fp->fs); /* Cluster size (byte) */
3113 if (ifptr > 0 &&
3114 (ofs - 1) / bcs >= (ifptr - 1) / bcs) { /* When seek to same or following cluster, */
3115 fp->fptr = (ifptr - 1) & ~(bcs - 1); /* start from the current cluster */
3116 ofs -= fp->fptr;
3117 clst = fp->clust;
3118 } else { /* When seek to back cluster, */
3119 clst = fp->sclust; /* start from the first cluster */
3120#if !_FS_READONLY
3121 if (clst == 0) { /* If no cluster chain, create a new chain */
3122 clst = create_chain(fp->fs, 0);
3123 if (clst == 1) ABORT(fp->fs, FR_INT_ERR);
3124 if (clst == 0xFFFFFFFF) ABORT(fp->fs, FR_DISK_ERR);
3125 fp->sclust = clst;
3126 }
3127#endif
3128 fp->clust = clst;
3129 }
3130 if (clst != 0) {
3131 while (ofs > bcs) { /* Cluster following loop */
3132#if !_FS_READONLY
3133 if (fp->flag & FA_WRITE) { /* Check if in write mode or not */
3134 clst = create_chain(fp->fs, clst); /* Force stretch if in write mode */
3135 if (clst == 0) { /* When disk gets full, clip file size */
3136 ofs = bcs; break;
3137 }
3138 } else
3139#endif
3140 clst = get_fat(fp->fs, clst); /* Follow cluster chain if not in write mode */
3141 if (clst == 0xFFFFFFFF) ABORT(fp->fs, FR_DISK_ERR);
3142 if (clst <= 1 || clst >= fp->fs->n_fatent) ABORT(fp->fs, FR_INT_ERR);
3143 fp->clust = clst;
3144 fp->fptr += bcs;
3145 ofs -= bcs;
3146 }
3147 fp->fptr += ofs;
3148 if (ofs % SS(fp->fs)) {
3149 nsect = clust2sect(fp->fs, clst); /* Current sector */
3150 if (!nsect) ABORT(fp->fs, FR_INT_ERR);
3151 nsect += ofs / SS(fp->fs);
3152 }
3153 }
3154 }
3155 if (fp->fptr % SS(fp->fs) && nsect != fp->dsect) { /* Fill sector cache if needed */
3156#if !_FS_TINY
3157#if !_FS_READONLY
3158 if (fp->flag & FA__DIRTY) { /* Write-back dirty sector cache */
3159 if (disk_write(fp->fs->drv, fp->buf, fp->dsect, 1) != RES_OK)
3160 ABORT(fp->fs, FR_DISK_ERR);
3161 fp->flag &= ~FA__DIRTY;
3162 }
3163#endif
3164 if (disk_read(fp->fs->drv, fp->buf, nsect, 1) != RES_OK) /* Fill sector cache */
3165 ABORT(fp->fs, FR_DISK_ERR);
3166#endif
3167 fp->dsect = nsect;
3168 }
3169#if !_FS_READONLY
3170 if (fp->fptr > fp->fsize) { /* Set file change flag if the file size is extended */
3171 fp->fsize = fp->fptr;
3172 fp->flag |= FA__WRITTEN;
3173 }
3174#endif
3175 }
3176
3177 LEAVE_FF(fp->fs, res);
3178}
static MSG_ENTRY create_chain[]
static BOOLEAN disk_read(ULONG DeviceId, u64 physical, void *dest, u32 count)
Definition: btrfs.c:253
@ RES_OK
Definition: diskio.h:23
#define ABORT(fs, res)
Definition: ff.c:46
DWORD clust2sect(FATFS *fs, DWORD clst)
Definition: ff.c:800
#define FA__DIRTY
Definition: ff.h:303
#define FA__WRITTEN
Definition: ff.h:302
#define CREATE_LINKMAP
Definition: ff.h:327
#define FA_WRITE
Definition: ff.h:298
#define _FS_READONLY
Definition: ffconf.h:11
static NTSTATUS disk_write(RDPCLIENT *This, NTHANDLE handle, uint8 *data, uint32 length, uint32 offset, uint32 *result)
Definition: disk.c:585
#define DWORD
Definition: nt_native.h:44
BYTE csize
Definition: ff.h:81
BYTE drv
Definition: ff.h:80
DWORD n_fatent
Definition: ff.h:100
DWORD fptr
Definition: ff.h:119
BYTE buf[_MAX_SS]
Definition: ff.h:135
DWORD fsize
Definition: ff.h:120
DWORD clust
Definition: ff.h:122
DWORD dsect
Definition: ff.h:123
BYTE flag
Definition: ff.h:117
DWORD sclust
Definition: ff.h:121
BYTE err
Definition: ff.h:118

◆ f_mkdir()

FRESULT f_mkdir ( const TCHAR path)

Definition at line 3595 of file ff.c.

3598{
3599 FRESULT res;
3600 DIR dj;
3601 BYTE *dir, n;
3602 DWORD dsc, dcl, pcl, tm = GET_FATTIME();
3604
3605
3606 /* Get logical drive number */
3607 res = find_volume(&dj.fs, &path, 1);
3608 if (res == FR_OK) {
3609 INIT_BUF(dj);
3610 res = follow_path(&dj, path); /* Follow the file path */
3611 if (res == FR_OK) res = FR_EXIST; /* Any object with same name is already existing */
3612 if (_FS_RPATH && res == FR_NO_FILE && (dj.fn[NSFLAG] & NS_DOT))
3614 if (res == FR_NO_FILE) { /* Can create a new directory */
3615 dcl = create_chain(dj.fs, 0); /* Allocate a cluster for the new directory table */
3616 res = FR_OK;
3617 if (dcl == 0) res = FR_DENIED; /* No space to allocate a new cluster */
3618 if (dcl == 1) res = FR_INT_ERR;
3619 if (dcl == 0xFFFFFFFF) res = FR_DISK_ERR;
3620 if (res == FR_OK) /* Flush FAT */
3621 res = sync_window(dj.fs);
3622 if (res == FR_OK) { /* Initialize the new directory table */
3623 dsc = clust2sect(dj.fs, dcl);
3624 dir = dj.fs->win;
3625 mem_set(dir, 0, SS(dj.fs));
3626 mem_set(dir + DIR_Name, ' ', 11); /* Create "." entry */
3627 dir[DIR_Name] = '.';
3628 dir[DIR_Attr] = AM_DIR;
3631 st_clust(dir, dcl);
3632 mem_cpy(dir + SZ_DIRE, dir, SZ_DIRE); /* Create ".." entry */
3633 dir[SZ_DIRE + 1] = '.'; pcl = dj.sclust;
3634 if (dj.fs->fs_type == FS_FAT32 && pcl == dj.fs->dirbase)
3635 pcl = 0;
3636 st_clust(dir + SZ_DIRE, pcl);
3637 for (n = dj.fs->csize; n; n--) { /* Write dot entries and clear following sectors */
3638 dj.fs->winsect = dsc++;
3639 dj.fs->wflag = 1;
3640 res = sync_window(dj.fs);
3641 if (res != FR_OK) break;
3642 mem_set(dir, 0, SS(dj.fs));
3643 }
3644 }
3645 if (res == FR_OK) res = dir_register(&dj); /* Register the object to the directoy */
3646 if (res != FR_OK) {
3647 remove_chain(dj.fs, dcl); /* Could not register, remove cluster chain */
3648 } else {
3649 dir = dj.dir;
3650 dir[DIR_Attr] = AM_DIR; /* Attribute */
3651 ST_DWORD(dir + DIR_CrtTime, tm); /* Created time */
3652 ST_DWORD(dir + DIR_WrtTime, tm); /* Modified time */
3653 st_clust(dir, dcl); /* Table start cluster */
3654 dj.fs->wflag = 1;
3655 res = sync_fs(dj.fs);
3656 }
3657 }
3658 FREE_BUF();
3659 }
3660
3661 LEAVE_FF(dj.fs, res);
3662}
static void mem_set(void *dst, int val, UINT cnt)
Definition: ff.c:524
static void st_clust(BYTE *dir, DWORD cl)
Definition: ff.c:1252
#define DIR_CrtTime
Definition: ff.c:413
#define SZ_DIRE
Definition: ff.c:426
static FRESULT sync_window(FATFS *fs)
Definition: ff.c:700
#define GET_FATTIME()
Definition: ff.c:67
static FRESULT dir_register(DIR *dp)
Definition: ff.c:1578
static FRESULT remove_chain(FATFS *fs, DWORD clst)
Definition: ff.c:937
#define DIR_WrtTime
Definition: ff.c:417
#define DIR_Name
Definition: ff.c:409
#define AM_DIR
Definition: ff.h:321
#define ST_DWORD(ptr, val)
Definition: ff.h:343
GLdouble n
Definition: glext.h:7729
DWORD dirbase
Definition: ff.h:104
DWORD winsect
Definition: ff.h:106
Definition: time.h:68

Referenced by main().

◆ f_mkfs()

FRESULT f_mkfs ( const TCHAR path,
BYTE  sfd,
UINT  au 
)

Definition at line 4068 of file ff.c.

4073{
4074 static const WORD vst[] = { 1024, 512, 256, 128, 64, 32, 16, 8, 4, 2, 0};
4075 static const WORD cst[] = {32768, 16384, 8192, 4096, 2048, 16384, 8192, 4096, 2048, 1024, 512};
4076 int vol;
4077 BYTE fmt, md, sys, *tbl, pdrv, part;
4078 DWORD n_clst, vs, n, wsect;
4079 UINT i;
4080 DWORD b_vol, b_fat, b_dir, b_data; /* LBA */
4081 DWORD n_vol, n_rsv, n_fat, n_dir; /* Size */
4082 FATFS *fs;
4083 DSTATUS stat;
4084#if _USE_TRIM
4085 DWORD eb[2];
4086#endif
4087
4088
4089 /* Check mounted drive and clear work area */
4090 if (sfd > 1) return FR_INVALID_PARAMETER;
4091 vol = get_ldnumber(&path);
4092 if (vol < 0) return FR_INVALID_DRIVE;
4093 fs = FatFs[vol];
4094 if (!fs) return FR_NOT_ENABLED;
4095 fs->fs_type = 0;
4096 pdrv = LD2PD(vol); /* Physical drive */
4097 part = LD2PT(vol); /* Partition (0:auto detect, 1-4:get from partition table)*/
4098
4099 /* Get disk statics */
4100 stat = disk_initialize(pdrv);
4101 if (stat & STA_NOINIT) return FR_NOT_READY;
4102 if (stat & STA_PROTECT) return FR_WRITE_PROTECTED;
4103#if _MAX_SS != _MIN_SS /* Get disk sector size */
4104 if (disk_ioctl(pdrv, GET_SECTOR_SIZE, &SS(fs)) != RES_OK || SS(fs) > _MAX_SS || SS(fs) < _MIN_SS)
4105 return FR_DISK_ERR;
4106#endif
4107 if (_MULTI_PARTITION && part) {
4108 /* Get partition information from partition table in the MBR */
4109 if (disk_read(pdrv, fs->win, 0, 1) != RES_OK) return FR_DISK_ERR;
4110 if (LD_WORD(fs->win + BS_55AA) != 0xAA55) return FR_MKFS_ABORTED;
4111 tbl = &fs->win[MBR_Table + (part - 1) * SZ_PTE];
4112 if (!tbl[4]) return FR_MKFS_ABORTED; /* No partition? */
4113 b_vol = LD_DWORD(tbl + 8); /* Volume start sector */
4114 n_vol = LD_DWORD(tbl + 12); /* Volume size */
4115 } else {
4116 /* Create a partition in this function */
4117 if (disk_ioctl(pdrv, GET_SECTOR_COUNT, &n_vol) != RES_OK || n_vol < 128)
4118 return FR_DISK_ERR;
4119 b_vol = (sfd) ? 0 : 63; /* Volume start sector */
4120 n_vol -= b_vol; /* Volume size */
4121 }
4122
4123 if (au & (au - 1)) au = 0;
4124 if (!au) { /* AU auto selection */
4125 vs = n_vol / (2000 / (SS(fs) / 512));
4126 for (i = 0; vs < vst[i]; i++) ;
4127 au = cst[i];
4128 }
4129 if (au >= _MIN_SS) au /= SS(fs); /* Number of sectors per cluster */
4130 if (!au) au = 1;
4131 if (au > 128) au = 128;
4132
4133 /* Pre-compute number of clusters and FAT sub-type */
4134 n_clst = n_vol / au;
4135 fmt = FS_FAT12;
4136 if (n_clst >= MIN_FAT16) fmt = FS_FAT16;
4137 if (n_clst >= MIN_FAT32) fmt = FS_FAT32;
4138
4139 /* Determine offset and size of FAT structure */
4140 if (fmt == FS_FAT32) {
4141 n_fat = ((n_clst * 4) + 8 + SS(fs) - 1) / SS(fs);
4142 n_rsv = 32;
4143 n_dir = 0;
4144 } else {
4145 n_fat = (fmt == FS_FAT12) ? (n_clst * 3 + 1) / 2 + 3 : (n_clst * 2) + 4;
4146 n_fat = (n_fat + SS(fs) - 1) / SS(fs);
4147 n_rsv = 1;
4148 if (fmt == FS_FAT12)
4149 n_dir = (DWORD)N_ROOTDIR12 * SZ_DIRE / SS(fs);
4150 else
4151 n_dir = (DWORD)N_ROOTDIR16 * SZ_DIRE / SS(fs);
4152 }
4153 b_fat = b_vol + n_rsv; /* FAT area start sector */
4154 b_dir = b_fat + n_fat * N_FATS; /* Directory area start sector */
4155 b_data = b_dir + n_dir; /* Data area start sector */
4156 if (n_vol < b_data + au - b_vol) return FR_MKFS_ABORTED; /* Too small volume */
4157
4158 /* Align data start sector to erase block boundary (for flash memory media) */
4159 if (disk_ioctl(pdrv, GET_BLOCK_SIZE, &n) != RES_OK || !n || n > 32768) n = 1;
4160 n = (b_data + n - 1) & ~(n - 1); /* Next nearest erase block from current data start */
4161 n = (n - b_data) / N_FATS;
4162 if (fmt == FS_FAT32) { /* FAT32: Move FAT offset */
4163 n_rsv += n;
4164 b_fat += n;
4165 } else if (fmt == FS_FAT16) { /* FAT16: Expand FAT size */
4166 n_fat += n;
4167 } // else /* if (fmt == FS_FAT12) */ {} /* FAT12: Do nothing */
4168
4169 /* Determine number of clusters and final check of validity of the FAT sub-type */
4170 n_clst = (n_vol - n_rsv - n_fat * N_FATS - n_dir) / au;
4171 if ( (fmt == FS_FAT16 && n_clst < MIN_FAT16)
4172 || (fmt == FS_FAT32 && n_clst < MIN_FAT32))
4173 return FR_MKFS_ABORTED;
4174
4175 /* Determine system ID in the partition table */
4176 if (fmt == FS_FAT32) {
4177 sys = 0x0C; /* FAT32X */
4178 } else {
4179 if (fmt == FS_FAT12 && n_vol < 0x10000) {
4180 sys = 0x01; /* FAT12(<65536) */
4181 } else {
4182 sys = (n_vol < 0x10000) ? 0x04 : 0x06; /* FAT16(<65536) : FAT12/16(>=65536) */
4183 }
4184 }
4185
4186 if (_MULTI_PARTITION && part) {
4187 /* Update system ID in the partition table */
4188 tbl = &fs->win[MBR_Table + (part - 1) * SZ_PTE];
4189 tbl[4] = sys;
4190 if (disk_write(pdrv, fs->win, 0, 1) != RES_OK) /* Write it to teh MBR */
4191 return FR_DISK_ERR;
4192 md = 0xF8;
4193 } else {
4194 if (sfd) { /* No partition table (SFD) */
4195 md = 0xF0;
4196 } else { /* Create partition table (FDISK) */
4197 mem_set(fs->win, 0, SS(fs));
4198 tbl = fs->win + MBR_Table; /* Create partition table for single partition in the drive */
4199 tbl[1] = 1; /* Partition start head */
4200 tbl[2] = 1; /* Partition start sector */
4201 tbl[3] = 0; /* Partition start cylinder */
4202 tbl[4] = sys; /* System type */
4203 tbl[5] = 254; /* Partition end head */
4204 n = (b_vol + n_vol) / 63 / 255;
4205 tbl[6] = (BYTE)(n >> 2 | 63); /* Partition end sector */
4206 tbl[7] = (BYTE)n; /* End cylinder */
4207 ST_DWORD(tbl + 8, 63); /* Partition start in LBA */
4208 ST_DWORD(tbl + 12, n_vol); /* Partition size in LBA */
4209 ST_WORD(fs->win + BS_55AA, 0xAA55); /* MBR signature */
4210 if (disk_write(pdrv, fs->win, 0, 1) != RES_OK) /* Write it to the MBR */
4211 return FR_DISK_ERR;
4212 md = 0xF8;
4213 }
4214 }
4215
4216 /* Create BPB in the VBR */
4217 tbl = fs->win; /* Clear sector */
4218 mem_set(tbl, 0, SS(fs));
4219 mem_cpy(tbl, "\xEB\xFE\x90" "MSDOS5.0", 11);/* Boot jump code, OEM name */
4220 i = SS(fs); /* Sector size */
4221 ST_WORD(tbl + BPB_BytsPerSec, i);
4222 tbl[BPB_SecPerClus] = (BYTE)au; /* Sectors per cluster */
4223 ST_WORD(tbl + BPB_RsvdSecCnt, n_rsv); /* Reserved sectors */
4224 tbl[BPB_NumFATs] = N_FATS; /* Number of FATs */
4225 i = (fmt == FS_FAT32) ? 0 : (fmt == FS_FAT12 ? N_ROOTDIR12 : N_ROOTDIR16); /* Number of root directory entries */
4226 ST_WORD(tbl + BPB_RootEntCnt, i);
4227 if (n_vol < 0x10000) { /* Number of total sectors */
4228 ST_WORD(tbl + BPB_TotSec16, n_vol);
4229 } else {
4230 ST_DWORD(tbl + BPB_TotSec32, n_vol);
4231 }
4232 tbl[BPB_Media] = md; /* Media descriptor */
4233 ST_DWORD(tbl + BPB_HiddSec, b_vol); /* Hidden sectors */
4234 n = GET_FATTIME(); /* Use current time as VSN */
4235 if (fmt == FS_FAT32) {
4236 ST_WORD(tbl + BPB_SecPerTrk, 63); /* Number of sectors per track */
4237 ST_WORD(tbl + BPB_NumHeads, 255); /* Number of heads */
4238 ST_DWORD(tbl + BS_VolID32, n); /* VSN */
4239 ST_DWORD(tbl + BPB_FATSz32, n_fat); /* Number of sectors per FAT */
4240 ST_DWORD(tbl + BPB_RootClus, 2); /* Root directory start cluster (2) */
4241 ST_WORD(tbl + BPB_FSInfo, 1); /* FSINFO record offset (VBR + 1) */
4242 ST_WORD(tbl + BPB_BkBootSec, 6); /* Backup boot record offset (VBR + 6) */
4243 tbl[BS_DrvNum32] = 0x80; /* Drive number */
4244 tbl[BS_BootSig32] = 0x29; /* Extended boot signature */
4245 mem_cpy(tbl + BS_VolLab32, "NO NAME " "FAT32 ", 19); /* Volume label, FAT signature */
4246 } else if (fmt == FS_FAT16) {
4247 ST_WORD(tbl + BPB_SecPerTrk, 63); /* Number of sectors per track */
4248 ST_WORD(tbl + BPB_NumHeads, 255); /* Number of heads */
4249 ST_DWORD(tbl + BS_VolID, n); /* VSN */
4250 ST_WORD(tbl + BPB_FATSz16, n_fat); /* Number of sectors per FAT */
4251 tbl[BS_DrvNum] = 0x80; /* Drive number */
4252 tbl[BS_BootSig] = 0x29; /* Extended boot signature */
4253 mem_cpy(tbl + BS_VolLab, "NO NAME " "FAT16 ", 19); /* Volume label, FAT signature */
4254 } else /* if (fmt == FS_FAT12) */ {
4255 /* Assume floppy characteristics */
4256 ST_WORD(tbl + BPB_SecPerTrk, 0x12); /* Number of sectors per track */
4257 ST_WORD(tbl + BPB_NumHeads, 0x02); /* Number of heads */
4258 ST_DWORD(tbl + BS_VolID, n); /* VSN */
4259 ST_WORD(tbl + BPB_FATSz16, n_fat); /* Number of sectors per FAT */
4260 tbl[BS_DrvNum] = 0x00; /* Drive number */
4261 tbl[BS_BootSig] = 0x29; /* Extended boot signature */
4262 mem_cpy(tbl + BS_VolLab, "NO NAME " "FAT12 ", 19); /* Volume label, FAT signature */
4263 }
4264 ST_WORD(tbl + BS_55AA, 0xAA55); /* Signature (Offset is fixed here regardless of sector size) */
4265 if (disk_write(pdrv, tbl, b_vol, 1) != RES_OK) /* Write it to the VBR sector */
4266 return FR_DISK_ERR;
4267 if (fmt == FS_FAT32) /* Write it to the backup VBR if needed (VBR + 6) */
4268 disk_write(pdrv, tbl, b_vol + 6, 1);
4269
4270 /* Initialize FAT area */
4271 wsect = b_fat;
4272 for (i = 0; i < N_FATS; i++) { /* Initialize each FAT copy */
4273 mem_set(tbl, 0, SS(fs)); /* 1st sector of the FAT */
4274 n = md; /* Media descriptor byte */
4275 if (fmt != FS_FAT32) {
4276 n |= (fmt == FS_FAT12) ? 0x00FFFF00 : 0xFFFFFF00;
4277 ST_DWORD(tbl + 0, n); /* Reserve cluster #0-1 (FAT12/16) */
4278 } else {
4279 n |= 0xFFFFFF00;
4280 ST_DWORD(tbl + 0, n); /* Reserve cluster #0-1 (FAT32) */
4281 ST_DWORD(tbl + 4, 0xFFFFFFFF);
4282 ST_DWORD(tbl + 8, 0x0FFFFFFF); /* Reserve cluster #2 for root directory */
4283 }
4284 if (disk_write(pdrv, tbl, wsect++, 1) != RES_OK)
4285 return FR_DISK_ERR;
4286 mem_set(tbl, 0, SS(fs)); /* Fill following FAT entries with zero */
4287 for (n = 1; n < n_fat; n++) { /* This loop may take a time on FAT32 volume due to many single sector writes */
4288 if (disk_write(pdrv, tbl, wsect++, 1) != RES_OK)
4289 return FR_DISK_ERR;
4290 }
4291 }
4292
4293 /* Initialize root directory */
4294 i = (fmt == FS_FAT32) ? au : (UINT)n_dir;
4295 do {
4296 if (disk_write(pdrv, tbl, wsect++, 1) != RES_OK)
4297 return FR_DISK_ERR;
4298 } while (--i);
4299
4300#if _USE_TRIM /* Erase data area if needed */
4301 {
4302 eb[0] = wsect; eb[1] = wsect + (n_clst - ((fmt == FS_FAT32) ? 1 : 0)) * au - 1;
4303 disk_ioctl(pdrv, CTRL_TRIM, eb);
4304 }
4305#endif
4306
4307 /* Create FSINFO if needed */
4308 if (fmt == FS_FAT32) {
4309 ST_DWORD(tbl + FSI_LeadSig, 0x41615252);
4310 ST_DWORD(tbl + FSI_StrucSig, 0x61417272);
4311 ST_DWORD(tbl + FSI_Free_Count, n_clst - 1); /* Number of free clusters */
4312 ST_DWORD(tbl + FSI_Nxt_Free, 2); /* Last allocated cluster# */
4313 ST_WORD(tbl + BS_55AA, 0xAA55);
4314 disk_write(pdrv, tbl, b_vol + 1, 1); /* Write original (VBR + 1) */
4315 disk_write(pdrv, tbl, b_vol + 7, 1); /* Write backup (VBR + 7) */
4316 }
4317
4318 return (disk_ioctl(pdrv, CTRL_SYNC, 0) == RES_OK) ? FR_OK : FR_DISK_ERR;
4319}
#define md
Definition: compat-1.3.h:2013
DSTATUS disk_initialize(BYTE pdrv)
Definition: diskio.c:66
DRESULT disk_ioctl(BYTE pdrv, BYTE cmd, void *buff)
Definition: diskio.c:169
#define CTRL_SYNC
Definition: diskio.h:54
#define GET_SECTOR_COUNT
Definition: diskio.h:55
#define STA_PROTECT
Definition: diskio.h:48
#define STA_NOINIT
Definition: diskio.h:46
#define GET_SECTOR_SIZE
Definition: diskio.h:56
BYTE DSTATUS
Definition: diskio.h:19
#define GET_BLOCK_SIZE
Definition: diskio.h:57
#define CTRL_TRIM
Definition: diskio.h:58
#define N_ROOTDIR12
Definition: ff.c:4063
#define BS_DrvNum
Definition: ff.c:383
#define BS_VolLab
Definition: ff.c:387
#define FSI_LeadSig
Definition: ff.c:401
#define FSI_Nxt_Free
Definition: ff.c:404
#define BPB_BkBootSec
Definition: ff.c:394
#define FSI_StrucSig
Definition: ff.c:402
static FATFS * FatFs[_VOLUMES]
Definition: ff.c:448
#define N_FATS
Definition: ff.c:4065
#define BPB_Media
Definition: ff.c:377
#define BPB_HiddSec
Definition: ff.c:381
#define MIN_FAT32
Definition: ff.c:362
#define BPB_TotSec16
Definition: ff.c:376
#define BPB_FSInfo
Definition: ff.c:393
#define BS_BootSig32
Definition: ff.c:397
#define BPB_FATSz16
Definition: ff.c:378
#define BPB_FATSz32
Definition: ff.c:389
#define BS_55AA
Definition: ff.c:407
#define BPB_TotSec32
Definition: ff.c:382
#define BPB_RootClus
Definition: ff.c:392
#define BS_VolLab32
Definition: ff.c:399
#define BPB_BytsPerSec
Definition: ff.c:371
#define BS_BootSig
Definition: ff.c:385
static int get_ldnumber(const TCHAR **path)
Definition: ff.c:2114
#define BPB_NumHeads
Definition: ff.c:380
#define BS_DrvNum32
Definition: ff.c:395
#define BPB_RootEntCnt
Definition: ff.c:375
#define BPB_SecPerClus
Definition: ff.c:372
#define BPB_RsvdSecCnt
Definition: ff.c:373
#define FSI_Free_Count
Definition: ff.c:403
#define MBR_Table
Definition: ff.c:405
#define BPB_SecPerTrk
Definition: ff.c:379
#define N_ROOTDIR16
Definition: ff.c:4064
#define MIN_FAT16
Definition: ff.c:361
#define SZ_PTE
Definition: ff.c:406
#define BPB_NumFATs
Definition: ff.c:374
#define LD2PD(vol)
Definition: ff.h:46
#define ST_WORD(ptr, val)
Definition: ff.h:342
#define LD2PT(vol)
Definition: ff.h:47
#define _MAX_SS
Definition: ffconf.h:163
#define _MIN_SS
Definition: ffconf.h:162
#define _MULTI_PARTITION
Definition: ffconf.h:154
unsigned short WORD
Definition: ntddk_ex.h:93
static vector_t * vs
Definition: server.c:127
Definition: dsound.c:943

Referenced by main().

◆ f_mount()

FRESULT f_mount ( FATFS fs,
const TCHAR path,
BYTE  opt 
)

Definition at line 2402 of file ff.c.

2407{
2408 FATFS *cfs;
2409 int vol;
2410 FRESULT res;
2411 const TCHAR *rp = path;
2412
2413
2414 vol = get_ldnumber(&rp);
2415 if (vol < 0) return FR_INVALID_DRIVE;
2416 cfs = FatFs[vol]; /* Pointer to fs object */
2417
2418 if (cfs) {
2419#if _FS_LOCK
2420 clear_lock(cfs);
2421#endif
2422#if _FS_REENTRANT /* Discard sync object of the current volume */
2423 if (!ff_del_syncobj(cfs->sobj)) return FR_INT_ERR;
2424#endif
2425 cfs->fs_type = 0; /* Clear old fs object */
2426 }
2427
2428 if (fs) {
2429 fs->fs_type = 0; /* Clear new fs object */
2430#if _FS_REENTRANT /* Create sync object for the new volume */
2431 if (!ff_cre_syncobj((BYTE)vol, &fs->sobj)) return FR_INT_ERR;
2432#endif
2433 }
2434 FatFs[vol] = fs; /* Register new fs object */
2435
2436 if (!fs || opt != 1) return FR_OK; /* Do not mount now, it will be mounted later */
2437
2438 res = find_volume(&fs, &path, 0); /* Force mounted the volume */
2439 LEAVE_FF(fs, res);
2440}
char TCHAR
Definition: xmlstorage.h:189

Referenced by need_mount().

◆ f_open()

FRESULT f_open ( FIL fp,
const TCHAR path,
BYTE  mode 
)

Definition at line 2449 of file ff.c.

2454{
2455 FRESULT res;
2456 DIR dj;
2457 BYTE *dir;
2459#if !_FS_READONLY
2460 DWORD dw, cl;
2461#endif
2462
2463
2464 if (!fp) return FR_INVALID_OBJECT;
2465 fp->fs = 0; /* Clear file object */
2466
2467 /* Get logical drive number */
2468#if !_FS_READONLY
2470 res = find_volume(&dj.fs, &path, (BYTE)(mode & ~FA_READ));
2471#else
2472 mode &= FA_READ;
2473 res = find_volume(&dj.fs, &path, 0);
2474#endif
2475 if (res == FR_OK) {
2476 INIT_BUF(dj);
2477 res = follow_path(&dj, path); /* Follow the file path */
2478 dir = dj.dir;
2479#if !_FS_READONLY /* R/W configuration */
2480 if (res == FR_OK) {
2481 if (!dir) /* Default directory itself */
2483#if _FS_LOCK
2484 else
2485 res = chk_lock(&dj, (mode & ~FA_READ) ? 1 : 0);
2486#endif
2487 }
2488 /* Create or Open a file */
2490 if (res != FR_OK) { /* No file, create new */
2491 if (res == FR_NO_FILE) /* There is no file to open, create a new entry */
2492#if _FS_LOCK
2493 res = enq_lock() ? dir_register(&dj) : FR_TOO_MANY_OPEN_FILES;
2494#else
2495 res = dir_register(&dj);
2496#endif
2497 mode |= FA_CREATE_ALWAYS; /* File is created */
2498 dir = dj.dir; /* New entry */
2499 }
2500 else { /* Any object is already existing */
2501 if (dir[DIR_Attr] & (AM_RDO | AM_DIR)) { /* Cannot overwrite it (R/O or DIR) */
2502 res = FR_DENIED;
2503 } else {
2504 if (mode & FA_CREATE_NEW) /* Cannot create as new file */
2505 res = FR_EXIST;
2506 }
2507 }
2508 if (res == FR_OK && (mode & FA_CREATE_ALWAYS)) { /* Truncate it if overwrite mode */
2509 dw = GET_FATTIME();
2510 ST_DWORD(dir + DIR_CrtTime, dw);/* Set created time */
2511 ST_DWORD(dir + DIR_WrtTime, dw);/* Set modified time */
2512 dir[DIR_Attr] = 0; /* Reset attribute */
2513 ST_DWORD(dir + DIR_FileSize, 0);/* Reset file size */
2514 cl = ld_clust(dj.fs, dir); /* Get cluster chain */
2515 st_clust(dir, 0); /* Reset cluster */
2516 dj.fs->wflag = 1;
2517 if (cl) { /* Remove the cluster chain if exist */
2518 dw = dj.fs->winsect;
2519 res = remove_chain(dj.fs, cl);
2520 if (res == FR_OK) {
2521 dj.fs->last_clust = cl - 1; /* Reuse the cluster hole */
2522 res = move_window(dj.fs, dw);
2523 }
2524 }
2525 }
2526 }
2527 else { /* Open an existing file */
2528 if (res == FR_OK) { /* Following succeeded */
2529 if (dir[DIR_Attr] & AM_DIR) { /* It is a directory */
2530 res = FR_NO_FILE;
2531 } else {
2532 if ((mode & FA_WRITE) && (dir[DIR_Attr] & AM_RDO)) /* R/O violation */
2533 res = FR_DENIED;
2534 }
2535 }
2536 }
2537 if (res == FR_OK) {
2538 if (mode & FA_CREATE_ALWAYS) /* Set file change flag if created or overwritten */
2539 mode |= FA__WRITTEN;
2540 fp->dir_sect = dj.fs->winsect; /* Pointer to the directory entry */
2541 fp->dir_ptr = dir;
2542#if _FS_LOCK
2543 fp->lockid = inc_lock(&dj, (mode & ~FA_READ) ? 1 : 0);
2544 if (!fp->lockid) res = FR_INT_ERR;
2545#endif
2546 }
2547
2548#else /* R/O configuration */
2549 if (res == FR_OK) { /* Follow succeeded */
2550 dir = dj.dir;
2551 if (!dir) { /* Current directory itself */
2553 } else {
2554 if (dir[DIR_Attr] & AM_DIR) /* It is a directory */
2555 res = FR_NO_FILE;
2556 }
2557 }
2558#endif
2559 FREE_BUF();
2560
2561 if (res == FR_OK) {
2562 fp->flag = mode; /* File access mode */
2563 fp->err = 0; /* Clear error flag */
2564 fp->sclust = ld_clust(dj.fs, dir); /* File start cluster */
2565 fp->fsize = LD_DWORD(dir + DIR_FileSize); /* File size */
2566 fp->fptr = 0; /* File pointer */
2567 fp->dsect = 0;
2568#if _USE_FASTSEEK
2569 fp->cltbl = 0; /* Normal seek mode */
2570#endif
2571 fp->fs = dj.fs; /* Validate file object */
2572 fp->id = fp->fs->id;
2573 }
2574 }
2575
2576 LEAVE_FF(dj.fs, res);
2577}
#define DIR_FileSize
Definition: ff.c:420
static DWORD ld_clust(FATFS *fs, const BYTE *dir)
Definition: ff.c:1235
#define FA_OPEN_ALWAYS
Definition: ff.h:301
#define FA_READ
Definition: ff.h:294
#define FA_CREATE_NEW
Definition: ff.h:299
#define FA_CREATE_ALWAYS
Definition: ff.h:300
GLenum mode
Definition: glext.h:6217
REFIID LPVOID DWORD_PTR dw
Definition: atlbase.h:40
WORD id
Definition: ff.h:85
DWORD last_clust
Definition: ff.h:94
BYTE * dir_ptr
Definition: ff.h:126
DWORD dir_sect
Definition: ff.h:125
WORD id
Definition: ff.h:116

Referenced by main().

◆ f_opendir()

FRESULT f_opendir ( DIR dp,
const TCHAR path 
)

Definition at line 3187 of file ff.c.

3191{
3192 FRESULT res;
3193 FATFS* fs;
3195
3196
3197 if (!dp) return FR_INVALID_OBJECT;
3198
3199 /* Get logical drive number */
3200 res = find_volume(&fs, &path, 0);
3201 if (res == FR_OK) {
3202 dp->fs = fs;
3203 INIT_BUF(*dp);
3204 res = follow_path(dp, path); /* Follow the path to the directory */
3205 FREE_BUF();
3206 if (res == FR_OK) { /* Follow completed */
3207 if (dp->dir) { /* It is not the origin directory itself */
3208 if (dp->dir[DIR_Attr] & AM_DIR) /* The object is a sub directory */
3209 dp->sclust = ld_clust(fs, dp->dir);
3210 else /* The object is a file */
3211 res = FR_NO_PATH;
3212 }
3213 if (res == FR_OK) {
3214 dp->id = fs->id;
3215 res = dir_sdi(dp, 0); /* Rewind directory */
3216#if _FS_LOCK
3217 if (res == FR_OK) {
3218 if (dp->sclust) {
3219 dp->lockid = inc_lock(dp, 0); /* Lock the sub directory */
3220 if (!dp->lockid)
3222 } else {
3223 dp->lockid = 0; /* Root directory need not to be locked */
3224 }
3225 }
3226#endif
3227 }
3228 }
3229 if (res == FR_NO_FILE) res = FR_NO_PATH;
3230 }
3231 if (res != FR_OK) dp->fs = 0; /* Invalidate the directory object if function faild */
3232
3233 LEAVE_FF(fs, res);
3234}
WORD id
Definition: ff.h:145

Referenced by main().

◆ f_printf()

int f_printf ( FIL fp,
const TCHAR str,
  ... 
)

◆ f_putc()

int f_putc ( TCHAR  c,
FIL fp 
)

◆ f_puts()

int f_puts ( const TCHAR str,
FIL cp 
)

◆ f_read()

FRESULT f_read ( FIL fp,
void buff,
UINT  btr,
UINT br 
)

Definition at line 2586 of file ff.c.

2592{
2593 FRESULT res;
2594 DWORD clst, sect, remain;
2595 UINT rcnt, cc;
2596 BYTE csect, *rbuff = (BYTE*)buff;
2597
2598
2599 *br = 0; /* Clear read byte counter */
2600
2601 res = validate(fp); /* Check validity */
2602 if (res != FR_OK) LEAVE_FF(fp->fs, res);
2603 if (fp->err) /* Check error */
2604 LEAVE_FF(fp->fs, (FRESULT)fp->err);
2605 if (!(fp->flag & FA_READ)) /* Check access mode */
2606 LEAVE_FF(fp->fs, FR_DENIED);
2607 remain = fp->fsize - fp->fptr;
2608 if (btr > remain) btr = (UINT)remain; /* Truncate btr by remaining bytes */
2609
2610 for ( ; btr; /* Repeat until all data read */
2611 rbuff += rcnt, fp->fptr += rcnt, *br += rcnt, btr -= rcnt) {
2612 if ((fp->fptr % SS(fp->fs)) == 0) { /* On the sector boundary? */
2613 csect = (BYTE)(fp->fptr / SS(fp->fs) & (fp->fs->csize - 1)); /* Sector offset in the cluster */
2614 if (!csect) { /* On the cluster boundary? */
2615 if (fp->fptr == 0) { /* On the top of the file? */
2616 clst = fp->sclust; /* Follow from the origin */
2617 } else { /* Middle or end of the file */
2618#if _USE_FASTSEEK
2619 if (fp->cltbl)
2620 clst = clmt_clust(fp, fp->fptr); /* Get cluster# from the CLMT */
2621 else
2622#endif
2623 clst = get_fat(fp->fs, fp->clust); /* Follow cluster chain on the FAT */
2624 }
2625 if (clst < 2) ABORT(fp->fs, FR_INT_ERR);
2626 if (clst == 0xFFFFFFFF) ABORT(fp->fs, FR_DISK_ERR);
2627 fp->clust = clst; /* Update current cluster */
2628 }
2629 sect = clust2sect(fp->fs, fp->clust); /* Get current sector */
2630 if (!sect) ABORT(fp->fs, FR_INT_ERR);
2631 sect += csect;
2632 cc = btr / SS(fp->fs); /* When remaining bytes >= sector size, */
2633 if (cc) { /* Read maximum contiguous sectors directly */
2634 if (csect + cc > fp->fs->csize) /* Clip at cluster boundary */
2635 cc = fp->fs->csize - csect;
2636 if (disk_read(fp->fs->drv, rbuff, sect, cc) != RES_OK)
2637 ABORT(fp->fs, FR_DISK_ERR);
2638#if !_FS_READONLY && _FS_MINIMIZE <= 2 /* Replace one of the read sectors with cached data if it contains a dirty sector */
2639#if _FS_TINY
2640 if (fp->fs->wflag && fp->fs->winsect - sect < cc)
2641 mem_cpy(rbuff + ((fp->fs->winsect - sect) * SS(fp->fs)), fp->fs->win, SS(fp->fs));
2642#else
2643 if ((fp->flag & FA__DIRTY) && fp->dsect - sect < cc)
2644 mem_cpy(rbuff + ((fp->dsect - sect) * SS(fp->fs)), fp->buf, SS(fp->fs));
2645#endif
2646#endif
2647 rcnt = SS(fp->fs) * cc; /* Number of bytes transferred */
2648 continue;
2649 }
2650#if !_FS_TINY
2651 if (fp->dsect != sect) { /* Load data sector if not in cache */
2652#if !_FS_READONLY
2653 if (fp->flag & FA__DIRTY) { /* Write-back dirty sector cache */
2654 if (disk_write(fp->fs->drv, fp->buf, fp->dsect, 1) != RES_OK)
2655 ABORT(fp->fs, FR_DISK_ERR);
2656 fp->flag &= ~FA__DIRTY;
2657 }
2658#endif
2659 if (disk_read(fp->fs->drv, fp->buf, sect, 1) != RES_OK) /* Fill sector cache */
2660 ABORT(fp->fs, FR_DISK_ERR);
2661 }
2662#endif
2663 fp->dsect = sect;
2664 }
2665 rcnt = SS(fp->fs) - ((UINT)fp->fptr % SS(fp->fs)); /* Get partial sector data from sector buffer */
2666 if (rcnt > btr) rcnt = btr;
2667#if _FS_TINY
2668 if (move_window(fp->fs, fp->dsect) != FR_OK) /* Move sector window */
2669 ABORT(fp->fs, FR_DISK_ERR);
2670 mem_cpy(rbuff, &fp->fs->win[fp->fptr % SS(fp->fs)], rcnt); /* Pick partial sector */
2671#else
2672 mem_cpy(rbuff, &fp->buf[fp->fptr % SS(fp->fs)], rcnt); /* Pick partial sector */
2673#endif
2674 }
2675
2676 LEAVE_FF(fp->fs, FR_OK);
2677}
static unsigned char buff[32768]
Definition: fatten.c:17
uint32_t cc
Definition: isohybrid.c:75

Referenced by main().

◆ f_readdir()

FRESULT f_readdir ( DIR dp,
FILINFO fno 
)

Definition at line 3275 of file ff.c.

3279{
3280 FRESULT res;
3282
3283
3284 res = validate(dp); /* Check validity of the object */
3285 if (res == FR_OK) {
3286 if (!fno) {
3287 res = dir_sdi(dp, 0); /* Rewind the directory object */
3288 } else {
3289 INIT_BUF(*dp);
3290 res = dir_read(dp, 0); /* Read an item */
3291 if (res == FR_NO_FILE) { /* Reached end of directory */
3292 dp->sect = 0;
3293 res = FR_OK;
3294 }
3295 if (res == FR_OK) { /* A valid entry is found */
3296 get_fileinfo(dp, fno); /* Get the object information */
3297 res = dir_next(dp, 0); /* Increment index for next */
3298 if (res == FR_NO_FILE) {
3299 dp->sect = 0;
3300 res = FR_OK;
3301 }
3302 }
3303 FREE_BUF();
3304 }
3305 }
3306
3307 LEAVE_FF(dp->fs, res);
3308}
static void get_fileinfo(DIR *dp, FILINFO *fno)
Definition: ff.c:1703
static FRESULT dir_next(DIR *dp, int stretch)
Definition: ff.c:1128
DWORD sect
Definition: ff.h:149

Referenced by main().

◆ f_rename()

FRESULT f_rename ( const TCHAR path_old,
const TCHAR path_new 
)

Definition at line 3713 of file ff.c.

3717{
3718 FRESULT res;
3719 DIR djo, djn;
3720 BYTE buf[21], *dir;
3721 DWORD dw;
3723
3724
3725 /* Get logical drive number of the source object */
3726 res = find_volume(&djo.fs, &path_old, 1);
3727 if (res == FR_OK) {
3728 djn.fs = djo.fs;
3729 INIT_BUF(djo);
3730 res = follow_path(&djo, path_old); /* Check old object */
3731 if (_FS_RPATH && res == FR_OK && (djo.fn[NSFLAG] & NS_DOT))
3733#if _FS_LOCK
3734 if (res == FR_OK) res = chk_lock(&djo, 2);
3735#endif
3736 if (res == FR_OK) { /* Old object is found */
3737 if (!djo.dir) { /* Is root dir? */
3738 res = FR_NO_FILE;
3739 } else {
3740 mem_cpy(buf, djo.dir + DIR_Attr, 21); /* Save information about object except name */
3741 mem_cpy(&djn, &djo, sizeof (DIR)); /* Duplicate the directory object */
3742 if (get_ldnumber(&path_new) >= 0) /* Snip drive number off and ignore it */
3743 res = follow_path(&djn, path_new); /* and make sure if new object name is not conflicting */
3744 else
3746 if (res == FR_OK) res = FR_EXIST; /* The new object name is already existing */
3747 if (res == FR_NO_FILE) { /* It is a valid path and no name collision */
3748 res = dir_register(&djn); /* Register the new entry */
3749 if (res == FR_OK) {
3750/* Start of critical section where any interruption can cause a cross-link */
3751 dir = djn.dir; /* Copy information about object except name */
3752 mem_cpy(dir + 13, buf + 2, 19);
3753 dir[DIR_Attr] = buf[0] | AM_ARC;
3754 djo.fs->wflag = 1;
3755 if ((dir[DIR_Attr] & AM_DIR) && djo.sclust != djn.sclust) { /* Update .. entry in the sub-directory if needed */
3756 dw = clust2sect(djo.fs, ld_clust(djo.fs, dir));
3757 if (!dw) {
3758 res = FR_INT_ERR;
3759 } else {
3760 res = move_window(djo.fs, dw);
3761 dir = djo.fs->win + SZ_DIRE * 1; /* Ptr to .. entry */
3762 if (res == FR_OK && dir[1] == '.') {
3763 st_clust(dir, djn.sclust);
3764 djo.fs->wflag = 1;
3765 }
3766 }
3767 }
3768 if (res == FR_OK) {
3769 res = dir_remove(&djo); /* Remove old entry */
3770 if (res == FR_OK)
3771 res = sync_fs(djo.fs);
3772 }
3773/* End of critical section */
3774 }
3775 }
3776 }
3777 }
3778 FREE_BUF();
3779 }
3780
3781 LEAVE_FF(djo.fs, res);
3782}
static FRESULT dir_remove(DIR *dp)
Definition: ff.c:1656
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751

Referenced by main().

◆ f_setlabel()

FRESULT f_setlabel ( const TCHAR label)

Definition at line 3906 of file ff.c.

3909{
3910 FRESULT res;
3911 DIR dj;
3912 BYTE vn[11];
3913 UINT i, j, sl;
3914 WCHAR w;
3915 DWORD tm;
3916
3917
3918 /* Get logical drive number */
3919 res = find_volume(&dj.fs, &label, 1);
3920 if (res) LEAVE_FF(dj.fs, res);
3921
3922 /* Create a volume label in directory form */
3923 vn[0] = 0;
3924 for (sl = 0; label[sl]; sl++) ; /* Get name length */
3925 for ( ; sl && label[sl - 1] == ' '; sl--) ; /* Remove trailing spaces */
3926 if (sl) { /* Create volume label in directory form */
3927 i = j = 0;
3928 do {
3929#if _USE_LFN && _LFN_UNICODE
3930 w = ff_convert(ff_wtoupper(label[i++]), 0);
3931#else
3932 w = (BYTE)label[i++];
3933 if (IsDBCS1(w))
3934 w = (j < 10 && i < sl && IsDBCS2(label[i])) ? w << 8 | (BYTE)label[i++] : 0;
3935#if _USE_LFN
3936 w = ff_convert(ff_wtoupper(ff_convert(w, 1)), 0);
3937#else
3938 if (IsLower(w)) w -= 0x20; /* To upper ASCII characters */
3939#ifdef _EXCVT
3940 if (w >= 0x80) w = ExCvt[w - 0x80]; /* To upper extended characters (SBCS cfg) */
3941#else
3942 if (!_DF1S && w >= 0x80) w = 0; /* Reject extended characters (ASCII cfg) */
3943#endif
3944#endif
3945#endif
3946 if (!w || chk_chr("\"*+,.:;<=>\?[]|\x7F", w) || j >= (UINT)((w >= 0x100) ? 10 : 11)) /* Reject invalid characters for volume label */
3948 if (w >= 0x100) vn[j++] = (BYTE)(w >> 8);
3949 vn[j++] = (BYTE)w;
3950 } while (i < sl);
3951 while (j < 11) vn[j++] = ' '; /* Fill remaining name field */
3952 if (vn[0] == DDEM) LEAVE_FF(dj.fs, FR_INVALID_NAME); /* Reject illegal name (heading DDEM) */
3953 }
3954
3955 /* Set volume label */
3956 dj.sclust = 0; /* Open root directory */
3957 res = dir_sdi(&dj, 0);
3958 if (res == FR_OK) {
3959 res = dir_read(&dj, 1); /* Get an entry with AM_VOL */
3960 if (res == FR_OK) { /* A volume label is found */
3961 if (vn[0]) {
3962 mem_cpy(dj.dir, vn, 11); /* Change the volume label name */
3963 tm = GET_FATTIME();
3964 ST_DWORD(dj.dir + DIR_CrtTime, tm);
3965 ST_DWORD(dj.dir + DIR_WrtTime, tm);
3966 } else {
3967 dj.dir[0] = DDEM; /* Remove the volume label */
3968 }
3969 dj.fs->wflag = 1;
3970 res = sync_fs(dj.fs);
3971 } else { /* No volume label is found or error */
3972 if (res == FR_NO_FILE) {
3973 res = FR_OK;
3974 if (vn[0]) { /* Create volume label as new */
3975 res = dir_alloc(&dj, 1); /* Allocate an entry for volume label */
3976 if (res == FR_OK) {
3977 mem_set(dj.dir, 0, SZ_DIRE); /* Set volume label */
3978 mem_cpy(dj.dir, vn, 11);
3979 dj.dir[DIR_Attr] = AM_VOL;
3980 tm = GET_FATTIME();
3981 ST_DWORD(dj.dir + DIR_CrtTime, tm);
3982 ST_DWORD(dj.dir + DIR_WrtTime, tm);
3983 dj.fs->wflag = 1;
3984 res = sync_fs(dj.fs);
3985 }
3986 }
3987 }
3988 }
3989 }
3990
3991 LEAVE_FF(dj.fs, res);
3992}
#define DDEM
Definition: ff.c:428
static int chk_chr(const char *str, int chr)
Definition: ff.c:543
#define _DF1S
Definition: ff.c:125
static FRESULT dir_alloc(DIR *dp, UINT nent)
Definition: ff.c:1199
#define IsLower(c)
Definition: ff.c:325
static const BYTE ExCvt[]
Definition: ff.c:486
#define AM_VOL
Definition: ff.h:319
WCHAR ff_wtoupper(WCHAR chr)
Definition: ccsbcs.c:304
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint vn
Definition: glfuncs.h:238

Referenced by main().

◆ f_stat()

FRESULT f_stat ( const TCHAR path,
FILINFO fno 
)

Definition at line 3369 of file ff.c.

3373{
3374 FRESULT res;
3375 DIR dj;
3377
3378
3379 /* Get logical drive number */
3380 res = find_volume(&dj.fs, &path, 0);
3381 if (res == FR_OK) {
3382 INIT_BUF(dj);
3383 res = follow_path(&dj, path); /* Follow the file path */
3384 if (res == FR_OK) { /* Follow completed */
3385 if (dj.dir) { /* Found an object */
3386 if (fno) get_fileinfo(&dj, fno);
3387 } else { /* It is root directory */
3389 }
3390 }
3391 FREE_BUF();
3392 }
3393
3394 LEAVE_FF(dj.fs, res);
3395}

◆ f_sync()

FRESULT f_sync ( FIL fp)

Definition at line 2809 of file ff.c.

2812{
2813 FRESULT res;
2814 DWORD tm;
2815 BYTE *dir;
2816
2817
2818 res = validate(fp); /* Check validity of the object */
2819 if (res == FR_OK) {
2820 if (fp->flag & FA__WRITTEN) { /* Is there any change to the file? */
2821#if !_FS_TINY
2822 if (fp->flag & FA__DIRTY) { /* Write-back cached data if needed */
2823 if (disk_write(fp->fs->drv, fp->buf, fp->dsect, 1) != RES_OK)
2824 LEAVE_FF(fp->fs, FR_DISK_ERR);
2825 fp->flag &= ~FA__DIRTY;
2826 }
2827#endif
2828 /* Update the directory entry */
2829 res = move_window(fp->fs, fp->dir_sect);
2830 if (res == FR_OK) {
2831 dir = fp->dir_ptr;
2832 dir[DIR_Attr] |= AM_ARC; /* Set archive bit */
2833 ST_DWORD(dir + DIR_FileSize, fp->fsize); /* Update file size */
2834 st_clust(dir, fp->sclust); /* Update start cluster */
2835 tm = GET_FATTIME(); /* Update modified time */
2838 fp->flag &= ~FA__WRITTEN;
2839 fp->fs->wflag = 1;
2840 res = sync_fs(fp->fs);
2841 }
2842 }
2843 }
2844
2845 LEAVE_FF(fp->fs, res);
2846}
#define DIR_LstAccDate
Definition: ff.c:415

Referenced by f_close().

◆ f_truncate()

FRESULT f_truncate ( FIL fp)

Definition at line 3470 of file ff.c.

3473{
3474 FRESULT res;
3475 DWORD ncl;
3476
3477
3478 res = validate(fp); /* Check validity of the object */
3479 if (res == FR_OK) {
3480 if (fp->err) { /* Check error */
3481 res = (FRESULT)fp->err;
3482 } else {
3483 if (!(fp->flag & FA_WRITE)) /* Check access mode */
3484 res = FR_DENIED;
3485 }
3486 }
3487 if (res == FR_OK) {
3488 if (fp->fsize > fp->fptr) {
3489 fp->fsize = fp->fptr; /* Set file size to current R/W point */
3490 fp->flag |= FA__WRITTEN;
3491 if (fp->fptr == 0) { /* When set file size to zero, remove entire cluster chain */
3492 res = remove_chain(fp->fs, fp->sclust);
3493 fp->sclust = 0;
3494 } else { /* When truncate a part of the file, remove remaining clusters */
3495 ncl = get_fat(fp->fs, fp->clust);
3496 res = FR_OK;
3497 if (ncl == 0xFFFFFFFF) res = FR_DISK_ERR;
3498 if (ncl == 1) res = FR_INT_ERR;
3499 if (res == FR_OK && ncl < fp->fs->n_fatent) {
3500 res = put_fat(fp->fs, fp->clust, 0x0FFFFFFF);
3501 if (res == FR_OK) res = remove_chain(fp->fs, ncl);
3502 }
3503 }
3504#if !_FS_TINY
3505 if (res == FR_OK && (fp->flag & FA__DIRTY)) {
3506 if (disk_write(fp->fs->drv, fp->buf, fp->dsect, 1) != RES_OK)
3507 res = FR_DISK_ERR;
3508 else
3509 fp->flag &= ~FA__DIRTY;
3510 }
3511#endif
3512 }
3513 if (res != FR_OK) fp->err = (FRESULT)res;
3514 }
3515
3516 LEAVE_FF(fp->fs, res);
3517}
FRESULT put_fat(FATFS *fs, DWORD clst, DWORD val)
Definition: ff.c:873

◆ f_unlink()

FRESULT f_unlink ( const TCHAR path)

Definition at line 3526 of file ff.c.

3529{
3530 FRESULT res;
3531 DIR dj, sdj;
3532 BYTE *dir;
3533 DWORD dclst = 0;
3535
3536
3537 /* Get logical drive number */
3538 res = find_volume(&dj.fs, &path, 1);
3539 if (res == FR_OK) {
3540 INIT_BUF(dj);
3541 res = follow_path(&dj, path); /* Follow the file path */
3542 if (_FS_RPATH && res == FR_OK && (dj.fn[NSFLAG] & NS_DOT))
3543 res = FR_INVALID_NAME; /* Cannot remove dot entry */
3544#if _FS_LOCK
3545 if (res == FR_OK) res = chk_lock(&dj, 2); /* Cannot remove open object */
3546#endif
3547 if (res == FR_OK) { /* The object is accessible */
3548 dir = dj.dir;
3549 if (!dir) {
3550 res = FR_INVALID_NAME; /* Cannot remove the origin directory */
3551 } else {
3552 if (dir[DIR_Attr] & AM_RDO)
3553 res = FR_DENIED; /* Cannot remove R/O object */
3554 }
3555 if (res == FR_OK) {
3556 dclst = ld_clust(dj.fs, dir);
3557 if (dclst && (dir[DIR_Attr] & AM_DIR)) { /* Is it a sub-directory ? */
3558#if _FS_RPATH
3559 if (dclst == dj.fs->cdir) { /* Is it the current directory? */
3560 res = FR_DENIED;
3561 } else
3562#endif
3563 {
3564 mem_cpy(&sdj, &dj, sizeof (DIR)); /* Open the sub-directory */
3565 sdj.sclust = dclst;
3566 res = dir_sdi(&sdj, 2);
3567 if (res == FR_OK) {
3568 res = dir_read(&sdj, 0); /* Read an item (excluding dot entries) */
3569 if (res == FR_OK) res = FR_DENIED; /* Not empty? (cannot remove) */
3570 if (res == FR_NO_FILE) res = FR_OK; /* Empty? (can remove) */
3571 }
3572 }
3573 }
3574 }
3575 if (res == FR_OK) {
3576 res = dir_remove(&dj); /* Remove the directory entry */
3577 if (res == FR_OK && dclst) /* Remove the cluster chain if exist */
3578 res = remove_chain(dj.fs, dclst);
3579 if (res == FR_OK) res = sync_fs(dj.fs);
3580 }
3581 }
3582 FREE_BUF();
3583 }
3584
3585 LEAVE_FF(dj.fs, res);
3586}

Referenced by main().

◆ f_utime()

FRESULT f_utime ( const TCHAR path,
const FILINFO fno 
)

Definition at line 3791 of file ff.c.

3795{
3796 FRESULT res;
3797 DIR dj;
3798 BYTE *dir;
3800
3801
3802 /* Get logical drive number */
3803 res = find_volume(&dj.fs, &path, 1);
3804 if (res == FR_OK) {
3805 INIT_BUF(dj);
3806 res = follow_path(&dj, path); /* Follow the file path */
3807 FREE_BUF();
3808 if (_FS_RPATH && res == FR_OK && (dj.fn[NSFLAG] & NS_DOT))
3810 if (res == FR_OK) {
3811 dir = dj.dir;
3812 if (!dir) { /* Root directory */
3814 } else { /* File or sub-directory */
3815 ST_WORD(dir + DIR_WrtTime, fno->ftime);
3816 ST_WORD(dir + DIR_WrtDate, fno->fdate);
3817 dj.fs->wflag = 1;
3818 res = sync_fs(dj.fs);
3819 }
3820 }
3821 }
3822
3823 LEAVE_FF(dj.fs, res);
3824}
#define DIR_WrtDate
Definition: ff.c:418
WORD fdate
Definition: ff.h:170
WORD ftime
Definition: ff.h:171

◆ f_write()

FRESULT f_write ( FIL fp,
const void buff,
UINT  btw,
UINT bw 
)

Definition at line 2687 of file ff.c.

2693{
2694 FRESULT res;
2695 DWORD clst, sect;
2696 UINT wcnt, cc;
2697 const BYTE *wbuff = (const BYTE*)buff;
2698 BYTE csect;
2699
2700
2701 *bw = 0; /* Clear write byte counter */
2702
2703 res = validate(fp); /* Check validity */
2704 if (res != FR_OK) LEAVE_FF(fp->fs, res);
2705 if (fp->err) /* Check error */
2706 LEAVE_FF(fp->fs, (FRESULT)fp->err);
2707 if (!(fp->flag & FA_WRITE)) /* Check access mode */
2708 LEAVE_FF(fp->fs, FR_DENIED);
2709 if (fp->fptr + btw < fp->fptr) btw = 0; /* File size cannot reach 4GB */
2710
2711 for ( ; btw; /* Repeat until all data written */
2712 wbuff += wcnt, fp->fptr += wcnt, *bw += wcnt, btw -= wcnt) {
2713 if ((fp->fptr % SS(fp->fs)) == 0) { /* On the sector boundary? */
2714 csect = (BYTE)(fp->fptr / SS(fp->fs) & (fp->fs->csize - 1)); /* Sector offset in the cluster */
2715 if (!csect) { /* On the cluster boundary? */
2716 if (fp->fptr == 0) { /* On the top of the file? */
2717 clst = fp->sclust; /* Follow from the origin */
2718 if (clst == 0) /* When no cluster is allocated, */
2719 clst = create_chain(fp->fs, 0); /* Create a new cluster chain */
2720 } else { /* Middle or end of the file */
2721#if _USE_FASTSEEK
2722 if (fp->cltbl)
2723 clst = clmt_clust(fp, fp->fptr); /* Get cluster# from the CLMT */
2724 else
2725#endif
2726 clst = create_chain(fp->fs, fp->clust); /* Follow or stretch cluster chain on the FAT */
2727 }
2728 if (clst == 0) break; /* Could not allocate a new cluster (disk full) */
2729 if (clst == 1) ABORT(fp->fs, FR_INT_ERR);
2730 if (clst == 0xFFFFFFFF) ABORT(fp->fs, FR_DISK_ERR);
2731 fp->clust = clst; /* Update current cluster */
2732 if (fp->sclust == 0) fp->sclust = clst; /* Set start cluster if the first write */
2733 }
2734#if _FS_TINY
2735 if (fp->fs->winsect == fp->dsect && sync_window(fp->fs)) /* Write-back sector cache */
2736 ABORT(fp->fs, FR_DISK_ERR);
2737#else
2738 if (fp->flag & FA__DIRTY) { /* Write-back sector cache */
2739 if (disk_write(fp->fs->drv, fp->buf, fp->dsect, 1) != RES_OK)
2740 ABORT(fp->fs, FR_DISK_ERR);
2741 fp->flag &= ~FA__DIRTY;
2742 }
2743#endif
2744 sect = clust2sect(fp->fs, fp->clust); /* Get current sector */
2745 if (!sect) ABORT(fp->fs, FR_INT_ERR);
2746 sect += csect;
2747 cc = btw / SS(fp->fs); /* When remaining bytes >= sector size, */
2748 if (cc) { /* Write maximum contiguous sectors directly */
2749 if (csect + cc > fp->fs->csize) /* Clip at cluster boundary */
2750 cc = fp->fs->csize - csect;
2751 if (disk_write(fp->fs->drv, wbuff, sect, cc) != RES_OK)
2752 ABORT(fp->fs, FR_DISK_ERR);
2753#if _FS_MINIMIZE <= 2
2754#if _FS_TINY
2755 if (fp->fs->winsect - sect < cc) { /* Refill sector cache if it gets invalidated by the direct write */
2756 mem_cpy(fp->fs->win, wbuff + ((fp->fs->winsect - sect) * SS(fp->fs)), SS(fp->fs));
2757 fp->fs->wflag = 0;
2758 }
2759#else
2760 if (fp->dsect - sect < cc) { /* Refill sector cache if it gets invalidated by the direct write */
2761 mem_cpy(fp->buf, wbuff + ((fp->dsect - sect) * SS(fp->fs)), SS(fp->fs));
2762 fp->flag &= ~FA__DIRTY;
2763 }
2764#endif
2765#endif
2766 wcnt = SS(fp->fs) * cc; /* Number of bytes transferred */
2767 continue;
2768 }
2769#if _FS_TINY
2770 if (fp->fptr >= fp->fsize) { /* Avoid silly cache filling at growing edge */
2771 if (sync_window(fp->fs)) ABORT(fp->fs, FR_DISK_ERR);
2772 fp->fs->winsect = sect;
2773 }
2774#else
2775 if (fp->dsect != sect) { /* Fill sector cache with file data */
2776 if (fp->fptr < fp->fsize &&
2777 disk_read(fp->fs->drv, fp->buf, sect, 1) != RES_OK)
2778 ABORT(fp->fs, FR_DISK_ERR);
2779 }
2780#endif
2781 fp->dsect = sect;
2782 }
2783 wcnt = SS(fp->fs) - ((UINT)fp->fptr % SS(fp->fs));/* Put partial sector into file I/O buffer */
2784 if (wcnt > btw) wcnt = btw;
2785#if _FS_TINY
2786 if (move_window(fp->fs, fp->dsect) != FR_OK) /* Move sector window */
2787 ABORT(fp->fs, FR_DISK_ERR);
2788 mem_cpy(&fp->fs->win[fp->fptr % SS(fp->fs)], wbuff, wcnt); /* Fit partial sector */
2789 fp->fs->wflag = 1;
2790#else
2791 mem_cpy(&fp->buf[fp->fptr % SS(fp->fs)], wbuff, wcnt); /* Fit partial sector */
2792 fp->flag |= FA__DIRTY;
2793#endif
2794 }
2795
2796 if (fp->fptr > fp->fsize) fp->fsize = fp->fptr; /* Update file size if needed */
2797 fp->flag |= FA__WRITTEN; /* Set file change flag */
2798
2799 LEAVE_FF(fp->fs, FR_OK);
2800}
static int bw
Definition: maze.c:120

Referenced by main().

◆ ff_convert()

WCHAR ff_convert ( WCHAR  chr,
UINT  dir 
)

Definition at line 275 of file ccsbcs.c.

279{
280 WCHAR c;
281
282
283 if (chr < 0x80) { /* ASCII */
284 c = chr;
285
286 } else {
287 if (dir) { /* OEM code to Unicode */
288 c = (chr >= 0x100) ? 0 : Tbl[chr - 0x80];
289
290 } else { /* Unicode to OEM code */
291 for (c = 0; c < 0x80; c++) {
292 if (chr == Tbl[c]) break;
293 }
294 c = (c + 0x80) & 0xFF;
295 }
296 }
297
298 return c;
299}
static const WCHAR Tbl[]
Definition: ccsbcs.c:30
const GLubyte * c
Definition: glext.h:8905
#define c
Definition: ke_i.h:80

Referenced by create_name(), f_getlabel(), f_setlabel(), and get_fileinfo().

◆ ff_wtoupper()

WCHAR ff_wtoupper ( WCHAR  chr)

Definition at line 304 of file ccsbcs.c.

307{
308 static const WCHAR lower[] = { /* Lower case characters to be converted */
309 /* Latin Supplement */ 0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF,
310 /* Latin Extended-A */ 0x101,0x103,0x105,0x107,0x109,0x10B,0x10D,0x10F,0x111,0x113,0x115,0x117,0x119,0x11B,0x11D,0x11F,0x121,0x123,0x125,0x127,0x129,0x12B,0x12D,0x12F,0x131,0x133,0x135,0x137,0x13A,0x13C,0x13E,0x140,0x142,0x144,0x146,0x148,0x14B,0x14D,0x14F,0x151,0x153,0x155,0x157,0x159,0x15B,0x15D,0x15F,0x161,0x163,0x165,0x167,0x169,0x16B,0x16D,0x16F,0x171,0x173,0x175,0x177,0x17A,0x17C,0x17E,
311 /* Latin Extended-B */ 0x183,0x185,0x188,0x18C,0x192,0x199,0x1A1,0x1A3,0x1A8,0x1AD,0x1B0,0x1B4,0x1B6,0x1B9,0x1BD,0x1C6,0x1C9,0x1CC,0x1CE,0x1D0,0x1D2,0x1D4,0x1D6,0x1D8,0x1DA,0x1DC,0x1DD,0x1DF,0x1E1,0x1E3,0x1E5,0x1E7,0x1E9,0x1EB,0x1ED,0x1EF,0x1F3,0x1F5,0x1FB,0x1FD,0x1FF,0x201,0x203,0x205,0x207,0x209,0x20B,0x20D,0x20F,0x211,0x213,0x215,0x217,
312 /* Greek, Coptic */ 0x3B1,0x3B2,0x3B3,0x3B4,0x3B5,0x3B6,0x3B7,0x3B8,0x3B9,0x3BA,0x3BB,0x3BC,0x3BD,0x3BE,0x3BF,0x3C0,0x3C1,0x3C3,0x3C4,0x3C5,0x3C6,0x3C7,0x3C8,0x3C9,0x3CA,0x3CB,0x3CC,0x3CD,0x3CE,0x3E3,0x3E5,0x3E7,0x3E9,0x3EB,
313 /* Cyrillic */ 0x430,0x431,0x432,0x433,0x434,0x435,0x436,0x437,0x438,0x439,0x43A,0x43B,0x43C,0x43D,0x43E,0x43F,0x440,0x441,0x442,0x443,0x444,0x445,0x446,0x447,0x448,0x449,0x44A,0x44B,0x44C,0x44D,0x44E,0x44F,0x452,0x453,0x454,0x455,0x456,0x457,0x458,0x459,0x45A,0x45B,0x45C,0x45E,0x45F,0x461,0x463,0x465,0x467,0x469,0x46B,0x46D,0x46F,0x471,0x473,0x475,0x477,0x479,0x47B,0x47D,0x47F,0x481,0x491,0x493,0x495,0x497,0x499,0x49B,0x49D,0x49F,0x4A1,0x4A3,0x4A5,0x4A7,0x4A9,0x4AB,0x4AD,0x4AF,0x4B1,0x4B3,0x4B5,0x4B7,0x4B9,0x4BB,0x4BD,0x4BF,0x4C2,0x4C4,0x4C8,0x4D1,0x4D3,0x4D5,0x4D7,0x4D9,0x4DB,0x4DD,0x4DF,0x4E1,0x4E3,0x4E5,0x4E7,0x4E9,0x4EB,0x4ED,0x4EF,0x4F1,0x4F3,0x4F5,0x4F9,
314 /* Armenian */ 0x561,0x562,0x563,0x564,0x565,0x566,0x567,0x568,0x569,0x56A,0x56B,0x56C,0x56D,0x56E,0x56F,0x570,0x571,0x572,0x573,0x574,0x575,0x576,0x577,0x578,0x579,0x57A,0x57B,0x57C,0x57D,0x57E,0x57F,0x580,0x581,0x582,0x583,0x584,0x585,0x586,
315 /* Latin Extended Additional */ 0x1E01,0x1E03,0x1E05,0x1E07,0x1E09,0x1E0B,0x1E0D,0x1E0F,0x1E11,0x1E13,0x1E15,0x1E17,0x1E19,0x1E1B,0x1E1D,0x1E1F,0x1E21,0x1E23,0x1E25,0x1E27,0x1E29,0x1E2B,0x1E2D,0x1E2F,0x1E31,0x1E33,0x1E35,0x1E37,0x1E39,0x1E3B,0x1E3D,0x1E3F,0x1E41,0x1E43,0x1E45,0x1E47,0x1E49,0x1E4B,0x1E4D,0x1E4F,0x1E51,0x1E53,0x1E55,0x1E57,0x1E59,0x1E5B,0x1E5D,0x1E5F,0x1E61,0x1E63,0x1E65,0x1E67,0x1E69,0x1E6B,0x1E6D,0x1E6F,0x1E71,0x1E73,0x1E75,0x1E77,0x1E79,0x1E7B,0x1E7D,0x1E7F,0x1E81,0x1E83,0x1E85,0x1E87,0x1E89,0x1E8B,0x1E8D,0x1E8F,0x1E91,0x1E93,0x1E95,0x1E97,0x1E99,0x1E9B,0x1E9D,0x1E9F,0x1EA1,0x1EA3,0x1EA5,0x1EA7,0x1EA9,0x1EAB,0x1EAD,0x1EAF,0x1EB1,0x1EB3,0x1EB5,0x1EB7,0x1EB9,0x1EBB,0x1EBD,0x1EBF,0x1EC1,0x1EC3,0x1EC5,0x1EC7,0x1EC9,0x1ECB,0x1ECD,0x1ECF,0x1ED1,0x1ED3,0x1ED5,0x1ED7,0x1ED9,0x1EDB,0x1EDD,0x1EDF,0x1EE1,0x1EE3,0x1EE5,0x1EE7,0x1EE9,0x1EEB,0x1EED,0x1EEF,0x1EF1,0x1EF3,0x1EF5,0x1EF7,0x1EF9,
316 /* Number forms */ 0x2170,0x2171,0x2172,0x2173,0x2174,0x2175,0x2176,0x2177,0x2178,0x2179,0x217A,0x217B,0x217C,0x217D,0x217E,0x217F,
317 /* Full-width */ 0xFF41,0xFF42,0xFF43,0xFF44,0xFF45,0xFF46,0xFF47,0xFF48,0xFF49,0xFF4A,0xFF4B,0xFF4C,0xFF4D,0xFF4E,0xFF4F,0xFF50,0xFF51,0xFF52,0xFF53,0xFF54,0xFF55,0xFF56,0xFF57,0xFF58,0xFF59,0xFF5A
318 };
319 static const WCHAR upper[] = { /* Upper case characters correspond to lower[] */
320 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0x178,
321 0x100,0x102,0x104,0x106,0x108,0x10A,0x10C,0x10E,0x110,0x112,0x114,0x116,0x118,0x11A,0x11C,0x11E,0x120,0x122,0x124,0x126,0x128,0x12A,0x12C,0x12E,0x130,0x132,0x134,0x136,0x139,0x13B,0x13D,0x13F,0x141,0x143,0x145,0x147,0x14A,0x14C,0x14E,0x150,0x152,0x154,0x156,0x158,0x15A,0x15C,0x15E,0x160,0x162,0x164,0x166,0x168,0x16A,0x16C,0x16E,0x170,0x172,0x174,0x176,0x179,0x17B,0x17D,
322 0x182,0x184,0x187,0x18B,0x191,0x198,0x1A0,0x1A2,0x1A7,0x1AC,0x1AF,0x1B3,0x1B5,0x1B8,0x1BC,0x1C4,0x1C7,0x1CA,0x1CD,0x1CF,0x1D1,0x1D3,0x1D5,0x1D7,0x1D9,0x1DB,0x18E,0x1DE,0x1E0,0x1E2,0x1E4,0x1E6,0x1E8,0x1EA,0x1EC,0x1EE,0x1F1,0x1F4,0x1FA,0x1FC,0x1FE,0x200,0x202,0x204,0x206,0x208,0x20A,0x20C,0x20E,0x210,0x212,0x214,0x216,
323 0x391,0x392,0x393,0x394,0x395,0x396,0x397,0x398,0x399,0x39A,0x39B,0x39C,0x39D,0x39E,0x39F,0x3A0,0x3A1,0x3A3,0x3A4,0x3A5,0x3A6,0x3A7,0x3A8,0x3A9,0x3AA,0x3AB,0x38C,0x38E,0x38F,0x3E2,0x3E4,0x3E6,0x3E8,0x3EA,
324 0x410,0x411,0x412,0x413,0x414,0x415,0x416,0x417,0x418,0x419,0x41A,0x41B,0x41C,0x41D,0x41E,0x41F,0x420,0x421,0x422,0x423,0x424,0x425,0x426,0x427,0x428,0x429,0x42A,0x42B,0x42C,0x42D,0x42E,0x42F,0x402,0x403,0x404,0x405,0x406,0x407,0x408,0x409,0x40A,0x40B,0x40C,0x40E,0x40F,0x460,0x462,0x464,0x466,0x468,0x46A,0x46C,0x46E,0x470,0x472,0x474,0x476,0x478,0x47A,0x47C,0x47E,0x480,0x490,0x492,0x494,0x496,0x498,0x49A,0x49C,0x49E,0x4A0,0x4A2,0x4A4,0x4A6,0x4A8,0x4AA,0x4AC,0x4AE,0x4B0,0x4B2,0x4B4,0x4B6,0x4B8,0x4BA,0x4BC,0x4BE,0x4C1,0x4C3,0x5C7,0x4D0,0x4D2,0x4D4,0x4D6,0x4D8,0x4DA,0x4DC,0x4DE,0x4E0,0x4E2,0x4E4,0x4E6,0x4E8,0x4EA,0x4EC,0x4EE,0x4F0,0x4F2,0x4F4,0x4F8,
325 0x531,0x532,0x533,0x534,0x535,0x536,0x537,0x538,0x539,0x53A,0x53B,0x53C,0x53D,0x53E,0x53F,0x540,0x541,0x542,0x543,0x544,0x545,0x546,0x547,0x548,0x549,0x54A,0x54B,0x54C,0x54D,0x54E,0x54F,0x550,0x551,0x552,0x553,0x554,0x555,0x556,
326 0x1E00,0x1E02,0x1E04,0x1E06,0x1E08,0x1E0A,0x1E0C,0x1E0E,0x1E10,0x1E12,0x1E14,0x1E16,0x1E18,0x1E1A,0x1E1C,0x1E1E,0x1E20,0x1E22,0x1E24,0x1E26,0x1E28,0x1E2A,0x1E2C,0x1E2E,0x1E30,0x1E32,0x1E34,0x1E36,0x1E38,0x1E3A,0x1E3C,0x1E3E,0x1E40,0x1E42,0x1E44,0x1E46,0x1E48,0x1E4A,0x1E4C,0x1E4E,0x1E50,0x1E52,0x1E54,0x1E56,0x1E58,0x1E5A,0x1E5C,0x1E5E,0x1E60,0x1E62,0x1E64,0x1E66,0x1E68,0x1E6A,0x1E6C,0x1E6E,0x1E70,0x1E72,0x1E74,0x1E76,0x1E78,0x1E7A,0x1E7C,0x1E7E,0x1E80,0x1E82,0x1E84,0x1E86,0x1E88,0x1E8A,0x1E8C,0x1E8E,0x1E90,0x1E92,0x1E94,0x1E96,0x1E98,0x1E9A,0x1E9C,0x1E9E,0x1EA0,0x1EA2,0x1EA4,0x1EA6,0x1EA8,0x1EAA,0x1EAC,0x1EAE,0x1EB0,0x1EB2,0x1EB4,0x1EB6,0x1EB8,0x1EBA,0x1EBC,0x1EBE,0x1EC0,0x1EC2,0x1EC4,0x1EC6,0x1EC8,0x1ECA,0x1ECC,0x1ECE,0x1ED0,0x1ED2,0x1ED4,0x1ED6,0x1ED8,0x1EDA,0x1EDC,0x1EDE,0x1EE0,0x1EE2,0x1EE4,0x1EE6,0x1EE8,0x1EEA,0x1EEC,0x1EEE,0x1EF0,0x1EF2,0x1EF4,0x1EF6,0x1EF8,
327 0x2160,0x2161,0x2162,0x2163,0x2164,0x2165,0x2166,0x2167,0x2168,0x2169,0x216A,0x216B,0x216C,0x216D,0x216E,0x216F,
328 0xFF21,0xFF22,0xFF23,0xFF24,0xFF25,0xFF26,0xFF27,0xFF28,0xFF29,0xFF2A,0xFF2B,0xFF2C,0xFF2D,0xFF2E,0xFF2F,0xFF30,0xFF31,0xFF32,0xFF33,0xFF34,0xFF35,0xFF36,0xFF37,0xFF38,0xFF39,0xFF3A
329 };
330 UINT i, n, hi, li;
331
332
333 if (chr < 0x80) { /* ASCII characters (acceleration) */
334 if (chr >= 0x61 && chr <= 0x7A) chr -= 0x20;
335
336 } else { /* Non ASCII characters (table search) */
337 n = 12; li = 0; hi = sizeof lower / sizeof lower[0];
338 do {
339 i = li + (hi - li) / 2;
340 if (chr == lower[i]) break;
341 if (chr > lower[i]) li = i; else hi = i;
342 } while (--n);
343 if (n) chr = upper[i];
344 }
345
346 return chr;
347}
LARGE_INTEGER li
Definition: fxtimerapi.cpp:235

Referenced by cmp_lfn(), create_name(), and f_setlabel().

◆ get_fattime()

DWORD get_fattime ( void  )

Definition at line 20 of file fatten.c.

21{
22 /* 31-25: Year(0-127 org.1980), 24-21: Month(1-12), 20-16: Day(1-31) */
23 /* 15-11: Hour(0-23), 10-5: Minute(0-59), 4-0: Second(0-29 *2) */
24
25 time_t rawtime;
26 struct tm * timeinfo;
27
28 time(&rawtime);
29 timeinfo = localtime(&rawtime);
30
31 {
32 union FatTime {
33 struct {
34 DWORD Second : 5; // div 2
35 DWORD Minute : 6;
36 DWORD Hour : 5;
37 DWORD Day : 5;
38 DWORD Month : 4;
39 DWORD Year : 7; // year-1980
40 };
41 DWORD whole;
42 } myTime = {
43 {
44 timeinfo->tm_sec / 2,
45 timeinfo->tm_min,
46 timeinfo->tm_hour,
47 timeinfo->tm_mday,
48 timeinfo->tm_mon + 1,
49 timeinfo->tm_year - 80,
50 }
51 };
52
53 return myTime.whole;
54 }
55}
WCHAR Second[]
Definition: FormatMessage.c:12
__kernel_time_t time_t
Definition: linux.h:252
_In_ PLARGE_INTEGER _In_ BOOLEAN _Out_ PFAT_TIME_STAMP FatTime
Definition: fatprocs.h:1917
__u16 time
Definition: mkdosfs.c:8
_CRTIMP struct tm *__cdecl localtime(const time_t *_Time)
Definition: time.h:416
int tm_mon
Definition: time.h:73
int tm_year
Definition: time.h:74
int tm_hour
Definition: time.h:71
int tm_sec
Definition: time.h:69
int tm_mday
Definition: time.h:72
int tm_min
Definition: time.h:70