summaryrefslogtreecommitdiff
path: root/firmware/drivers/fat.c
diff options
context:
space:
mode:
authorBjörn Stenberg <bjorn@haxx.se>2002-11-18 11:58:43 +0000
committerBjörn Stenberg <bjorn@haxx.se>2002-11-18 11:58:43 +0000
commiteee2c01697f90e3be4d7c1b0c57f6921c78e85b9 (patch)
tree071d638ff388222972a70f55997412cc23dcef29 /firmware/drivers/fat.c
parent7aabb1ab66b3126b987200528b62f4a3fb98d205 (diff)
downloadrockbox-eee2c01697f90e3be4d7c1b0c57f6921c78e85b9.tar.gz
rockbox-eee2c01697f90e3be4d7c1b0c57f6921c78e85b9.zip
Added longname handling to fat_remove().
Added proper 0xffff padding of last longname entry. add_dir_entry() now makes sure shortname is unique. Changed update_file_size() to use dir-as-file handling. Simplified create_dos_name() since we never use shortnames. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@2853 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware/drivers/fat.c')
-rw-r--r--firmware/drivers/fat.c373
1 files changed, 235 insertions, 138 deletions
diff --git a/firmware/drivers/fat.c b/firmware/drivers/fat.c
index 534d48bf76..a3ed62e4bc 100644
--- a/firmware/drivers/fat.c
+++ b/firmware/drivers/fat.c
@@ -100,7 +100,6 @@
100#define FATDIR_FILESIZE 28 100#define FATDIR_FILESIZE 28
101 101
102#define FATLONG_ORDER 0 102#define FATLONG_ORDER 0
103#define FATLONG_ATTR 11
104#define FATLONG_TYPE 12 103#define FATLONG_TYPE 12
105#define FATLONG_CHKSUM 13 104#define FATLONG_CHKSUM 13
106 105
@@ -648,9 +647,9 @@ static int write_long_name(struct fat_file* file,
648 unsigned char* entry; 647 unsigned char* entry;
649 unsigned int idx = firstentry % DIR_ENTRIES_PER_SECTOR; 648 unsigned int idx = firstentry % DIR_ENTRIES_PER_SECTOR;
650 unsigned int sector = firstentry / DIR_ENTRIES_PER_SECTOR; 649 unsigned int sector = firstentry / DIR_ENTRIES_PER_SECTOR;
651 unsigned int i, j=0, nameidx; 650 unsigned int i, j=0;
652 unsigned char chksum = 0; 651 unsigned char chksum = 0;
653 unsigned int namelen = strlen(name); 652 int nameidx=0, namelen = strlen(name);
654 int rc; 653 int rc;
655 654
656 LDEBUGF("write_long_name(file:%x, first:%d, num:%d, name:%s)\n", 655 LDEBUGF("write_long_name(file:%x, first:%d, num:%d, name:%s)\n",
@@ -669,9 +668,10 @@ static int write_long_name(struct fat_file* file,
669 chksum = ((chksum & 1) ? 0x80 : 0) + (chksum >> 1) + shortname[j++]; 668 chksum = ((chksum & 1) ? 0x80 : 0) + (chksum >> 1) + shortname[j++];
670 669
671 /* calc position of last name segment */ 670 /* calc position of last name segment */
672 for (nameidx=0; 671 if ( namelen > NAME_BYTES_PER_ENTRY )
673 nameidx < (namelen - NAME_BYTES_PER_ENTRY); 672 for (nameidx=0;
674 nameidx += NAME_BYTES_PER_ENTRY); 673 nameidx < (namelen - NAME_BYTES_PER_ENTRY);
674 nameidx += NAME_BYTES_PER_ENTRY);
675 675
676 for (i=0; i < numentries; i++) { 676 for (i=0; i < numentries; i++) {
677 /* new sector? */ 677 /* new sector? */
@@ -685,10 +685,15 @@ static int write_long_name(struct fat_file* file,
685 if (rc<1) 685 if (rc<1)
686 return -4; 686 return -4;
687 687
688 /* grab next sector */ 688 /* read next sector */
689 rc = fat_readwrite(file, 1, buf, false); 689 rc = fat_readwrite(file, 1, buf, false);
690 if (rc<1) 690 if (rc<0) {
691 LDEBUGF("Failed writing new sector: %d\n",rc);
691 return -5; 692 return -5;
693 }
694 if (rc==0)
695 /* end of dir */
696 memset(buf, 0, sizeof buf);
692 697
693 sector++; 698 sector++;
694 idx = 0; 699 idx = 0;
@@ -707,13 +712,34 @@ static int write_long_name(struct fat_file* file,
707 if ( i+1 < numentries ) { 712 if ( i+1 < numentries ) {
708 /* longname entry */ 713 /* longname entry */
709 int k, l = nameidx; 714 int k, l = nameidx;
715
710 entry[FATLONG_ORDER] = numentries-i-1; 716 entry[FATLONG_ORDER] = numentries-i-1;
711 if (i==0) 717 if (i==0) {
718 /* mark this as last long entry */
712 entry[FATLONG_ORDER] |= 0x40; 719 entry[FATLONG_ORDER] |= 0x40;
713 for (k=0; k<5 && name[l]; k++) entry[k*2 + 1] = name[l++]; 720
714 for (k=0; k<6 && name[l]; k++) entry[k*2 + 14] = name[l++]; 721 /* pad name with 0xffff */
715 for (k=0; k<2 && name[l]; k++) entry[k*2 + 28] = name[l++]; 722 for (k=1; k<12; k++) entry[k] = 0xff;
716 entry[FATLONG_ATTR] = FAT_ATTR_LONG_NAME; 723 for (k=14; k<26; k++) entry[k] = 0xff;
724 for (k=28; k<32; k++) entry[k] = 0xff;
725 };
726 /* set name */
727 for (k=0; k<5 && l <= namelen; k++) {
728 entry[k*2 + 1] = name[l++];
729 entry[k*2 + 2] = 0;
730 }
731 for (k=0; k<6 && l <= namelen; k++) {
732 entry[k*2 + 14] = name[l++];
733 entry[k*2 + 15] = 0;
734 }
735 for (k=0; k<2 && l <= namelen; k++) {
736 entry[k*2 + 28] = name[l++];
737 entry[k*2 + 29] = 0;
738 }
739
740 entry[FATDIR_ATTR] = FAT_ATTR_LONG_NAME;
741 entry[FATDIR_FSTCLUSLO] = 0;
742 entry[FATLONG_TYPE] = 0;
717 entry[FATLONG_CHKSUM] = chksum; 743 entry[FATLONG_CHKSUM] = chksum;
718 LDEBUGF("Longname entry %d: %.13s\n", idx, name+nameidx); 744 LDEBUGF("Longname entry %d: %.13s\n", idx, name+nameidx);
719 } 745 }
@@ -726,14 +752,13 @@ static int write_long_name(struct fat_file* file,
726 } 752 }
727 idx++; 753 idx++;
728 nameidx -= NAME_BYTES_PER_ENTRY; 754 nameidx -= NAME_BYTES_PER_ENTRY;
729 //dbg_dump_buffer(buf, SECTOR_SIZE, 0);
730 } 755 }
731 756
732 /* update last sector */ 757 /* update last sector */
733 rc = fat_seek(file, sector); 758 rc = fat_seek(file, sector);
734 if (rc<0) 759 if (rc<0)
735 return -5; 760 return -5;
736 761
737 rc = fat_readwrite(file, 1, buf, true); 762 rc = fat_readwrite(file, 1, buf, true);
738 if (rc<1) 763 if (rc<1)
739 return -6; 764 return -6;
@@ -751,8 +776,10 @@ static int add_dir_entry(struct fat_dir* dir,
751 unsigned int sector; 776 unsigned int sector;
752 bool done = false; 777 bool done = false;
753 bool eof = false; 778 bool eof = false;
779 bool last = false;
754 int entries_needed, entries_found = 0; 780 int entries_needed, entries_found = 0;
755 int namelen = strlen(name); 781 int namelen = strlen(name);
782 int firstentry;
756 783
757 LDEBUGF( "add_dir_entry(%s,%x)\n", 784 LDEBUGF( "add_dir_entry(%s,%x)\n",
758 name, file->firstcluster); 785 name, file->firstcluster);
@@ -767,6 +794,9 @@ static int add_dir_entry(struct fat_dir* dir,
767 if (namelen % NAME_BYTES_PER_ENTRY) 794 if (namelen % NAME_BYTES_PER_ENTRY)
768 entries_needed++; 795 entries_needed++;
769 796
797 restart:
798 firstentry = 0;
799
770 err=fat_seek(&dir->file, 0); 800 err=fat_seek(&dir->file, 0);
771 if (err<0) 801 if (err<0)
772 return -1; 802 return -1;
@@ -803,7 +833,7 @@ static int add_dir_entry(struct fat_dir* dir,
803 } 833 }
804 834
805 /* look for free slots */ 835 /* look for free slots */
806 for (i=0; i < DIR_ENTRIES_PER_SECTOR; i++) 836 for (i=0; i < DIR_ENTRIES_PER_SECTOR && !done; i++)
807 { 837 {
808 unsigned char firstbyte = buf[i * DIR_ENTRY_SIZE]; 838 unsigned char firstbyte = buf[i * DIR_ENTRY_SIZE];
809 switch (firstbyte) { 839 switch (firstbyte) {
@@ -811,6 +841,8 @@ static int add_dir_entry(struct fat_dir* dir,
811 entries_found = entries_needed; 841 entries_found = entries_needed;
812 LDEBUGF("Found last entry %d\n", 842 LDEBUGF("Found last entry %d\n",
813 sector * DIR_ENTRIES_PER_SECTOR + i); 843 sector * DIR_ENTRIES_PER_SECTOR + i);
844 last = true;
845 done = true;
814 break; 846 break;
815 847
816 case 0xe5: /* free entry */ 848 case 0xe5: /* free entry */
@@ -822,55 +854,90 @@ static int add_dir_entry(struct fat_dir* dir,
822 854
823 default: 855 default:
824 entries_found = 0; 856 entries_found = 0;
857
858 /* check that our intended shortname doesn't already exist */
859 if (!strncmp(shortname, buf + i * DIR_ENTRY_SIZE, 12)) {
860 /* filename exists already. make a new one */
861 snprintf(shortname+8, 4, "%03X", (unsigned)rand() & 0xfff);
862 LDEBUGF("Duplicate shortname, changing to %s\n",
863 shortname);
864
865 /* name has changed, we need to restart search */
866 goto restart;
867 }
825 break; 868 break;
826 } 869 }
827 870
828 if (entries_found == entries_needed) 871 if (!firstentry && (entries_found == entries_needed)) {
829 { 872 firstentry = sector * DIR_ENTRIES_PER_SECTOR + i;
830 int firstentry = sector * DIR_ENTRIES_PER_SECTOR + i;
831 873
832 /* if we're not extending the dir, we must go back to first 874 /* if we're not extending the dir,
833 free entry */ 875 we must go back to first free entry */
834 if (firstbyte) 876 if (!last)
835 firstentry -= (entries_needed - 1); 877 firstentry -= (entries_needed - 1);
878 }
879 }
880 }
836 881
837 LDEBUGF("Adding longname to entry %d in sector %d\n", 882 sector = firstentry / DIR_ENTRIES_PER_SECTOR;
838 i, sector); 883 LDEBUGF("Adding longname to entry %d in sector %d\n",
884 firstentry, sector);
839 885
840 err = write_long_name(&dir->file, firstentry, 886 err = write_long_name(&dir->file, firstentry,
841 entries_needed, name, shortname); 887 entries_needed, name, shortname);
842 if (err < 0) 888 if (err < 0)
843 return -5; 889 return -5;
844 890
845 /* remember where the shortname dir entry is located */ 891 /* remember where the shortname dir entry is located */
846 file->dirsector = dir->file.lastsector; 892 file->direntry = firstentry + entries_needed - 1;
847 file->direntry = 893 file->direntries = entries_needed;
848 (i + entries_needed - 1) % DIR_ENTRIES_PER_SECTOR; 894 file->dircluster = dir->file.firstcluster;
895 LDEBUGF("Added new dir entry %d, using %d slots.\n",
896 file->direntry, file->direntries);
849 897
850 /* advance the last_empty_entry marker? */ 898 /* advance the end-of-dir marker? */
851 if (firstbyte == 0) 899 if (last)
852 { 900 {
853 i++; 901 unsigned int lastentry = firstentry + entries_needed;
854 if (i < DIR_ENTRIES_PER_SECTOR) 902
855 { 903 LDEBUGF("Updating end-of-dir entry %d\n",lastentry);
856 /* next entry is now last */ 904
857 buf[i*DIR_ENTRY_SIZE] = 0; 905 if (lastentry % DIR_ENTRIES_PER_SECTOR)
858 } 906 {
859 else 907 int idx = (lastentry % DIR_ENTRIES_PER_SECTOR) * DIR_ENTRY_SIZE;
860 { 908
861 /* add a new sector/cluster for last entry */ 909 err=fat_seek(&dir->file, lastentry / DIR_ENTRIES_PER_SECTOR);
862 memset(buf, 0, sizeof buf); 910 if (err<0)
863 do { 911 return -6;
864 err = fat_readwrite(&dir->file, 1, buf, true); 912
865 if (err<1) 913 err = fat_readwrite(&dir->file, 1, buf, false);
866 return -6; 914 if (err<1)
867 } while (dir->file.sectornum < 915 return -7;
868 (int)fat_bpb.bpb_secperclus); 916
869 } 917 /* clear last entry */
870 } 918 buf[idx] = 0;
871 done = true; 919
872 break; 920 err=fat_seek(&dir->file, lastentry / DIR_ENTRIES_PER_SECTOR);
873 } 921 if (err<0)
922 return -8;
923
924 /* we must clear entire last cluster */
925 do {
926 err = fat_readwrite(&dir->file, 1, buf, true);
927 if (err<1)
928 return -9;
929 memset(buf, 0, sizeof buf);
930 } while (dir->file.sectornum < (int)fat_bpb.bpb_secperclus);
931 }
932 else
933 {
934 /* add a new sector/cluster for last entry */
935 memset(buf, 0, sizeof buf);
936 do {
937 err = fat_readwrite(&dir->file, 1, buf, true);
938 if (err<1)
939 return -10;
940 } while (dir->file.sectornum < (int)fat_bpb.bpb_secperclus);
874 } 941 }
875 } 942 }
876 943
@@ -916,106 +983,70 @@ unsigned char char2dos(unsigned char c)
916 983
917static int create_dos_name(unsigned char *name, unsigned char *newname) 984static int create_dos_name(unsigned char *name, unsigned char *newname)
918{ 985{
919 unsigned char n[12]; 986 int i,j;
920 unsigned char c;
921 int i;
922 char *ext;
923 987
924 strncpy(n, name, sizeof n);
925
926 ext = strchr(n, '.');
927 if(ext)
928 {
929 *ext++ = 0;
930 }
931
932 /* The file name is either empty, or there was only an extension.
933 In either case it is illegal. */
934 if(n[0] == 0)
935 {
936 return -2;
937 }
938
939 /* Name part */ 988 /* Name part */
940 for(i = 0;n[i] && (i < 8);i++) 989 for (i=0, j=0; name[i] && (j < 8); i++)
941 {
942 c = char2dos(n[i]);
943 if(c)
944 {
945 newname[i] = toupper(c);
946 }
947 }
948 while(i < 8)
949 { 990 {
950 newname[i++] = ' '; 991 unsigned char c = char2dos(name[i]);
992 if (c)
993 newname[j++] = toupper(c);
951 } 994 }
995 while (j < 8)
996 newname[j++] = ' ';
952 997
953 /* Extension part */ 998 /* Extension part */
954 for (i = 0;ext && ext[i] && (i < 3);i++) 999 snprintf(newname+8, 4, "%03X", (unsigned)rand() & 0xfff);
955 {
956 c = char2dos(ext[i]);
957 if (c)
958 {
959 newname[8+i] = toupper(c);
960 }
961 }
962 while(i < 3)
963 {
964 newname[8+i++] = ' ';
965 }
966 1000
967 newname[11] = 0;
968 return 0; 1001 return 0;
969} 1002}
970 1003
971static int update_file_size( struct fat_file* file, int size ) 1004static int update_file_size( struct fat_file* file, int size )
972{ 1005{
973 unsigned char buf[SECTOR_SIZE]; 1006 unsigned char buf[SECTOR_SIZE];
974 int sector = file->dirsector + fat_bpb.startsector; 1007 int sector = file->direntry / DIR_ENTRIES_PER_SECTOR;
975 unsigned char* entry = buf + file->direntry * DIR_ENTRY_SIZE; 1008 unsigned char* entry =
1009 buf + DIR_ENTRY_SIZE * (file->direntry % DIR_ENTRIES_PER_SECTOR);
976 unsigned int* sizeptr; 1010 unsigned int* sizeptr;
977 unsigned short* clusptr; 1011 unsigned short* clusptr;
1012 struct fat_file dir;
978 int err; 1013 int err;
979 1014
980 LDEBUGF("update_file_size(cluster:%x entry:%d sector:%x size:%d)\n", 1015 LDEBUGF("update_file_size(cluster:%x entry:%d size:%d)\n",
981 file->firstcluster, file->direntry, file->dirsector, size); 1016 file->firstcluster, file->direntry, size);
982 1017
983 if ( file->direntry >= DIR_ENTRIES_PER_SECTOR ) 1018 /* create a temporary file handle for the dir holding this file */
984 panicf("update_file_size(): Illegal entry %d!\n",file->direntry); 1019 err = fat_open(file->dircluster, &dir, NULL);
1020 if (err<0)
1021 return -1;
985 1022
986 if ( file->direntry < 0 ) 1023 err = fat_seek( &dir, sector );
987 panicf("update_file_size(): Illegal entry %d!\n",file->direntry); 1024 if (err<0)
1025 return -2;
988 1026
989 err = ata_read_sectors(sector, 1, buf); 1027 err = fat_readwrite(&dir, 1, buf, false);
990 if (err) 1028 if (err<1)
991 { 1029 return -3;
992 DEBUGF( "update_file_size() - Couldn't read dir sector %d"
993 " (error code %d)\n", sector, err);
994 return -1;
995 }
996 1030
997 if ( size == -1 ) { 1031 if (!entry[0] || entry[0] == 0xe5)
998 /* mark entry deleted */ 1032 panicf("Updating size on empty dir entry %d\n", file->direntry);
999 entry[0] = 0xe5;
1000 }
1001 else {
1002 clusptr = (short*)(entry + FATDIR_FSTCLUSHI);
1003 *clusptr = SWAB16(file->firstcluster >> 16);
1004 1033
1005 clusptr = (short*)(entry + FATDIR_FSTCLUSLO); 1034 clusptr = (short*)(entry + FATDIR_FSTCLUSHI);
1006 *clusptr = SWAB16(file->firstcluster & 0xffff); 1035 *clusptr = SWAB16(file->firstcluster >> 16);
1036
1037 clusptr = (short*)(entry + FATDIR_FSTCLUSLO);
1038 *clusptr = SWAB16(file->firstcluster & 0xffff);
1007 1039
1008 sizeptr = (int*)(entry + FATDIR_FILESIZE); 1040 sizeptr = (int*)(entry + FATDIR_FILESIZE);
1009 *sizeptr = SWAB32(size); 1041 *sizeptr = SWAB32(size);
1010 }
1011 1042
1012 err = ata_write_sectors(sector, 1, buf); 1043 err = fat_seek( &dir, sector );
1013 if (err) 1044 if (err<0)
1014 { 1045 return -4;
1015 DEBUGF( "update_file_size() - Couldn't write dir sector %d" 1046
1016 " (error code %d)\n", sector, err); 1047 err = fat_readwrite(&dir, 1, buf, true);
1017 return -2; 1048 if (err<1)
1018 } 1049 return -5;
1019 1050
1020 return 0; 1051 return 0;
1021} 1052}
@@ -1057,8 +1088,9 @@ int fat_open(unsigned int startcluster,
1057 1088
1058 /* remember where the file's dir entry is located */ 1089 /* remember where the file's dir entry is located */
1059 if ( dir ) { 1090 if ( dir ) {
1060 file->dirsector = dir->sector;
1061 file->direntry = dir->entry - 1; 1091 file->direntry = dir->entry - 1;
1092 file->direntries = dir->entrycount;
1093 file->dircluster = dir->file.firstcluster;
1062 } 1094 }
1063 LDEBUGF("fat_open(%x), entry %d\n",startcluster,file->direntry); 1095 LDEBUGF("fat_open(%x), entry %d\n",startcluster,file->direntry);
1064 return 0; 1096 return 0;
@@ -1113,7 +1145,7 @@ int fat_closewrite(struct fat_file *file, int size)
1113 } 1145 }
1114 } 1146 }
1115 1147
1116 if (file->dirsector) 1148 if (file->dircluster)
1117 if (update_file_size(file, size) < 0) 1149 if (update_file_size(file, size) < 0)
1118 return -1; 1150 return -1;
1119 1151
@@ -1152,9 +1184,69 @@ int fat_remove(struct fat_file* file)
1152 update_fat_entry(last,0); 1184 update_fat_entry(last,0);
1153 last = next; 1185 last = next;
1154 } 1186 }
1155 update_file_size(file, -1); 1187
1156 file->dirsector = 0; 1188 /* free all dir entries */
1189 if ( file->dircluster ) {
1190 unsigned char buf[SECTOR_SIZE];
1191 struct fat_file dir;
1192 unsigned int entry = file->direntry - file->direntries + 1;
1193 unsigned int sector = entry / DIR_ENTRIES_PER_SECTOR;
1194 unsigned int i;
1195 int err;
1196
1197 /* create a temporary file handle for the dir holding this file */
1198 err = fat_open(file->dircluster, &dir, NULL);
1199 if (err<0)
1200 return -1;
1201
1202 err = fat_seek( &dir, sector );
1203 if (err<0)
1204 return -2;
1205
1206 err = fat_readwrite(&dir, 1, buf, false);
1207 if (err<1)
1208 return -3;
1209
1210 for (i=0; i < file->direntries; i++) {
1211 LDEBUGF("Clearing dir entry %d (%d/%d)\n",
1212 entry, i+1, file->direntries);
1213 buf[(entry % DIR_ENTRIES_PER_SECTOR) * DIR_ENTRY_SIZE] = 0xe5;
1214 entry++;
1215
1216 if ( (entry % DIR_ENTRIES_PER_SECTOR) == 0 ) {
1217 /* flush this sector */
1218 err = fat_seek(&dir, sector);
1219 if (err<0)
1220 return -4;
1221
1222 err = fat_readwrite(&dir, 1, buf, true);
1223 if (err<1)
1224 return -5;
1225
1226 if ( i+1 < file->direntries ) {
1227 /* read next sector */
1228 err = fat_readwrite(&dir, 1, buf, false);
1229 if (err<1)
1230 return -6;
1231 }
1232 sector++;
1233 }
1234 }
1235
1236 if ( entry % DIR_ENTRIES_PER_SECTOR ) {
1237 /* flush this sector */
1238 err = fat_seek(&dir, sector);
1239 if (err<0)
1240 return -7;
1241
1242 err = fat_readwrite(&dir, 1, buf, true);
1243 if (err<1)
1244 return -8;
1245 }
1246 }
1247
1157 file->firstcluster = 0; 1248 file->firstcluster = 0;
1249 file->dircluster = 0;
1158 1250
1159 return 0; 1251 return 0;
1160} 1252}
@@ -1384,9 +1476,11 @@ int fat_getnext(struct fat_dir *dir, struct fat_direntry *entry)
1384 int sectoridx=0; 1476 int sectoridx=0;
1385 static unsigned char cached_buf[SECTOR_SIZE]; 1477 static unsigned char cached_buf[SECTOR_SIZE];
1386 1478
1479 dir->entrycount = 0;
1480
1387 while(!done) 1481 while(!done)
1388 { 1482 {
1389 if ( dir->entry >= DIR_ENTRIES_PER_SECTOR || !dir->sector ) 1483 if ( !(dir->entry % DIR_ENTRIES_PER_SECTOR) || !dir->sector )
1390 { 1484 {
1391 err = fat_readwrite(&dir->file, 1, cached_buf, false); 1485 err = fat_readwrite(&dir->file, 1, cached_buf, false);
1392 if (err==0) { 1486 if (err==0) {
@@ -1400,7 +1494,6 @@ int fat_getnext(struct fat_dir *dir, struct fat_direntry *entry)
1400 return -1; 1494 return -1;
1401 } 1495 }
1402 dir->sector = dir->file.lastsector; 1496 dir->sector = dir->file.lastsector;
1403 dir->entry = 0;
1404 } 1497 }
1405 1498
1406 for (i = dir->entry % DIR_ENTRIES_PER_SECTOR; 1499 for (i = dir->entry % DIR_ENTRIES_PER_SECTOR;
@@ -1414,15 +1507,19 @@ int fat_getnext(struct fat_dir *dir, struct fat_direntry *entry)
1414 if (firstbyte == 0xe5) { 1507 if (firstbyte == 0xe5) {
1415 /* free entry */ 1508 /* free entry */
1416 sectoridx = 0; 1509 sectoridx = 0;
1510 dir->entrycount = 0;
1417 continue; 1511 continue;
1418 } 1512 }
1419 1513
1420 if (firstbyte == 0) { 1514 if (firstbyte == 0) {
1421 /* last entry */ 1515 /* last entry */
1422 entry->name[0] = 0; 1516 entry->name[0] = 0;
1517 dir->entrycount = 0;
1423 return 0; 1518 return 0;
1424 } 1519 }
1425 1520
1521 dir->entrycount++;
1522
1426 /* longname entry? */ 1523 /* longname entry? */
1427 if ( ( cached_buf[entrypos + FATDIR_ATTR] & 1524 if ( ( cached_buf[entrypos + FATDIR_ATTR] &
1428 FAT_ATTR_LONG_NAME_MASK ) == FAT_ATTR_LONG_NAME ) { 1525 FAT_ATTR_LONG_NAME_MASK ) == FAT_ATTR_LONG_NAME ) {