Correct FAT long file name padding character

git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@3794 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
patacongo 2011-07-18 00:20:58 +00:00
parent c20c6dfe92
commit 0673ba578e
5 changed files with 72 additions and 51 deletions

View File

@ -1923,3 +1923,8 @@
allocation (fat_allocatedirentry()). I looks like it could be allocation (fat_allocatedirentry()). I looks like it could be
initializing the wrong sectors! NOTE: This function was in initializing the wrong sectors! NOTE: This function was in
fs_fat32utils.c in earlier releases. fs_fat32utils.c in earlier releases.
* arch/arm/src/stm32_sdio.c: Correct an important DMA-related bug;
SDIO transfer completion events and DMA completion eventes were
not being coordinated correctly.
* configs/stm3210e-eval/nsh2: Enable FAT long file name support

View File

@ -755,7 +755,7 @@ static void stm32_dmacallback(DMA_HANDLE handle, uint8_t isr, void *arg)
stm32_sample((struct stm32_dev_s*)arg, SAMPLENDX_DMA_CALLBACK); stm32_sample((struct stm32_dev_s*)arg, SAMPLENDX_DMA_CALLBACK);
/* Then terminate the transfer (we should already have the SDIO transfer /* Then terminate the transfer (we should already have the SDIO transfer
* done interrupt. If now, the transfer will appropriately time out. * done interrupt. If not, the transfer will appropriately time out).
*/ */
priv->xfrflags |= SDIO_DMADONE_FLAG; priv->xfrflags |= SDIO_DMADONE_FLAG;

View File

@ -522,7 +522,7 @@ CONFIG_FB_HWCURSORIMAGE=n
# #
CONFIG_FS_FAT=y CONFIG_FS_FAT=y
CONFIG_FAT_LCNAMES=y CONFIG_FAT_LCNAMES=y
CONFIG_FAT_LFN=n CONFIG_FAT_LFN=y
CONFIG_FAT_MAXFNAME=32 CONFIG_FAT_MAXFNAME=32
CONFIG_FS_NXFFS=n CONFIG_FS_NXFFS=n
CONFIG_FS_ROMFS=n CONFIG_FS_ROMFS=n

View File

