diff --git a/src/fat_unformat.c b/src/fat_unformat.c index 87e8c05e..5b297354 100644 --- a/src/fat_unformat.c +++ b/src/fat_unformat.c @@ -176,6 +176,7 @@ static int fat_copy_file(disk_t *disk, const partition_t *partition, const unsig 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; @@ -203,7 +204,7 @@ static int fat_unformat_aux(struct ph_param *params, const struct ph_options *op } offset_end=current_search_space->end; current_search_space=td_list_entry(list_search_space->list.next, alloc_data_t, list); - offset=current_search_space->start; + 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); @@ -306,7 +307,9 @@ static int fat_unformat_aux(struct ph_param *params, const struct ph_options *op if(check_enter_key_or_s(stdscr)) { log_info("PhotoRec has been stopped\n"); + params->offset=offset; offset = offset_end; + ind_stop=1; } } } @@ -314,9 +317,19 @@ static int fat_unformat_aux(struct ph_param *params, const struct ph_options *op } } free(buffer_start); - return 0; + return ind_stop; } +/* fat_unformat() + * @param struct ph_param *params + * @param const struct ph_options *options + * @param alloc_data_t *list_search_space + * + * @returns: + * 0: Completed or not possible + * 1: Stop by user request + * params->offset is set + */ int fat_unformat(struct ph_param *params, const struct ph_options *options, alloc_data_t *list_search_space) { unsigned int sectors_per_cluster=0; @@ -344,7 +357,6 @@ int fat_unformat(struct ph_param *params, const struct ph_options *options, allo update_blocksize(params->blocksize, list_search_space, offset); } /* start_data is relative to the disk */ - fat_unformat_aux(params, options, start_data, list_search_space); - return 0; + return fat_unformat_aux(params, options, start_data, list_search_space); } diff --git a/src/photorec.c b/src/photorec.c index a171e436..9ac6d007 100644 --- a/src/photorec.c +++ b/src/photorec.c @@ -942,3 +942,45 @@ void set_filename(file_recovery_t *file_recovery, struct ph_param *params) } } +static void set_search_start_aux(alloc_data_t **new_current_search_space, alloc_data_t *list_search_space, const uint64_t offset) +{ + struct td_list_head *search_walker = NULL; + td_list_for_each(search_walker, &list_search_space->list) + { + alloc_data_t *current_search_space; + current_search_space=td_list_entry(search_walker, alloc_data_t, list); + if(current_search_space->start<=offset && offset<= current_search_space->end) + { + *new_current_search_space=current_search_space; + return; + } + } + /* not found */ + *new_current_search_space=list_search_space; +} + +uint64_t set_search_start(struct ph_param *params, alloc_data_t **new_current_search_space, alloc_data_t *list_search_space) +{ + uint64_t offset=(*new_current_search_space)->start; + if(params->offset!=-1) + { + offset=params->offset; + set_search_start_aux(new_current_search_space, list_search_space, offset); + } + else if(params->cmd_run!=NULL && params->cmd_run[0]!='\0') + { + offset=0; + while(*params->cmd_run==',') + params->cmd_run++; + while(*params->cmd_run >= '0' && *params->cmd_run <= '9') + { + offset=offset * 10 + (*params->cmd_run - '0'); + params->cmd_run++; + } + offset*=params->disk->sector_size; + set_search_start_aux(new_current_search_space, list_search_space, offset); + } + return offset; +} + + diff --git a/src/photorec.h b/src/photorec.h index 520f1073..e2572177 100644 --- a/src/photorec.h +++ b/src/photorec.h @@ -54,6 +54,7 @@ struct ph_param unsigned int dir_num; unsigned int file_nbr; file_stat_t *file_stats; + uint64_t offset; }; int get_prev_file_header(alloc_data_t *list_search_space, alloc_data_t **current_search_space, uint64_t *offset); @@ -75,6 +76,7 @@ unsigned int photorec_mkdir(const char *recup_dir, const unsigned int initial_di void info_list_search_space(const alloc_data_t *list_search_space, const alloc_data_t *current_search_space, const unsigned int sector_size, const int keep_corrupted_file, const int verbose); void free_search_space(alloc_data_t *list_search_space); void set_filename(file_recovery_t *file_recovery, struct ph_param *params); +uint64_t set_search_start(struct ph_param *params, alloc_data_t **new_current_search_space, alloc_data_t *list_search_space); #ifdef __cplusplus } /* closing brace for extern "C" */ #endif diff --git a/src/phrecn.c b/src/phrecn.c index e533b2fd..b385e3bb 100644 --- a/src/phrecn.c +++ b/src/phrecn.c @@ -186,6 +186,7 @@ static alloc_data_t *file_add_data(alloc_data_t *data, const uint64_t offset, co * 1: Stop by user request * 2: Cannot create file * 3: No space left + * >0: params->offset is set */ static int photorec_aux(struct ph_param *params, const struct ph_options *options, alloc_data_t *list_search_space) @@ -212,7 +213,7 @@ static int photorec_aux(struct ph_param *params, const struct ph_options *option previous_time=start_time; memset(buffer_olddata,0,blocksize); current_search_space=td_list_entry(list_search_space->list.next, alloc_data_t, list); - offset=current_search_space->start; + 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, params->disk->sector_size, 0, options->verbose); if(options->verbose > 1) @@ -339,6 +340,7 @@ static int photorec_aux(struct ph_param *params, const struct ph_options *option { log_critical("Cannot create file %s: %s\n", file_recovery.filename, strerror(errno)); ind_stop=2; + params->offset=offset; } } } @@ -377,6 +379,7 @@ static int photorec_aux(struct ph_param *params, const struct ph_options *option { /* Warn the user */ ind_stop=3; + params->offset=file_recovery.location.start; } } } @@ -490,6 +493,10 @@ static int photorec_aux(struct ph_param *params, const struct ph_options *option { previous_time=current_time; ind_stop=photorec_progressbar(stdscr, params->pass, params, offset, current_time); + if(file_recovery.file_stat!=NULL) + params->offset=file_recovery.location.start; + else + params->offset=offset; } } #endif @@ -754,8 +761,51 @@ int photorec(struct ph_param *params, const struct ph_options *options, alloc_da params->real_start_time=time(NULL); params->dir_num=1; params->file_stats=init_file_stats(options->list_file_format); + params->offset=-1; if(params->cmd_run!=NULL && params->cmd_run[0]!='\0') { + while(params->cmd_run[0]==',') + params->cmd_run++; + if(strncmp(params->cmd_run,"status=unformat",15)==0) + { + params->status=STATUS_UNFORMAT; + params->cmd_run+=15; + } + else if(strncmp(params->cmd_run,"status=find_offset",18)==0) + { + params->status=STATUS_FIND_OFFSET; + params->cmd_run+=18; + } + else if(strncmp(params->cmd_run,"status=ext2_on_bf",17)==0) + { + params->status=STATUS_EXT2_ON_BF; + params->cmd_run+=17; + } + else if(strncmp(params->cmd_run,"status=ext2_on_save_everything",33)==0) + { + params->status=STATUS_EXT2_ON_SAVE_EVERYTHING; + params->cmd_run+=33; + } + else if(strncmp(params->cmd_run,"status=ext2_on",14)==0) + { + params->status=STATUS_EXT2_ON; + params->cmd_run+=14; + } + else if(strncmp(params->cmd_run,"status=ext2_off_bf",18)==0) + { + params->status=STATUS_EXT2_OFF_BF; + params->cmd_run+=18; + } + else if(strncmp(params->cmd_run,"status=ext2_off_save_everything",34)==0) + { + params->status=STATUS_EXT2_OFF_SAVE_EVERYTHING; + params->cmd_run+=34; + } + else if(strncmp(params->cmd_run,"status=ext2_off",15)==0) + { + params->status=STATUS_EXT2_OFF; + params->cmd_run+=15; + } } else { @@ -785,8 +835,8 @@ int photorec(struct ph_param *params, const struct ph_options *options, alloc_da log_info("Pass %u (blocksize=%u) ", params->pass, params->blocksize); switch(params->status) { - case STATUS_FIND_OFFSET: log_info("STATUS_FIND_OFFSET\n"); break; case STATUS_UNFORMAT: log_info("STATUS_UNFORMAT\n"); break; + case STATUS_FIND_OFFSET: log_info("STATUS_FIND_OFFSET\n"); break; case STATUS_EXT2_ON: log_info("STATUS_EXT2_ON\n"); break; case STATUS_EXT2_ON_BF: log_info("STATUS_EXT2_ON_BF\n"); break; case STATUS_EXT2_OFF: log_info("STATUS_EXT2_OFF\n"); break; @@ -842,6 +892,7 @@ int photorec(struct ph_param *params, const struct ph_options *options, alloc_da ind_stop=photorec_aux(params, options, list_search_space); } session_save(list_search_space, params, options, carve_free_space_only); + if(ind_stop==3) { /* no more space */ #ifdef HAVE_NCURSES @@ -896,8 +947,10 @@ int photorec(struct ph_param *params, const struct ph_options *options, alloc_da #endif } } + if(ind_stop==0) { + params->offset=-1; switch(params->status) { case STATUS_UNFORMAT: diff --git a/src/sessionp.c b/src/sessionp.c index 1d792eb4..69ae8a8e 100644 --- a/src/sessionp.c +++ b/src/sessionp.c @@ -209,7 +209,40 @@ int session_save(alloc_data_t *list_free_space, struct ph_param *params, const fprintf(f_session,"freespace,"); else fprintf(f_session,"wholespace,"); - fprintf(f_session,"search,inter\n"); + fprintf(f_session,"search,"); + switch(params->status) + { + case STATUS_UNFORMAT: + fprintf(f_session, "status=unformat,"); + break; + case STATUS_FIND_OFFSET: + fprintf(f_session, "status=find_offset,"); + break; + case STATUS_EXT2_ON_BF: + fprintf(f_session, "status=ext2_on_bf,"); + break; + case STATUS_EXT2_ON_SAVE_EVERYTHING: + fprintf(f_session, "status=ext2_on_save_everything,"); + break; + case STATUS_EXT2_ON: + fprintf(f_session, "status=ext2_on,"); + break; + case STATUS_EXT2_OFF_SAVE_EVERYTHING: + fprintf(f_session, "status=ext2_off_save_everything,"); + break; + case STATUS_EXT2_OFF_BF: + fprintf(f_session, "status=ext2_off_bf,"); + break; + case STATUS_EXT2_OFF: + fprintf(f_session, "status=ext2_off,"); + break; + case STATUS_QUIT: + break; + } + if(params->status!=STATUS_QUIT && params->offset!=-1) + fprintf(f_session, "%llu,", + (long long unsigned)(params->offset/params->disk->sector_size)); + fprintf(f_session,"inter\n"); td_list_for_each(free_walker, &list_free_space->list) { alloc_data_t *current_free_space;