diff options
author | Björn Stenberg <bjorn@haxx.se> | 2002-04-27 22:32:37 +0000 |
---|---|---|
committer | Björn Stenberg <bjorn@haxx.se> | 2002-04-27 22:32:37 +0000 |
commit | 24a2de64ace053944e4a4ab1644240dc243f5293 (patch) | |
tree | 2475bbfdcecc3c06b2f7b5982722ed7b168a1f21 /firmware | |
parent | 334e64b521c1bd3ba0dc57cf39815b4dc6a60684 (diff) | |
download | rockbox-24a2de64ace053944e4a4ab1644240dc243f5293.tar.gz rockbox-24a2de64ace053944e4a4ab1644240dc243f5293.zip |
Added longname handling
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@276 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware')
-rw-r--r-- | firmware/drivers/fat.c | 80 | ||||
-rw-r--r-- | firmware/drivers/fat.h | 6 |
2 files changed, 70 insertions, 16 deletions
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, | |||
123 | static int create_dos_name(unsigned char *name, unsigned char *newname); | 123 | static int create_dos_name(unsigned char *name, unsigned char *newname); |
124 | #endif | 124 | #endif |
125 | 125 | ||
126 | /* fat cache */ | ||
126 | static unsigned char *fat_cache[256]; | 127 | static unsigned char *fat_cache[256]; |
127 | static int fat_cache_dirty[256]; | 128 | static int fat_cache_dirty[256]; |
128 | 129 | ||
130 | /* sectors cache for longname use */ | ||
131 | static unsigned char lastsector[SECTOR_SIZE]; | ||
132 | static unsigned char lastsector2[SECTOR_SIZE]; | ||
133 | |||
129 | #ifdef TEST_FAT | 134 | #ifdef TEST_FAT |
130 | 135 | ||
131 | #include "debug.h" | 136 | #include "debug.h" |
@@ -788,13 +793,6 @@ int fat_create_file(struct bpb *bpb, unsigned int currdir, char *name) | |||
788 | 793 | ||
789 | static int parse_direntry(struct fat_direntry *de, unsigned char *buf) | 794 | static int parse_direntry(struct fat_direntry *de, unsigned char *buf) |
790 | { | 795 | { |
791 | /* is this a long filename entry? */ | ||
792 | if ( ( buf[FATDIR_ATTR] & FAT_ATTR_LONG_NAME_MASK ) == | ||
793 | FAT_ATTR_LONG_NAME ) | ||
794 | { | ||
795 | return 0; | ||
796 | } | ||
797 | |||
798 | memset(de, 0, sizeof(struct fat_direntry)); | 796 | memset(de, 0, sizeof(struct fat_direntry)); |
799 | de->attr = buf[FATDIR_ATTR]; | 797 | de->attr = buf[FATDIR_ATTR]; |
800 | de->crttimetenth = buf[FATDIR_CRTTIMETENTH]; | 798 | de->crttimetenth = buf[FATDIR_CRTTIMETENTH]; |
@@ -930,26 +928,84 @@ int fat_getnext(struct bpb *bpb, | |||
930 | int i; | 928 | int i; |
931 | int err; | 929 | int err; |
932 | unsigned char firstbyte; | 930 | unsigned char firstbyte; |
931 | int longarray[20]; | ||
932 | int longs=0; | ||
933 | int sectoridx=0; | ||
933 | 934 | ||
934 | while(!done) | 935 | while(!done) |
935 | { | 936 | { |
936 | /* Look for a free slot */ | ||
937 | for(i = ent->entry;i < SECTOR_SIZE/32;i++) | 937 | for(i = ent->entry;i < SECTOR_SIZE/32;i++) |
938 | { | 938 | { |
939 | firstbyte = ent->cached_buf[i*32]; | 939 | firstbyte = ent->cached_buf[i*32]; |
940 | |||
940 | if(firstbyte == 0xe5) | 941 | if(firstbyte == 0xe5) |
942 | /* free entry */ | ||
941 | continue; | 943 | continue; |
942 | 944 | ||
943 | if(firstbyte == 0) | 945 | if(firstbyte == 0) |
944 | /* no more entries */ | 946 | /* last entry */ |
945 | return -1; | 947 | return -1; |
946 | 948 | ||
947 | if ( parse_direntry(entry, &ent->cached_buf[i*32]) ) { | 949 | /* longname entry? */ |
948 | done = 1; | 950 | if ( ( ent->cached_buf[i*32 + FATDIR_ATTR] & |
949 | break; | 951 | FAT_ATTR_LONG_NAME_MASK ) == FAT_ATTR_LONG_NAME ) { |
952 | longarray[longs++] = i*32 + sectoridx; | ||
953 | } | ||
954 | else { | ||
955 | if ( parse_direntry(entry, &ent->cached_buf[i*32]) ) { | ||
956 | |||
957 | /* replace shortname with longname? */ | ||
958 | if ( longs ) { | ||
959 | int j,k,l=0; | ||
960 | |||
961 | /* iterate backwards through the dir entries */ | ||
962 | for (j=longs-1; j>=0; j--) { | ||
963 | unsigned char* ptr = ent->cached_buf; | ||
964 | int index = longarray[j]; | ||
965 | |||
966 | /* current or cached sector? */ | ||
967 | if ( sectoridx >= SECTOR_SIZE ) { | ||
968 | if ( sectoridx >= SECTOR_SIZE*2 ) { | ||
969 | if ( index >= SECTOR_SIZE ) { | ||
970 | if ( index >= SECTOR_SIZE*2 ) | ||
971 | ptr = ent->cached_buf; | ||
972 | else | ||
973 | ptr = lastsector; | ||
974 | } | ||
975 | else | ||
976 | ptr = lastsector2; | ||
977 | } | ||
978 | else { | ||
979 | if ( index < SECTOR_SIZE ) | ||
980 | ptr = lastsector; | ||
981 | } | ||
982 | |||
983 | index &= SECTOR_SIZE-1; | ||
984 | } | ||
985 | |||
986 | /* piece together the name subcomponents */ | ||
987 | for (k=0; k<5; k++) | ||
988 | entry->name[l++] = ptr[index + k*2 + 1]; | ||
989 | for (k=0; k<6; k++) | ||
990 | entry->name[l++] = ptr[index + k*2 + 14]; | ||
991 | for (k=0; k<2; k++) | ||
992 | entry->name[l++] = ptr[index + k*2 + 28]; | ||
993 | } | ||
994 | entry->name[l]=0; | ||
995 | } | ||
996 | done = 1; | ||
997 | break; | ||
998 | } | ||
950 | } | 999 | } |
951 | } | 1000 | } |
952 | 1001 | ||
1002 | /* save this sector, for longname use */ | ||
1003 | if ( sectoridx ) | ||
1004 | memcpy( lastsector2, ent->cached_buf, SECTOR_SIZE ); | ||
1005 | else | ||
1006 | memcpy( lastsector, ent->cached_buf, SECTOR_SIZE ); | ||
1007 | sectoridx += SECTOR_SIZE; | ||
1008 | |||
953 | /* Next sector? */ | 1009 | /* Next sector? */ |
954 | if(i < SECTOR_SIZE/32) | 1010 | if(i < SECTOR_SIZE/32) |
955 | { | 1011 | { |
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 | |||
64 | 64 | ||
65 | struct fat_direntry | 65 | struct fat_direntry |
66 | { | 66 | { |
67 | unsigned char name[12]; /* Name plus \0 */ | 67 | unsigned char name[256]; /* Name plus \0 */ |
68 | unsigned short attr; /* Attributes */ | 68 | unsigned short attr; /* Attributes */ |
69 | unsigned char crttimetenth; /* Millisecond creation | 69 | unsigned char crttimetenth; /* Millisecond creation |
70 | time stamp (0-199) */ | 70 | time stamp (0-199) */ |
@@ -74,8 +74,6 @@ struct fat_direntry | |||
74 | unsigned short wrttime; /* Last write time */ | 74 | unsigned short wrttime; /* Last write time */ |
75 | unsigned short wrtdate; /* Last write date */ | 75 | unsigned short wrtdate; /* Last write date */ |
76 | unsigned int filesize; /* File size in bytes */ | 76 | unsigned int filesize; /* File size in bytes */ |
77 | unsigned short fstclusterlo; | ||
78 | unsigned short fstclusterhi; | ||
79 | int firstcluster; /* fstclusterhi<<16 + fstcluslo */ | 77 | int firstcluster; /* fstclusterhi<<16 + fstcluslo */ |
80 | }; | 78 | }; |
81 | 79 | ||
@@ -91,7 +89,7 @@ struct fat_dirent | |||
91 | int entry; | 89 | int entry; |
92 | unsigned int cached_sec; | 90 | unsigned int cached_sec; |
93 | unsigned int num_sec; | 91 | unsigned int num_sec; |
94 | char cached_buf[SECTOR_SIZE]; | 92 | unsigned char cached_buf[SECTOR_SIZE]; |
95 | }; | 93 | }; |
96 | 94 | ||
97 | struct fat_fileent | 95 | struct fat_fileent |