@ -263,6 +263,7 @@ static int fat_open(FAR struct file *filep, const char *relpath,
if ((oflags & O_CREAT) == 0) if ((oflags & O_CREAT) == 0)
{ {
/* No.. then we fail with -ENOENT */ /* No.. then we fail with -ENOENT */
ret = -ENOENT; ret = -ENOENT;
goto errout_with_semaphore; goto errout_with_semaphore;
} }

View File

@ -239,9 +239,10 @@ static inline int fat_parsesfname(const char **path,
return OK; return OK;
} }
/* Accept only the printable character set. Note the first byte /* Accept only the printable character set (excluding space). Note
* of the name could be 0x05 meaning that is it 0xe5, but this is * that the first byte of the name could be 0x05 meaning that is it
* not a printable character in this character in either case. * 0xe5, but this is not a printable character in this character in
* either case.
*/ */
else if (!isgraph(ch)) else if (!isgraph(ch))
@ -471,9 +472,9 @@ static inline int fat_parselfname(const char **path,
return OK; return OK;
} }
/* Accept only the printable character set */ /* Accept only the printable character set (including space) */
else if (!isgraph(ch)) else if (!isprint(ch))
{ {
goto errout; goto errout;
} }
@ -871,14 +872,13 @@ static bool fat_cmplfnchunk(uint8_t *chunk, const uint8_t *substr, int nchunk)
for (i = 0; i < nchunk; i++) for (i = 0; i < nchunk; i++)
{ {
/* Get the next character from the name string. If we encounter the /* Get the next character from the name string (which might be the NUL
* NUL terminator in the name string, then the rest of the characters * terminating character).
* in the directory should be spaces.
*/ */
if (*substr == 0) if (*substr == '\0')
{ {
ch = ' '; ch = '\0';
} }
else else
{ {
@ -896,10 +896,17 @@ static bool fat_cmplfnchunk(uint8_t *chunk, const uint8_t *substr, int nchunk)
return false; return false;
} }
/* Yes.. the characters match. Try the next character from the /* The characters match. If we just matched the NUL terminating
* directory entry. * 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); chunk += sizeof(wchar_t);
} }
@ -921,43 +928,45 @@ static bool fat_cmplfnchunk(uint8_t *chunk, const uint8_t *substr, int nchunk)
static bool fat_cmplfname(const uint8_t *direntry, const uint8_t *substr) static bool fat_cmplfname(const uint8_t *direntry, const uint8_t *substr)
{ {
uint8_t *chunk; uint8_t *chunk;
int offset;
int len; int len;
bool match;
/* How much of string do we have to compare? */ /* How much of string do we have to compare? (including the NUL
* terminator).
*/
len = strlen((char*)substr); len = strlen((char*)substr) + 1;
/* Check bytes 1-5 */ /* Check bytes 1-5 */
chunk = LDIR_PTRWCHAR1_5(direntry); chunk = LDIR_PTRWCHAR1_5(direntry);
if (fat_cmplfnchunk(chunk, substr, 5)) match = fat_cmplfnchunk(chunk, substr, 5);
if (match)
{ {
/* Advance the string pointer. Don't go past the end of the string. */ /* Don't go past the end of the sub-string */
offset = MIN(5, len); if (len > 5)
/* Check bytes 6-11 (or if offset == 0, verify that they are spaces) */
chunk = LDIR_PTRWCHAR6_11(direntry);
if (fat_cmplfnchunk(chunk, &substr[offset], 6))
{ {
/* Advance the string pointer. Don't go past the end of the /* Check bytes 6-11 */
* string.
*/
offset = MIN(11, len); chunk = LDIR_PTRWCHAR6_11(direntry);
match = fat_cmplfnchunk(chunk, &substr[5], 6);
if (match)
{
/* Don't go past the end of the sub-string */
/* Check bytes 12-13 (or if offset == 0, verify that they are if (len > 11)
* spaces) {
*/ /* Check bytes 12-13 */
chunk = LDIR_PTRWCHAR12_13(direntry); chunk = LDIR_PTRWCHAR12_13(direntry);
return fat_cmplfnchunk(chunk, &substr[offset], 2); match = fat_cmplfnchunk(chunk, &substr[11], 2);
}
}
} }
} }
return false; return match;
} }
#endif #endif
@ -982,17 +991,19 @@ static inline int fat_findlfnentry(struct fat_mountpt_s *fs,
uint8_t nfullentries; uint8_t nfullentries;
uint8_t nentries; uint8_t nentries;
uint8_t remainder; uint8_t remainder;
uint8_t checksum; uint8_t checksum = 0;
int offset; int offset;
int namelen; int namelen;
int ret; int ret;
/* Get the length of the long file name (size of the fd_lfname array is /* 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). * LDIR_MAXFNAME+1 we do not have to check the length of the string).
* NOTE that the name length is incremented to include the NUL terminating
* character that must also be written to the directory entry.
*/ */
namelen = strlen((char*)dirinfo->fd_lfname); namelen = strlen((char*)dirinfo->fd_lfname) + 1;
DEBUGASSERT(namelen <= LDIR_MAXFNAME); DEBUGASSERT(namelen <= LDIR_MAXFNAME+1);
/* How many LFN directory entries are we expecting? */ /* How many LFN directory entries are we expecting? */
@ -1266,10 +1277,12 @@ static inline int fat_allocatelfnentry(struct fat_mountpt_s *fs,
/* Get the length of the long file name (size of the fd_lfname array is /* 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). * LDIR_MAXFNAME+1 we do not have to check the length of the string).
* NOTE that the name length is incremented to include the NUL terminating
* character that must also be written to the directory entry.
*/ */
namelen = strlen((char *)dirinfo->fd_lfname); namelen = strlen((char *)dirinfo->fd_lfname) + 1;
DEBUGASSERT(namelen <= LDIR_MAXFNAME); DEBUGASSERT(namelen <= LDIR_MAXFNAME+1);
/* How many LFN directory entries are we expecting? */ /* How many LFN directory entries are we expecting? */
@ -1709,16 +1722,16 @@ static int fat_putsfname(struct fat_mountpt_s *fs, struct fat_dirinfo_s *dirinfo
} }
/**************************************************************************** /****************************************************************************
* Name: fat_putlfnspaces * Name: fat_initlfname
* *
* Desciption: There are 13 characters per LFN entry, broken up into three * 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 * chunks for characts 1-5, 6-11, and 12-13. This function will put the
* space characters into one chunk. * 0xffff characters into one chunk.
* *
****************************************************************************/ ****************************************************************************/
#ifdef CONFIG_FAT_LFN #ifdef CONFIG_FAT_LFN
static void fat_putlfnspaces(uint8_t *chunk, int nchunk) static void fat_initlfname(uint8_t *chunk, int nchunk)
{ {
int i; int i;
@ -1726,9 +1739,9 @@ static void fat_putlfnspaces(uint8_t *chunk, int nchunk)
for (i = 0; i < nchunk; i++) for (i = 0; i < nchunk; i++)
{ {
/* The write the unicode space character into the directory entry. */ /* The write the 16-bit 0xffff character into the directory entry. */
fat_putuint16((uint8_t *)chunk, (uint16_t)' '); fat_putuint16((uint8_t *)chunk, (uint16_t)0xffff);
chunk += sizeof(wchar_t); chunk += sizeof(wchar_t);
} }
} }
@ -1791,10 +1804,12 @@ static int fat_putlfname(struct fat_mountpt_s *fs, struct fat_dirinfo_s *dirinfo
/* Get the length of the long file name (size of the fd_lfname array is /* 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). * LDIR_MAXFNAME+1 we do not have to check the length of the string).
* NOTE that the name length is incremented to include the NUL terminating
* character that must also be written to the directory entry.
*/ */
namelen = strlen((char*)dirinfo->fd_lfname); namelen = strlen((char*)dirinfo->fd_lfname) + 1;
DEBUGASSERT(namelen <= LDIR_MAXFNAME); DEBUGASSERT(namelen <= LDIR_MAXFNAME+1);
/* How many LFN directory entries do we need to write? */ /* How many LFN directory entries do we need to write? */
@ -1858,11 +1873,11 @@ static int fat_putlfname(struct fat_mountpt_s *fs, struct fat_dirinfo_s *dirinfo
{ {
int nbytes; int nbytes;
/* Initialize the "last" directory entry name to all spaces */ /* Initialize the "last" directory entry name to all 0xffff */
fat_putlfnspaces(LDIR_PTRWCHAR1_5(direntry), 5); fat_initlfname(LDIR_PTRWCHAR1_5(direntry), 5);
fat_putlfnspaces(LDIR_PTRWCHAR6_11(direntry), 6); fat_initlfname(LDIR_PTRWCHAR6_11(direntry), 6);
fat_putlfnspaces(LDIR_PTRWCHAR12_13(direntry), 2); fat_initlfname(LDIR_PTRWCHAR12_13(direntry), 2);
/* Store the tail portion of the long file name in directory entry */ /* Store the tail portion of the long file name in directory entry */