1313#include <strings.h>
1414#include <ahci.h>
1515
16- int detect_fat_type (int8 * buf ) {
16+ static int fat16_is_reserved_name (cstring name ) {
17+ return strcmp (name , "." ) == 0 || strcmp (name , ".." ) == 0 ;
18+ }
19+
20+ partition_fs_type_t detect_fat_type_enum (const int8 * buf ) {
1721 fat16_boot_sector_t * bs = (fat16_boot_sector_t * )buf ;
1822
1923 if (bs -> sectors_per_fat != 0 && bs -> max_root_dir_entries != 0 ) {
@@ -22,37 +26,16 @@ int detect_fat_type(int8* buf) {
2226 uint32_t cluster_count = data_sectors / bs -> sectors_per_cluster ;
2327
2428 if (cluster_count < 4085 ) {
25- return 12 ;
29+ return FS_FAT12 ;
2630 } else if (cluster_count < 65525 ) {
27- return 16 ;
31+ return FS_FAT16 ;
2832 } else {
29- return 1 ;
33+ return FS_UNKNOWN ;
3034 }
3135 } else if (bs -> max_root_dir_entries == 0 ) {
32- return 32 ;
36+ return FS_FAT32 ;
3337 } else {
34- return FAT_OK ;
35- }
36- }
37-
38- static int fat16_is_reserved_name (const char * name ) {
39- return strcmp (name , "." ) == 0 || strcmp (name , ".." ) == 0 ;
40- }
41-
42- partition_fs_type_t detect_fat_type_enum (const int8 * buf ){
43- int fat = detect_fat_type (buf );
44-
45- switch (fat ){
46- case 12 :
47- return FS_FAT12 ;
48- case 16 :
49- return FS_FAT16 ;
50- case 32 :
51- return FS_FAT32 ;
52- case 1 :
53- case 0 :
54- default :
55- return FS_UNKNOWN ;
38+ return FS_UNKNOWN ;
5639 }
5740}
5841
@@ -171,50 +154,60 @@ void fat16_list_root(fat16_fs_t* fs) {
171154 }
172155 }
173156 }
174-
175- print ("\n" );
176157}
177158
178159
179- int fat16_find_path (
180- fat16_fs_t * fs ,
181- const char * path ,
182- fat16_dir_entry_t * out
183- ) {
184- char part [13 ];
185- uint16_t current_cluster = FAT16_ROOT_CLUSTER ;
160+ int fat16_find_path (fat16_fs_t * fs , const char * path , fat16_dir_entry_t * out ) {
161+ if (!fs || !path || !* path ) return FAT_ERR_NOT_FOUND ;
162+
163+ uint16_t current_cluster = FAT16_ROOT_CLUSTER ; // start at root
186164 const char * p = path ;
165+ char part [13 ];
187166
167+ // Skip leading slashes
188168 while (* p == '/' ) p ++ ;
189169
170+ // Root path
171+ if (* p == 0 ) {
172+ out -> first_cluster = FAT16_ROOT_CLUSTER ;
173+ out -> attr = 0x10 ; // mark as directory
174+ return FAT_OK ;
175+ }
176+
190177 while (* p ) {
178+ // Extract next path component
191179 int len = 0 ;
192180 while (p [len ] && p [len ] != '/' ) len ++ ;
181+ if (len >= sizeof (part )) return FAT_ERR_NOT_FOUND ;
193182
194183 memcpy (part , p , len );
195184 part [len ] = 0 ;
196185
197- if (current_cluster == 0 ) {
198- if (fat16_find_file (fs , part , out ) != 0 )
199- return FAT_ERR_NOT_FOUND ;
200- } else {
201- if (fat16_find_in_dir (fs , current_cluster , part , out ) != 0 )
202- return FAT_ERR_NOT_FOUND ;
203- }
186+ fat16_dir_entry_t entry ;
187+ int ret = fat16_find_in_dir (fs , current_cluster , part , & entry );
188+ if (ret != FAT_OK ) return FAT_ERR_NOT_FOUND ;
189+
190+ // Update current cluster for next iteration
191+ current_cluster = entry .first_cluster ;
192+
193+ // If not last component, must be a directory
194+ if (p [len ] == '/' && !(entry .attr & 0x10 ))
195+ return FAT_ERR_NOT_FOUND ;
204196
205197 p += len ;
206198 while (* p == '/' ) p ++ ;
207199
208- if (* p ) {
209- if (!( out -> attr & 0x10 ))
210- return FAT_ERR_NOT_FOUND ; // not a directory
211- current_cluster = out -> first_cluster ;
200+ if (* p == 0 ) {
201+ // last component reached
202+ * out = entry ;
203+ return FAT_OK ;
212204 }
213205 }
214206
215- return FAT_OK ;
207+ return FAT_ERR_NOT_FOUND ;
216208}
217209
210+
218211int fat16_match_name (fat16_dir_entry_t * e , const char * name ) {
219212 char fatname [11 ];
220213 fat16_format_name (name , fatname );
@@ -407,28 +400,6 @@ int fat16_find_file(fat16_fs_t* fs, const char* name, fat16_dir_entry_t* out) {
407400 return FAT_ERR_NOT_FOUND ;
408401}
409402
410-
411- void fat16_read_file (fat16_fs_t * fs , fat16_dir_entry_t * file ) {
412- uint16_t cluster = file -> first_cluster ;
413- uint8_t buf [512 ];
414-
415- while (cluster < 0xFFF8 ) {
416- uint32_t lba =
417- fs -> data_start +
418- (cluster - 2 ) * fs -> bs .sectors_per_cluster ;
419-
420- for (int s = 0 ; s < fs -> bs .sectors_per_cluster ; s ++ ) {
421- ahci_read_sector (fs -> portno , lba + s , buf , 1 );
422- for (int i = 0 ; i < 512 ; i ++ )
423- printfnoln ("%c" , buf [i ]);
424- }
425-
426- cluster = fat16_read_fat_fs (fs , cluster );
427- }
428-
429- print ("\n" );
430- }
431-
432403int fat16_open (fat16_fs_t * fs , const char * path , fat16_file_t * f ) {
433404 uint16_t parent ;
434405 char name [13 ];
@@ -464,11 +435,13 @@ int fat16_read(fat16_file_t* f, uint8_t* out, uint32_t size) {
464435 uint32_t sector_in_cluster =
465436 (f -> pos / 512 ) % f -> fs -> bs .sectors_per_cluster ;
466437
467- uint16_t cluster = f -> cluster ;
438+ uint16_t cluster = f -> entry .first_cluster ;
439+ uint32_t idx = f -> pos / cluster_size ;
468440
469- // Advance cluster only when needed
470- while (cluster_index -- ) {
441+ for (uint32_t i = 0 ; i < idx ; i ++ ) {
471442 cluster = fat16_read_fat_fs (f -> fs , cluster );
443+ if (cluster >= FAT16_EOC )
444+ return read ;
472445 }
473446
474447 uint32_t lba =
@@ -854,8 +827,6 @@ int fat16_unlink(fat16_fs_t* fs, uint16_t parent_cluster, const char* name) {
854827 return fat16_delete_entry_in_cluster (fs , parent_cluster , fatname );
855828}
856829
857-
858-
859830int fat16_truncate (fat16_file_t * f , uint32_t new_size ) {
860831 if (new_size >= f -> entry .filesize )
861832 return FAT_OK ;
@@ -1234,9 +1205,10 @@ int fat16_ls(fat16_fs_t* fs, const char* path) {
12341205}
12351206
12361207int fat16_cd (fat16_fs_t * fs , const char * path , uint16_t * pwd_cluster ) {
1237- uint16_t new_cluster ;
1208+ uint16_t new_cluster = 0 ;
1209+ uint16_t current = * pwd_cluster ;
12381210
1239- if (fat16_resolve_path (fs , path , * pwd_cluster , & new_cluster ) != 0 ) {
1211+ if (fat16_resolve_path (fs , path , current , & new_cluster ) != 0 ) {
12401212 printf ("cd: no such directory: %s\n" , path );
12411213 return FAT_ERR_NOT_FOUND ;
12421214 }
@@ -1256,8 +1228,6 @@ int fat16_resolve_path(
12561228 uint16_t current_cluster ;
12571229
12581230 const char * p = path ;
1259-
1260- // skip leading '/'
12611231 while (* p == '/' ) p ++ ;
12621232
12631233 // absolute path starts from root
@@ -1378,38 +1348,72 @@ int fat16_rmdir(fat16_fs_t* fs, uint16_t dir_cluster)
13781348{
13791349 uint8_t buf [512 ];
13801350
1381- debug_printf ("[fat16] rmdir cluster=%u\n" , dir_cluster );
1382-
13831351 if (dir_cluster < 2 )
13841352 return FAT_ERR_NOT_FOUND ;
13851353
1386- uint32_t lba = fat16_cluster_lba ( fs , dir_cluster ) ;
1354+ uint16_t cluster = dir_cluster ;
13871355
1388- for ( uint32_t s = 0 ; s < fs -> bs . sectors_per_cluster ; s ++ ) {
1389- ahci_read_sector ( fs -> portno , lba + s , buf , 1 );
1390- fat16_dir_entry_t * e = ( fat16_dir_entry_t * ) buf ;
1356+ /* ---------- PASS 1: recurse & free children ---------- */
1357+ while ( cluster < FAT16_EOC ) {
1358+ uint32_t lba = fat16_cluster_lba ( fs , cluster ) ;
13911359
1392- for (int i = 0 ; i < DIR_ENTRIES_PER_SECTOR ; i ++ ) {
1360+ for (uint32_t s = 0 ; s < fs -> bs .sectors_per_cluster ; s ++ ) {
1361+ ahci_read_sector (fs -> portno , lba + s , buf , 1 );
1362+ fat16_dir_entry_t * e = (fat16_dir_entry_t * )buf ;
13931363
1394- if (e [i ].name [0 ] == 0x00 )
1395- goto done ;
1364+ for (int i = 0 ; i < DIR_ENTRIES_PER_SECTOR ; i ++ ) {
1365+ if (e [i ].name [0 ] == 0x00 )
1366+ goto pass2 ;
13961367
1397- if (e [i ].name [0 ] == 0xE5 )
1398- continue ;
1368+ if (e [i ].name [0 ] == 0xE5 )
1369+ continue ;
13991370
1400- if (! memcmp (e [i ].name , ". " , 11 ) ||
1401- ! memcmp (e [i ].name , ".. " , 11 ))
1402- continue ;
1371+ if (fat16_name_eq (e [i ].name , "." ) ||
1372+ fat16_name_eq (e [i ].name , ".." ))
1373+ continue ;
14031374
1404- if (e [i ].attr & 0x10 )
1405- fat16_rmdir (fs , e [i ].first_cluster );
1406- else
1407- fat16_free_chain (fs , e [i ].first_cluster );
1375+ if (e [i ].first_cluster < 2 )
1376+ continue ;
1377+
1378+ if (e [i ].attr & 0x10 )
1379+ fat16_rmdir (fs , e [i ].first_cluster );
1380+ else
1381+ fat16_free_chain (fs , e [i ].first_cluster );
1382+
1383+ e [i ].name [0 ] = 0xE5 ;
1384+ ahci_write_sector (fs -> portno , lba + s , buf , 1 );
1385+ }
1386+ }
1387+
1388+ cluster = fat16_read_fat_fs (fs , cluster );
1389+ }
1390+
1391+ pass2 :
1392+ cluster = dir_cluster ;
1393+
1394+ /* ---------- PASS 2: mark entries deleted ---------- */
1395+ while (cluster < FAT16_EOC ) {
1396+ uint32_t lba = fat16_cluster_lba (fs , cluster );
14081397
1409- e [i ].name [0 ] = 0xE5 ;
1398+ for (uint32_t s = 0 ; s < fs -> bs .sectors_per_cluster ; s ++ ) {
1399+ ahci_read_sector (fs -> portno , lba + s , buf , 1 );
1400+ fat16_dir_entry_t * e = (fat16_dir_entry_t * )buf ;
1401+
1402+ for (int i = 0 ; i < DIR_ENTRIES_PER_SECTOR ; i ++ ) {
1403+ if (e [i ].name [0 ] == 0x00 )
1404+ goto done ;
1405+
1406+ if (fat16_name_eq (e [i ].name , "." ) ||
1407+ fat16_name_eq (e [i ].name , ".." ))
1408+ continue ;
1409+
1410+ e [i ].name [0 ] = 0xE5 ;
1411+ }
1412+
1413+ ahci_write_sector (fs -> portno , lba + s , buf , 1 );
14101414 }
14111415
1412- ahci_write_sector (fs -> portno , lba + s , buf , 1 );
1416+ cluster = fat16_read_fat_fs (fs , cluster );
14131417 }
14141418
14151419done :
0 commit comments