summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristophe Grenier <grenier@cgsecurity.org>2015-09-03 08:04:04 +0200
committerChristophe Grenier <grenier@cgsecurity.org>2015-09-03 08:04:04 +0200
commit00557961744f0a88000678db179a84a4a0e4fdfd (patch)
treedb0bae677a788104fa71edaebcbfa30402833179
parentac980c4a61e0158ce5ceec8555a89b38eac5066c (diff)
PhotoRec: reduce the number of backward search
-rw-r--r--src/file_dad.c7
-rw-r--r--src/file_dv.c7
-rw-r--r--src/file_dvr.c3
-rw-r--r--src/file_edb.c3
-rw-r--r--src/file_ext2.c3
-rw-r--r--src/file_fdb.c3
-rw-r--r--src/file_gsm.c9
-rw-r--r--src/file_indd.c11
-rw-r--r--src/file_jpg.c36
-rw-r--r--src/file_m2ts.c14
-rw-r--r--src/file_mov.c1
-rw-r--r--src/file_mp3.c6
-rw-r--r--src/file_mpg.c27
-rw-r--r--src/file_ogg.c3
-rw-r--r--src/file_par2.c7
-rw-r--r--src/file_png.c13
-rw-r--r--src/file_psf.c3
-rw-r--r--src/file_tar.c7
-rw-r--r--src/file_tiff.c3
-rw-r--r--src/file_wtv.c3
-rw-r--r--src/file_zip.c6
-rw-r--r--src/filegen.c42
-rw-r--r--src/filegen.h1
-rw-r--r--src/photorec.h1
-rw-r--r--src/psearchn.c3
25 files changed, 189 insertions, 33 deletions
diff --git a/src/file_dad.c b/src/file_dad.c
index 863b023..5ce0db1 100644
--- a/src/file_dad.c
+++ b/src/file_dad.c
@@ -73,13 +73,16 @@ static data_check_t data_check_dad(const unsigned char *buffer, const unsigned i
static int header_check_dad(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)
{
const struct dad_header *dad=(const struct dad_header *)buffer;
+ if(le32(dad->size)<16)
+ return 0;
if(file_recovery->file_stat!=NULL &&
file_recovery->file_stat->file_hint==&file_hint_dad &&
(file_recovery->calculated_file_size==file_recovery->file_size ||
file_recovery->blocksize < 16))
+ {
+ header_ignored(file_recovery_new);
return 0;
- if(le32(dad->size)<16)
- return 0;
+ }
reset_file_recovery(file_recovery_new);
file_recovery_new->extension=file_hint_dad.extension;
file_recovery_new->min_filesize=le32(dad->size);
diff --git a/src/file_dv.c b/src/file_dv.c
index ac8de0f..e44b859 100644
--- a/src/file_dv.c
+++ b/src/file_dv.c
@@ -136,11 +136,14 @@ static void file_check_dv_PAL(file_recovery_t *fr)
static int header_check_dv(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)
{
+ if(buffer[0]!=0x1f || buffer[1]!=0x07 || buffer[2]!=0x00 || buffer[5]!=0x78 || buffer[6]!=0x78 || buffer[7]!=0x78)
+ return 0;
if(file_recovery->file_stat!=NULL &&
file_recovery->file_stat->file_hint==&file_hint_dv)
+ {
+ header_ignored(file_recovery_new);
return 0;
- if(buffer[0]!=0x1f || buffer[1]!=0x07 || buffer[2]!=0x00 || buffer[5]!=0x78 || buffer[6]!=0x78 || buffer[7]!=0x78)
- return 0;
+ }
reset_file_recovery(file_recovery_new);
file_recovery_new->extension=file_hint_dv.extension;
if((buffer[3]&0x80)==0)
diff --git a/src/file_dvr.c b/src/file_dvr.c
index 7b6b415..bf2c9b1 100644
--- a/src/file_dvr.c
+++ b/src/file_dvr.c
@@ -46,7 +46,10 @@ static int header_check_dvr(const unsigned char *buffer, const unsigned int buff
if(memcmp(&buffer[8], "XVID", 4)!=0)
return 0;
if(file_recovery->file_stat!=NULL && file_recovery->file_stat->file_hint==&file_hint_dvr)
+ {
+ header_ignored(file_recovery_new);
return 0;
+ }
reset_file_recovery(file_recovery_new);
file_recovery_new->extension=file_hint_dvr.extension;
file_recovery_new->min_filesize=0x10;
diff --git a/src/file_edb.c b/src/file_edb.c
index 9224e19..0f57496 100644
--- a/src/file_edb.c
+++ b/src/file_edb.c
@@ -49,7 +49,10 @@ static int header_check_edb(const unsigned char *buffer, const unsigned int buff
if(file_recovery->file_stat!=NULL &&
file_recovery->file_stat->file_hint==&file_hint_edb &&
file_recovery->file_size==4096)
+ {
+ header_ignored(file_recovery_new);
return 0;
+ }
reset_file_recovery(file_recovery_new);
file_recovery_new->extension=file_hint_edb.extension;
return 1;
diff --git a/src/file_ext2.c b/src/file_ext2.c
index 0b6f050..4c77219 100644
--- a/src/file_ext2.c
+++ b/src/file_ext2.c
@@ -62,7 +62,10 @@ static int header_check_ext2_fs(const unsigned char *buffer, const unsigned int
if(file_recovery->file_stat!=NULL &&
file_recovery->file_stat->file_hint==&file_hint_ext2_fs &&
file_recovery->calculated_file_size==(uint64_t)le32(sb->s_blocks_count)*(EXT2_MIN_BLOCK_SIZE<<le32(sb->s_log_block_size)))
+ {
+ header_ignored(file_recovery_new);
return 0;
+ }
reset_file_recovery(file_recovery_new);
file_recovery_new->extension=file_hint_ext2_fs.extension;
file_recovery_new->calculated_file_size=(uint64_t)le32(sb->s_blocks_count)*(EXT2_MIN_BLOCK_SIZE<<le32(sb->s_log_block_size));
diff --git a/src/file_fdb.c b/src/file_fdb.c
index 611e0ba..0ac5ebd 100644
--- a/src/file_fdb.c
+++ b/src/file_fdb.c
@@ -45,7 +45,10 @@ static int header_check_fdb(const unsigned char *buffer, const unsigned int buff
{
if(file_recovery->file_stat!=NULL &&
file_recovery->file_stat->file_hint==&file_hint_fdb)
+ {
+ header_ignored(file_recovery_new);
return 0;
+ }
reset_file_recovery(file_recovery_new);
file_recovery_new->extension=file_hint_fdb.extension;
return 1;
diff --git a/src/file_gsm.c b/src/file_gsm.c
index d163550..7955344 100644
--- a/src/file_gsm.c
+++ b/src/file_gsm.c
@@ -68,9 +68,6 @@ static int header_check_gsm(const unsigned char *buffer, const unsigned int buff
{
const struct block_header *hdr;
unsigned int i=0;
- if(file_recovery->file_stat!=NULL
- && file_recovery->file_stat->file_hint==&file_hint_gsm)
- return 0;
for(i=0, hdr=(const struct block_header *)buffer;
i * sizeof(struct block_header) < file_recovery_new->blocksize;
i++, hdr++)
@@ -80,6 +77,12 @@ static int header_check_gsm(const unsigned char *buffer, const unsigned int buff
}
if(i<3)
return 0;
+ if(file_recovery->file_stat!=NULL
+ && file_recovery->file_stat->file_hint==&file_hint_gsm)
+ {
+ header_ignored(file_recovery_new);
+ return 0;
+ }
reset_file_recovery(file_recovery_new);
file_recovery_new->extension=file_hint_gsm.extension;
file_recovery_new->min_filesize=sizeof(struct block_header);
diff --git a/src/file_indd.c b/src/file_indd.c
index 5f3ae24..22b71df 100644
--- a/src/file_indd.c
+++ b/src/file_indd.c
@@ -123,14 +123,17 @@ static int header_check_indd(const unsigned char *buffer, const unsigned int buf
const struct InDesignMasterPage *hdr0 = (const struct InDesignMasterPage *)buffer;
const struct InDesignMasterPage *hdr1 = (const struct InDesignMasterPage *)&buffer[4096];
hdr=(le64(hdr0->fSequenceNumber) > le64(hdr1->fSequenceNumber) ? hdr0 : hdr1);
- if(file_recovery->file_stat!=NULL &&
- file_recovery->file_stat->file_hint==&file_hint_indd &&
- file_recovery->file_size <= 8192)
- return 0;
if(hdr->fObjectStreamEndian!=1 && hdr->fObjectStreamEndian!=2)
return 0;
if(le32(hdr->fFilePages)==0)
return 0;
+ if(file_recovery->file_stat!=NULL &&
+ file_recovery->file_stat->file_hint==&file_hint_indd &&
+ file_recovery->file_size <= 8192)
+ {
+ header_ignored(file_recovery_new);
+ return 0;
+ }
reset_file_recovery(file_recovery_new);
#ifdef DJGPP
file_recovery_new->extension="ind";
diff --git a/src/file_jpg.c b/src/file_jpg.c
index fad75d1..45d95cb 100644
--- a/src/file_jpg.c
+++ b/src/file_jpg.c
@@ -394,10 +394,16 @@ static int header_check_jpg(const unsigned char *buffer, const unsigned int buff
unsigned int height=0;
jpg_get_size(buffer, buffer_size, &height, &width);
if(file_recovery->file_stat->file_hint==&file_hint_indd)
+ {
+ header_ignored(file_recovery_new);
return 0;
+ }
if(file_recovery->file_stat->file_hint==&file_hint_doc &&
strstr(file_recovery->filename, ".albm")!=NULL)
+ {
+ header_ignored(file_recovery_new);
return 0;
+ }
if( file_recovery->file_stat->file_hint==&file_hint_jpg)
{
/* Don't recover the thumb instead of the jpg itself */
@@ -407,6 +413,7 @@ static int header_check_jpg(const unsigned char *buffer, const unsigned int buff
log_info("jpg %llu %llu\n",
(long long unsigned)file_recovery->calculated_file_size,
(long long unsigned)file_recovery->file_size);
+ header_ignored(file_recovery_new);
return 0;
}
/* Don't recover the thumb instead of the jpg itself */
@@ -414,40 +421,69 @@ static int header_check_jpg(const unsigned char *buffer, const unsigned int buff
buffer[3]==0xe0 &&
width>0 && width<200 && height>0 && height<200)
{
+ header_ignored(file_recovery_new);
return 0;
}
/* Some JPG have two APP1 markers, avoid to dicard the first one */
if( buffer[3]==0xe1 &&
memcmp(&buffer[6], "http://ns.adobe.com/xap/", 24)==0)
{
+ header_ignored(file_recovery_new);
return 0;
}
if(file_recovery->file_check==&file_check_mpo)
+ {
+ header_ignored(file_recovery_new);
return 0;
+ }
}
/* Don't extract jpg inside AVI */
if( file_recovery->file_stat->file_hint==&file_hint_riff &&
(memcmp(buffer, jpg_header_app0_avi, sizeof(jpg_header_app0_avi))==0 ||
file_recovery->data_check == &data_check_avi_stream))
+ {
+ header_ignored(file_recovery_new);
return 0;
+ }
/* Don't extract jpg inside MOV */
if( file_recovery->file_stat->file_hint==&file_hint_mov &&
memcmp(buffer, jpg_header_app0_jfif11_null, sizeof(jpg_header_app0_jfif11_null))==0)
+ {
+ header_ignored(file_recovery_new);
return 0;
+ }
/* Don't extract jpg inside rw2 */
if( file_recovery->file_stat->file_hint==&file_hint_rw2 &&
file_recovery->file_size <= 8192)
+ {
+ header_ignored(file_recovery_new);
return 0;
+ }
if(buffer[3]==0xdb) /* DQT */
+ {
+ header_ignored(file_recovery_new);
return 0;
+ }
if(buffer[3]==0xc4) /* DHT - needed to recover .cr2 */
+ {
+ header_ignored(file_recovery_new);
return 0;
+ }
if(buffer[3]==0xe0 && (buffer[6]!='J' || buffer[7]!='F')) /* Should be JFIF/JFXX */
+ {
+ header_ignored(file_recovery_new);
return 0;
+ }
if(buffer[3]==0xe1 && (buffer[6]!='E' || buffer[7]!='x' || buffer[8]!='i'|| buffer[9]!='f')) /* Should be EXIF */
+ {
+ header_ignored(file_recovery_new);
return 0;
+ }
if(buffer[3]==0xfe && (!isprint(buffer[6]) || !isprint(buffer[7])))
+ {
+ header_ignored(file_recovery_new);
return 0;
+ }
}
while(i+4<buffer_size && buffer[i]==0xff && is_marker_valid(buffer[i+1]))
{
diff --git a/src/file_m2ts.c b/src/file_m2ts.c
index dfba92e..bc50fa8 100644
--- a/src/file_m2ts.c
+++ b/src/file_m2ts.c
@@ -118,17 +118,19 @@ static void file_rename_ts_192(file_recovery_t *file_recovery)
static int header_check_m2ts(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)
{
unsigned int i;
- if(file_recovery->file_stat!=NULL &&
- file_recovery->file_stat->file_hint==&file_hint_m2ts &&
- (file_recovery->data_check==&data_check_ts_192 ||
- file_recovery->blocksize < 5))
- return 0;
/* BDAV MPEG-2 transport stream */
/* Each frame is 192 byte long and begins by a TS_SYNC_BYTE */
for(i=4; i<buffer_size && buffer[i]==0x47; i+=192);
if(i<buffer_size)
return 0;
- reset_file_recovery(file_recovery_new);
+ if(file_recovery->file_stat!=NULL &&
+ file_recovery->file_stat->file_hint==&file_hint_m2ts &&
+ (file_recovery->data_check==&data_check_ts_192 ||
+ file_recovery->blocksize < 5))
+ {
+ header_ignored(file_recovery_new);
+ return 0;
+ } reset_file_recovery(file_recovery_new);
if( memcmp(&buffer[0xd7], &buffer[0xe8], 4)==0)
{
if( memcmp(&buffer[0xd7], hdmv_header, sizeof(hdmv_header))==0 ||
diff --git a/src/file_mov.c b/src/file_mov.c
index 49eef85..05e59d9 100644
--- a/src/file_mov.c
+++ b/src/file_mov.c
@@ -117,6 +117,7 @@ static int header_check_mov(const unsigned char *buffer, const unsigned int buff
(file_recovery->calculated_file_size == file_recovery->file_size ||
file_recovery->blocksize < 16))
{ /* PhotoRec is already trying to recover this mov file */
+ header_ignored(file_recovery_new);
return 0;
}
return header_check_mov_aux(buffer, buffer_size, safe_header_only, file_recovery, file_recovery_new);
diff --git a/src/file_mp3.c b/src/file_mp3.c
index e5e793a..b2414fc 100644
--- a/src/file_mp3.c
+++ b/src/file_mp3.c
@@ -167,11 +167,17 @@ static int header_check_mp3(const unsigned char *buffer, const unsigned int buff
{
if(file_recovery->file_stat->file_hint==&file_hint_mp3 ||
file_recovery->file_stat->file_hint==&file_hint_mkv)
+ {
+ header_ignored(file_recovery_new);
return 0;
+ }
/* RGV values from TIFF may be similar to the beginning of an mp3 */
if(file_recovery->file_stat->file_hint==&file_hint_tiff &&
buffer[0]==buffer[3] && buffer[1]==buffer[4] && buffer[2]==buffer[5])
+ {
+ header_ignored(file_recovery_new);
return 0;
+ }
}
while(potential_frame_offset+1 < buffer_size &&
potential_frame_offset+1 < 2048)
diff --git a/src/file_mpg.c b/src/file_mpg.c
index 1873e38..9a09c9f 100644
--- a/src/file_mpg.c
+++ b/src/file_mpg.c
@@ -177,7 +177,10 @@ static int header_check_mpg_Pack(const unsigned char *buffer, const unsigned int
return 1;
}
if(file_recovery->file_stat!=NULL && file_recovery->file_stat->file_hint==&file_hint_mpg)
+ {
+ header_ignored(file_recovery_new);
return 0;
+ }
reset_file_recovery(file_recovery_new);
file_recovery_new->extension=file_hint_mpg.extension;
if(file_recovery_new->blocksize < 14)
@@ -220,7 +223,10 @@ static int header_check_mpg_Pack(const unsigned char *buffer, const unsigned int
return 1;
}
if(file_recovery->file_stat!=NULL && file_recovery->file_stat->file_hint==&file_hint_mpg)
+ {
+ header_ignored(file_recovery_new);
return 0;
+ }
reset_file_recovery(file_recovery_new);
file_recovery_new->extension=file_hint_mpg.extension;
if(file_recovery_new->blocksize < 14)
@@ -234,8 +240,6 @@ static int header_check_mpg_Pack(const unsigned char *buffer, const unsigned int
static int header_check_mpg_System(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)
{
- if(file_recovery->file_stat!=NULL && file_recovery->file_stat->file_hint==&file_hint_mpg)
- return 0;
/* MPEG-1 http://andrewduncan.ws/MPEG/MPEG-1.ps */
/* ISO/IEC INTERNATIONAL 13818-1 STANDARD
system_header_start_code 32
@@ -265,6 +269,11 @@ static int header_check_mpg_System(const unsigned char *buffer, const unsigned i
return 0;
i+=ret;
}
+ if(file_recovery->file_stat!=NULL && file_recovery->file_stat->file_hint==&file_hint_mpg)
+ {
+ header_ignored(file_recovery_new);
+ return 0;
+ }
reset_file_recovery(file_recovery_new);
file_recovery_new->extension=file_hint_mpg.extension;
file_recovery_new->data_check=&data_check_mpg;
@@ -276,8 +285,6 @@ static int header_check_mpg_System(const unsigned char *buffer, const unsigned i
static int header_check_mpg_Sequence(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)
{
- if(file_recovery->file_stat!=NULL && file_recovery->file_stat->file_hint==&file_hint_mpg)
- return 0;
/* MPEG-1 sequence header code 0x1B3 */
/* horizontal size>0 */
if((buffer[4]<<4)+(buffer[5]>>4)>0 &&
@@ -300,6 +307,11 @@ static int header_check_mpg_Sequence(const unsigned char *buffer, const unsigned
return 0;
i+=ret;
}
+ if(file_recovery->file_stat!=NULL && file_recovery->file_stat->file_hint==&file_hint_mpg)
+ {
+ header_ignored(file_recovery_new);
+ return 0;
+ }
reset_file_recovery(file_recovery_new);
file_recovery_new->extension=file_hint_mpg.extension;
file_recovery_new->data_check=&data_check_mpg;
@@ -311,8 +323,6 @@ static int header_check_mpg_Sequence(const unsigned char *buffer, const unsigned
static int header_check_mpg4_ElemVideo(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)
{
- if(file_recovery->file_stat!=NULL && file_recovery->file_stat->file_hint==&file_hint_mpg)
- return 0;
/* ISO/IEC 14496-2 (MPEG-4 video) ELEMENTARY VIDEO HEADER - visual object start code */
/* is_visual_object_identifier */
if((buffer[4]&0xf0)==0x80 &&
@@ -332,6 +342,11 @@ static int header_check_mpg4_ElemVideo(const unsigned char *buffer, const unsign
return 0;
i+=ret;
}
+ if(file_recovery->file_stat!=NULL && file_recovery->file_stat->file_hint==&file_hint_mpg)
+ {
+ header_ignored(file_recovery_new);
+ return 0;
+ }
reset_file_recovery(file_recovery_new);
file_recovery_new->extension=file_hint_mpg.extension;
file_recovery_new->data_check=&data_check_mpg;
diff --git a/src/file_ogg.c b/src/file_ogg.c
index 3c1d95e..ab572f3 100644
--- a/src/file_ogg.c
+++ b/src/file_ogg.c
@@ -56,7 +56,10 @@ static int header_check_ogg(const unsigned char *buffer, const unsigned int buff
file_recovery->file_stat->file_hint==&file_hint_ogg &&
(file_recovery->blocksize < 27+255 ||
file_recovery->calculated_file_size == file_recovery->file_size))
+ {
+ header_ignored(file_recovery_new);
return 0;
+ }
reset_file_recovery(file_recovery_new);
file_recovery_new->calculated_file_size=0;
if(file_recovery_new->blocksize > 27+255)
diff --git a/src/file_par2.c b/src/file_par2.c
index e473ee0..68628b7 100644
--- a/src/file_par2.c
+++ b/src/file_par2.c
@@ -114,11 +114,14 @@ static void file_rename_par2(file_recovery_t *file_recovery)
static int header_check_par2(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)
{
const uint64_t length=le64((*(const uint64_t *)(&buffer[8])));
+ if(length % 4 !=0 || length < 16)
+ return 0;
if(file_recovery->file_stat!=NULL &&
file_recovery->file_stat->file_hint==&file_hint_par2)
+ {
+ header_ignored(file_recovery_new);
return 0;
- if(length % 4 !=0 || length < 16)
- return 0;
+ }
reset_file_recovery(file_recovery_new);
file_recovery_new->extension=file_hint_par2.extension;
file_recovery_new->file_rename=&file_rename_par2;
diff --git a/src/file_png.c b/src/file_png.c
index f71f5a2..d61ae1f 100644
--- a/src/file_png.c
+++ b/src/file_png.c
@@ -129,17 +129,20 @@ static void file_check_png(file_recovery_t *fr)
static int header_check_png(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)
{
+ if( !((isupper(buffer[8+4]) || islower(buffer[8+4])) &&
+ (isupper(buffer[8+5]) || islower(buffer[8+5])) &&
+ (isupper(buffer[8+6]) || islower(buffer[8+6])) &&
+ (isupper(buffer[8+7]) || islower(buffer[8+7]))))
+ return 0;
/* SolidWorks files contains a png */
if(file_recovery->file_stat!=NULL &&
file_recovery->file_stat->file_hint==&file_hint_doc &&
(strcmp(file_recovery->extension,"sld")==0 ||
strcmp(file_recovery->extension,"sldprt")==0))
+ {
+ header_ignored(file_recovery_new);
return 0;
- if( !((isupper(buffer[8+4]) || islower(buffer[8+4])) &&
- (isupper(buffer[8+5]) || islower(buffer[8+5])) &&
- (isupper(buffer[8+6]) || islower(buffer[8+6])) &&
- (isupper(buffer[8+7]) || islower(buffer[8+7]))))
- return 0;
+ }
reset_file_recovery(file_recovery_new);
file_recovery_new->extension=file_hint_png.extension;
file_recovery_new->min_filesize=16;
diff --git a/src/file_psf.c b/src/file_psf.c
index 299ac1d..657cbb2 100644
--- a/src/file_psf.c
+++ b/src/file_psf.c
@@ -45,7 +45,10 @@ static int header_check_psf(const unsigned char *buffer, const unsigned int buff
{
if(file_recovery->file_stat!=NULL &&
file_recovery->file_stat->file_hint==&file_hint_psf)
+ {
+ header_ignored(file_recovery_new);
return 0;
+ }
reset_file_recovery(file_recovery_new);
file_recovery_new->extension=file_hint_psf.extension;
file_recovery_new->calculated_file_size=((uint64_t)buffer[28]<<24)+((uint64_t)buffer[29]<<16)+((uint64_t)buffer[30]<<8)+((uint64_t)buffer[31]<<0) + 272;
diff --git a/src/file_tar.c b/src/file_tar.c
index 793a208..53bf921 100644
--- a/src/file_tar.c
+++ b/src/file_tar.c
@@ -67,10 +67,13 @@ struct posix_header
int header_check_tar(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)
{
const struct posix_header *h=(const struct posix_header *)buffer;
- if(file_recovery->file_stat!=NULL && file_recovery->file_stat->file_hint==&file_hint_tar)
- return 0;
if(!isspace(h->chksum[0]) && !((unsigned) (h->chksum[0]) - '0' <= 7))
return 0;
+ if(file_recovery->file_stat!=NULL && file_recovery->file_stat->file_hint==&file_hint_tar)
+ {
+ header_ignored(file_recovery_new);
+ return 0;
+ }
reset_file_recovery(file_recovery_new);
file_recovery_new->extension=file_hint_tar.extension;
file_recovery_new->min_filesize=512;
diff --git a/src/file_tiff.c b/src/file_tiff.c
index f2795bc..8e7805b 100644
--- a/src/file_tiff.c
+++ b/src/file_tiff.c
@@ -345,7 +345,10 @@ static int header_check_tiff_le_new(const unsigned char *buffer, const unsigned
if(file_recovery->file_stat!=NULL &&
file_recovery->file_stat->file_hint==&file_hint_raf &&
memcmp(buffer, raf_fp, 15)==0)
+ {
+ header_ignored(file_recovery_new);
return 0;
+ }
reset_file_recovery(file_recovery_new);
file_recovery_new->extension=file_hint_tiff.extension;
/* Canon RAW */
diff --git a/src/file_wtv.c b/src/file_wtv.c
index e099132..711570e 100644
--- a/src/file_wtv.c
+++ b/src/file_wtv.c
@@ -52,7 +52,10 @@ static int header_check_wtv(const unsigned char *buffer, const unsigned int buff
if(file_recovery->file_stat!=NULL &&
file_recovery->file_stat->file_hint==&file_hint_wtv &&
file_recovery->file_size<=0x3000)
+ {
+ header_ignored(file_recovery_new);
return 0;
+ }
reset_file_recovery(file_recovery_new);
file_recovery_new->extension=file_hint_wtv.extension;
file_recovery_new->calculated_file_size=((uint64_t)le32(*size))<<12;
diff --git a/src/file_zip.c b/src/file_zip.c
index e510013..a831279 100644
--- a/src/file_zip.c
+++ b/src/file_zip.c
@@ -780,13 +780,19 @@ static int header_check_zip(const unsigned char *buffer, const unsigned int buff
(strcmp(file_recovery->extension,"doc")==0 ||
strcmp(file_recovery->extension,"psmodel")==0)
&& memcmp(&buffer[30], "macrolog_1.mac", 14)==0)
+ {
+ header_ignored(file_recovery_new);
return 0;
+ }
/* A zip file begins by ZIP_FILE_ENTRY, this signature can also be
* found for each compressed file */
if(file_recovery->file_stat!=NULL &&
file_recovery->file_stat->file_hint==&file_hint_zip &&
safe_header_only==0)
+ {
+ header_ignored(file_recovery_new);
return 0;
+ }
reset_file_recovery(file_recovery_new);
file_recovery_new->min_filesize=21;
file_recovery_new->file_check=&file_check_zip;
diff --git a/src/filegen.c b/src/filegen.c
index 49f56a3..598abcf 100644
--- a/src/filegen.c
+++ b/src/filegen.c
@@ -582,3 +582,45 @@ int file_rename_unicode(file_recovery_t *file_recovery, const void *buffer, cons
free(new_filename);
return 0;
}
+
+static uint64_t offset_skipped_header=0;
+
+void header_ignored(const file_recovery_t *file_recovery_new)
+{
+ if(file_recovery_new==NULL)
+ {
+ offset_skipped_header=0;
+ return ;
+ }
+ if(file_recovery_new->location.start==0 || offset_skipped_header==0)
+ offset_skipped_header=file_recovery_new->location.start;
+}
+
+void get_prev_location_smart(alloc_data_t *list_search_space, alloc_data_t **current_search_space, uint64_t *offset, const uint64_t prev_location)
+{
+ alloc_data_t *file_space=*current_search_space;
+ uint64_t size=0;
+ int nbr;
+ if(offset_skipped_header==0)
+ return ;
+ offset_skipped_header=0;
+ /* Search backward the first fragment of a file not successfully recovered
+ * Limit the search to 3 fragments or 200 MB */
+ for(nbr=0; nbr<3 && size < (uint64_t)200*1024*1024; nbr++)
+ {
+ file_space=td_list_entry(file_space->list.prev, alloc_data_t, list);
+ if(file_space==list_search_space)
+ return;
+ if(file_space->start <= offset_skipped_header && offset_skipped_header < file_space->end)
+ {
+ *current_search_space=file_space;
+ *offset=offset_skipped_header;
+ return ;
+ }
+ if(file_space->start < prev_location)
+ return ;
+ size+=file_space->end - file_space->start + 1;
+ *current_search_space=file_space;
+ *offset=file_space->start;
+ }
+}
diff --git a/src/filegen.h b/src/filegen.h
index 2b38921..97b3426 100644
--- a/src/filegen.h
+++ b/src/filegen.h
@@ -134,6 +134,7 @@ void register_header_check(const unsigned int offset, const void *value, const u
file_stat_t * init_file_stats(file_enable_t *files_enable);
int file_rename(file_recovery_t *file_recovery, const void *buffer, const int buffer_size, const int offset, const char *new_ext, const int force_ext);
int file_rename_unicode(file_recovery_t *file_recovery, const void *buffer, const int buffer_size, const int offset, const char *new_ext, const int force_ext);
+void header_ignored(const file_recovery_t *file_recovery_new);
#ifdef __cplusplus
} /* closing brace for extern "C" */
diff --git a/src/photorec.h b/src/photorec.h
index 544c689..b69f756 100644
--- a/src/photorec.h
+++ b/src/photorec.h
@@ -65,6 +65,7 @@ struct ph_param
};
void get_prev_location(alloc_data_t *list_search_space, alloc_data_t **current_search_space, uint64_t *offset, const uint64_t prev_location);
+void get_prev_location_smart(alloc_data_t *list_search_space, alloc_data_t **current_search_space, uint64_t *offset, const uint64_t prev_location);
int get_prev_file_header(alloc_data_t *list_search_space, alloc_data_t **current_search_space, uint64_t *offset);
int file_finish_bf(file_recovery_t *file_recovery, struct ph_param *params,
alloc_data_t *list_search_space);
diff --git a/src/psearchn.c b/src/psearchn.c
index 865777f..ef094e5 100644
--- a/src/psearchn.c
+++ b/src/psearchn.c
@@ -251,6 +251,7 @@ pstatus_t photorec_aux(struct ph_param *params, const struct ph_options *options
(unsigned long long)((params->partition->part_size-1)/params->disk->sector_size));
}
params->disk->pread(params->disk, buffer, READ_SIZE, offset);
+ header_ignored(NULL);
while(current_search_space!=list_search_space)
{
pfstatus_t file_recovered=PFSTATUS_BAD;
@@ -368,7 +369,7 @@ pstatus_t photorec_aux(struct ph_param *params, const struct ph_options *options
else
{
back=0;
- get_prev_location(list_search_space, &current_search_space, &offset, file_recovery.location.start);
+ get_prev_location_smart(list_search_space, &current_search_space, &offset, file_recovery.location.start);
}
}
if(current_search_space==list_search_space)