static int fat_unformat_aux(struct ph_param *params, const struct ph_options *options, const uint64_t start_offset, alloc_data_t *list_search_space) { int ind_stop=0; uint64_t offset; uint64_t offset_end; unsigned char *buffer_start; unsigned char *buffer; time_t start_time; time_t previous_time; const unsigned int blocksize=params->blocksize; const unsigned int read_size=(blocksize>65536?blocksize:65536); alloc_data_t *current_search_space; file_recovery_t file_recovery; disk_t *disk=params->disk; const partition_t *partition=params->partition; reset_file_recovery(&file_recovery); file_recovery.blocksize=blocksize; buffer_start=(unsigned char *)MALLOC(READ_SIZE); buffer=buffer_start; start_time=time(NULL); previous_time=start_time; current_search_space=td_list_entry(list_search_space->list.prev, alloc_data_t, list); if(current_search_space==list_search_space) { free(buffer_start); return 0; } offset_end=current_search_space->end; current_search_space=td_list_entry(list_search_space->list.next, alloc_data_t, list); offset=set_search_start(params, ¤t_search_space, list_search_space); if(options->verbose>0) info_list_search_space(list_search_space, current_search_space, disk->sector_size, 0, options->verbose); disk->pread(disk, buffer, READ_SIZE, offset); for(;offset < offset_end; offset+=blocksize) { if(memcmp(buffer, ". ", 8+3)==0 && memcmp(&buffer[0x20], ".. ", 8+3)==0) { file_data_t *dir_list; dir_list=dir_fat_aux(buffer,read_size,0,0); if(dir_list!=NULL) { const file_data_t *current_file; log_info("Sector %llu\n", (long long unsigned)offset/disk->sector_size); dir_aff_log(NULL, dir_list); del_search_space(list_search_space, offset, offset + blocksize -1); current_file=dir_list; while(current_file!=NULL) { if(strcmp(current_file->name,".")==0 && LINUX_S_ISDIR(current_file->stat.st_mode)!=0 && current_file!=dir_list) current_file=NULL; else if(current_file->stat.st_ino>2 && LINUX_S_ISREG(current_file->stat.st_mode)!=0) { const uint64_t file_start=start_offset + (uint64_t)(current_file->stat.st_ino - 2) * blocksize; #ifdef DJGPP const uint64_t file_end=file_start+(current_file->file_size+blocksize-1)/blocksize*blocksize - 1; #else const uint64_t file_end=file_start+(current_file->stat.st_size+blocksize-1)/blocksize*blocksize - 1; #endif if(file_end < partition->part_offset + partition->part_size) { if(fat_copy_file(disk, partition, blocksize, start_offset, params->recup_dir, params->dir_num, current_file)==0) { params->file_nbr++; del_search_space(list_search_space, file_start, file_end); } current_file=current_file->next; } else current_file=NULL; } else current_file=current_file->next; } delete_list_file(dir_list); } } buffer+=blocksize; if(buffer+read_size>buffer_start+READ_SIZE) { buffer=buffer_start; if(options->verbose>1) { log_verbose("Reading sector %10llu/%llu\n", (unsigned long long)((offset-partition->part_offset)/disk->sector_size), (unsigned long long)((partition->part_size-1)/disk->sector_size)); } if(disk->pread(disk, buffer, READ_SIZE, offset) != READ_SIZE) { #ifdef HAVE_NCURSES wmove(stdscr,11,0); wclrtoeol(stdscr); wprintw(stdscr,"Error reading sector %10lu\n", (unsigned long)((offset-partition->part_offset)/disk->sector_size)); #endif } #ifdef HAVE_NCURSES { time_t current_time; current_time=time(NULL); if(current_time>previous_time) { const time_t elapsed_time=current_time - params->real_start_time; previous_time=current_time; wmove(stdscr,9,0); wclrtoeol(stdscr); log_info("Reading sector %10llu/%llu, %u files found\n", (unsigned long long)((offset-partition->part_offset)/disk->sector_size), (unsigned long long)(partition->part_size/disk->sector_size), params->file_nbr); wprintw(stdscr,"Reading sector %10llu/%llu, %u files found\n", (unsigned long long)((offset-partition->part_offset)/disk->sector_size), (unsigned long long)(partition->part_size/disk->sector_size), params->file_nbr); wmove(stdscr,10,0); wclrtoeol(stdscr); wprintw(stdscr,"Elapsed time %uh%02um%02us", (unsigned)(elapsed_time/60/60), (unsigned)(elapsed_time/60%60), (unsigned)(elapsed_time%60)); if(offset-partition->part_offset!=0) { wprintw(stdscr," - Estimated time to completion %uh%02um%02u\n", (unsigned)((partition->part_offset+partition->part_size-1-offset)*elapsed_time/(offset-partition->part_offset)/3600), (unsigned)(((partition->part_offset+partition->part_size-1-offset)*elapsed_time/(offset-partition->part_offset)/60)%60), (unsigned)((partition->part_offset+partition->part_size-1-offset)*elapsed_time/(offset-partition->part_offset))%60); } wrefresh(stdscr); if(check_enter_key_or_s(stdscr)) { log_info("PhotoRec has been stopped\n"); params->offset=offset; offset = offset_end; ind_stop=1; } } } #endif } } free(buffer_start); return ind_stop; }
static int pfind_sectors_per_cluster(disk_t *disk, partition_t *partition, const int verbose, unsigned int *sectors_per_cluster, uint64_t *offset_org, alloc_data_t *list_search_space) { uint64_t offset=0; unsigned int nbr_subdir=0; sector_cluster_t sector_cluster[10]; alloc_data_t *current_search_space; unsigned char *buffer_start=(unsigned char *)MALLOC(READ_SIZE); unsigned char *buffer=buffer_start; current_search_space=td_list_entry(list_search_space->list.next, alloc_data_t, list); if(current_search_space!=list_search_space) offset=current_search_space->start; if(verbose>0) info_list_search_space(list_search_space, current_search_space, disk->sector_size, 0, verbose); #ifdef HAVE_NCURSES wmove(stdscr,22,0); wattrset(stdscr, A_REVERSE); waddstr(stdscr," Stop "); wattroff(stdscr, A_REVERSE); #endif disk->pread(disk, buffer_start, READ_SIZE, offset); while(current_search_space!=list_search_space && nbr_subdir<10) { const uint64_t old_offset=offset; #ifdef HAVE_NCURSES if((offset&(1024*disk->sector_size-1))==0) { wmove(stdscr,9,0); wclrtoeol(stdscr); wprintw(stdscr,"Search subdirectory %10lu/%lu %u",(unsigned long)(offset/disk->sector_size),(unsigned long)(partition->part_size/disk->sector_size),nbr_subdir); wrefresh(stdscr); } #endif if(memcmp(buffer, ". ", 8+3)==0 && memcmp(&buffer[0x20], ".. ", 8+3)==0) { const unsigned long int cluster=(buffer[0*0x20+0x15]<<24) + (buffer[0*0x20+0x14]<<16) + (buffer[0*0x20+0x1B]<<8) + buffer[0*0x20+0x1A]; log_info("sector %lu, cluster %lu\n", (unsigned long)(offset/disk->sector_size), cluster); sector_cluster[nbr_subdir].cluster=cluster; sector_cluster[nbr_subdir].sector=offset/disk->sector_size; log_flush(); nbr_subdir++; } get_next_sector(list_search_space, ¤t_search_space, &offset, 512); buffer+=512; if( old_offset+512!=offset || buffer+512>buffer_start+READ_SIZE) { buffer=buffer_start; if(verbose>1) { log_verbose("Reading sector %10llu/%llu\n", (unsigned long long)((offset-partition->part_offset)/disk->sector_size), (unsigned long long)((partition->part_size-1)/disk->sector_size)); } if(disk->pread(disk, buffer_start, READ_SIZE, offset) != READ_SIZE) { } } } /* end while(current_search_space!=list_search_space) */ free(buffer_start); return find_sectors_per_cluster_aux(sector_cluster,nbr_subdir,sectors_per_cluster,offset_org,verbose,partition->part_size/disk->sector_size, UP_UNK); }
static int pfind_sectors_per_cluster(disk_t *disk, partition_t *partition, const int verbose, unsigned int *sectors_per_cluster, uint64_t *offset_org, alloc_data_t *list_search_space) { uint64_t offset=0; uint64_t next_offset=0; uint64_t diff_offset=0; time_t previous_time=0; unsigned int nbr_subdir=0; sector_cluster_t sector_cluster[10]; alloc_data_t *current_search_space; unsigned char *buffer_start=(unsigned char *)MALLOC(READ_SIZE); unsigned char *buffer=buffer_start; assert(disk->sector_size!=0); current_search_space=td_list_first_entry(&list_search_space->list, alloc_data_t, list); if(current_search_space!=list_search_space) offset=current_search_space->start; if(verbose>0) info_list_search_space(list_search_space, current_search_space, disk->sector_size, 0, verbose); #ifdef HAVE_NCURSES wmove(stdscr,22,0); wattrset(stdscr, A_REVERSE); waddstr(stdscr," Stop "); wattroff(stdscr, A_REVERSE); #endif disk->pread(disk, buffer_start, READ_SIZE, offset); while(current_search_space!=list_search_space && nbr_subdir<10) { const uint64_t old_offset=offset; if(buffer[0]=='.' && is_fat_directory(buffer)) { const unsigned long int cluster=fat_get_cluster_from_entry((const struct msdos_dir_entry *)buffer); log_info("sector %lu, cluster %lu\n", (unsigned long)(offset/disk->sector_size), cluster); sector_cluster[nbr_subdir].cluster=cluster; sector_cluster[nbr_subdir].sector=offset/disk->sector_size; log_flush(); nbr_subdir++; } get_next_sector(list_search_space, ¤t_search_space, &offset, 512); buffer+=512; if( old_offset+512!=offset || buffer+512>buffer_start+READ_SIZE) { buffer=buffer_start; #ifdef HAVE_NCURSES if(offset > next_offset) { const time_t current_time=time(NULL); if(current_time==previous_time) diff_offset<<=1; else diff_offset>>=1; if(diff_offset < disk->sector_size) diff_offset=disk->sector_size; next_offset=offset+diff_offset; previous_time=current_time; wmove(stdscr,9,0); wclrtoeol(stdscr); wprintw(stdscr,"Search subdirectory %10lu/%lu %u",(unsigned long)(offset/disk->sector_size),(unsigned long)(partition->part_size/disk->sector_size),nbr_subdir); wrefresh(stdscr); } #endif if(verbose>1) { log_verbose("Reading sector %10llu/%llu\n", (unsigned long long)((offset-partition->part_offset)/disk->sector_size), (unsigned long long)((partition->part_size-1)/disk->sector_size)); } if(disk->pread(disk, buffer_start, READ_SIZE, offset) != READ_SIZE) { #ifdef HAVE_NCURSES wmove(stdscr,11,0); wclrtoeol(stdscr); wprintw(stdscr,"Error reading sector %10lu\n", (unsigned long)((offset - partition->part_offset) / disk->sector_size)); #endif } } } /* end while(current_search_space!=list_search_space) */