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:
parent
0f03e3af31
commit
ca91b679a5
2 changed files with 49 additions and 65 deletions
|
@ -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 we have spanned over 3 sectors, the current
|
if ( sectoridx >= SECTOR_SIZE*2 ) {
|
||||||
buffer holds the last part and the other one
|
if ( ( index >= SECTOR_SIZE ) &&
|
||||||
the first part. */
|
( index < SECTOR_SIZE*2 ))
|
||||||
if(sectoridx >= FAT_DIR_BUFSIZE) {
|
ptr = dir->sectorcache[1];
|
||||||
if(index / FAT_DIR_BUFSIZE > 0)
|
|
||||||
ptr = dir->sectorcache[dir->bufindex];
|
|
||||||
else
|
else
|
||||||
ptr = dir->sectorcache[1 - dir->bufindex];
|
ptr = dir->sectorcache[2];
|
||||||
} else {
|
}
|
||||||
ptr = dir->sectorcache[dir->bufindex];
|
else {
|
||||||
|
if ( index < SECTOR_SIZE )
|
||||||
|
ptr = dir->sectorcache[1];
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Let the index point into the selected
|
index &= SECTOR_SIZE-1;
|
||||||
buffer */
|
}
|
||||||
index &= FAT_DIR_BUFSIZE-1;
|
|
||||||
|
|
||||||
/* Try to append each segment of the long name.
|
/* Try to append each segment of the long name. Check if we'd
|
||||||
Check if we'd exceed the buffer. Also check for
|
exceed the buffer. Also check for FAT padding characters 0xFFFF. */
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue