summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBjörn Stenberg <bjorn@haxx.se>2002-04-27 22:32:37 +0000
committerBjörn Stenberg <bjorn@haxx.se>2002-04-27 22:32:37 +0000
commit24a2de64ace053944e4a4ab1644240dc243f5293 (patch)
tree2475bbfdcecc3c06b2f7b5982722ed7b168a1f21
parent334e64b521c1bd3ba0dc57cf39815b4dc6a60684 (diff)
downloadrockbox-24a2de64ace053944e4a4ab1644240dc243f5293.zip
rockbox-24a2de64ace053944e4a4ab1644240dc243f5293.tar.gz
rockbox-24a2de64ace053944e4a4ab1644240dc243f5293.tar.bz2
rockbox-24a2de64ace053944e4a4ab1644240dc243f5293.tar.xz
Added longname handling
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@276 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--firmware/drivers/fat.c80
-rw-r--r--firmware/drivers/fat.h6
2 files changed, 70 insertions, 16 deletions
diff --git a/firmware/drivers/fat.c b/firmware/drivers/fat.c
index 3eab47e..dc933be 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 e259255..907f7b3 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