📄 ff.c.bak
字号:
if (wDiskWrite(fp->buffer, fp->curr_sect, 1) != RES_OK) goto fk_error;
fp->flag &= ~FA__DIRTY;
}
#endif
if (ofs > fp->fsize) ofs = fp->fsize; /* Clip offset by file size */
fp->fptr = ofs; fp->sect_clust = 1; /* Re-initialize file pointer */
/* Seek file pinter if needed */
if (ofs) {
ofs = (ofs - 1) / 512; /* Calcurate current sector */
sc = fs->sects_clust; /* Number of sectors in a cluster */
fp->sect_clust = sc - ((BYTE)ofs % sc); /* Calcurate sector counter */
ofs /= sc; /* Number of clusters to skip */
clust = fp->org_clust; /* Seek to current cluster */
while (ofs--)
clust = prvGetCluster(clust);
if ((clust < 2) || (clust >= fs->max_clust)) goto fk_error;
fp->curr_clust = clust;
fp->curr_sect = prvClust2Sect(clust) + sc - fp->sect_clust; /* Current sector */
if (fp->fptr % 512) { /* Load currnet sector if needed */
if (wDiskRead(fp->buffer, fp->curr_sect, 1) != RES_OK)
goto fk_error;
}
}
return FR_OK;
fk_error: /* Abort this file due to an unrecoverable error */
fp->flag |= FA__ERROR;
return FR_RW_ERROR;
}
/*-------------------------------------------------*/
/* Synchronize between File and Disk without Close */
#ifndef _FS_READONLY
FRESULT wFileSync (
FIL *fp /* Pointer to the file object */
)
{
BYTE *ptr;
FATFS *fs = FatFs;
if (!fs) return FR_NOT_ENABLED;
if ((wDiskStatus() & STA_NOINIT) || !fs->fs_type)
return FR_INCORRECT_DISK_CHANGE;
/* Has the file been written? */
if (fp->flag & FA__WRITTEN) {
/* Write back data buffer if needed */
if (fp->flag & FA__DIRTY) {
if (wDiskWrite(fp->buffer, fp->curr_sect, 1) != RES_OK) return FR_RW_ERROR;
fp->flag &= ~FA__DIRTY;
}
/* Update the directory entry */
if (!prvMoveWindow(fp->dir_sect)) return FR_RW_ERROR;
ptr = fp->dir_ptr;
*(ptr+11) |= AM_ARC; /* Set archive bit */
ST_DWORD(ptr+28, fp->fsize); /* Update file size */
ST_WORD(ptr+26, fp->org_clust); /* Update start cluster */
ST_WORD(ptr+20, fp->org_clust >> 16);
ST_DWORD(ptr+22, wGetTime()); /* Updated time */
fs->winflag = 1;
fp->flag &= ~FA__WRITTEN;
}
if (!prvMoveWindow(0)) return FR_RW_ERROR;
return FR_OK;
}
#endif /* _FS_READONLY */
/*------------*/
/* Close File */
FRESULT wFileClose (
FIL *fp /* Pointer to the file object to be closed */
)
{
FRESULT res;
#ifndef _FS_READONLY
res = wFileSync(fp);
#else
res = FR_OK;
#endif
if (res == FR_OK) {
fp->flag = 0;
FatFs->files--;
}
return res;
}
#if _FS_MINIMIZE <= 1
/*---------------------------*/
/* Initialize directory scan */
FRESULT wDirOpen (
DIR *scan, /* Pointer to directory object to initialize */
const char *path /* Pointer to the directory path, null str means the root */
)
{
FRESULT res;
BYTE *dir;
char fn[8+3+1];
if ((res = prvCheckMounted()) != FR_OK) return res;
res = prvTracePath(scan, fn, path, &dir); /* Trace the directory path */
if (res == FR_OK) { /* Trace completed */
if (dir != NULL) { /* It is not a root dir */
if (*(dir+11) & AM_DIR) { /* The entry is a directory */
scan->clust = ((DWORD)LD_WORD(dir+20) << 16) | LD_WORD(dir+26);
scan->sect = prvClust2Sect(scan->clust);
scan->index = 0;
} else { /* The entry is not directory */
res = FR_NO_FILE;
}
}
}
return res;
}
/*----------------------------------*/
/* Read Directory Entry in Sequense */
FRESULT wDirRead (
DIR *scan, /* Pointer to the directory object */
FILINFO *finfo /* Pointer to file information to return */
)
{
BYTE *dir, c;
FATFS *fs = FatFs;
if (!fs) return FR_NOT_ENABLED;
finfo->fname[0] = 0;
finfo->flfn[0] = 0;
if ((wDiskStatus() & STA_NOINIT) || !fs->fs_type) return FR_NOT_READY;
while (scan->sect) {
if (!prvMoveWindow(scan->sect)) return FR_RW_ERROR;
dir = &(fs->win[(scan->index & 15) * 32]); /* pointer to the directory entry */
c = *dir;
if (c == 0) break; /* Has it reached to end of dir? */
{
if ((c != 0xE5) && (c != '.') && !(*(dir+11) & AM_VOL)) /* Is it a valid entry? */
prvGetFileinfo(finfo, dir);
else if (*(dir+11) == AM_LFN)
prvGetLFN(finfo, dir);
}
if (!prvNextDirEntry(scan)) scan->sect = 0; /* Next entry */
if (finfo->fname[0]) break; /* Found valid entry */
}
return FR_OK;
}
#if _FS_MINIMIZE == 0
/*-----------------*/
/* Get File Status */
FRESULT wFileStatus (
const char *path, /* Pointer to the file path */
FILINFO *finfo /* Pointer to file information to return */
)
{
FRESULT res;
BYTE *dir;
DIR dirscan;
char fn[8+3+1];
if ((res = prvCheckMounted()) != FR_OK) return res;
res = prvTracePath(&dirscan, fn, path, &dir); /* Trace the file path */
if (res == FR_OK) /* Trace completed */
prvGetFileinfo(finfo, dir);
return res;
}
#ifndef _FS_READONLY
/*-----------------------------*/
/* Get Number of Free Clusters */
FRESULT wFreeClusters (
DWORD *nclust /* Pointer to the double word to return number of free clusters */
)
{
DWORD n, clust, sect;
BYTE fat, f, *p;
FRESULT res;
FATFS *fs = FatFs;
if ((res = prvCheckMounted()) != FR_OK) return res;
/* Count number of free clusters */
fat = fs->fs_type;
n = 0;
if (fat == FS_FAT12) {
clust = 2;
do {
if ((WORD)prvGetCluster(clust) == 0) n++;
} while (++clust < fs->max_clust);
} else {
clust = fs->max_clust;
sect = fs->fatbase;
f = 0; p = 0;
do {
if (!f) {
if (!prvMoveWindow(sect++)) return FR_RW_ERROR;
p = fs->win;
}
if (fat == FS_FAT16) {
if (LD_WORD(p) == 0) n++;
p += 2; f += 1;
} else {
if (LD_DWORD(p) == 0) n++;
p += 4; f += 2;
}
} while (--clust);
}
*nclust = n;
return FR_OK;
}
/*------------------------------*/
/* Delete a File or a Directory */
FRESULT wDelete (
const char *path /* Pointer to the file or directory path */
)
{
FRESULT res;
BYTE *dir, *sdir;
DWORD dclust, dsect;
DIR dirscan;
char fn[8+3+1];
FATFS *fs = FatFs;
if ((res = prvCheckMounted()) != FR_OK) return res;
if (wDiskStatus() & STA_PROTECT) return FR_WRITE_PROTECTED;
res = prvTracePath(&dirscan, fn, path, &dir); /* Trace the file path */
if (res != FR_OK) return res; /* Trace failed */
if (dir == NULL) return FR_NO_FILE; /* It is a root directory */
if (*(dir+11) & AM_RDO) return FR_DENIED; /* It is a R/O item */
dsect = fs->winsect;
dclust = ((DWORD)LD_WORD(dir+20) << 16) | LD_WORD(dir+26);
if (*(dir+11) & AM_DIR) { /* It is a sub-directory */
dirscan.clust = dclust; /* Check if the sub-dir is empty or not */
dirscan.sect = prvClust2Sect(dclust);
dirscan.index = 0;
do {
if (!prvMoveWindow(dirscan.sect)) return FR_RW_ERROR;
sdir = &(fs->win[(dirscan.index & 15) * 32]);
if (*sdir == 0) break;
if (!((*sdir == 0xE5) || (*sdir == '.')) && !(*(sdir+11) & AM_VOL))
return FR_DENIED; /* The directory is not empty */
} while (prvNextDirEntry(&dirscan));
}
if (!prvMoveWindow(dsect)) return FR_RW_ERROR; /* Mark the directory entry 'deleted' */
*dir = 0xE5;
fs->winflag = 1;
if (!prvRemoveChain(dclust)) return FR_RW_ERROR; /* Remove the cluster chain */
if (!prvMoveWindow(0)) return FR_RW_ERROR;
return FR_OK;
}
/*--------------------*/
/* Create a Directory */
FRESULT wDirMake (
const char *path /* Pointer to the directory path */
)
{
FRESULT res;
BYTE *dir, *w, n;
DWORD sect, dsect, dclust, pclust, tim;
DIR dirscan;
char fn[8+3+1];
FATFS *fs = FatFs;
if ((res = prvCheckMounted()) != FR_OK) return res;
if (wDiskStatus() & STA_PROTECT) return FR_WRITE_PROTECTED;
res = prvTracePath(&dirscan, fn, path, &dir); /* Trace the file path */
if (res == FR_OK) return FR_DENIED; /* Any file or directory is already existing */
if (res != FR_NO_FILE) return res;
dir = prvReserveDirEntry(&dirscan); /* Reserve a directory entry */
if (dir == NULL) return FR_DENIED;
sect = fs->winsect;
dsect = prvClust2Sect(dclust = prvCreateChain(0)); /* Get a new cluster for new directory */
if (!dsect) return FR_DENIED;
if (!prvMoveWindow(0)) return 0;
w = fs->win;
memset(w, 0, 512); /* Initialize the directory table */
for (n = fs->sects_clust - 1; n; n--) {
if (wDiskWrite(w, dsect+n, 1) != RES_OK) return FR_RW_ERROR;
}
fs->winsect = dsect; /* Create dot directories */
memset(w, ' ', 8+3);
*w = '.';
*(w+11) = AM_DIR;
tim = wGetTime();
ST_DWORD(w+22, tim);
ST_WORD(w+26, dclust);
ST_WORD(w+20, dclust >> 16);
memcpy(w+32, w, 32); *(w+33) = '.';
pclust = dirscan.sclust;
if (fs->fs_type == FS_FAT32 && pclust == fs->dirbase) pclust = 0;
ST_WORD(w+32+26, pclust);
ST_WORD(w+32+20, pclust >> 16);
fs->winflag = 1;
if (!prvMoveWindow(sect)) return FR_RW_ERROR;
memcpy(dir, fn, 8+3); /* Initialize the new entry */
*(dir+11) = AM_DIR;
*(dir+12) = fn[11];
memset(dir+13, 0, 32-13);
ST_DWORD(dir+22, tim); /* Created time */
ST_WORD(dir+26, dclust); /* Table start cluster */
ST_WORD(dir+20, dclust >> 16);
fs->winflag = 1;
if (!prvMoveWindow(0)) return FR_RW_ERROR;
return FR_OK;
}
/*-----------------------*/
/* Change File Attribute */
FRESULT wFileChAttr (
const char *path, /* Pointer to the file path */
BYTE value, /* Attribute bits */
BYTE mask /* Attribute mask to change */
)
{
FRESULT res;
BYTE *dir;
DIR dirscan;
char fn[8+3+1];
FATFS *fs = FatFs;
if ((res = prvCheckMounted()) != FR_OK) return res;
if (wDiskStatus() & STA_PROTECT) return FR_WRITE_PROTECTED;
res = prvTracePath(&dirscan, fn, path, &dir); /* Trace the file path */
if (res == FR_OK) { /* Trace completed */
if (dir == NULL) {
res = FR_NO_FILE;
} else {
mask &= AM_RDO|AM_HID|AM_SYS|AM_ARC; /* Valid attribute mask */
*(dir+11) = (value & mask) | (*(dir+11) & ~mask); /* Apply attribute change */
fs->winflag = 1;
if (!prvMoveWindow(0)) res = FR_RW_ERROR;
}
}
return res;
}
/*-----------------------*/
/* Rename File/Directory */
FRESULT wFileRename (
const char *path_old, /* Pointer to the old name */
const char *path_new /* Pointer to the new name */
)
{
FRESULT res;
DWORD sect_old;
BYTE *dir_old, *dir_new, direntry[32-11];
DIR dirscan;
char fn[8+3+1];
FATFS *fs = FatFs;
if ((res = prvCheckMounted()) != FR_OK) return res;
if (wDiskStatus() & STA_PROTECT) return FR_WRITE_PROTECTED;
res = prvTracePath(&dirscan, fn, path_old, &dir_old); /* Check old object */
if (res != FR_OK) return res; /* The old object is not found */
if (!dir_old) return FR_NO_FILE;
sect_old = fs->winsect; /* Save the object information */
memcpy(direntry, dir_old+11, 32-11);
res = prvTracePath(&dirscan, fn, path_new, &dir_new); /* Check new object */
if (res == FR_OK) return FR_DENIED; /* The new object name is already existing */
if (res != FR_NO_FILE) return res;
dir_new = prvReserveDirEntry(&dirscan); /* Reserve a directory entry */
if (dir_new == NULL) return FR_DENIED;
memcpy(dir_new+11, direntry, 32-11); /* Create new entry */
memcpy(dir_new, fn, 8+3);
*(dir_new+12) = fn[11];
fs->winflag = 1;
if (!prvMoveWindow(sect_old)) return FR_RW_ERROR; /* Remove old entry */
*dir_old = 0xE5;
fs->winflag = 1;
if (!prvMoveWindow(0)) return FR_RW_ERROR;
return FR_OK;
}
#endif /* _FS_READONLY */
#endif /* _FS_MINIMIZE == 0 */
#endif /* _FS_MINIMIZE <= 1 */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -