PhotoRec: expert can stop pass 0 and set the blocksize

This commit is contained in:
Christophe Grenier 2008-01-14 23:48:51 +01:00
parent 3c8e7a507a
commit 9a9764e493
9 changed files with 84 additions and 53 deletions

View file

@ -1,5 +1,5 @@
%define ver_progsreiserfs 0.3.1-rc8
%define ver_ntfsprogs 1.13.1
%define ver_ntfsprogs 2.0.0
Summary: Tool to check and undelete partition
Summary(pl.UTF8): Narzędzie sprawdzające i odzyskujące partycje

View file

@ -767,7 +767,7 @@ int fat32_boot_sector(disk_t *disk_car, partition_t *partition, const int verbos
{
menu=4;
options="DORL";
}
}
}
else
{

View file

@ -161,7 +161,7 @@ static int test_EXT2(disk_t *disk_car, const struct ext2_super_block *sb,partiti
(le16(sb->s_errors) != EXT2_ERRORS_CONTINUE) &&
(le16(sb->s_errors) != EXT2_ERRORS_RO) &&
(le16(sb->s_errors) != EXT2_ERRORS_PANIC))
return 5;
return 4;
if ((le16(sb->s_state) & ~(EXT2_VALID_FS | EXT2_ERROR_FS))!=0)
return 5;
if (le32(sb->s_blocks_count) == 0) /* reject empty filesystem */

View file

@ -254,7 +254,7 @@ static file_data_t *fat12_dir(disk_t *disk_car, const partition_t *partition, di
memset(buffer_dir,0,fat_sector_size(fat_header)*cluster_size*10);
for(cluster=first_cluster, nbr_cluster=0;
((cluster&0x0ff8)!=(unsigned)FAT12_EOC) && (cluster>=2) && (nbr_cluster<10) && (stop==0);
cluster=get_next_cluster(disk_car,partition, UP_FAT12,le16(fat_header->reserved), cluster), nbr_cluster++)
cluster=get_next_cluster(disk_car, partition, UP_FAT12, le16(fat_header->reserved), cluster), nbr_cluster++)
{
uint64_t start=partition->part_offset+(uint64_t)(le16(fat_header->reserved)+fat_header->fats*le16(fat_header->fat_length)+(get_dir_entries(fat_header)*32+fat_sector_size(fat_header)-1)/fat_sector_size(fat_header)+(uint64_t)(cluster-2)*cluster_size)*fat_sector_size(fat_header);
if(dir_data->verbose>0)

View file

@ -58,6 +58,30 @@ static void register_header_check_pst(file_stat_t *file_stat)
#define INDEX_TYPE_OFFSET 0x0A
#define FILE_SIZE_POINTER 0xA8
#define FILE_SIZE_POINTER_64 0xB8
/*
Outlook 2000
0x0000 uchar signature[4];
0x000a uchar indexType;
0x00a8 uint32_t total_file_size;
0x00b8 uint32_t backPointer2;
0x00bc uint32_t offsetIndex2;
0x00c0 uint32_t backPointer1;
0x00c4 uint32_t offsetIndex1;
0x01cd uchar encryptionType;
Outlook 2003
0x0000 uchar signature[4];
0x000a uchar indexType;
0x00b8 uint64_t total_file_size;
0x00d8 uint64_t backPointer2;
0x00e0 uint64_t offsetIndex2;
0x00e8 uint64_t backPointer1;
0x00f0 uint64_t offsetIndex1;
0x0201 uchar encryptionType;
More information about the file structure can be found at
http://www.five-ten-sg.com/libpst/
*/
static int header_check_pst(const unsigned char *buffer, const unsigned int buffer_size, const unsigned int safe_header_only, const file_recovery_t *file_recovery, file_recovery_t *file_recovery_new)
{
@ -75,18 +99,23 @@ static int header_check_pst(const unsigned char *buffer, const unsigned int buff
}
if(memcmp(buffer,pst_header,sizeof(pst_header))==0)
{
reset_file_recovery(file_recovery_new);
file_recovery_new->extension=file_hint_pst.extension;
if(buffer[INDEX_TYPE_OFFSET]==0x0e)
{
/* Outlook 2000 and older versions */
reset_file_recovery(file_recovery_new);
file_recovery_new->extension=file_hint_pst.extension;
file_recovery_new->calculated_file_size=(uint64_t)buffer[FILE_SIZE_POINTER] +
(((uint64_t)buffer[FILE_SIZE_POINTER+1])<<8) +
(((uint64_t)buffer[FILE_SIZE_POINTER+2])<<16) +
(((uint64_t)buffer[FILE_SIZE_POINTER+3])<<24);
file_recovery_new->data_check=&data_check_size;
file_recovery_new->file_check=&file_check_size;
return 1;
}
else
else if(buffer[INDEX_TYPE_OFFSET]==0x17)
{ /* Outlook 2003 */
reset_file_recovery(file_recovery_new);
file_recovery_new->extension=file_hint_pst.extension;
file_recovery_new->calculated_file_size=(uint64_t)buffer[FILE_SIZE_POINTER_64] +
(((uint64_t)buffer[FILE_SIZE_POINTER_64+1])<<8) +
(((uint64_t)buffer[FILE_SIZE_POINTER_64+2])<<16) +
@ -95,10 +124,10 @@ static int header_check_pst(const unsigned char *buffer, const unsigned int buff
(((uint64_t)buffer[FILE_SIZE_POINTER_64+5])<<40) +
(((uint64_t)buffer[FILE_SIZE_POINTER_64+6])<<48) +
(((uint64_t)buffer[FILE_SIZE_POINTER_64+7])<<56);
file_recovery_new->data_check=&data_check_size;
file_recovery_new->file_check=&file_check_size;
return 1;
}
file_recovery_new->data_check=&data_check_size;
file_recovery_new->file_check=&file_check_size;
return 1;
}
return 0;
}

View file

@ -233,7 +233,7 @@ static void change_geometry_ncurses(disk_t *disk_car)
if(cyl_modified==0)
{ /* Round up */
disk_car->CHS.cylinder=(((disk_car->disk_size/disk_car->sector_size+disk_car->CHS.head)/(disk_car->CHS.head+1))+disk_car->CHS.sector-1)/disk_car->CHS.sector-1;
}
}
} else
wprintw(stdscr,"Illegal sectors value");
}
@ -254,7 +254,7 @@ static void change_geometry_ncurses(disk_t *disk_car)
if(cyl_modified==0)
{ /* Round up */
disk_car->CHS.cylinder=(((disk_car->disk_size/disk_car->sector_size+disk_car->CHS.head)/(disk_car->CHS.head+1))+disk_car->CHS.sector-1)/disk_car->CHS.sector-1;
}
}
} else
wprintw(stdscr,"Illegal sector size");
}

