static int header_check_amr(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(memcmp(buffer,amr_header,sizeof(amr_header))==0) { reset_file_recovery(file_recovery_new); #if 0 file_recovery_new->calculated_file_size=6; file_recovery_new->data_check=&data_check_amr; file_recovery_new->file_check=&file_check_size; #endif file_recovery_new->extension=file_hint_amr.extension; return 1; } return 0; }
static int header_check_vmdk3(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 VMDK3Header *hdr=(const VMDK3Header *)buffer; const unsigned int cluster_sectors = le32(hdr->granularity); if(cluster_sectors==0) return 0; reset_file_recovery(file_recovery_new); #ifdef DJGPP file_recovery_new->extension="vmd"; #else file_recovery_new->extension=file_hint_vmdk.extension; #endif file_recovery_new->min_filesize=512; return 1; }
static int header_check_dbx(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 size=(uint64_t)buffer[DBX_SIZE_POINTER] + (((uint64_t)buffer[DBX_SIZE_POINTER+1])<<8) + (((uint64_t)buffer[DBX_SIZE_POINTER+2])<<16) + (((uint64_t)buffer[DBX_SIZE_POINTER+3])<<24); if(size < DBX_SIZE_POINTER + 4) return 0; reset_file_recovery(file_recovery_new); file_recovery_new->extension="dbx"; file_recovery_new->calculated_file_size=size; file_recovery_new->data_check=&data_check_size; file_recovery_new->file_check=&file_check_size; return 1; }
static int header_check_reg_9x(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 creg_file_header*header=(const struct creg_file_header*)buffer; if(le32(header->rgdb_offset)+4 > buffer_size) return 0; { const struct rgdb_block*block=(const struct rgdb_block*)(buffer+le32(header->rgdb_offset)); if(memcmp(block,"RGDB",4)!=0) return 0; reset_file_recovery(file_recovery_new); file_recovery_new->min_filesize=0x1000; file_recovery_new->extension=file_hint_reg.extension; return 1; } }
static int header_check_psd(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(memcmp(buffer,psd_header,sizeof(psd_header))==0) { reset_file_recovery(file_recovery_new); file_recovery_new->min_filesize=70; file_recovery_new->extension=file_hint_psd.extension; /* File header */ file_recovery_new->calculated_file_size=0x1a; file_recovery_new->data_check=&psd_skip_color_mode; file_recovery_new->file_check=&file_check_psd; return 1; } return 0; }
static int header_check_a(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) { static const unsigned char a_header_debian[14] = { '!','<','a','r','c','h','>','\n','d','e','b','i','a','n'}; static const char magic[2]= { 0x60, 0x0a}; const struct file_header *fh=(const struct file_header *)&buffer[8]; if(memcmp(fh->magic, magic, 2)!=0) return 0; /* http://en.wikipedia.org/wiki/Ar_%28Unix%29 */ reset_file_recovery(file_recovery_new); if(memcmp(buffer,a_header_debian,sizeof(a_header_debian))==0) file_recovery_new->extension="deb"; else file_recovery_new->extension=file_hint_a.extension; return 1; }
static int header_check_ldf(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[0x00]==0x01 && buffer[0x01]==0x0f && buffer[0x02]==0x00 && buffer[0x03]==0x00 && buffer[0x08]==0x00 && buffer[0x09]==0x00 && buffer[0x0a]==0x00 && buffer[0x0b]==0x00 && buffer[0x0c]==0x00 && buffer[0x0d]==0x00 && buffer[0x0e]==0x00 && buffer[0x0f]==0x00 && buffer[0x10]==0x00 && buffer[0x11]==0x00 && buffer[0x12]==0x00 && buffer[0x13]==0x00 && buffer[0x14]==0x00 && buffer[0x15]==0x00 && buffer[0x16]==0x02 && buffer[0x17]==0x00 && buffer[0x18]==0x63 && buffer[0x19]==0x00 && buffer[0x1A]==0x00 && buffer[0x1B]==0x00) { reset_file_recovery(file_recovery_new); file_recovery_new->extension=file_hint_ldf.extension; return 1; } return 0; }
static int header_check_dxf(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(memcmp(buffer, header_dxf, sizeof(header_dxf))==0 || memcmp(buffer, header_dxf_dos, sizeof(header_dxf_dos))==0 || memcmp(buffer, header_dxflib, sizeof(header_dxflib))==0 || memcmp(buffer, header_dxflib_dos, sizeof(header_dxflib_dos))==0) { reset_file_recovery(file_recovery_new); file_recovery_new->extension=file_hint_dxf.extension; file_recovery_new->data_check=&data_check_dxf; file_recovery_new->file_check=&file_check_dxf; return 1; } return 0; }
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) { /* SolidWorks files contains a png */ if(file_recovery!=NULL && 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)) return 0; reset_file_recovery(file_recovery_new); file_recovery_new->extension=file_hint_png.extension; file_recovery_new->calculated_file_size=8; file_recovery_new->data_check=&data_check_png; file_recovery_new->file_check=&file_check_size; return 1; }
static int header_check_le16_txt(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; for(i=0; i+1 < buffer_size; i+=2) { if(!( buffer[i+1]=='\0' && (isprint(buffer[i]) || buffer[i]=='\n' || buffer[i]=='\r' || buffer[i]==0xbb))) { if(i<40) return 0; reset_file_recovery(file_recovery_new); file_recovery_new->calculated_file_size=i; file_recovery_new->data_check=&data_check_size; file_recovery_new->file_check=&file_check_size; file_recovery_new->extension="utf16"; return 1; } } reset_file_recovery(file_recovery_new); file_recovery_new->calculated_file_size=i; file_recovery_new->data_check=&data_check_size; file_recovery_new->file_check=&file_check_size; file_recovery_new->extension="utf16"; return 1; }
static int header_check_fit(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 fits_header* h = (const struct fits_header *)buffer; if (h->header_size < 12) return 0; reset_file_recovery(file_recovery_new); file_recovery_new->extension = file_hint_fit.extension; file_recovery_new->min_filesize = 12; file_recovery_new->calculated_file_size=(uint64_t)le32(h->data_size) + h->header_size; if(h->header_size >= 14) file_recovery_new->calculated_file_size+=2; /* CRC at the end of the file */ file_recovery_new->data_check=&data_check_size; file_recovery_new->file_check=&file_check_size; return 1; }
static int header_check_rx2(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(memcmp(&buffer[0], rx2_header, sizeof(rx2_header))==0 && memcmp(&buffer[8], "REX2HEAD", 8)==0) { const struct rx2_header *rx2=(const struct rx2_header *)buffer; reset_file_recovery(file_recovery_new); file_recovery_new->extension=file_hint_rx2.extension; file_recovery_new->calculated_file_size=(uint64_t)be32(rx2->size)+8; file_recovery_new->data_check=&data_check_size; file_recovery_new->file_check=&file_check_size; return 1; } return 0; }
static int header_check_xmp(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[35]=='\0') return 0; if(file_recovery->file_stat!=NULL && (file_recovery->file_stat->file_hint==&file_hint_pdf || file_recovery->file_stat->file_hint==&file_hint_tiff)) return 0; /* Adobe's Extensible Metadata Platform */ reset_file_recovery(file_recovery_new); file_recovery_new->data_check=&data_check_txt; file_recovery_new->file_check=&file_check_size; file_recovery_new->extension="xmp"; return 1; }
static int header_check_xfs_inode(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 xfs_dinode_core_t *inode=(const xfs_dinode_core_t *)buffer; if(safe_header_only>0) return 0; if(inode->di_version!=2 || inode->di_pad[0]!=0 || inode->di_pad[1]!=0 || inode->di_pad[2]!=0 || inode->di_pad[3]!=0 || inode->di_pad[4]!=0 || inode->di_pad[5]!=0 || inode->di_pad[6]!=0 || inode->di_pad[7]!=0) return 0; reset_file_recovery(file_recovery_new); file_recovery_new->extension=file_hint_xfs.extension; file_recovery_new->data_check=&data_check_stopasap; return 1; }
static int header_check_aif(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 aif_header *hdr=(const struct aif_header *)buffer; if(be32(hdr->ckSize)<4) return 0; if(buffer[8]=='A' && buffer[9]=='I' && buffer[10]=='F' && (buffer[11]=='F' || buffer[11]=='C')) { reset_file_recovery(file_recovery_new); file_recovery_new->extension=file_hint_aif.extension; file_recovery_new->calculated_file_size=be32(hdr->ckSize)+8; file_recovery_new->data_check=&data_check_size; file_recovery_new->file_check=&file_check_size; return 1; } return 0; }
static int header_check_wv(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 WavpackHeader *wv=(const WavpackHeader*)buffer; if(le32(wv->block_index)!=0) return 0; if(sizeof(WavpackHeader) > le32(wv->ckSize)+8) return 0; reset_file_recovery(file_recovery_new); file_recovery_new->extension=file_hint_wv.extension; file_recovery_new->min_filesize=le32(wv->ckSize)+8; if(file_recovery_new->blocksize < 8) return 1; file_recovery_new->data_check=&data_check_wv; file_recovery_new->file_check=&file_check_size; return 1; }
static int header_check_bac(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 block_header *hdr=(const struct block_header *)buffer; if(be32(hdr->BlockSize) < 0x18) return 0; reset_file_recovery(file_recovery_new); file_recovery_new->extension=file_hint_bac.extension; file_recovery_new->min_filesize=be32(hdr->BlockSize); file_recovery_new->calculated_file_size=0; if(file_recovery_new->blocksize >= 0x18) { file_recovery_new->data_check=&data_check_bac; file_recovery_new->file_check=&file_check_size; } return 1; }
static int header_check_dex(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 dex_header *dex=(const struct dex_header*)buffer; if(!isdigit(buffer[4]) || !isdigit(buffer[5]) || !isdigit(buffer[6]) || buffer[7]!=0x00) return 0; if(le32(dex->header_size) < 0x28) return 0; if(le32(dex->header_size) >= le32(dex->file_size)) return 0; reset_file_recovery(file_recovery_new); file_recovery_new->extension=file_hint_dex.extension; file_recovery_new->calculated_file_size=le32(dex->file_size); file_recovery_new->data_check=&data_check_size; file_recovery_new->file_check=&file_check_size; return 1; }
static int header_check_flv(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 flv_header *flv=(const struct flv_header *)buffer; if((flv->type_flags & 0xfa)==0 && be32(flv->data_offset)>=9) { reset_file_recovery(file_recovery_new); file_recovery_new->extension=file_hint_flv.extension; if(file_recovery_new->blocksize < 15) return 1; file_recovery_new->calculated_file_size=be32(flv->data_offset); file_recovery_new->data_check=&data_check_flv; file_recovery_new->file_check=&file_check_size; return 1; } return 0; }
static int header_check_tiff_le_new(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 char raf_fp[15]={0x49, 0x49, 0x2a, 0x00, 0x08, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xf0, 0x0d, 0x00, 0x01}; const char *potential_error=NULL; const TIFFHeader *header=(const TIFFHeader *)buffer; if((uint32_t)le32(header->tiff_diroff) < sizeof(TIFFHeader)) return 0; /* Avoid a false positiv with some RAF files */ 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; } if(file_recovery->file_stat!=NULL && file_recovery->file_stat->file_hint==&file_hint_jpg) { header_ignored(file_recovery_new); return 0; } reset_file_recovery(file_recovery_new); file_recovery_new->extension=file_hint_tiff.extension; /* Canon RAW */ if(buffer[8]=='C' && buffer[9]=='R' && buffer[10]==2) file_recovery_new->extension="cr2"; else if(find_tag_from_tiff_header_le(header, buffer_size, TIFFTAG_DNGVERSION, &potential_error)!=NULL) { /* Adobe Digital Negative, ie. NIKON D50 */ file_recovery_new->extension="dng"; } else { const char *tag_make; tag_make=find_tag_from_tiff_header_le(header, buffer_size, TIFFTAG_MAKE, &potential_error); if(tag_make!=NULL && tag_make >= (const char *)buffer && tag_make < (const char *)buffer + buffer_size - 20) { if(strcmp(tag_make, "SONY")==0) file_recovery_new->extension="sr2"; else if(strncmp(tag_make, "SONY ",5)==0) file_recovery_new->extension="arw"; } } file_recovery_new->time=get_date_from_tiff_header(header, buffer_size); file_recovery_new->file_check=&file_check_tiff; return 1; }
static int header_check_mng(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; reset_file_recovery(file_recovery_new); file_recovery_new->extension="mng"; file_recovery_new->min_filesize=16; if(file_recovery_new->blocksize < 8) return 1; file_recovery_new->calculated_file_size=8; file_recovery_new->data_check=&data_check_mng; file_recovery_new->file_check=&file_check_size; return 1; }
static int header_check_dbf(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) { /* 0x03 YY MM DD reserved=0 */ if(buffer[0]==0x3 && ((buffer[1]>80 && buffer[1]<120) || buffer[1]<20) && (buffer[2]>=1 && buffer[2]<=12) && (buffer[3]>=1 && buffer[3]<=31) && buffer[12]==0 && buffer[13]==0 && buffer[14]==0 && buffer[15]==0 && buffer[16]==0 && buffer[17]==0 && buffer[18]==0 && buffer[19]==0 && buffer[20]==0 && buffer[21]==0 && buffer[22]==0 && buffer[23]==0 && buffer[24]==0 && buffer[25]==0 && buffer[26]==0 && buffer[27]==0 && buffer[30]==0 && buffer[31]==0) { reset_file_recovery(file_recovery_new); file_recovery_new->extension=file_hint_dbf.extension; return 1; } return 0; }
static int header_check_vmdk4(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 VMDK4Header *hdr=(const VMDK4Header *)buffer; const unsigned int cluster_sectors = le64(hdr->granularity); const unsigned int l2_size = le32(hdr->num_gtes_per_gte); const uint32_t l1_entry_sectors = l2_size * cluster_sectors; if (l1_entry_sectors <= 0) return 0; reset_file_recovery(file_recovery_new); #ifdef DJGPP file_recovery_new->extension="vmd"; #else file_recovery_new->extension=file_hint_vmdk.extension; #endif file_recovery_new->min_filesize=512; return 1; }
static int header_check_rtf(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; for(i=0; i<16; i++) if(buffer[i]=='\0') return 0; /* Avoid a false positive with .snt */ if(file_recovery->file_stat!=NULL && file_recovery->file_stat->file_hint==&file_hint_doc) return 0; reset_file_recovery(file_recovery_new); file_recovery_new->data_check=&data_check_txt; file_recovery_new->file_check=&file_check_size; /* Rich Text Format */ file_recovery_new->extension="rtf"; return 1; }
static int header_check_cdt(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(memcmp(&buffer[12], cdt_header, sizeof(cdt_header))==0) { reset_file_recovery(file_recovery_new); if(buffer[0]==0xee) file_recovery_new->extension="cdl"; /* ConceptDraw PRO Library File */ else if(buffer[0]==0xef) file_recovery_new->extension="cdd"; /* ConceptDraw PRO Document */ else if(buffer[0]==0xf0) file_recovery_new->extension="cdt"; /* ConceptDraw PRO Template */ else file_recovery_new->extension=file_hint_cdt.extension; return 1; } return 0; }
static int header_check_7z(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(memcmp(buffer, header_7z, sizeof(header_7z))==0) { const struct header_7z *buffer_7z=(const struct header_7z *)buffer; reset_file_recovery(file_recovery_new); file_recovery_new->extension=file_hint_7z.extension; file_recovery_new->min_filesize=31; /* Signature size 12 + Start header size 20 */ file_recovery_new->calculated_file_size=(uint64_t)le64(buffer_7z->nextHeaderOffset)+ le64(buffer_7z->nextHeaderSize) + 12 + 20; file_recovery_new->data_check=&data_check_size; file_recovery_new->file_check=&file_check_size; return 1; } return 0; }
static int header_check_flac(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 uint32_t *p32=(const uint32_t *)&buffer[4]; const uint32_t size=be32(*p32)&0x00ffffff; reset_file_recovery(file_recovery_new); #ifdef DJGPP file_recovery_new->extension="flc"; #else file_recovery_new->extension=file_hint_flac.extension; #endif file_recovery_new->min_filesize=4+size; #if 0 file_recovery_new->calculated_file_size=4; file_recovery_new->data_check=&data_check_flac_metadata; #endif return 1; }
static int header_check_fs(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 transaction_header *hdr=(const struct transaction_header *)&buffer[4]; const uint64_t len=be64(hdr->len); if(len < sizeof(struct transaction_header)-8) return 0; if(hdr->status!=' ' && hdr->status!='p' && hdr->status!='c' && hdr->status!='u') return 0; reset_file_recovery(file_recovery_new); file_recovery_new->extension=file_hint_fs.extension; if(file_recovery_new->blocksize < 0x11) return 1; file_recovery_new->data_check=&data_check_fs; file_recovery_new->file_check=&file_check_size; file_recovery_new->calculated_file_size=4; return 1; }
static int header_check_evt(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 evt_chunk *chunk=(const struct evt_chunk *)buffer; const struct evt_chunk *chunk2=(const struct evt_chunk *)&buffer[le32(chunk->size)]; if(le32(chunk->size) != 0x30) return 0; if(le32(chunk2->size) < 8) return 0; reset_file_recovery(file_recovery_new); file_recovery_new->extension=file_hint_evt.extension; if(file_recovery_new->blocksize >= 8) { file_recovery_new->calculated_file_size=le32(chunk->size); file_recovery_new->data_check=&data_check_evt; file_recovery_new->file_check=&file_check_size; } return 1; }
static int header_check_fob(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) { static const unsigned char sign_navnl[5] = {'N','A','V','N','L'}; static const unsigned char sign_navw[4] = {'N','A','V','W'}; unsigned int tmp=0; const unsigned char *pos1=(const unsigned char *)td_memmem(buffer, buffer_size, sign_navnl, sizeof(sign_navnl)); const unsigned char *pos2=(const unsigned char *)td_memmem(buffer, buffer_size, sign_navw, sizeof(sign_navw)); if(pos1==NULL && pos2==NULL) return 0; if(pos1!=NULL) tmp=pos1-buffer; if(pos2!=NULL && pos2-buffer > tmp) tmp=pos2-buffer; reset_file_recovery(file_recovery_new); file_recovery_new->extension=file_hint_fob.extension; file_recovery_new->min_filesize=tmp; return 1; }