@ @ requires \valid(disk_car); @ requires valid_disk(disk_car); @ requires \valid_read(partition); @ requires valid_partition(partition); @ requires \valid_read(dir_data); @ requires \valid(dir_list); @ requires \separated(disk_car, partition, dir_data, dir_list); @ decreases 0; @*/
| 363 | @ decreases 0; |
| 364 | @*/ |
| 365 | static int fat_dir(disk_t *disk_car, const partition_t *partition, dir_data_t *dir_data, const unsigned long int first_cluster, file_info_t *dir_list) |
| 366 | { |
| 367 | const struct fat_dir_struct *ls=(const struct fat_dir_struct*)dir_data->private_dir_data; |
| 368 | const struct fat_boot_sector*fat_header=ls->boot_sector; |
| 369 | unsigned int cluster=first_cluster; |
| 370 | if(fat_header->sectors_per_cluster<1) |
| 371 | { |
| 372 | #ifndef DISABLED_FOR_FRAMAC |
| 373 | log_error("FAT: Can't list files, bad cluster size.\n"); |
| 374 | #endif |
| 375 | return -1; |
| 376 | } |
| 377 | if(fat_sector_size(fat_header)==0) |
| 378 | { |
| 379 | #ifndef DISABLED_FOR_FRAMAC |
| 380 | log_error("FAT: Can't list files, bad sector size.\n"); |
| 381 | #endif |
| 382 | return -1; |
| 383 | } |
| 384 | if(cluster==0) |
| 385 | { |
| 386 | if(partition->upart_type!=UP_FAT32) |
| 387 | return fat1x_rootdir(disk_car, partition, dir_data, fat_header, dir_list); |
| 388 | if(le32(fat_header->root_cluster)<2) |
| 389 | { |
| 390 | #ifndef DISABLED_FOR_FRAMAC |
| 391 | log_error("FAT32: Can't list files, bad root cluster.\n"); |
| 392 | #endif |
| 393 | return -1; |
| 394 | } |
| 395 | cluster=le32(fat_header->root_cluster); |
| 396 | } |
| 397 | if(get_next_cluster(disk_car, partition, partition->upart_type, le16(fat_header->reserved), cluster)==0) |
| 398 | { |
| 399 | #ifndef DISABLED_FOR_FRAMAC |
| 400 | log_warning("FAT: Directory entry is marked as free.\n"); |
| 401 | #endif |
| 402 | } |
| 403 | { |
| 404 | const unsigned int cluster_size=fat_header->sectors_per_cluster * fat_sector_size(fat_header); |
| 405 | unsigned char *buffer_dir=(unsigned char *)MALLOC(32*NBR_ENTRIES_MAX); |
| 406 | unsigned int nbr_cluster; |
| 407 | const unsigned int nbr_cluster_max=32*NBR_ENTRIES_MAX/cluster_size; |
| 408 | int stop=0; |
| 409 | uint64_t start_fat1,start_data,part_size; |
| 410 | unsigned long int no_of_cluster,fat_length; |
| 411 | fat_method_t fat_meth=FAT_FOLLOW_CLUSTER; |
| 412 | memset(buffer_dir,0,32*NBR_ENTRIES_MAX); |
| 413 | fat_length=le16(fat_header->fat_length)>0?le16(fat_header->fat_length):le32(fat_header->fat32_length); |
| 414 | part_size=(fat_sectors(fat_header)>0?fat_sectors(fat_header):le32(fat_header->total_sect)); |
| 415 | start_fat1=le16(fat_header->reserved); |
| 416 | start_data=start_fat1+fat_header->fats*fat_length+(get_dir_entries(fat_header)*32+disk_car->sector_size-1)/disk_car->sector_size; |
| 417 | no_of_cluster=(part_size-start_data)/fat_header->sectors_per_cluster; |
| 418 | nbr_cluster=0; |
| 419 | while(!is_EOC(cluster, partition->upart_type) && cluster>=2 && nbr_cluster<nbr_cluster_max && stop==0) |
| 420 | { |
| 421 | const uint64_t start=partition->part_offset+(uint64_t)(start_data+(cluster-2)*fat_header->sectors_per_cluster)*fat_sector_size(fat_header); |
| 422 | // if(dir_data->verbose>0) |
nothing calls this directly
no test coverage detected