Newer
Older
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
return ret;
}
/* Get a pointer to the directory entry */
diroffset = DIRSEC_BYTENDX(fs, dirinfo->dir.fd_index);
direntry = &fs->fs_buffer[diroffset];
/* Check if we are at the end of the directory */
if (direntry[DIR_NAME] == DIR0_ALLEMPTY)
{
return -ENOENT;
}
/* Check if we have found the directory entry that we are looking for */
if (direntry[DIR_NAME] != DIR0_EMPTY &&
!(DIR_GETATTRIBUTES(direntry) & FATATTR_VOLUMEID) &&
!memcmp(&direntry[DIR_NAME], dirinfo->fd_name, DIR_MAXFNAME) )
{
/* Yes.. Return success */
dirinfo->fd_seq.ds_sector = fs->fs_currentsector;
dirinfo->fd_seq.ds_offset = diroffset;
dirinfo->fd_seq.ds_cluster = dirinfo->dir.fd_currcluster;
dirinfo->fd_seq.ds_startsector = startsector;
/* Position the last long file name directory entry at the same
* position.
*/
dirinfo->fd_seq.ds_lfnsector = dirinfo->fd_seq.ds_sector;
dirinfo->fd_seq.ds_lfnoffset = dirinfo->fd_seq.ds_offset;
dirinfo->fd_seq.ds_lfncluster = dirinfo->fd_seq.ds_cluster;
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
#endif
return OK;
}
/* No... get the next directory index and try again */
if (fat_nextdirentry(fs, &dirinfo->dir) != OK)
{
return -ENOENT;
}
}
}
/****************************************************************************
* Name: fat_cmplfnchunk
*
* Desciption: There are 13 characters per LFN entry, broken up into three
* chunks for characts 1-5, 6-11, and 12-13. This function will perform
* the comparison of a single chunk.
*
****************************************************************************/
#ifdef CONFIG_FAT_LFN
static bool fat_cmplfnchunk(uint8_t *chunk, const uint8_t *substr, int nchunk)
/* Check bytes 1-nchunk */
for (i = 0; i < nchunk; i++)
{
/* Get the next character from the name string (which might be the NUL
* terminating character).
/* Get the next unicode character from the chunk. We only handle
* ASCII. For ASCII, the upper byte should be zero and the lower
* should match the ASCII code.
wch = (wchar_t)fat_getuint16((uint8_t*)chunk);
/* The characters match. If we just matched the NUL terminating
* character, then the strings match and we are finished.
if (ch == '\0')
{
return true;
}
/* Try the next character from the directory entry. */
chunk += sizeof(wchar_t);
}
/* All of the characters in the chunk match.. Return success */
return true;
}
#endif
/****************************************************************************
* Name: fat_cmplfname
*
* Desciption: Given an LFN directory entry, compare a substring of the name
* to a portion in the directory entry.
*
****************************************************************************/
#ifdef CONFIG_FAT_LFN
static bool fat_cmplfname(const uint8_t *direntry, const uint8_t *substr)
/* How much of string do we have to compare? (including the NUL
* terminator).
*/
len = strlen((char*)substr) + 1;
/* Check bytes 1-5 */
chunk = LDIR_PTRWCHAR1_5(direntry);
match = fat_cmplfnchunk(chunk, substr, 5);
chunk = LDIR_PTRWCHAR6_11(direntry);
match = fat_cmplfnchunk(chunk, &substr[5], 6);
chunk = LDIR_PTRWCHAR12_13(direntry);
match = fat_cmplfnchunk(chunk, &substr[11], 2);
}
#endif
/****************************************************************************
* Name: fat_findlfnentry
*
* Desciption: Find a sequence of long file name directory entries.
*
* NOTE: As a side effect, this function returns with the sector containing
* the short file name directory entry in the cache.
*
****************************************************************************/
#ifdef CONFIG_FAT_LFN
static inline int fat_findlfnentry(struct fat_mountpt_s *fs,
struct fat_dirinfo_s *dirinfo)
{
uint16_t diroffset;
uint8_t *direntry;
uint8_t lastseq;
uint8_t seqno;
uint8_t nfullentries;
uint8_t nentries;
uint8_t remainder;
int offset;
int namelen;
int ret;
/* Get the length of the long file name (size of the fd_lfname array is
* LDIR_MAXFNAME+1 we do not have to check the length of the string).
namelen = strlen((char*)dirinfo->fd_lfname);
DEBUGASSERT(namelen <= LDIR_MAXFNAME+1);
/* How many LFN directory entries are we expecting? */
nfullentries = namelen / LDIR_MAXLFNCHARS;
remainder = namelen - nfullentries * LDIR_MAXLFNCHARS;
nentries = nfullentries;
if (remainder > 0)
{
nentries++;
}
DEBUGASSERT(nentries > 0 && nentries <= LDIR_MAXLFNS);
/* This is the first sequency number we are looking for, the sequence
* number of the last LFN entry (remember that they appear in reverse
* order.. from last to first).
*/
/* Save the starting sector of the directory. This is needed later to
* re-scan the directory, looking duplicate short alias names.
*/
startsector = dirinfo->dir.fd_currsector;
/* Search, beginning with the current sector, for a directory entry this
* the match shore name
*/
for (;;)
{
/* Read the next sector into memory */
ret = fat_fscacheread(fs, dirinfo->dir.fd_currsector);
if (ret < 0)
{
/* Get a pointer to the directory entry */
diroffset = DIRSEC_BYTENDX(fs, dirinfo->dir.fd_index);
direntry = &fs->fs_buffer[diroffset];
/* Check if we are at the end of the directory */
if (direntry[DIR_NAME] == DIR0_ALLEMPTY)
{
return -ENOENT;
}
/* Is this an LFN entry? Does it have the sequence number we are
* looking for?
*/
if (LDIR_GETATTRIBUTES(direntry) != LDDIR_LFNATTR ||
LDIR_GETSEQ(direntry) != seqno)
{
/* No, restart the search at the next entry */
seqno = lastseq;
}
/* Yes.. If this is not the "last" LFN entry, then the checksum must
* also be the same.
*/
if (seqno == lastseq)
{
/* Just save the checksum for subsequent checks */
checksum = LDIR_GETCHECKSUM(direntry);
}
/* Not the first entry in the sequence. Does the checksum match the
* previous sequences?
*/
else if (checksum != LDIR_GETCHECKSUM(direntry))
{
/* No, restart the search at the next entry */
seqno = lastseq;
}
/* Check if the name substring in this LFN matches the corresponding
* substring of the name we are looking for.
offset = ((seqno & LDIR0_SEQ_MASK) - 1) * LDIR_MAXLFNCHARS;
if (fat_cmplfname(direntry, &dirinfo->fd_lfname[offset]))
{
/* Yes.. it matches. Check the sequence number. Is this the
* "last" LFN entry (i.e., the one that appears first)?
*/
if (seqno == lastseq)
{
/* Yes.. Save information about this LFN entry position */
dirinfo->fd_seq.ds_lfnsector = fs->fs_currentsector;
dirinfo->fd_seq.ds_lfnoffset = diroffset;
dirinfo->fd_seq.ds_lfncluster = dirinfo->dir.fd_currcluster;
dirinfo->fd_seq.ds_startsector = startsector;
seqno &= LDIR0_SEQ_MASK;
}
/* Is this the first sequence number (i.e., the LFN entry that
* will appear last)?
*/
if (seqno == 1)
{
/* We have found all of the LFN entries. The next directory
* entry should be the one containing the short file name
* alias and all of the meat about the file or directory.
*/
if (fat_nextdirentry(fs, &dirinfo->dir) != OK)
{
return -ENOENT;
}
/* Make sure that the directory entry is in the sector cache */
ret = fat_fscacheread(fs, dirinfo->dir.fd_currsector);
if (ret < 0)
{
return ret;
}
/* Get a pointer to the directory entry */
diroffset = DIRSEC_BYTENDX(fs, dirinfo->dir.fd_index);
direntry = &fs->fs_buffer[diroffset];
/* Verify the checksum */
if (fat_lfnchecksum(&direntry[DIR_NAME]) == checksum)
{
/* Success! Save the position of the directory entry and
* return success.
*/
dirinfo->fd_seq.ds_sector = fs->fs_currentsector;
dirinfo->fd_seq.ds_offset = diroffset;
dirinfo->fd_seq.ds_cluster = dirinfo->dir.fd_currcluster;
return OK;
}
/* Bad news.. reset and continue with this entry (which is
* probably not an LFN entry unless the file systen is
* seriously corrupted.
*/
seqno = lastseq;
continue;
}
/* No.. there are more LFN entries to go. Decrement the sequence
* number and check the next directory entry.
*/
seqno--;
}
else
{
/* No.. the names do not match. Restart the search at the next
* entry.
*/
seqno = lastseq;
}
/* Continue at the next directory entry */
next_entry:
if (fat_nextdirentry(fs, &dirinfo->dir) != OK)
{
return -ENOENT;
}
/****************************************************************************
* Name: fat_allocatesfnentry
*
* Desciption: Find a free directory entry for a short file name entry.
*
****************************************************************************/
static inline int fat_allocatesfnentry(struct fat_mountpt_s *fs,
struct fat_dirinfo_s *dirinfo)
{
uint16_t diroffset;
uint8_t *direntry;
#ifdef CONFIG_FAT_LFN
off_t startsector;
#endif
/* Save the sector number of the first sector of the directory. We don't
* really need this for short file name entries; this is just done for
* consistency with the long file name logic.
*/
#ifdef CONFIG_FAT_LFN
startsector = dirinfo->dir.fd_currsector;
#endif
/* Then search for a free short file name directory entry */
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
for (;;)
{
/* Read the directory sector into fs_buffer */
ret = fat_fscacheread(fs, dirinfo->dir.fd_currsector);
if (ret < 0)
{
/* Make sure that the return value is NOT -ENOSPC */
return -EIO;
}
/* Get a pointer to the entry at fd_index */
diroffset = (dirinfo->dir.fd_index & DIRSEC_NDXMASK(fs)) * DIR_SIZE;
direntry = &fs->fs_buffer[diroffset];
/* Check if this directory entry is empty */
ch = direntry[DIR_NAME];
if (ch == DIR0_ALLEMPTY || ch == DIR0_EMPTY)
{
/* It is empty -- we have found a directory entry */
dirinfo->fd_seq.ds_sector = fs->fs_currentsector;
dirinfo->fd_seq.ds_offset = diroffset;
dirinfo->fd_seq.ds_cluster = dirinfo->dir.fd_currcluster;
dirinfo->fd_seq.ds_startsector = startsector;
/* Set the "last" long file name offset to the same entry */
dirinfo->fd_seq.ds_lfnsector = dirinfo->fd_seq.ds_sector;
dirinfo->fd_seq.ds_lfnoffset = dirinfo->fd_seq.ds_offset;
dirinfo->fd_seq.ds_lfncluster = dirinfo->fd_seq.ds_cluster;
return OK;
}
/* It is not empty try the next one */
ret = fat_nextdirentry(fs, &dirinfo->dir);
if (ret < 0)
{
/* This will return -ENOSPC if we have examined all of the
* directory entries without finding a free entry.
*/
return ret;
}
}
}
/****************************************************************************
* Desciption: Find a sequence of free directory entries for a several long
* and one short file name entry.
* On entry, dirinfo.dir refers to the first interesting entry the directory.
*
****************************************************************************/
#ifdef CONFIG_FAT_LFN
static inline int fat_allocatelfnentry(struct fat_mountpt_s *fs,
struct fat_dirinfo_s *dirinfo)
{
uint16_t diroffset;
uint8_t *direntry;
uint8_t nentries;
uint8_t remainder;
uint8_t needed;
/* Get the length of the long file name (size of the fd_lfname array is
* LDIR_MAXFNAME+1 we do not have to check the length of the string).
namelen = strlen((char *)dirinfo->fd_lfname);
DEBUGASSERT(namelen <= LDIR_MAXFNAME+1);
/* How many LFN directory entries are we expecting? */
nentries = namelen / LDIR_MAXLFNCHARS;
remainder = namelen - nentries * LDIR_MAXLFNCHARS;
if (remainder > 0)
{
nentries++;
}
DEBUGASSERT(nentries > 0 && nentries <= LDIR_MAXLFNS);
/* Plus another for short file name entry that follows the sequence of LFN
* entries.
*/
nentries++;
/* Save the sector number of the first sector of the directory. We will
* need this later for re-scanning the directory to verify that a FAT file
* name is unique.
*/
startsector = dirinfo->dir.fd_currsector;
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
/* Now, search the directory looking for a sequence for free entries that
* long.
*/
needed = nentries;
for (;;)
{
/* Read the directory sector into fs_buffer */
ret = fat_fscacheread(fs, dirinfo->dir.fd_currsector);
if (ret < 0)
{
/* Make sure that the return value is NOT -ENOSPC */
return -EIO;
}
/* Get a pointer to the entry at fd_index */
diroffset = (dirinfo->dir.fd_index & DIRSEC_NDXMASK(fs)) * DIR_SIZE;
direntry = &fs->fs_buffer[diroffset];
/* Check if this directory entry is empty */
if (ch == DIR0_ALLEMPTY || ch == DIR0_EMPTY)
{
/* It is empty -- we have found a directory entry. Is this the
* "last" LFN entry (i.e., the one that occurs first)?
*/
if (needed == nentries)
{
/* Yes.. remember the position of this entry */
dirinfo->fd_seq.ds_lfnsector = fs->fs_currentsector;
dirinfo->fd_seq.ds_lfnoffset = diroffset;
dirinfo->fd_seq.ds_lfncluster = dirinfo->dir.fd_currcluster;
dirinfo->fd_seq.ds_startsector = startsector;
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
/* Is this last entry we need (i.e., the entry for the short
* file name entry)?
*/
if (needed <= 1)
{
/* Yes.. remember the position of this entry and return
* success.
*/
dirinfo->fd_seq.ds_sector = fs->fs_currentsector;
dirinfo->fd_seq.ds_offset = diroffset;
dirinfo->fd_seq.ds_cluster = dirinfo->dir.fd_currcluster;
return OK;
}
/* Otherwise, just decrement the number of directory entries
* needed and continue looking.
*/
needed--;
}
/* The directory entry is not available */
else
{
/* Reset the search and continue looking */
needed = nentries;
}
/* Try the next directory entry */
ret = fat_nextdirentry(fs, &dirinfo->dir);
if (ret < 0)
{
/* This will return -ENOSPC if we have examined all of the
* directory entries without finding a free entry.
*/
return ret;
}
}
}
#endif
/****************************************************************************
* Desciption: Get the 8.3 filename from a directory entry. On entry, the
* short file name entry is already in the cache.
*
****************************************************************************/
static inline int fat_getsfname(uint8_t *direntry, char *buffer,
unsigned int buflen)
#ifdef CONFIG_FAT_LCNAMES
uint8_t ntflags;
#endif
int ch;
int ndx;
/* Check if we will be doing upper to lower case conversions */
#ifdef CONFIG_FAT_LCNAMES
ntflags = DIR_GETNTRES(direntry);
#endif
/* Reserve a byte for the NUL terminator */
/* Get the 8-byte filename */
for (ndx = 0; ndx < 8 && buflen > 0; ndx++)
{
/* Get the next filename character from the directory entry */
/* Any space (or ndx==8) terminates the filename */
if (ch == ' ')
{
break;
}
/* In this version, we never write 0xe5 in the directory filenames
* (because we do not handle any character sets where 0xe5 is valid
* in a filaname), but we could encounted this in a filesystem
* written by some other system
*/
if (ndx == 0 && ch == DIR0_E5)
{
ch = 0xe5;
}
/* Check if we should perform upper to lower case conversion
* of the (whole) filename.
*/
#ifdef CONFIG_FAT_LCNAMES
if (ntflags & FATNTRES_LCNAME && isupper(ch))
{
ch = tolower(ch);
}
#endif
/* Copy the next character into the filename */
*buffer++ = ch;
buflen--;
}
/* Check if there is an extension */
if (direntry[8] != ' ' && buflen > 0)
{
/* Yes, output the dot before the extension */
*buffer++ = '.';
buflen--;
/* Then output the (up to) 3 character extension */
for (ndx = 8; ndx < 11 && buflen > 0; ndx++)
{
/* Get the next extensions character from the directory entry */
ch = direntry[DIR_NAME + ndx];
/* Any space (or ndx==11) terminates the extension */
if (ch == ' ')
{
break;
}
/* Check if we should perform upper to lower case conversion
* of the (whole) filename.
*/
#ifdef CONFIG_FAT_LCNAMES
if (ntflags & FATNTRES_LCEXT && isupper(ch))
{
ch = tolower(ch);
}
#endif
/* Copy the next character into the filename */
*buffer++ = ch;
buflen--;
}
}
/* Put a null terminator at the end of the filename. We don't have to
* check if there is room because we reserved a byte for the NUL
* terminator at the beginning of this function.
*/
*buffer = '\0';
return OK;
}
/****************************************************************************
* Desciption: There are 13 characters per LFN entry, broken up into three
* chunks for characts 1-5, 6-11, and 12-13. This function will get the
* file name characters from one chunk.
*
****************************************************************************/
static void fat_getlfnchunk(uint8_t *chunk, uint8_t *dest, int nchunk)
for (i = 0; i < nchunk; i++)
/* Get the next unicode character from the chunk. We only handle ASCII.
* For ASCII, the upper byte should be zero and the lower should match
* the ASCII code.
*/
wch = (wchar_t)fat_getuint16(chunk);
*dest++ = (uint8_t)(wch & 0xff);
chunk += sizeof(wchar_t);
}
}
#endif
/****************************************************************************
* Name: fat_getlfname
*
* Desciption: Get the long filename from a sequence of directory entries.
* On entry, the "last" long file name entry is in the cache. Returns with
* the short file name entry in the cache.
*
****************************************************************************/
#ifdef CONFIG_FAT_LFN
static inline int fat_getlfname(struct fat_mountpt_s *fs, struct fs_dirent_s *dir)
{
uint8_t lfname[LDIR_MAXLFNCHARS];
uint16_t diroffset;
uint8_t *direntry;
uint8_t seqno;
uint8_t offset;
uint8_t checksum;
int nsrc;
int i;
/* Get a reference to the current directory entry */
diroffset = (dir->u.fat.fd_index & DIRSEC_NDXMASK(fs)) * DIR_SIZE;
direntry = &fs->fs_buffer[diroffset];
/* Get the starting sequence number */
seqno = LDIR_GETSEQ(direntry);
DEBUGASSERT((seqno & LDIR0_LAST) != 0);
/* Sanity check */
rawseq = (seqno & LDIR0_SEQ_MASK);
if (rawseq < 1 || rawseq > LDIR_MAXLFNS)
{
return -EINVAL;
}
/* Save the checksum value */
checksum = LDIR_GETCHECKSUM(direntry);
/* Loop until the whole file name has been transferred */
for (;;)
{
/* Get the string offset associated with the "last" entry. */
offset = (rawseq - 1) * LDIR_MAXLFNCHARS;
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
/* Will any of this file name fit into the destination buffer? */
if (offset < NAME_MAX)
{
/* Yes.. extract and convert the unicode name */
fat_getlfnchunk(LDIR_PTRWCHAR1_5(direntry), lfname, 5);
fat_getlfnchunk(LDIR_PTRWCHAR6_11(direntry), &lfname[5], 6);
fat_getlfnchunk(LDIR_PTRWCHAR12_13(direntry), &lfname[11], 2);
/* Ignore trailing spaces on the "last" directory entry. The
* number of characters avaiable is LDIR_MAXLFNCHARS or that
* minus the number of trailing spaces on the "last" directory
* entry.
*/
nsrc = LDIR_MAXLFNCHARS;
if ((seqno & LDIR0_LAST) != 0)
{
/* Reduce the number of characters by the number of trailing
* spaces.
*/
for (; nsrc > 0 && lfname[nsrc-1] == ' '; nsrc--);
/* Further reduce the length so that it fits in the destination
* buffer.
*/
if (offset + nsrc > NAME_MAX)
{
nsrc = NAME_MAX - offset;
}
/* Add a null terminator to the destination string (the actual
* length of the destination buffer is NAME_MAX+1, so the NUL
* terminator will fit).
*/
dir->fd_dir.d_name[offset+nsrc] = '\0';
}
/* Then transfer the characters */
for (i = 0; i < nsrc && offset+i < NAME_MAX; i++)
{
dir->fd_dir.d_name[offset+i] = lfname[i];
}
}
/* Read next directory entry */
if (fat_nextdirentry(fs, &dir->u.fat) != OK)
{
return -ENOENT;
}
/* Make sure that the directory sector into the sector cache */
ret = fat_fscacheread(fs, dir->u.fat.fd_currsector);
if (ret < 0)
{
return ret;
}
/* Get a reference to the current directory entry */
diroffset = (dir->u.fat.fd_index & DIRSEC_NDXMASK(fs)) * DIR_SIZE;
direntry = &fs->fs_buffer[diroffset];
/* Get the next expected sequence number. */
if (seqno < 1)
{
/* We just completed processing the "first" long file name entry
* and we just read the short file name entry. Verify that the
* checksum of the short file name matches the checksum that we
* found in the long file name entries.
*/
if (fat_lfnchecksum(direntry) == checksum)
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
{
/* Yes.. return success! */
return OK;
}
/* No, the checksum is bad. */
return -EINVAL;
}
/* Verify the next long file name entry. Is this an LFN entry? Does it
* have the sequence number we are looking for? Does the checksum
* match the previous entries?
*/
if (LDIR_GETATTRIBUTES(direntry) != LDDIR_LFNATTR ||
LDIR_GETSEQ(direntry) != seqno ||
LDIR_GETCHECKSUM(direntry) != checksum)
{
return -EINVAL;
}
}
}
#endif
patacongo
committed
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
/****************************************************************************
* Name: fat_dirverify
*
* Desciption:
* Verify that every entry preceding this one is marked with something
* other than DIR0_ALLEMPTY. This is necessary only in the root directory
* of freshly formatted volumes. In that case, all entries are set to
* zero.
*
* This function also assures that the sector containing the entry is in
* the sector cache.
*
****************************************************************************/
static int fat_dirverify(struct fat_mountpt_s *fs, struct fat_dirinfo_s *dirinfo,
uint16_t offset)
{
uint8_t *direntry;
uint16_t i;
int ret;
/* Make sure that the sector containing the directory entry is in the sector
* cache.
*/
ret = fat_fscacheread(fs, dirinfo->dir.fd_currsector);
if (ret < 0)
{
return ret;
}
/* Check every entry preceding this one */
for (i = 0; i < offset; i += DIR_SIZE)
{
/* Is the rest of the directory marked empty? */
direntry = &fs->fs_buffer[i];
if (direntry[DIR_NAME] == DIR0_ALLEMPTY)
{
/* Then mark the just the entry as empty */
fs->fs_dirty = true;
direntry[DIR_NAME] = DIR0_EMPTY;
}
}
return OK;
}
/****************************************************************************
* Name: fat_putsfname
*
* Desciption: Write the short directory entry name.
*
* Assumption: The directory sector is in the cache.
*
****************************************************************************/
static int fat_putsfname(struct fat_mountpt_s *fs, struct fat_dirinfo_s *dirinfo)
{
uint8_t *direntry = &fs->fs_buffer[dirinfo->fd_seq.ds_offset];
patacongo
committed
/* Write the short directory entry */
memcpy(&direntry[DIR_NAME], dirinfo->fd_name, DIR_MAXFNAME);
DIR_PUTNTRES(direntry, dirinfo->fd_ntflags);
#else
DIR_PUTNTRES(direntry, 0);
#endif
fs->fs_dirty = true;
return OK;
}
/****************************************************************************
*
* Desciption: There are 13 characters per LFN entry, broken up into three
* chunks for characts 1-5, 6-11, and 12-13. This function will put the
* 0xffff characters into one chunk.
*
****************************************************************************/
#ifdef CONFIG_FAT_LFN
static void fat_initlfname(uint8_t *chunk, int nchunk)