📄 ff.lst
字号:
C51 COMPILER V7.06 FF 03/06/2010 17:37:27 PAGE 16
920
921
922
923 /*-----------------------------------------------------------------------*/
924 /* Register an object to the directory */
925 /*-----------------------------------------------------------------------*/
926 #if !_FS_READONLY
927 static
928 FRESULT dir_register ( /* FR_OK:Successful, FR_DENIED:No free entry or too many SFN collision, FR_DISK_ERR
-:Disk error */
929 DIR *dj /* Target directory with object name to be created */
930 )
931 {
932 1 FRESULT res;
933 1 BYTE c, *dir;
934 1 #if _USE_LFN /* LFN configuration */
WORD n, ne, is;
BYTE sn[12], *fn, sum;
WCHAR *lfn;
fn = dj->fn; lfn = dj->lfn;
mem_cpy(sn, fn, 12);
if (_FS_RPATH && (sn[11] & NS_DOT)) return FR_INVALID_NAME; /* Cannot create dot entry */
if (sn[11] & NS_LOSS) { /* When LFN is out of 8.3 format, generate a numbered name */
fn[11] = 0; dj->lfn = NULL; /* Find only SFN */
for (n = 1; n < 100; n++) {
gen_numname(fn, sn, lfn, n); /* Generate a numbered name */
res = dir_find(dj); /* Check if the name collides with existing SFN */
if (res != FR_OK) break;
}
if (n == 100) return FR_DENIED; /* Abort if too many collisions */
if (res != FR_NO_FILE) return res; /* Abort if the result is other than 'not collided' */
fn[11] = sn[11]; dj->lfn = lfn;
}
if (sn[11] & NS_LFN) { /* When LFN is to be created, reserve reserve an SFN + LFN entries. */
for (ne = 0; lfn[ne]; ne++) ;
ne = (ne + 25) / 13;
} else { /* Otherwise reserve only an SFN entry. */
ne = 1;
}
/* Reserve contiguous entries */
res = dir_seek(dj, 0);
if (res != FR_OK) return res;
n = is = 0;
do {
res = move_window(dj->fs, dj->sect);
if (res != FR_OK) break;
c = *dj->dir; /* Check the entry status */
if (c == 0xE5 || c == 0) { /* Is it a blank entry? */
if (n == 0) is = dj->index; /* First index of the contigulus entry */
if (++n == ne) break; /* A contiguous entry that requiered count is found */
} else {
n = 0; /* Not a blank entry. Restart to search */
}
res = dir_next(dj, TRUE); /* Next entry with table streach */
} while (res == FR_OK);
C51 COMPILER V7.06 FF 03/06/2010 17:37:27 PAGE 17
if (res == FR_OK && ne > 1) { /* Initialize LFN entry if needed */
res = dir_seek(dj, is);
if (res == FR_OK) {
sum = sum_sfn(dj->fn); /* Sum of the SFN tied to the LFN */
ne--;
do { /* Store LFN entries in bottom first */
res = move_window(dj->fs, dj->sect);
if (res != FR_OK) break;
fit_lfn(dj->lfn, dj->dir, (BYTE)ne, sum);
dj->fs->wflag = 1;
res = dir_next(dj, FALSE); /* Next entry */
} while (res == FR_OK && --ne);
}
}
#else /* Non LFN configuration */
997 1 res = dir_seek(dj, 0);
998 1 if (res == FR_OK) {
999 2 do { /* Find a blank entry for the SFN */
1000 3 res = move_window(dj->fs, dj->sect);
1001 3 if (res != FR_OK) break;
1002 3 c = *dj->dir;
1003 3 if (c == 0xE5 || c == 0) break; /* Is it a blank entry? */
1004 3 res = dir_next(dj, TRUE); /* Next entry with table streach */
1005 3 } while (res == FR_OK);
1006 2 }
1007 1 #endif
1008 1
1009 1 if (res == FR_OK) { /* Initialize the SFN entry */
1010 2 res = move_window(dj->fs, dj->sect);
1011 2 if (res == FR_OK) {
1012 3 dir = dj->dir;
1013 3 mem_set(dir, 0, 32); /* Clean the entry */
1014 3 mem_cpy(dir, dj->fn, 11); /* Put SFN */
1015 3 dir[DIR_NTres] = *(dj->fn+11) & 0x18; /* Put NT flag */
1016 3 dj->fs->wflag = 1;
1017 3 }
1018 2 }
1019 1
1020 1 return res;
1021 1 }
1022 #endif /* !_FS_READONLY */
1023
1024
1025
1026
1027 /*-----------------------------------------------------------------------*/
1028 /* Remove an object from the directory */
1029 /*-----------------------------------------------------------------------*/
1030 #if !_FS_READONLY && !_FS_MINIMIZE
1031 static
1032 FRESULT dir_remove ( /* FR_OK: Successful, FR_DISK_ERR: A disk error */
1033 DIR *dj /* Directory object pointing the entry to be removed */
1034 )
1035 {
1036 1 FRESULT res;
1037 1 #if _USE_LFN /* LFN configuration */
WORD i;
i = dj->index; /* SFN index */
res = dir_seek(dj, (WORD)((dj->lfn_idx == 0xFFFF) ? i : dj->lfn_idx)); /* Goto the SFN or top of the LFN
-entries */
C51 COMPILER V7.06 FF 03/06/2010 17:37:27 PAGE 18
if (res == FR_OK) {
do {
res = move_window(dj->fs, dj->sect);
if (res != FR_OK) break;
*dj->dir = 0xE5; /* Mark the entry "deleted" */
dj->fs->wflag = 1;
if (dj->index >= i) break; /* When reached SFN, all entries of the object has been deleted. */
res = dir_next(dj, FALSE); /* Next entry */
} while (res == FR_OK);
if (res == FR_NO_FILE) res = FR_INT_ERR;
}
#else /* Non LFN configuration */
1055 1 res = dir_seek(dj, dj->index);
1056 1 if (res == FR_OK) {
1057 2 res = move_window(dj->fs, dj->sect);
1058 2 if (res == FR_OK) {
1059 3 *dj->dir = 0xE5; /* Mark the entry "deleted" */
1060 3 dj->fs->wflag = 1;
1061 3 }
1062 2 }
1063 1 #endif
1064 1
1065 1 return res;
1066 1 }
1067 #endif /* !_FS_READONLY */
1068
1069
1070
1071
1072 /*-----------------------------------------------------------------------*/
1073 /* Pick a segment and create the object name in directory form */
1074 /*-----------------------------------------------------------------------*/
1075
1076
1077 static
1078 FRESULT create_name (
1079 DIR *dj, /* Pointer to the directory object */
1080 const XCHAR **path /* Pointer to pointer to the segment in the path string */
1081 )
1082 {
1083 1 #ifdef _EXCVT
static const BYTE cvt[] = _EXCVT;
#endif
1086 1 #if _USE_LFN /* LFN configuration */
BYTE b, cf;
WCHAR w, *lfn;
int i, ni, si, di;
const XCHAR *p;
/* Create LFN in Unicode */
si = di = 0;
p = *path;
lfn = dj->lfn;
for (;;) {
w = p[si++]; /* Get a character */
if (w < L' ' || w == L'/' || w == L'\\') break; /* Break on end of segment */
if (di >= _MAX_LFN) /* Reject too long name */
return FR_INVALID_NAME;
#if !_LFN_UNICODE
w &= 0xFF;
if (IsDBCS1(w)) { /* If it is a DBC 1st byte */
C51 COMPILER V7.06 FF 03/06/2010 17:37:27 PAGE 19
BYTE c = p[si++]; /* Get 2nd byte */
if (!IsDBCS2(c)) /* Reject invalid code for DBC */
return FR_INVALID_NAME;
w = (w << 8) + c;
}
w = ff_convert(w, 1); /* Convert OEM to Unicode */
if (!w) return FR_INVALID_NAME; /* Reject invalid code */
#endif
if (w < 0x80 && chk_chr("\"*:<>\?|\x7F", w)) /* Reject unallowable chars for LFN */
return FR_INVALID_NAME;
lfn[di++] = w; /* Store the Unicode char */
}
*path = &p[si]; /* Rerurn pointer to the next segment */
cf = (w < L' ') ? NS_LAST : 0; /* Set last segment flag if end of path */
#if _FS_RPATH
if ((di == 1 && lfn[di - 1] == L'.') || /* Is this a dot entry? */
(di == 2 && lfn[di - 1] == L'.' && lfn[di - 2] == L'.')) {
lfn[di] = 0;
for (i = 0; i < 11; i++)
dj->fn[i] = (i < di) ? '.' : ' ';
dj->fn[i] = cf | NS_DOT; /* This is a dot entry */
return FR_OK;
}
#endif
while (di) { /* Strip trailing spaces and dots */
w = lfn[di - 1];
if (w != L' ' && w != L'.') break;
di--;
}
if (!di) return FR_INVALID_NAME; /* Reject null string */
lfn[di] = 0; /* LFN is created */
/* Create SFN in directory form */
mem_set(dj->fn, ' ', 11);
for (si = 0; lfn[si] == L' ' || lfn[si] == L'.'; si++) ; /* Strip leading spaces and dots */
if (si) cf |= NS_LOSS | NS_LFN;
while (di && lfn[di - 1] != '.') di--; /* Find extension (di<=si: no extension) */
b = i = 0; ni = 8;
for (;;) {
w = lfn[si++]; /* Get an LFN char */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -