diff --git a/src/exfat_dir.c b/src/exfat_dir.c index 040088f3..6291eb5f 100644 --- a/src/exfat_dir.c +++ b/src/exfat_dir.c @@ -82,6 +82,30 @@ static inline void exfat16_towchar(wchar_t *dst, const uint8_t *src, size_t len) #define ATTR_ARCH 32 /* archived */ #define EXFAT_MKMODE(a,m) ((m & (a & ATTR_RO ? LINUX_S_IRUGO|LINUX_S_IXUGO : LINUX_S_IRWXUGO)) | (a & ATTR_DIR ? LINUX_S_IFDIR : LINUX_S_IFREG)) +static unsigned int exfat_get_next_cluster(disk_t *disk_car,const partition_t *partition, const int offset, const unsigned int cluster) +{ + unsigned char *buffer=(unsigned char*)MALLOC(disk_car->sector_size); + unsigned int next_cluster; + const uint32_t *p32=(const uint32_t*)buffer; + const unsigned long int offset_s=cluster/(disk_car->sector_size/4); + const unsigned long int offset_o=cluster%(disk_car->sector_size/4); + if((unsigned)disk_car->pread(disk_car, buffer, disk_car->sector_size, + partition->part_offset + offset + (uint64_t)offset_s * disk_car->sector_size) != disk_car->sector_size) + { + log_error("exfat_get_next_cluster read error\n"); + free(buffer); + return 0; + } + /* FAT32 used 28 bits, the 4 high bits are reserved + * 0x00000000: free cluster + * 0x0FFFFFF7: bad cluster + * 0x0FFFFFF8+: EOC End of cluster + * */ + next_cluster=le32(p32[offset_o])&0xFFFFFFF; + free(buffer); + return next_cluster; +} + static int dir_exfat_aux(const unsigned char*buffer, const unsigned int size, const unsigned int param, file_info_t *dir_list) { /* @@ -167,17 +191,15 @@ static int exfat_dir(disk_t *disk, const partition_t *partition, dir_data_t *dir unsigned int cluster; unsigned char *buffer_dir=(unsigned char *)MALLOC(NBR_CLUSTER_MAX << cluster_shift); unsigned int nbr_cluster; -// unsigned int clus_blocknr; - unsigned int total_clusters; + const unsigned int total_clusters=le32(exfat_header->total_clusters); exfat_method_t exfat_meth=exFAT_FOLLOW_CLUSTER; int stop=0; + const uint64_t start_exfat1=le32(exfat_header->fat_blocknr) << exfat_header->blocksize_bits; if(first_cluster<2) cluster=le32(exfat_header->rootdir_clusnr); else cluster=first_cluster; memset(buffer_dir, 0, NBR_CLUSTER_MAX<clus_blocknr); - total_clusters=le32(exfat_header->total_clusters); nbr_cluster=0; while(!is_EOC(cluster) && cluster>=2 && nbr_clusterupart_type, start_exfat1, cluster); - const unsigned int next_cluster=0; + const unsigned int next_cluster=exfat_get_next_cluster(disk, partition, start_exfat1, cluster); if((next_cluster>=2 && next_cluster<=total_clusters) || is_EOC(next_cluster)) cluster=next_cluster; @@ -216,7 +237,7 @@ static int exfat_dir(disk_t *disk, const partition_t *partition, dir_data_t *dir { /* Deleted directories are composed of "free" clusters */ #if 0 while(++clusterupart_type, start_exfat1, cluster)!=0); + exfat_get_next_cluster(disk, partition, start_exfat1, cluster)!=0); #endif } nbr_cluster++; @@ -333,7 +354,7 @@ static int exfat_copy(disk_t *disk, const partition_t *partition, dir_data_t *di { if(exfat_meth==exFAT_FOLLOW_CLUSTER) { - const unsigned int next_cluster=get_next_cluster(disk, partition, UP_FAT32, start_exfat1, cluster); + const unsigned int next_cluster=exfat_get_next_cluster(disk, partition, start_exfat1, cluster); if(next_cluster>=2 && next_cluster<=total_clusters) cluster=next_cluster; else if(cluster==file->st_ino && next_cluster==0) @@ -346,7 +367,7 @@ static int exfat_copy(disk_t *disk, const partition_t *partition, dir_data_t *di else if(exfat_meth==exFAT_NEXT_FREE_CLUSTER) { /* Deleted file are composed of "free" clusters */ while(++clusterupart_type, start_exfat1, cluster)!=0); + exfat_get_next_cluster(disk, partition, start_exfat1, cluster)!=0); } } }