/* Primary superblock is at 0x8000 */ int recover_JFS(disk_t *disk_car, const struct jfs_superblock *sb,partition_t *partition,const int verbose, const int dump_ind) { if(test_JFS(disk_car, sb, partition, dump_ind)!=0) return 1; set_JFS_info(sb, partition); partition->part_type_i386=P_LINUX; partition->part_type_sun=PSUN_LINUX; partition->part_type_mac=PMAC_LINUX; partition->part_type_gpt=GPT_ENT_TYPE_LINUX_DATA; partition->part_size=(uint64_t)le32(sb->s_pbsize) * le64(sb->s_size) + le32(sb->s_bsize) * (le24(sb->s_fsckpxd.len)+le24(sb->s_logpxd.len)); partition->sborg_offset=64*512; partition->sb_size=JFS_SUPERBLOCK_SIZE; partition->sb_offset=0; guid_cpy(&partition->part_uuid, (const efi_guid_t *)&sb->s_uuid); if(verbose>0) { log_info("\n"); log_info("recover_JFS: s_blocksize=%u\n",partition->blocksize); log_info("recover_JFS: s_size %lu\n",(long unsigned int)le64(sb->s_size)); log_info("recover_JFS: s_fsckpxd.len:%d\n", (int)le24(sb->s_fsckpxd.len)); log_info("recover_JFS: s_logpxd.len:%d\n", (int)le24(sb->s_logpxd.len)); log_info("recover_JFS: part_size %lu\n",(long unsigned)(partition->part_size/disk_car->sector_size)); } return 0; }
int recover_EXFAT(const disk_t *disk, const struct exfat_super_block *exfat_header, partition_t *partition) { if(test_EXFAT(exfat_header)!=0) return 1; partition->sborg_offset=0; partition->sb_size=12 << exfat_header->blocksize_bits; partition->part_type_i386=P_EXFAT; partition->part_type_gpt=GPT_ENT_TYPE_MS_BASIC_DATA; partition->part_size=(uint64_t)le64(exfat_header->nr_sectors) * disk->sector_size; #ifdef DEBUG_EXFAT log_info("recover_EXFAT:\n"); log_info("start_sector=%llu\n", (long long unsigned)le64(exfat_header->start_sector)); log_info("blocksize=%u\n", (12<<exfat_header->blocksize_bits)); log_info("part_offset=%llu\n", partition->part_offset); #endif if((le64(exfat_header->start_sector) * disk ->sector_size + (12 << exfat_header->blocksize_bits) == partition->part_offset) || (disk->arch==&arch_none && (12 << exfat_header->blocksize_bits) == partition->part_offset)) { partition->sb_offset=12 << exfat_header->blocksize_bits; partition->part_offset-=partition->sb_offset; } set_EXFAT_info(partition, exfat_header); return 0; }
static int header_check_indd(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 InDesignMasterPage *hdr; 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(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) { if(header_ignored_adv(file_recovery, file_recovery_new)==0) return 0; } reset_file_recovery(file_recovery_new); #ifdef DJGPP file_recovery_new->extension="ind"; #else file_recovery_new->extension=file_hint_indd.extension; #endif /* Contiguous object pages may follow, file_check_indd will search for them */ file_recovery_new->calculated_file_size=(uint64_t)(le32(hdr->fFilePages))*4096; file_recovery_new->file_check=&file_check_indd; #ifdef DEBUG_INDD log_info("header_check_indd: Guessed length: %llu.\n", (long long unsigned)file_recovery_new->calculated_file_size); #endif return 1; }
static int header_check_elf(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 Elf32_Ehdr *hdr32=(const Elf32_Ehdr *)buffer; if(hdr32->e_ident[EI_DATA]!=ELFDATA2LSB && hdr32->e_ident[EI_DATA]!=ELFDATA2MSB) return 0; if((hdr32->e_ident[EI_DATA]==ELFDATA2LSB ? le32(hdr32->e_version) : be32(hdr32->e_version)) != 1) return 0; /* http://en.wikipedia.org/wiki/Executable_and_Linkable_Format */ reset_file_recovery(file_recovery_new); file_recovery_new->extension=file_hint_elf.extension; if(hdr32->e_ident[EI_CLASS]==ELFCLASS32) { const uint32_t tmp=(hdr32->e_ident[EI_DATA]==ELFDATA2LSB ? le32(hdr32->e_shoff) : be32(hdr32->e_shoff)); file_recovery_new->min_filesize=(hdr32->e_ident[EI_DATA]==ELFDATA2LSB ? le32(hdr32->e_phoff) : be32(hdr32->e_phoff)); if(file_recovery_new->min_filesize < tmp) file_recovery_new->min_filesize=tmp; } else { const Elf64_Ehdr *hdr64=(const Elf64_Ehdr *)buffer; const uint64_t tmp=(hdr64->e_ident[EI_DATA]==ELFDATA2LSB ? le64(hdr64->e_shoff) : be64(hdr64->e_shoff)); file_recovery_new->min_filesize=(hdr64->e_ident[EI_DATA]==ELFDATA2LSB ? le64(hdr64->e_phoff) : be64(hdr64->e_phoff)); if(file_recovery_new->min_filesize < tmp) file_recovery_new->min_filesize=tmp; } return 1; }
int PartitionHandle::CheckGPT(int PartNum) { GPT_HEADER *gpt_header = (GPT_HEADER *) malloc(MAX_SECTOR_SIZE); if(!gpt_header) return -1; // Read and validate the extended boot record if (!interface->readSectors(1, 1, gpt_header)) { free(gpt_header); return -1; } if(strncmp(gpt_header->magic, "EFI PART", 8) != 0) { free(gpt_header); return -1; } gpt_header->part_table_lba = le64(gpt_header->part_table_lba); gpt_header->part_entries = le32(gpt_header->part_entries); gpt_header->part_entry_size = le32(gpt_header->part_entry_size); gpt_header->part_entry_checksum = le32(gpt_header->part_entry_checksum); u8 * sector_buf = (u8 *) malloc(MAX_SECTOR_SIZE); if(!sector_buf) { free(gpt_header); return -1; } u64 next_lba = gpt_header->part_table_lba; for(u32 i = 0; i < gpt_header->part_entries; ++i) { if (!interface->readSectors(next_lba, 1, sector_buf)) break; for(u32 n = 0; n < sectorSize/gpt_header->part_entry_size; ++n, ++i) { GUID_PART_ENTRY * part_entry = (GUID_PART_ENTRY *) (sector_buf+gpt_header->part_entry_size*n); if(memcmp(part_entry->part_type_guid, TYPE_UNUSED, 16) == 0) continue; bool bootable = (memcmp(part_entry->part_type_guid, TYPE_BIOS, 16) == 0); AddPartition("GUID-Entry", le64(part_entry->part_first_lba), le64(part_entry->part_last_lba), bootable, PARTITION_TYPE_GPT, PartNum); } next_lba++; } free(sector_buf); free(gpt_header); return 0; }
dir_partition_t dir_partition_exfat_init(disk_t *disk, const partition_t *partition, dir_data_t *dir_data, const int verbose) { static struct exfat_dir_struct *ls; struct exfat_super_block *exfat_header; set_secwest(); /* Load boot sector */ exfat_header=(struct exfat_super_block *)MALLOC(0x200); if(disk->pread(disk, exfat_header, 0x200, partition->part_offset) != 0x200) { log_error("Can't read exFAT boot sector.\n"); free(exfat_header); return DIR_PART_EIO; } if(le16(exfat_header->signature)!=0xAA55 || memcmp(exfat_header->oem_id, "EXFAT ", sizeof(exfat_header->oem_id))!=0) { log_error("Not an exFAT boot sector.\n"); free(exfat_header); return DIR_PART_EIO; } ls=(struct exfat_dir_struct *)MALLOC(sizeof(*ls)); ls->boot_sector=exfat_header; #ifdef HAVE_ICONV if ((ls->cd = iconv_open("UTF-8", "UTF-16LE")) == (iconv_t)(-1)) { log_error("dir_partition_exfat_init: iconv_open failed\n"); } #endif #ifdef DEBUG_EXFAT log_info("start_sector=%llu\n", (long long unsigned)le64(exfat_header->start_sector)); log_info("nr_sectors =%llu\n", (long long unsigned)le64(exfat_header->nr_sectors)); log_info("fat_blocknr =%u\n",le32(exfat_header->fat_blocknr)); log_info("fat_block_counts=%u\n", le32(exfat_header->fat_block_counts)); log_info("clus_blocknr=%u\n", le32(exfat_header->clus_blocknr)); log_info("total_clusters=%u\n", le32(exfat_header->total_clusters)); log_info("rootdir_clusnr=%u\n", le32(exfat_header->rootdir_clusnr)); log_info("serial_number=0x%08x\n", le32(exfat_header->serial_number)); log_info("state=0x%x\n", le16(exfat_header->state)); log_info("blocksize_bits=%u\n", exfat_header->blocksize_bits); log_info("block_per_clus_bits=%u\n", exfat_header->block_per_clus_bits); log_info("number_of_fats=%u\n", exfat_header->number_of_fats); log_info("drive_select=0x%x\n", exfat_header->drive_select); log_info("allocated_percent=%u\n", exfat_header->allocated_percent); #endif strncpy(dir_data->current_directory,"/",sizeof(dir_data->current_directory)); dir_data->current_inode=0; dir_data->param=FLAG_LIST_DELETED; dir_data->verbose=verbose; dir_data->capabilities=CAPA_LIST_DELETED; dir_data->copy_file=exfat_copy; dir_data->close=dir_partition_exfat_close; dir_data->local_dir=NULL; dir_data->private_dir_data=ls; dir_data->get_dir=exfat_dir; return DIR_PART_OK; }
static void partition_generate_gpt_entry(struct gpt_ent* gpt_entry, const partition_t *partition, const disk_t *disk_car) { guid_cpy(&gpt_entry->ent_type, &partition->part_type_gpt); gpt_entry->ent_lba_start=le64(partition->part_offset / disk_car->sector_size); gpt_entry->ent_lba_end=le64((partition->part_offset + partition->part_size - 1) / disk_car->sector_size); str2UCSle((uint16_t *)&gpt_entry->ent_name, partition->partname, sizeof(gpt_entry->ent_name)/2); if(guid_cmp(partition->part_uuid, GPT_ENT_TYPE_UNUSED)!=0) guid_cpy(&gpt_entry->ent_uuid, &partition->part_uuid); else efi_generate_uuid(&gpt_entry->ent_uuid); gpt_entry->ent_attr=le64(0); /* May need fixing */ }
int recover_rfs(disk_t *disk_car, const struct reiserfs_super_block *sb,partition_t *partition,const int verbose, const int dump_ind) { const struct reiser4_master_sb *sb4=(const struct reiser4_master_sb *)sb; if(test_rfs(disk_car, sb, partition, verbose)==0) { if(verbose>0 || dump_ind!=0) { log_info("\nrecover_rfs\n"); log_info("block_count=%u\n",(unsigned int)le32(sb->s_block_count)); log_info("block_size=%u\n",le16(sb->s_blocksize)); if(dump_ind!=0) { dump_log(sb,DEFAULT_SECTOR_SIZE); } } partition->part_size = (uint64_t)le32(sb->s_block_count) * le16(sb->s_blocksize); partition->part_type_i386 = P_LINUX; partition->part_type_mac= PMAC_LINUX; partition->part_type_sun= PSUN_LINUX; partition->part_type_gpt=GPT_ENT_TYPE_LINUX_DATA; guid_cpy(&partition->part_uuid, (const efi_guid_t *)&sb->s_uuid); set_rfs_info(sb, partition); return 0; } if(test_rfs4(disk_car, sb4, partition, verbose)==0) { const struct format40_super *fmt40_super=(const struct format40_super *)((const char*)sb4+le16(sb4->blocksize)); if(verbose>0 || dump_ind!=0) { log_info("\nrecover_rfs\n"); log_info("block_count=%lu\n",(unsigned long int)le64(fmt40_super->sb_block_count)); log_info("block_size=%u\n",le16(sb4->blocksize)); if(dump_ind!=0) { dump_log(sb,DEFAULT_SECTOR_SIZE); } } partition->part_size = (uint64_t)le64(fmt40_super->sb_block_count) * le16(sb4->blocksize); partition->part_type_i386 = P_LINUX; partition->part_type_mac= PMAC_LINUX; partition->part_type_sun= PSUN_LINUX; partition->part_type_gpt=GPT_ENT_TYPE_LINUX_DATA; guid_cpy(&partition->part_uuid, (const efi_guid_t *)&sb4->uuid); set_rfs4_info(sb4, partition); return 0; } return 1; }
int recover_MD_from_partition(disk_t *disk_car, partition_t *partition, const int verbose) { unsigned char *buffer=(unsigned char*)MALLOC(MD_SB_BYTES); /* MD version 0.90 */ { uint64_t offset=MD_NEW_SIZE_SECTORS(partition->part_size/512)*512; if(disk_car->pread(disk_car, buffer, MD_SB_BYTES, partition->part_offset + offset) == MD_SB_BYTES) { if(recover_MD(disk_car,(struct mdp_superblock_s*)buffer,partition,verbose,0)==0) { free(buffer); return 0; } } } /* MD version 1.0 */ if(partition->part_size > 8*2*512) { uint64_t offset=(((partition->part_size/512)-8*2) & ~(4*2-1))*512; if(disk_car->pread(disk_car, buffer, MD_SB_BYTES, partition->part_offset + offset) == MD_SB_BYTES) { const struct mdp_superblock_1 *sb1=(const struct mdp_superblock_1 *)buffer; if(le32(sb1->major_version)==1 && recover_MD(disk_car,(struct mdp_superblock_s*)buffer,partition,verbose,0)==0) { partition->part_offset-=le64(sb1->super_offset)*512-offset; free(buffer); return 0; } } } /* md 1.1 & 1.2 don't need special operation to be recovered */ free(buffer); return 1; }
static void file_check_axx(file_recovery_t *fr) { uint64_t offset=0x10; while(1) { struct SHeader header; unsigned int len; if(my_fseek(fr->handle, offset, SEEK_SET) < 0) return ; if (fread(&header, sizeof(header), 1, fr->handle)!=1) return ; len=le32(header.aoLength); #ifdef DEBUG_AAX log_info("axx 0x%llx 0x%x 0x%x/%d\n", (long long int)offset, len, header.oType, header.oType); #endif if(len<5) return ; offset+=len; if(header.oType==63) // eData { uint64_t fsize; if(len!=13) return ; if (fread(&fsize, sizeof(fsize), 1, fr->handle)!=1) return ; fsize=le64(fsize); offset+=fsize; fr->file_size=(fr->file_size < offset ? 0 : offset); return ; } } }
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 void search_add_hints(const disk_t *disk, uint64_t *try_offset, unsigned int *try_offset_nbr) { if(disk->arch==&arch_i386) { /* sometimes users choose Intel instead of GPT */ hint_insert(try_offset, 2*disk->sector_size+16384, try_offset_nbr); /* sometimes users don't choose Vista by mistake */ hint_insert(try_offset, 2048*512, try_offset_nbr); /* try to deal with incorrect geometry */ /* 0/1/1 */ hint_insert(try_offset, 32 * disk->sector_size, try_offset_nbr); hint_insert(try_offset, 63 * disk->sector_size, try_offset_nbr); /* 1/[01]/1 CHS x 16 63 */ hint_insert(try_offset, 16 * 63 * disk->sector_size, try_offset_nbr); hint_insert(try_offset, 17 * 63 * disk->sector_size, try_offset_nbr); hint_insert(try_offset, 16 * disk->geom.sectors_per_head * disk->sector_size, try_offset_nbr); hint_insert(try_offset, 17 * disk->geom.sectors_per_head * disk->sector_size, try_offset_nbr); /* 1/[01]/1 CHS x 240 63 */ hint_insert(try_offset, 240 * 63 * disk->sector_size, try_offset_nbr); hint_insert(try_offset, 241 * 63 * disk->sector_size, try_offset_nbr); hint_insert(try_offset, 240 * disk->geom.sectors_per_head * disk->sector_size, try_offset_nbr); hint_insert(try_offset, 241 * disk->geom.sectors_per_head * disk->sector_size, try_offset_nbr); /* 1/[01]/1 CHS x 255 63 */ hint_insert(try_offset, 255 * 63 * disk->sector_size, try_offset_nbr); hint_insert(try_offset, 256 * 63 * disk->sector_size, try_offset_nbr); hint_insert(try_offset, 255 * disk->geom.sectors_per_head * disk->sector_size, try_offset_nbr); hint_insert(try_offset, 256 * disk->geom.sectors_per_head * disk->sector_size, try_offset_nbr); /* Hints for NTFS backup */ if(disk->geom.cylinders>1) { CHS_t start; start.cylinder=disk->geom.cylinders-1; start.head=disk->geom.heads_per_cylinder-1; start.sector=disk->geom.sectors_per_head; hint_insert(try_offset, CHS2offset_inline(disk, &start), try_offset_nbr); if(disk->geom.cylinders>2) { start.cylinder--; hint_insert(try_offset, CHS2offset_inline(disk, &start), try_offset_nbr); } } hint_insert(try_offset, (disk->disk_size-disk->sector_size)/(2048*512)*(2048*512)-disk->sector_size, try_offset_nbr); } else if(disk->arch==&arch_gpt) { /* Hint for NTFS backup */ const unsigned int gpt_entries_size=128*sizeof(struct gpt_ent); const uint64_t hdr_lba_end=le64((disk->disk_size-1 - gpt_entries_size)/disk->sector_size - 1); const uint64_t ntfs_backup_offset=(hdr_lba_end-1)*disk->sector_size/(2048*512)*(2048*512)-disk->sector_size; hint_insert(try_offset, ntfs_backup_offset, try_offset_nbr); } else if(disk->arch==&arch_mac) { /* sometime users choose Mac instead of GPT for i386 Mac */ hint_insert(try_offset, 2*disk->sector_size+16384, try_offset_nbr); } }
int recover_BeFS(disk_t *disk_car, const struct disk_super_block *beos_block, partition_t *partition, const int dump_ind) { if(test_BeFS(disk_car,beos_block,partition,dump_ind)!=0) return 1; set_BeFS_info(beos_block, partition); partition->part_size=le64(beos_block->num_blocks) << le32(beos_block->block_shift); partition->part_type_i386=(unsigned char)P_BEOS; return 0; }
static int header_check_reg_nt(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 regf_file_header *header=(const struct regf_file_header*)buffer; if(le32(header->file_type) > 1) return 0; reset_file_recovery(file_recovery_new); file_recovery_new->min_filesize=0x1000; file_recovery_new->extension=file_hint_reg.extension; file_recovery_new->time=td_ntfs2utc(le64(header->modification_time)); return 1; }
void app_info64(u64 offset){ u64 authid = le64(self+offset); /* auth id */ offset += sizeof(u64); u32 vendor_id = le32(self+offset); /* vendor id */ offset += sizeof(u32); u32 self_type = le32(self+offset); /* app type */ offset += sizeof(u32); u64 version = le64(self+offset); /* app version */ offset += sizeof(u64); u64 padding = le64(self+offset); /* UNKNOWN */ offset += sizeof(u64); printf("--- APP INFO64 ---\n"); printf("Authotiry ID 0x%08x%08x\n",(u32)authid,(u32)(authid>>32)); printf("Vendor ID 0x%08x\n",vendor_id); printf("SELF Type 0x%08x\n",self_type); printf("Version 0x%08x%08x\n",(u32)version,(u32)(version>>32)); printf("Padding 0x%08x%08x\n",(u32)padding,(u32)(padding>>32)); }
void app_info(u64 offset){ u64 authid = le64(self+offset); /* auth id */ offset += sizeof(u64); u32 vendor_id = le32(self+offset); /* vendor id */ offset += sizeof(u32); u32 self_type = le32(self+offset); /* app type */ offset += sizeof(u32); u64 version = le64(self+offset); /* app version */ offset += sizeof(u64); u64 padding = le64(self+offset); /* UNKNOWN */ offset += sizeof(u64); printf("--- APP INFO ---\n"); printf("Authotiry ID 0x%016lx\n",authid); printf("Vendor ID 0x%08x\n",vendor_id); printf("SELF Type 0x%08x\n",self_type); printf("Version 0x%016lx\n",version); printf("Padding 0x%016lx\n",padding); }
static void set_btrfs_info(const struct btrfs_super_block *sb, partition_t *partition) { partition->upart_type=UP_BTRFS; partition->blocksize=le32(sb->dev_item.sector_size); set_part_name(partition, sb->label, sizeof(sb->label)); snprintf(partition->info, sizeof(partition->info), "btrfs blocksize=%u", partition->blocksize); if(le64(sb->bytenr)!=partition->part_offset + BTRFS_SUPER_INFO_OFFSET) { strcat(partition->info," Backup superblock"); } /* last mounted => date */ }
void control_information64(u64 offset){ uint32_t type = le32(self+offset); // 4== ; 6==;7== offset+=sizeof(uint32_t); uint32_t size = le32(self+offset); offset+=sizeof(uint32_t); uint64_t unknown = le64(self+offset); // 0;1 offset+=sizeof(uint64_t); printf("--- CONTROL INFORMATION64 ---\n"); printf("Type 0x%08x\n",type); printf("Size 0x%08x\n",size); printf("Unknown 0x%08x%08x\n",(u32)unknown,(u32)(unknown>>32)); }
static int test_ZFS(disk_t *disk, const struct vdev_boot_header *sb, const partition_t *partition, const int dump_ind) { if(le64(sb->vb_magic)!=VDEV_BOOT_MAGIC) return 1; if(dump_ind!=0) { if(partition!=NULL && disk!=NULL) log_info("\nZFS magic value at %u/%u/%u\n", offset2cylinder(disk,partition->part_offset), offset2head(disk,partition->part_offset), offset2sector(disk,partition->part_offset)); dump_log(sb,DEFAULT_SECTOR_SIZE); } 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 zip64_parse_end_central_dir(file_recovery_t *fr) { struct { uint64_t end_size; /** Size of zip64 end of central directory record */ uint16_t version_made; /** Version made by */ uint16_t version_needed; /** Version needed to extract */ uint32_t number_disk; /** Number of this disk */ uint32_t number_disk2; /** Number of the disk with the start of the central directory */ uint64_t number_entries; /** Total number of entries in the central directory on this disk */ uint64_t number_entries2; /** Total number of entries in the central directory */ uint64_t size; /** Size of the central directory */ uint64_t offset; /** Offset of start of central directory */ } __attribute__ ((__packed__)) dir; if (fread(&dir, sizeof(dir), 1, fr->handle) != 1) { #ifdef DEBUG_ZIP log_trace("zip: Unexpected EOF reading end_central_dir_64\n"); #endif return -1; } fr->file_size += sizeof(dir); if (dir.end_size > 0) { const uint64_t len = le64(dir.end_size); #ifdef HAVE_FSEEKO if (fseeko(fr->handle, len, SEEK_CUR) == -1) #else if (fseek(fr->handle, len, SEEK_CUR) == -1) #endif { #ifdef DEBUG_ZIP log_trace("zip: Unexpected EOF in end_central_dir_64: expected %llu bytes\n", (long long unsigned)len); #endif return -1; } fr->file_size += len; #ifdef DEBUG_ZIP log_trace("zip: End of 64b central dir of length %llu\n", (long long unsigned)len); #endif } return 0; }
int recover_MD(disk_t *disk_car, const struct mdp_superblock_s *sb, partition_t *partition, const int verbose, const int dump_ind) { if(test_MD(disk_car, sb, partition, dump_ind)==0) { set_MD_info(sb, partition, verbose); partition->part_type_i386=P_RAID; partition->part_type_sun=PSUN_RAID; partition->part_type_gpt=GPT_ENT_TYPE_LINUX_RAID; if(le32(sb->major_version)==0) { partition->part_size=(uint64_t)(le32(sb->size)<<1)*disk_car->sector_size+MD_RESERVED_BYTES; memcpy(&partition->part_uuid, &sb->set_uuid0, 4); memcpy((char*)(&partition->part_uuid)+4, &sb->set_uuid1, 3*4); } else { const struct mdp_superblock_1 *sb1=(const struct mdp_superblock_1 *)sb; partition->part_size=(uint64_t)le64(sb1->size) * (uint64_t)disk_car->sector_size+4096; memcpy(&partition->part_uuid, &sb1->set_uuid, 16); } return 0; } if(test_MD_be(disk_car, sb, partition, dump_ind)==0) { set_MD_info_be(sb, partition, verbose); partition->part_type_i386=P_RAID; partition->part_type_sun=PSUN_RAID; partition->part_type_gpt=GPT_ENT_TYPE_LINUX_RAID; if(be32(sb->major_version)==0) { partition->part_size=(uint64_t)(be32(sb->size)<<1)*disk_car->sector_size+MD_RESERVED_BYTES; memcpy(&partition->part_uuid, &sb->set_uuid0, 4); memcpy((char*)(&partition->part_uuid)+4, &sb->set_uuid1, 3*4); } else { const struct mdp_superblock_1 *sb1=(const struct mdp_superblock_1 *)sb; partition->part_size=(uint64_t)be64(sb1->size) * (uint64_t)disk_car->sector_size+4096; memcpy(&partition->part_uuid, &sb1->set_uuid, 16); } return 0; } return 1; }
int recover_VMFS(disk_t *disk, const struct vmfs_volume *sb, partition_t *partition, const int verbose, const int dump_ind) { const struct vmfs_lvm* lvm=(const struct vmfs_lvm*)(((const char *)sb)+0x200); if(test_VMFS(disk, sb, partition, dump_ind)!=0) return 1; if(partition==NULL) return 0; set_VMFS_info(sb, partition); partition->part_type_i386=P_VMFS; partition->part_size=(uint64_t)le64(lvm->size); partition->blocksize=0; partition->sborg_offset=0; partition->sb_offset=0; if(verbose>0) { log_info("\n"); } return 0; }
int recover_LVM2(disk_t *disk_car, const unsigned char *buf,partition_t *partition,const int verbose, const int dump_ind) { const struct lvm2_label_header *lh=(const struct lvm2_label_header *)buf; if(test_LVM2(disk_car,lh,partition,verbose,dump_ind)!=0) return 1; set_LVM2_info(partition); partition->part_type_i386=P_LVM; partition->part_type_sun=PSUN_LVM; partition->part_type_gpt=GPT_ENT_TYPE_LINUX_LVM; { const struct lvm2_pv_header *pvhdr; pvhdr=(const struct lvm2_pv_header *) (buf + le32(lh->offset_xl)); partition->part_size=le64(pvhdr->device_size_xl); } if(verbose>0) { log_info("part_size %lu\n",(long unsigned)(partition->part_size/disk_car->sector_size)); } return 0; }
static int header_check_bkf(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 mtf_db_hdr *hdr=(const struct mtf_db_hdr *)buffer; /* Microsoft Tape Format * The DBLK Type field is set to ‘TAPE’. * The Format Logical Address field is set to zero. * The Control Block ID field is set to zero. */ if(le64(hdr->fla)!=0 || le32(hdr->cbId)!=0 || hdr->strType>2 || le16(hdr->off)<sizeof(struct mtf_db_hdr)) return 0; #ifdef DEBUG_BKF log_info("off=%u\n", le16(hdr->off)); #endif reset_file_recovery(file_recovery_new); file_recovery_new->min_filesize=52; file_recovery_new->extension=file_hint_bkf.extension; file_recovery_new->file_check=&file_check_bkf; return 1; }
int recover_ZFS(disk_t *disk, const struct vdev_boot_header *sb,partition_t *partition,const int verbose, const int dump_ind) { if(test_ZFS(disk, sb, partition, dump_ind)!=0) return 1; if(partition==NULL) return 0; set_ZFS_info(sb, partition); partition->part_type_i386=P_LINUX; partition->part_type_mac=PMAC_LINUX; partition->part_type_sun=PSUN_LINUX; partition->part_type_gpt=GPT_ENT_TYPE_SOLARIS_USR; partition->part_size=(uint64_t)le64(sb->vb_offset); partition->blocksize=0; partition->sborg_offset=0; partition->sb_offset=0; if(verbose>0) { log_info("\n"); } return 0; }
/* Primary superblock is at 1024 (SUPERBLOCK_OFFSET) Group 0 begin at s_first_data_block */ int recover_btrfs(disk_t *disk, const struct btrfs_super_block *sb, partition_t *partition, const int verbose, const int dump_ind) { if(test_btrfs(sb)!=0) return 1; if(dump_ind!=0) { if(partition!=NULL && disk!=NULL) log_info("\nbtrfs magic value at %u/%u/%u\n", offset2cylinder(disk,partition->part_offset), offset2head(disk,partition->part_offset), offset2sector(disk,partition->part_offset)); dump_log(sb, BTRFS_SUPER_INFO_SIZE); } if(partition==NULL) return 0; set_btrfs_info(sb, partition); partition->part_type_i386=P_LINUX; partition->part_type_mac=PMAC_LINUX; partition->part_type_sun=PSUN_LINUX; partition->part_type_gpt=GPT_ENT_TYPE_LINUX_DATA; partition->part_size=(uint64_t)le64(sb->dev_item.total_bytes); guid_cpy(&partition->part_uuid, (const efi_guid_t *)&sb->fsid); if(verbose>0) { log_info("\n"); } partition->sborg_offset=BTRFS_SUPER_INFO_OFFSET; partition->sb_size=BTRFS_SUPER_INFO_SIZE; if(verbose>0) { if(disk==NULL) log_info("recover_btrfs: part_size %lu\n", (long unsigned)(partition->part_size / le32(sb->dev_item.sector_size))); else log_info("recover_btrfs: part_size %lu\n", (long unsigned)(partition->part_size / disk->sector_size)); } return 0; }
static int test_ufs(const disk_t *disk_car, const struct ufs_super_block *sb, partition_t *partition, const int verbose) { if(le32(sb->fs_magic)==UFS_MAGIC && le32(sb->fs_size) > 0 && (le32(sb->fs_fsize)==512 || le32(sb->fs_fsize)==1024 || le32(sb->fs_fsize)==2048 || le32(sb->fs_fsize)==4096)) { partition->upart_type = UP_UFS2_LE; if(verbose>1) log_info("\nUFS Marker at %u/%u/%u\n", offset2cylinder(disk_car,partition->part_offset),offset2head(disk_car,partition->part_offset),offset2sector(disk_car,partition->part_offset)); return 0; } if(be32(sb->fs_magic)==UFS_MAGIC && be32(sb->fs_size) > 0 && (be32(sb->fs_fsize)==512 || be32(sb->fs_fsize)==1024 || be32(sb->fs_fsize)==2048 || be32(sb->fs_fsize)==4096)) { partition->upart_type = UP_UFS; if(verbose>1) log_info("\nUFS Marker at %u/%u/%u\n", offset2cylinder(disk_car,partition->part_offset),offset2head(disk_car,partition->part_offset),offset2sector(disk_car,partition->part_offset)); return 0; } if(le32(sb->fs_magic)==UFS2_MAGIC && le64(sb->fs_u11.fs_u2.fs_size) > 0 && (le32(sb->fs_fsize)==512 || le32(sb->fs_fsize)==1024 || le32(sb->fs_fsize)==2048 || le32(sb->fs_fsize)==4096)) { partition->upart_type = UP_UFS2_LE; if(verbose>1) log_info("\nUFS2 Marker at %u/%u/%u\n", offset2cylinder(disk_car,partition->part_offset),offset2head(disk_car,partition->part_offset),offset2sector(disk_car,partition->part_offset)); return 0; } if(be32(sb->fs_magic)==UFS2_MAGIC && be64(sb->fs_u11.fs_u2.fs_size) > 0 && (be32(sb->fs_fsize)==512 || be32(sb->fs_fsize)==1024 || be32(sb->fs_fsize)==2048 || be32(sb->fs_fsize)==4096)) { partition->upart_type = UP_UFS2; if(verbose>1) log_info("\nUFS2 Marker at %u/%u/%u\n", offset2cylinder(disk_car,partition->part_offset),offset2head(disk_car,partition->part_offset),offset2sector(disk_car,partition->part_offset)); return 0; } return 1; }
Sint64 File::read64le() { return le64(read<Sint64>()); }
static uint64_t get64u(const void *buffer, const unsigned int offset) { const uint64_t *val=(const uint64_t *)((const unsigned char *)buffer+offset); return le64(*val); }