1
0
Fork 0
forked from len0rd/rockbox

Reverting the FAT32 driver change - it seems to have introduced a bug

git-svn-id: svn://svn.rockbox.org/rockbox/trunk@12152 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
Linus Nielsen Feltzing 2007-01-29 23:35:21 +00:00
parent 0f03e3af31
commit ca91b679a5
2 changed files with 49 additions and 65 deletions

View file

@ -16,7 +16,6 @@
* KIND, either express or implied. * KIND, either express or implied.
* *
****************************************************************************/ ****************************************************************************/
#include "config.h"
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
@ -2159,7 +2158,6 @@ int fat_opendir(IF_MV2(int volume,)
dir->entry = 0; dir->entry = 0;
dir->sector = 0; dir->sector = 0;
dir->bufindex = 0;
if (startcluster == 0) if (startcluster == 0)
startcluster = fat_bpb->bpb_rootclus; startcluster = fat_bpb->bpb_rootclus;
@ -2215,19 +2213,15 @@ int fat_getnext(struct fat_dir *dir, struct fat_direntry *entry)
int longarray[20]; int longarray[20];
int longs=0; int longs=0;
int sectoridx=0; int sectoridx=0;
/* Set the cache pointer to the sector buffer we are currently using */ unsigned char* cached_buf = dir->sectorcache[0];
unsigned char* cached_buf = dir->sectorcache[dir->bufindex];
dir->entrycount = 0; dir->entrycount = 0;
while(!done) while(!done)
{ {
if ( !(dir->entry % (DIR_ENTRIES_PER_SECTOR*FAT_DIR_BUFSECTORS)) || if ( !(dir->entry % DIR_ENTRIES_PER_SECTOR) || !dir->sector )
!dir->sector )
{ {
/* Always read 2 sectors at a time */ rc = fat_readwrite(&dir->file, 1, cached_buf, false);
rc = fat_readwrite(&dir->file, FAT_DIR_BUFSECTORS, cached_buf,
false);
if (rc == 0) { if (rc == 0) {
/* eof */ /* eof */
entry->name[0] = 0; entry->name[0] = 0;
@ -2241,8 +2235,8 @@ int fat_getnext(struct fat_dir *dir, struct fat_direntry *entry)
dir->sector = dir->file.lastsector; dir->sector = dir->file.lastsector;
} }
for (i = dir->entry % (DIR_ENTRIES_PER_SECTOR*FAT_DIR_BUFSECTORS); for (i = dir->entry % DIR_ENTRIES_PER_SECTOR;
i < (DIR_ENTRIES_PER_SECTOR*FAT_DIR_BUFSECTORS); i++) i < DIR_ENTRIES_PER_SECTOR; i++)
{ {
unsigned int entrypos = i * DIR_ENTRY_SIZE; unsigned int entrypos = i * DIR_ENTRY_SIZE;
@ -2283,44 +2277,40 @@ int fat_getnext(struct fat_dir *dir, struct fat_direntry *entry)
/* replace shortname with longname? */ /* replace shortname with longname? */
if ( longs ) { if ( longs ) {
int j; int j;
/* This should be enough to hold any name segment /* This should be enough to hold any name segment utf8-encoded */
utf8-encoded */
unsigned char shortname[13]; /* 8+3+dot+\0 */ unsigned char shortname[13]; /* 8+3+dot+\0 */
/* Add 1 for trailing \0 */ unsigned char longname_utf8segm[6*4 + 1]; /* Add 1 for trailing \0 */
unsigned char longname_utf8segm[6*4 + 1];
int longname_utf8len = 0; int longname_utf8len = 0;
/* Store it temporarily */ strcpy(shortname, entry->name); /* Temporarily store it */
strcpy(shortname, entry->name);
entry->name[0] = 0; entry->name[0] = 0;
/* iterate backwards through the dir entries */ /* iterate backwards through the dir entries */
for (j=longs-1; j>=0; j--) { for (j=longs-1; j>=0; j--) {
unsigned char* ptr = cached_buf;
int index = longarray[j]; int index = longarray[j];
unsigned char* ptr; /* current or cached sector? */
if ( sectoridx >= SECTOR_SIZE ) {
if ( sectoridx >= SECTOR_SIZE*2 ) {
if ( ( index >= SECTOR_SIZE ) &&
( index < SECTOR_SIZE*2 ))
ptr = dir->sectorcache[1];
else
ptr = dir->sectorcache[2];
}
else {
if ( index < SECTOR_SIZE )
ptr = dir->sectorcache[1];
}
/* If we have spanned over 3 sectors, the current index &= SECTOR_SIZE-1;
buffer holds the last part and the other one
the first part. */
if(sectoridx >= FAT_DIR_BUFSIZE) {
if(index / FAT_DIR_BUFSIZE > 0)
ptr = dir->sectorcache[dir->bufindex];
else
ptr = dir->sectorcache[1 - dir->bufindex];
} else {
ptr = dir->sectorcache[dir->bufindex];
} }
/* Let the index point into the selected /* Try to append each segment of the long name. Check if we'd
buffer */ exceed the buffer. Also check for FAT padding characters 0xFFFF. */
index &= FAT_DIR_BUFSIZE-1;
/* Try to append each segment of the long name.
Check if we'd exceed the buffer. Also check for
FAT padding characters 0xFFFF. */
if (fat_copy_long_name_segment(ptr + index + 1, 5, if (fat_copy_long_name_segment(ptr + index + 1, 5,
longname_utf8segm) == 0) longname_utf8segm) == 0) break;
break; // logf("SG: %s, EN: %s", longname_utf8segm, entry->name);
longname_utf8len += strlen(longname_utf8segm); longname_utf8len += strlen(longname_utf8segm);
if (longname_utf8len < FAT_FILENAME_BYTES) if (longname_utf8len < FAT_FILENAME_BYTES)
strcat(entry->name, longname_utf8segm); strcat(entry->name, longname_utf8segm);
@ -2328,8 +2318,8 @@ int fat_getnext(struct fat_dir *dir, struct fat_direntry *entry)
break; break;
if (fat_copy_long_name_segment(ptr + index + 14, 6, if (fat_copy_long_name_segment(ptr + index + 14, 6,
longname_utf8segm) == 0) longname_utf8segm) == 0) break;
break; // logf("SG: %s, EN: %s", longname_utf8segm, entry->name);
longname_utf8len += strlen(longname_utf8segm); longname_utf8len += strlen(longname_utf8segm);
if (longname_utf8len < FAT_FILENAME_BYTES) if (longname_utf8len < FAT_FILENAME_BYTES)
strcat(entry->name, longname_utf8segm); strcat(entry->name, longname_utf8segm);
@ -2337,8 +2327,8 @@ int fat_getnext(struct fat_dir *dir, struct fat_direntry *entry)
break; break;
if (fat_copy_long_name_segment(ptr + index + 28, 2, if (fat_copy_long_name_segment(ptr + index + 28, 2,
longname_utf8segm) == 0) longname_utf8segm) == 0) break;
break; // logf("SG: %s, EN: %s", longname_utf8segm, entry->name);
longname_utf8len += strlen(longname_utf8segm); longname_utf8len += strlen(longname_utf8segm);
if (longname_utf8len < FAT_FILENAME_BYTES) if (longname_utf8len < FAT_FILENAME_BYTES)
strcat(entry->name, longname_utf8segm); strcat(entry->name, longname_utf8segm);
@ -2348,18 +2338,19 @@ int fat_getnext(struct fat_dir *dir, struct fat_direntry *entry)
/* Does the utf8-encoded name fit into the entry? */ /* Does the utf8-encoded name fit into the entry? */
if (longname_utf8len >= FAT_FILENAME_BYTES) { if (longname_utf8len >= FAT_FILENAME_BYTES) {
/* Take the short DOS name. Need to utf8-encode it /* Take the short DOS name. Need to utf8-encode it since
since it may contain chars from the upper half it may contain chars from the upper half of the OEM
of the OEM code page which wouldn't be a valid code page which wouldn't be a valid utf8. Beware: this
utf8. Beware: this file will be shown with file will be shown with strange glyphs in file browser
strange glyphs in file browser since unicode since unicode 0x80 to 0x9F are control characters. */
0x80 to 0x9F are control characters. */
logf("SN-DOS: %s", shortname); logf("SN-DOS: %s", shortname);
unsigned char *utf8; unsigned char *utf8;
utf8 = iso_decode(shortname, entry->name, -1, utf8 = iso_decode(shortname, entry->name, -1, strlen(shortname));
strlen(shortname)); *utf8 = 0;
*utf8 = 0;
logf("SN: %s", entry->name); logf("SN: %s", entry->name);
} else {
// logf("LN: %s", entry->name);
// logf("LNLen: %d (%c)", longname_utf8len, entry->name[0]);
} }
} }
done = true; done = true;
@ -2370,14 +2361,13 @@ int fat_getnext(struct fat_dir *dir, struct fat_direntry *entry)
} }
} }
/* Did the name span across a buffer boundary? /* save this sector, for longname use */
Then we need to fill the second buffer as well and continue. */ if ( sectoridx )
if(!done) { memcpy( dir->sectorcache[2], dir->sectorcache[0], SECTOR_SIZE );
sectoridx += FAT_DIR_BUFSIZE; else
memcpy( dir->sectorcache[1], dir->sectorcache[0], SECTOR_SIZE );
sectoridx += SECTOR_SIZE;
dir->bufindex = 1 - dir->bufindex;
cached_buf = dir->sectorcache[dir->bufindex];
}
} }
return 0; return 0;
} }

View file

@ -73,19 +73,13 @@ struct fat_file
#endif #endif
}; };
#define FAT_DIR_BUFSECTORS 2 /* Needs to be an even number, at least 2 */
#define FAT_DIR_BUFSIZE (SECTOR_SIZE*FAT_DIR_BUFSECTORS)
struct fat_dir struct fat_dir
{ {
unsigned int entry; unsigned int entry;
unsigned int entrycount; unsigned int entrycount;
long sector; long sector;
struct fat_file file; struct fat_file file;
/* The buffer needs to be at least 3 sectors, so we make it 2*2 and unsigned char sectorcache[3][SECTOR_SIZE];
alternate between them */
unsigned char sectorcache[2][FAT_DIR_BUFSIZE];
unsigned int bufindex; /* Which buffer to be loaded next */
}; };