summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristophe Grenier <grenier@cgsecurity.org>2010-06-22 15:23:14 +0200
committerChristophe Grenier <grenier@cgsecurity.org>2010-06-22 15:23:14 +0200
commit6de815b1165e30897c52e0cbe819a602c8c5128a (patch)
tree68c1a6ef03bf7de02f27d75c560ab2001d9bf323
parentd31511c9d41ec475e453c1b359bfb3efbb040c73 (diff)
TestDisk: reduce the number of read operations
-rw-r--r--src/analyse.c14
-rw-r--r--src/analyse.h6
-rw-r--r--src/godmode.c66
-rw-r--r--src/partnone.c48
4 files changed, 75 insertions, 59 deletions
diff --git a/src/analyse.c b/src/analyse.c
index b55143f..fe8f962 100644
--- a/src/analyse.c
+++ b/src/analyse.c
@@ -126,7 +126,7 @@ int search_FAT_backup(unsigned char *buffer, disk_t *disk, partition_t *partitio
return 0;
}
-int search_type_0(unsigned char *buffer,disk_t *disk, partition_t *partition, const int verbose, const int dump_ind)
+int search_type_0(const unsigned char *buffer, disk_t *disk, partition_t *partition, const int verbose, const int dump_ind)
{
const pv_disk_t *pv=(const pv_disk_t *)buffer;
const struct disk_fatx *fatx_block=(const struct disk_fatx*)buffer;
@@ -151,8 +151,6 @@ int search_type_0(unsigned char *buffer,disk_t *disk, partition_t *partition, co
log_trace("search_type_0 lba=%lu\n",
(long unsigned)(partition->part_offset/disk->sector_size));
}
- if(disk->pread(disk, buffer, 8 * DEFAULT_SECTOR_SIZE, partition->part_offset) != 8 * DEFAULT_SECTOR_SIZE)
- return -1;
if(memcmp(swap_header->magic.magic, "SWAP", 4)==0 &&
recover_Linux_SWAP(swap_header, partition)==0)
return 1;
@@ -196,7 +194,7 @@ int search_type_0(unsigned char *buffer,disk_t *disk, partition_t *partition, co
return 0;
}
-int search_type_1(unsigned char *buffer, disk_t *disk,partition_t *partition,const int verbose, const int dump_ind)
+int search_type_1(const unsigned char *buffer, disk_t *disk, partition_t *partition, const int verbose, const int dump_ind)
{
const struct disklabel *bsd_header=(const struct disklabel *)(buffer+0x200);
const struct disk_super_block*beos_block=(const struct disk_super_block*)(buffer+0x200);
@@ -214,8 +212,6 @@ int search_type_1(unsigned char *buffer, disk_t *disk,partition_t *partition,con
log_trace("search_type_1 lba=%lu\n",
(long unsigned)(partition->part_offset/disk->sector_size));
}
- if(disk->pread(disk, buffer, 8 * DEFAULT_SECTOR_SIZE, partition->part_offset) != 8 * DEFAULT_SECTOR_SIZE)
- return -1;
if(le32(bsd_header->d_magic) == DISKMAGIC && le32(bsd_header->d_magic2)==DISKMAGIC &&
recover_BSD(disk, bsd_header, partition, verbose, dump_ind)==0)
return 1;
@@ -237,7 +233,7 @@ int search_type_1(unsigned char *buffer, disk_t *disk,partition_t *partition,con
return 0;
}
-int search_type_2(unsigned char *buffer, disk_t *disk,partition_t *partition,const int verbose, const int dump_ind)
+int search_type_2(const unsigned char *buffer, disk_t *disk, partition_t *partition, const int verbose, const int dump_ind)
{
const hfs_mdb_t *hfs_mdb=(const hfs_mdb_t *)(buffer+0x400);
const struct hfsp_vh *vh=(const struct hfsp_vh *)(buffer+0x400);
@@ -250,8 +246,6 @@ int search_type_2(unsigned char *buffer, disk_t *disk,partition_t *partition,con
log_trace("search_type_2 lba=%lu\n",
(long unsigned)(partition->part_offset/disk->sector_size));
}
- if(disk->pread(disk, (buffer + 0x400), 1024, partition->part_offset + 1024) != 1024)
- return -1;
if(le16(sb->s_magic)==EXT2_SUPER_MAGIC &&
recover_EXT2(disk, sb, partition, verbose, dump_ind)==0)
return 1;
@@ -328,7 +322,7 @@ int search_type_64(unsigned char *buffer, disk_t *disk,partition_t *partition,co
return 0;
}
-int search_type_128(unsigned char *buffer, disk_t *disk,partition_t *partition,const int verbose, const int dump_ind)
+int search_type_128(unsigned char *buffer, disk_t *disk, partition_t *partition, const int verbose, const int dump_ind)
{
const struct reiserfs_super_block *rfs=(const struct reiserfs_super_block *)(buffer+0x400);
const struct reiser4_master_sb *rfs4=(const struct reiser4_master_sb *)(buffer+0x400);
diff --git a/src/analyse.h b/src/analyse.h
index 1ead0ff..a1b19a3 100644
--- a/src/analyse.h
+++ b/src/analyse.h
@@ -23,9 +23,9 @@
extern "C" {
#endif
-int search_type_0(unsigned char *buffer, disk_t *disk_car,partition_t *partition,const int verbose, const int dump_ind);
-int search_type_1(unsigned char *buffer, disk_t *disk_car,partition_t *partition,const int verbose, const int dump_ind);
-int search_type_2(unsigned char *buffer, disk_t *disk_car,partition_t *partition,const int verbose, const int dump_ind);
+int search_type_0(const unsigned char *buffer, disk_t *disk_car,partition_t *partition,const int verbose, const int dump_ind);
+int search_type_1(const unsigned char *buffer, disk_t *disk_car,partition_t *partition,const int verbose, const int dump_ind);
+int search_type_2(const unsigned char *buffer, disk_t *disk_car,partition_t *partition,const int verbose, const int dump_ind);
int search_type_8(unsigned char *buffer, disk_t *disk_car,partition_t *partition,const int verbose, const int dump_ind);
int search_type_16(unsigned char *buffer, disk_t *disk_car,partition_t *partition,const int verbose, const int dump_ind);
int search_type_64(unsigned char *buffer, disk_t *disk_car,partition_t *partition,const int verbose, const int dump_ind);
diff --git a/src/godmode.c b/src/godmode.c
index 398e213..834261d 100644
--- a/src/godmode.c
+++ b/src/godmode.c
@@ -363,6 +363,7 @@ static unsigned int tab_insert(uint64_t *tab, const uint64_t offset, unsigned in
static list_part_t *search_part(disk_t *disk_car, const list_part_t *list_part_org, const int verbose, const int dump_ind, const int fast_mode, const int interface, const int search_vista_part, char **current_cmd)
{
unsigned char *buffer_disk;
+ unsigned char *buffer_disk0;
/* TODO use circular buffer for try_offset and try_offset_raid */
uint64_t try_offset[MAX_SEARCH_LOCATION];
uint64_t try_offset_raid[MAX_SEARCH_LOCATION];
@@ -387,6 +388,7 @@ static list_part_t *search_part(disk_t *disk_car, const list_part_t *list_part_o
(uint64_t)disk_car->geom.cylinders*disk_car->geom.heads_per_cylinder * disk_car->geom.sectors_per_head * disk_car->sector_size);
partition=partition_new(disk_car->arch);
buffer_disk=(unsigned char*)MALLOC(16*DEFAULT_SECTOR_SIZE);
+ buffer_disk0=(unsigned char*)MALLOC(16*DEFAULT_SECTOR_SIZE);
{
/* Will search for partition at current known partition location */
const list_part_t *element;
@@ -523,12 +525,6 @@ static list_part_t *search_part(disk_t *disk_car, const list_part_t *list_part_o
partition->part_offset=search_location;
if(res<=0 && test_nbr==0)
{
- if(search_now>0)
- res=search_type_2(buffer_disk,disk_car,partition,verbose,dump_ind);
- test_nbr++;
- }
- if(res<=0 && test_nbr==1)
- {
if(search_now_raid>0 || fast_mode>1)
{ /* Search Linux software RAID */
if(disk_car->pread(disk_car, buffer_disk, 8 * DEFAULT_SECTOR_SIZE, search_location) != 8 * DEFAULT_SECTOR_SIZE)
@@ -562,10 +558,10 @@ static list_part_t *search_part(disk_t *disk_car, const list_part_t *list_part_o
}
test_nbr++;
}
- if(res<=0 && test_nbr==2)
+ if(res<=0 && test_nbr==1)
{
if(fast_mode==0)
- test_nbr=7;
+ test_nbr=6;
else
{
if((disk_car->arch==&arch_i386 &&
@@ -576,22 +572,17 @@ static list_part_t *search_part(disk_t *disk_car, const list_part_t *list_part_o
test_nbr++;
}
}
+ if(res<=0 && test_nbr==2)
+ {
+ if((disk_car->arch==&arch_i386 &&
+ ((start.sector==13 && (start.head<=2 || fast_mode>1)) ||
+ (search_vista_part>0 && search_location%(2048*512)==(13-1)*512))) ||
+ (disk_car->arch!=&arch_i386 && (search_location%location_boundary==(13-1)*512)))
+ res=search_EXFAT_backup(buffer_disk, disk_car, partition);
+ test_nbr++;
+ }
if(res<=0 && test_nbr==3)
{
- if(fast_mode==0)
- test_nbr=7;
- else
- {
- if((disk_car->arch==&arch_i386 &&
- ((start.sector==13 && (start.head<=2 || fast_mode>1)) ||
- (search_vista_part>0 && search_location%(2048*512)==(13-1)*512))) ||
- (disk_car->arch!=&arch_i386 && (search_location%location_boundary==(13-1)*512)))
- res=search_EXFAT_backup(buffer_disk, disk_car, partition);
- test_nbr++;
- }
- }
- if(res<=0 && test_nbr==4)
- {
if((disk_car->arch==&arch_i386 &&
((start.sector==disk_car->geom.sectors_per_head &&
(start.head==disk_car->geom.heads_per_cylinder-1 || fast_mode>1)) ||
@@ -601,7 +592,7 @@ static list_part_t *search_part(disk_t *disk_car, const list_part_t *list_part_o
res=search_NTFS_backup(buffer_disk,disk_car,partition,verbose,dump_ind);
test_nbr++;
}
- if(res<=0 && test_nbr==5)
+ if(res<=0 && test_nbr==4)
{
if((disk_car->arch==&arch_i386 &&
((start.sector==disk_car->geom.sectors_per_head &&
@@ -612,7 +603,7 @@ static list_part_t *search_part(disk_t *disk_car, const list_part_t *list_part_o
res=search_HFS_backup(buffer_disk,disk_car,partition,verbose,dump_ind);
test_nbr++;
}
- if(res<=0 && test_nbr==6)
+ if(res<=0 && test_nbr==5)
{
int s_log_block_size;
/* try backup superblock */
@@ -651,19 +642,29 @@ static list_part_t *search_part(disk_t *disk_car, const list_part_t *list_part_o
}
test_nbr++;
}
- if(res<=0 && test_nbr==7)
+ if(res<=0 && test_nbr==6)
{
- if(search_now>0)
- {
- res=search_type_1(buffer_disk, disk_car,partition,verbose,dump_ind);
- test_nbr++;
- }
- else
+ if(search_now==0)
test_nbr=13;
+ else
+ {
+ if(disk_car->pread(disk_car, buffer_disk0, 8 * DEFAULT_SECTOR_SIZE, partition->part_offset) == 8 * DEFAULT_SECTOR_SIZE)
+ res=search_type_2(buffer_disk0,disk_car,partition,verbose,dump_ind);
+ else
+ res=-1;
+ test_nbr++;
+ }
+ }
+ if(res<=0 && test_nbr==7)
+ {
+ if(res==0)
+ res=search_type_1(buffer_disk0, disk_car,partition,verbose,dump_ind);
+ test_nbr++;
}
if(res<=0 && test_nbr==8)
{
- res=search_type_0(buffer_disk,disk_car,partition,verbose,dump_ind);
+ if(res==0)
+ res=search_type_0(buffer_disk0,disk_car,partition,verbose,dump_ind);
test_nbr++;
}
if(res<=0 && test_nbr==9)
@@ -889,6 +890,7 @@ static list_part_t *search_part(disk_t *disk_car, const list_part_t *list_part_o
#endif
}
part_free_list(list_part_bad);
+ free(buffer_disk0);
free(buffer_disk);
return list_part;
}
diff --git a/src/partnone.c b/src/partnone.c
index fe461bc..9b6505f 100644
--- a/src/partnone.c
+++ b/src/partnone.c
@@ -170,7 +170,7 @@ static int get_geometry_from_nonembr(const unsigned char *buffer, const int verb
return 0;
}
-static list_part_t *read_part_none(disk_t *disk_car, const int verbose, const int saveheader)
+static list_part_t *read_part_none(disk_t *disk, const int verbose, const int saveheader)
{
int insert_error=0;
unsigned char *buffer_disk;
@@ -179,36 +179,56 @@ static list_part_t *read_part_none(disk_t *disk_car, const int verbose, const in
int res=0;
partition=partition_new(&arch_none);
buffer_disk=(unsigned char *)MALLOC(16*DEFAULT_SECTOR_SIZE);
- partition->part_size=disk_car->disk_size;
- if(recover_MD_from_partition(disk_car, partition, verbose)==0)
+ partition->part_size=disk->disk_size;
+ if(recover_MD_from_partition(disk, partition, verbose)==0)
res=1;
else
partition_reset(partition,&arch_none);
if(res<=0)
- res=search_type_128(buffer_disk,disk_car,partition,verbose,0);
+ {
+ if(disk->pread(disk, buffer_disk, 8 * DEFAULT_SECTOR_SIZE, partition->part_offset) == 8 * DEFAULT_SECTOR_SIZE)
+ res=search_type_2(buffer_disk, disk, partition,verbose,0);
+ }
if(res<=0)
- res=search_type_64(buffer_disk,disk_car,partition,verbose,0);
+ {
+ res=search_type_1(buffer_disk, disk, partition,verbose,0);
+ }
if(res<=0)
- res=(recover_ISO(disk_car,(const struct iso_primary_descriptor*)(buffer_disk+0x200), partition, verbose, 0)==0);
+ {
+ res=search_type_0(buffer_disk, disk, partition,verbose,0);
+ }
if(res<=0)
- res=search_type_8(buffer_disk,disk_car,partition,verbose,0);
+ {
+ if(disk->pread(disk, buffer_disk, 4096, partition->part_offset + 4096) == 4096)
+ res=search_type_8(buffer_disk, disk, partition,verbose,0);
+ }
if(res<=0)
- res=search_type_16(buffer_disk,disk_car,partition,verbose,0);
+ {
+ if(disk->pread(disk, buffer_disk, 3 * DEFAULT_SECTOR_SIZE, partition->part_offset + 16 * 512) == 3 * DEFAULT_SECTOR_SIZE)
+ res=search_type_16(buffer_disk, disk, partition,verbose,0);
+ }
if(res<=0)
- res=search_type_2(buffer_disk,disk_car,partition,verbose,0);
+ {
+ if(disk->pread(disk, buffer_disk, 3 * DEFAULT_SECTOR_SIZE, partition->part_offset + 63 * 512) == 3 * DEFAULT_SECTOR_SIZE)
+ res=search_type_64(buffer_disk, disk, partition,verbose,0);
+ }
if(res<=0)
- res=search_type_1(buffer_disk,disk_car,partition,verbose,0);
+ res=(recover_ISO(disk, (const struct iso_primary_descriptor*)(buffer_disk+0x200), partition, verbose, 0)==0);
if(res<=0)
- res=search_type_0(buffer_disk,disk_car,partition,verbose,0);
+ {
+ /* 64k offset */
+ if(disk->pread(disk, buffer_disk, 11 * DEFAULT_SECTOR_SIZE, partition->part_offset + 126 * 512) == 11 * DEFAULT_SECTOR_SIZE)
+ res=search_type_128(buffer_disk, disk, partition,verbose,0);
+ }
free(buffer_disk);
if(res<=0)
partition_reset(partition,&arch_none);
- partition->part_size=disk_car->disk_size;
+ partition->part_size=disk->disk_size;
partition->order=NO_ORDER;
partition->status=STATUS_PRIM;
screen_buffer_reset();
- disk_car->arch->check_part(disk_car,verbose,partition,saveheader);
- aff_part_buffer(AFF_PART_ORDER|AFF_PART_STATUS,disk_car,partition);
+ disk->arch->check_part(disk, verbose,partition,saveheader);
+ aff_part_buffer(AFF_PART_ORDER|AFF_PART_STATUS,disk, partition);
list_part=insert_new_partition(NULL, partition, 0, &insert_error);
if(insert_error>0)
free(partition);