📄 landzo
字号:
ST_WORD(dir + LDIR_FstClusLO, 0);
i = (ord - 1) * 13; /* Get offset in the LFN buffer */
s = wc = 0;
do
{
if (wc != 0xFFFF) wc = lfnbuf[i++]; /* Get an effective char */
ST_WORD(dir + LfnOfs[s], wc); /* Put it */
if (!wc) wc = 0xFFFF; /* Padding chars following last char */
}
while (++s < 13);
if (wc == 0xFFFF || !lfnbuf[i]) ord |= LLE; /* Bottom LFN part is the start of LFN sequence */
dir[LDIR_Ord] = ord; /* Set the LFN order */
}
#endif
#endif
/*-----------------------------------------------------------------------*/
/* Create numbered name */
/*-----------------------------------------------------------------------*/
#if _USE_LFN
void gen_numname (
BYTE *dst, /* Pointer to generated SFN */
const BYTE *src, /* Pointer to source SFN to be modified */
const WCHAR *lfn, /* Pointer to LFN */
WORD seq /* Sequence number */
)
{
BYTE ns[8], c;
UINT i, j;
mem_cpy(dst, src, 11);
if (seq > 5) /* On many collisions, generate a hash number instead of sequential number */
{
do seq = (seq >> 1) + (seq << 15) + (WORD) * lfn++;
while (*lfn);
}
/* itoa (hexdecimal) */
i = 7;
do
{
c = (seq % 16) + '0';
if (c > '9') c += 7;
ns[i--] = c;
seq /= 16;
}
while (seq);
ns[i] = '~';
/* Append the number */
for (j = 0; j < i && dst[j] != ' '; j++)
{
if (IsDBCS1(dst[j]))
{
if (j == i - 1) break;
j++;
}
}
do
{
dst[j++] = (i < 8) ? ns[i++] : ' ';
}
while (j < 8);
}
#endif
/*-----------------------------------------------------------------------*/
/* Calculate sum of an SFN */
/*-----------------------------------------------------------------------*/
#if _USE_LFN
static
BYTE sum_sfn (
const BYTE *dir /* Ptr to directory entry */
)
{
BYTE sum = 0;
UINT n = 11;
do sum = (sum >> 1) + (sum << 7) + *dir++;
while (--n);
return sum;
}
#endif
/*-----------------------------------------------------------------------*/
/* Directory handling - Find an object in the directory */
/*-----------------------------------------------------------------------*/
static
FRESULT dir_find (
DIR *dj /* Pointer to the directory object linked to the file name */
)
{
FRESULT res;
BYTE c, *dir;
#if _USE_LFN
BYTE a, ord, sum;
#endif
res = dir_sdi(dj, 0); /* Rewind directory object */
if (res != FR_OK) return res;
#if _USE_LFN
ord = sum = 0xFF;
#endif
do
{
res = move_window(dj->fs, dj->sect);
if (res != FR_OK) break;
dir = dj->dir; /* Ptr to the directory entry of current index */
c = dir[DIR_Name];
if (c == 0)
{
res = FR_NO_FILE; /* Reached to end of table */
break;
}
#if _USE_LFN /* LFN configuration */
a = dir[DIR_Attr] & AM_MASK;
if (c == DDE || ((a & AM_VOL) && a != AM_LFN)) /* An entry without valid data */
{
ord = 0xFF;
}
else
{
if (a == AM_LFN) /* An LFN entry is found */
{
if (dj->lfn)
{
if (c & LLE) /* Is it start of LFN sequence? */
{
sum = dir[LDIR_Chksum];
c &= ~LLE;
ord = c; /* LFN start order */
dj->lfn_idx = dj->index;
}
/* Check validity of the LFN entry and compare it with given name */
ord = (c == ord && sum == dir[LDIR_Chksum] && cmp_lfn(dj->lfn, dir)) ? ord - 1 : 0xFF;
}
}
else /* An SFN entry is found */
{
if (!ord && sum == sum_sfn(dir)) break; /* LFN matched? */
ord = 0xFF;
dj->lfn_idx = 0xFFFF; /* Reset LFN sequence */
if (!(dj->fn[NS] & NS_LOSS) && !mem_cmp(dir, dj->fn, 11)) break; /* SFN matched? */
}
}
#else /* Non LFN configuration */
if (!(dir[DIR_Attr] & AM_VOL) && !mem_cmp(dir, dj->fn, 11)) /* Is it a valid entry? */
break;
#endif
res = dir_next(dj, 0); /* Next entry */
}
while (res == FR_OK);
return res;
}
/*-----------------------------------------------------------------------*/
/* Read an object from the directory */
/*-----------------------------------------------------------------------*/
#if _FS_MINIMIZE <= 1
static
FRESULT dir_read (
DIR *dj /* Pointer to the directory object that pointing the entry to be read */
)
{
FRESULT res;
BYTE c, *dir;
#if _USE_LFN
BYTE a, ord = 0xFF, sum = 0xFF;
#endif
res = FR_NO_FILE;
while (dj->sect)
{
res = move_window(dj->fs, dj->sect);
if (res != FR_OK) break;
dir = dj->dir; /* Ptr to the directory entry of current index */
c = dir[DIR_Name];
if (c == 0)
{
res = FR_NO_FILE; /* Reached to end of table */
break;
}
#if _USE_LFN /* LFN configuration */
a = dir[DIR_Attr] & AM_MASK;
if (c == DDE || (!_FS_RPATH && c == '.') || ((a & AM_VOL) && a != AM_LFN)) /* An entry without valid data */
{
ord = 0xFF;
}
else
{
if (a == AM_LFN) /* An LFN entry is found */
{
if (c & LLE) /* Is it start of LFN sequence? */
{
sum = dir[LDIR_Chksum];
c &= ~LLE;
ord = c;
dj->lfn_idx = dj->index;
}
/* Check LFN validity and capture it */
ord = (c == ord && sum == dir[LDIR_Chksum] && pick_lfn(dj->lfn, dir)) ? ord - 1 : 0xFF;
}
else /* An SFN entry is found */
{
if (ord || sum != sum_sfn(dir)) /* Is there a valid LFN? */
dj->lfn_idx = 0xFFFF; /* It has no LFN. */
break;
}
}
#else /* Non LFN configuration */
if (c != DDE && (_FS_RPATH || c != '.') && !(dir[DIR_Attr] & AM_VOL)) /* Is it a valid entry? */
break;
#endif
res = dir_next(dj, 0); /* Next entry */
if (res != FR_OK) break;
}
if (res != FR_OK) dj->sect = 0;
return res;
}
#endif
/*-----------------------------------------------------------------------*/
/* Register an object to the directory */
/*-----------------------------------------------------------------------*/
#if !_FS_READONLY
static
FRESULT dir_register ( /* FR_OK:Successful, FR_DENIED:No free entry or too many SFN collision, FR_DISK_ERR:Disk error */
DIR *dj /* Target directory with object name to be created */
)
{
FRESULT res;
BYTE c, *dir;
#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[NS] & NS_DOT)) /* Cannot create dot entry */
return FR_INVALID_NAME;
if (sn[NS] & NS_LOSS) /* When LFN is out of 8.3 format, generate a numbered name */
{
fn[NS] = 0;
dj->lfn = 0; /* 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[NS] = sn[NS];
dj->lfn = lfn;
}
if (sn[NS] & NS_LFN) /* When LFN is to be created, 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_sdi(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 == DDE || c == 0) /* Is it a blank entry? */
{
if (n == 0) is = dj->index; /* First index of the contiguous entry */
if (++n == ne) break; /* A contiguous entry that required count is found */
}
else
{
n = 0; /* Not a blank entry. Restart to search */
}
res = dir_next(dj, 1); /* Next entry with table stretch */
}
while (res == FR_OK);
if (res == FR_OK && ne > 1) /* Initialize LFN entry if needed */
{
res = dir_sdi(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, 0); /* Next entry */
}
while (res == FR_OK && --ne);
}
}
#else /* Non LFN configuration */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -