From 24a2de64ace053944e4a4ab1644240dc243f5293 Mon Sep 17 00:00:00 2001 From: Björn Stenberg Date: Sat, 27 Apr 2002 22:32:37 +0000 Subject: Added longname handling git-svn-id: svn://svn.rockbox.org/rockbox/trunk@276 a1c6a512-1295-4272-9138-f99709370657 --- firmware/drivers/fat.c | 80 ++++++++++++++++++++++++++++++++++++++++++-------- firmware/drivers/fat.h | 6 ++-- 2 files changed, 70 insertions(+), 16 deletions(-) (limited to 'firmware') diff --git a/firmware/drivers/fat.c b/firmware/drivers/fat.c index 3eab47e8b3..dc933be599 100644 --- a/firmware/drivers/fat.c +++ b/firmware/drivers/fat.c @@ -123,9 +123,14 @@ static unsigned int getcurrdostime(unsigned short *dosdate, static int create_dos_name(unsigned char *name, unsigned char *newname); #endif +/* fat cache */ static unsigned char *fat_cache[256]; static int fat_cache_dirty[256]; +/* sectors cache for longname use */ +static unsigned char lastsector[SECTOR_SIZE]; +static unsigned char lastsector2[SECTOR_SIZE]; + #ifdef TEST_FAT #include "debug.h" @@ -788,13 +793,6 @@ int fat_create_file(struct bpb *bpb, unsigned int currdir, char *name) static int parse_direntry(struct fat_direntry *de, unsigned char *buf) { - /* is this a long filename entry? */ - if ( ( buf[FATDIR_ATTR] & FAT_ATTR_LONG_NAME_MASK ) == - FAT_ATTR_LONG_NAME ) - { - return 0; - } - memset(de, 0, sizeof(struct fat_direntry)); de->attr = buf[FATDIR_ATTR]; de->crttimetenth = buf[FATDIR_CRTTIMETENTH]; @@ -930,26 +928,84 @@ int fat_getnext(struct bpb *bpb, int i; int err; unsigned char firstbyte; + int longarray[20]; + int longs=0; + int sectoridx=0; while(!done) { - /* Look for a free slot */ for(i = ent->entry;i < SECTOR_SIZE/32;i++) { firstbyte = ent->cached_buf[i*32]; + if(firstbyte == 0xe5) + /* free entry */ continue; if(firstbyte == 0) - /* no more entries */ + /* last entry */ return -1; - if ( parse_direntry(entry, &ent->cached_buf[i*32]) ) { - done = 1; - break; + /* longname entry? */ + if ( ( ent->cached_buf[i*32 + FATDIR_ATTR] & + FAT_ATTR_LONG_NAME_MASK ) == FAT_ATTR_LONG_NAME ) { + longarray[longs++] = i*32 + sectoridx; + } + else { + if ( parse_direntry(entry, &ent->cached_buf[i*32]) ) { + + /* replace shortname with longname? */ + if ( longs ) { + int j,k,l=0; + + /* iterate backwards through the dir entries */ + for (j=longs-1; j>=0; j--) { + unsigned char* ptr = ent->cached_buf; + int index = longarray[j]; + + /* current or cached sector? */ + if ( sectoridx >= SECTOR_SIZE ) { + if ( sectoridx >= SECTOR_SIZE*2 ) { + if ( index >= SECTOR_SIZE ) { + if ( index >= SECTOR_SIZE*2 ) + ptr = ent->cached_buf; + else + ptr = lastsector; + } + else + ptr = lastsector2; + } + else { + if ( index < SECTOR_SIZE ) + ptr = lastsector; + } + + index &= SECTOR_SIZE-1; + } + + /* piece together the name subcomponents */ + for (k=0; k<5; k++) + entry->name[l++] = ptr[index + k*2 + 1]; + for (k=0; k<6; k++) + entry->name[l++] = ptr[index + k*2 + 14]; + for (k=0; k<2; k++) + entry->name[l++] = ptr[index + k*2 + 28]; + } + entry->name[l]=0; + } + done = 1; + break; + } } } + /* save this sector, for longname use */ + if ( sectoridx ) + memcpy( lastsector2, ent->cached_buf, SECTOR_SIZE ); + else + memcpy( lastsector, ent->cached_buf, SECTOR_SIZE ); + sectoridx += SECTOR_SIZE; + /* Next sector? */ if(i < SECTOR_SIZE/32) { diff --git a/firmware/drivers/fat.h b/firmware/drivers/fat.h index e259255d51..907f7b326f 100644 --- a/firmware/drivers/fat.h +++ b/firmware/drivers/fat.h @@ -64,7 +64,7 @@ struct bpb struct fat_direntry { - unsigned char name[12]; /* Name plus \0 */ + unsigned char name[256]; /* Name plus \0 */ unsigned short attr; /* Attributes */ unsigned char crttimetenth; /* Millisecond creation time stamp (0-199) */ @@ -74,8 +74,6 @@ struct fat_direntry unsigned short wrttime; /* Last write time */ unsigned short wrtdate; /* Last write date */ unsigned int filesize; /* File size in bytes */ - unsigned short fstclusterlo; - unsigned short fstclusterhi; int firstcluster; /* fstclusterhi<<16 + fstcluslo */ }; @@ -91,7 +89,7 @@ struct fat_dirent int entry; unsigned int cached_sec; unsigned int num_sec; - char cached_buf[SECTOR_SIZE]; + unsigned char cached_buf[SECTOR_SIZE]; }; struct fat_fileent -- cgit v1.2.3