PhotoRec session management: restart PhotoRec at the same location than previously

This commit is contained in:
Christophe Grenier 2011-08-28 09:53:47 +02:00
parent 94082d99f5
commit 789bb8645b
5 changed files with 149 additions and 7 deletions

View file

@ -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, &current_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);
}

View file

@ -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;
}

View file

@ -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

View file

@ -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, &current_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:

View file

@ -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;