Some FAT long file name fixes

git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@3789 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
patacongo 2011-07-15 15:37:29 +00:00
parent 2d2f8e6f08
commit 42249bbbb2

View File

@ -863,38 +863,44 @@ static inline int fat_findsfnentry(struct fat_mountpt_s *fs,
#ifdef CONFIG_FAT_LFN #ifdef CONFIG_FAT_LFN
static bool fat_cmplfnchunk(uint8_t *chunk, const uint8_t *substr, int nchunk) static bool fat_cmplfnchunk(uint8_t *chunk, const uint8_t *substr, int nchunk)
{ {
int i; wchar_t wch;
uint8_t ch;
int i;
/* Check bytes 1-nchunk */ /* Check bytes 1-nchunk */
for (i = 0; i < nchunk; i++) for (i = 0; i < nchunk; i++)
{ {
wchar_t wch; /* Get the next character from the name string. If we encounter the
* NUL terminator in the name string, then the rest of the characters
/* If we encounter the NUL terminator in the name string, then it is * in the directory should be spaces.
* a match -- return TRUE.
*/ */
if (*substr == 0) if (*substr == 0)
{ {
return true; ch = ' ';
}
else
{
ch = *substr++;
} }
/* Get the next unicode character from the chunk. We only handle ASCII. /* Get the next unicode character from the chunk. We only handle
* For ASCII, the upper byte should be zero and the lower should match * ASCII. For ASCII, the upper byte should be zero and the lower
* the ASCII code. * should match the ASCII code.
*/ */
wch = (wchar_t)fat_getuint16((uint8_t*)chunk); wch = (wchar_t)fat_getuint16((uint8_t*)chunk);
if ((wch & 0xff) != (wchar_t)*substr) if ((wch & 0xff) != (wchar_t)ch)
{ {
return false; return false;
} }
/* Yes.. the characters match. Try the next */ /* Yes.. the characters match. Try the next character from the
* directory entry.
*/
chunk += sizeof(wchar_t); chunk += sizeof(wchar_t);
substr++;
} }
/* All of the characters in the chunk match.. Return success */ /* All of the characters in the chunk match.. Return success */
@ -915,21 +921,39 @@ 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;
/* How much of string do we have to compare? */
len = strlen(substr);
/* Check bytes 1-5 */ /* Check bytes 1-5 */
chunk = LDIR_PTRWCHAR1_5(direntry); chunk = LDIR_PTRWCHAR1_5(direntry);
if (fat_cmplfnchunk(chunk, substr, 5)) if (fat_cmplfnchunk(chunk, substr, 5))
{ {
/* Check bytes 6-11 */ /* Advance the string pointer. Don't go past the end of the string. */
offset = MIN(5, len);
/* Check bytes 6-11 (or if offset == 0, verify that they are spaces) */
chunk = LDIR_PTRWCHAR6_11(direntry); chunk = LDIR_PTRWCHAR6_11(direntry);
if (fat_cmplfnchunk(chunk, &substr[5], 6)) if (fat_cmplfnchunk(chunk, &substr[offset], 6))
{ {
/* Check bytes 12-13 */ /* Advance the string pointer. Don't go past the end of the
* string.
*/
offset = MIN(11, len);
/* Check bytes 12-13 (or if offset == 0, verify that they are
* spaces)
*/
chunk = LDIR_PTRWCHAR12_13(direntry); chunk = LDIR_PTRWCHAR12_13(direntry);
return fat_cmplfnchunk(chunk, &substr[11], 2); return fat_cmplfnchunk(chunk, &substr[offset], 2);
} }
} }
@ -1088,18 +1112,31 @@ static inline int fat_findlfnentry(struct fat_mountpt_s *fs,
return -ENOENT; return -ENOENT;
} }
/* Verify the checksum */ /* Make sure that the directory entry is in the sector cache */
if (fat_lfnchecksum(dirinfo->fd_name) == checksum) ret = fat_fscacheread(fs, dirinfo->dir.fd_currsector);
{ if (ret < 0)
/* Success! Save the position of the directory entry and {
* return success. return ret;
*/ }
dirinfo->fd_seq.ds_sector = fs->fs_currentsector; /* Get a pointer to the directory entry */
dirinfo->fd_seq.ds_offset = diroffset;
dirinfo->fd_seq.ds_cluster = dirinfo->dir.fd_currcluster; diroffset = DIRSEC_BYTENDX(fs, dirinfo->dir.fd_index);
return OK; 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 /* Bad news.. reset and continue with this entry (which is
@ -1689,7 +1726,7 @@ 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 spzed character into the directory entry. */ /* The write the unicode space character into the directory entry. */
fat_putuint16((uint8_t *)chunk, (uint16_t)' '); fat_putuint16((uint8_t *)chunk, (uint16_t)' ');
chunk += sizeof(wchar_t); chunk += sizeof(wchar_t);
@ -1836,7 +1873,7 @@ static int fat_putlfname(struct fat_mountpt_s *fs, struct fat_dirinfo_s *dirinfo
if (remainder > 0) if (remainder > 0)
{ {
nbytes = MIN(8, remainder); nbytes = MIN(6, remainder);
fat_putlfnchunk(LDIR_PTRWCHAR6_11(direntry), fat_putlfnchunk(LDIR_PTRWCHAR6_11(direntry),
&dirinfo->fd_lfname[offset+5], nbytes); &dirinfo->fd_lfname[offset+5], nbytes);
remainder -= nbytes; remainder -= nbytes;
@ -2017,7 +2054,11 @@ int fat_finddirentry(struct fat_mountpt_s *fs, struct fat_dirinfo_s *dirinfo,
return OK; return OK;
} }
/* Otherwise, loop until the path is found */ /* This is not the root directory */
dirinfo->fd_root = false;
/* Now loop until the directory entry corresponding to the path is found */
for (;;) for (;;)
{ {
@ -2141,7 +2182,7 @@ int fat_allocatedirentry(struct fat_mountpt_s *fs, struct fat_dirinfo_s *dirinfo
} }
else else
{ {
/* Fixed size FAT12/16 root directory is at fixxed offset/size */ /* Fixed size FAT12/16 root directory is at fixed offset/size */
dirinfo->dir.fd_currsector = fs->fs_rootbase; dirinfo->dir.fd_currsector = fs->fs_rootbase;
} }