View file

@ -35,7 +35,7 @@ static inline const void *td_memmem(const void *haystack, const unsigned int hay
/* Sanity check, otherwise the loop might search through the whole
memory. */
if (haystack_len < needle_len)
return NULL;
return NULL;
for (begin = (const char *) haystack; begin <= last_possible; ++begin)
if (begin[0] == ((const char *) needle)[0] &&

View file

@ -205,21 +205,21 @@ int repair_MFT(disk_t *disk_car, partition_t *partition, const int verbose, cons
log_info("Don't fix MFT mirror.\n");
}
else if(res1<res2)
{
{
/* Use MFT mirror */
if(ask_confirmation("Fix MFT ? (Y/N)")!=0)
use_MFT=2;
else
log_info("Don't fix MFT.\n");
}
else
}
else
{ /* res1==res2 */
if(res1<0)
log_error("MFT and MFT mirror are bad. Failed to repair them.\n");
else
log_error("Both MFT seems ok but they don't match, use chkdsk.\n");
if(expert==0)
{
{
if(res1<0)
display_message("MFT and MFT mirror are bad. Failed to repair them.\n");
else
@ -264,27 +264,27 @@ int repair_MFT(disk_t *disk_car, partition_t *partition, const int verbose, cons
default:
use_MFT=0;
break;
}
}
#endif
}
}
}
}
if(use_MFT==2)
{
if(disk_car->write(disk_car, mftmirr_size_bytes, buffer_mftmirr, mft_pos)!=0)
{
log_error("Failed to fix MFT: write error.\n");
display_message("Failed to fix MFT: write error.\n");
}
else
{
disk_car->sync(disk_car);
log_info("MFT fixed.\n");
display_message("MFT fixed.\n");
}
}
{
if(disk_car->write(disk_car, mftmirr_size_bytes, buffer_mftmirr, mft_pos)!=0)
{
log_error("Failed to fix MFT: write error.\n");
display_message("Failed to fix MFT: write error.\n");
}
else
{
disk_car->sync(disk_car);
log_info("MFT fixed.\n");
display_message("MFT fixed.\n");
}
}
else if(use_MFT==1)
{
{
if(disk_car->write(disk_car, mftmirr_size_bytes, buffer_mft, mftmirr_pos)!=0)
{
log_error("Failed to fix MFT mirror: write error.\n");

View file

@ -1102,6 +1102,8 @@ static int photorec_aux(disk_t *disk_car, partition_t *partition, const int verb
#endif
update_blocksize(*blocksize,list_search_space, start_offset);
free_list_search_space(&list_file);
/* An expert can stop and manually set the blocksize without stopping the recovery */
ind_stop=0;
}
free(buffer_start);
#ifdef HAVE_NCURSES
@ -2157,36 +2159,36 @@ static void interface_file_select(file_enable_t *files_enable, char**current_cmd
else
{
unsigned int cmd_length=0;
while((*current_cmd)[cmd_length]!='\0' && (*current_cmd)[cmd_length]!=',')
cmd_length++;
while((*current_cmd)[cmd_length]!='\0' && (*current_cmd)[cmd_length]!=',')
cmd_length++;
for(file_enable=&files_enable[0];file_enable->file_hint!=NULL;file_enable++)
{
{
if(file_enable->file_hint->extension!=NULL &&
strlen(file_enable->file_hint->extension)==cmd_length &&
memcmp(file_enable->file_hint->extension,*current_cmd,cmd_length)==0)
{
keep_asking=1;
{
keep_asking=1;
(*current_cmd)+=cmd_length;
while(*current_cmd[0]==',')
(*current_cmd)++;
if(strncmp(*current_cmd,"enable",6)==0)
{
(*current_cmd)+=6;
while(*current_cmd[0]==',')
(*current_cmd)++;
if(strncmp(*current_cmd,"enable",6)==0)
{
(*current_cmd)+=6;
file_enable->enable=1;
}
else if(strncmp(*current_cmd,"disable",7)==0)
{
(*current_cmd)+=7;
}
else if(strncmp(*current_cmd,"disable",7)==0)
{
(*current_cmd)+=7;
file_enable->enable=0;
}
else
{
log_critical("Syntax error %s\n",*current_cmd);
return;
}
else
{
log_critical("Syntax error %s\n",*current_cmd);
return;
}
}
}
}
}
} while(keep_asking>0);
return;
}