Example #1
0
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 */
}
Example #2
0
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;
}
Example #3
0
File: jfs.c Project: Tom9X/TestDisk
/*
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;
}
Example #4
0
int recover_LVM(disk_t *disk_car, const pv_disk_t *pv,partition_t *partition,const int verbose, const int dump_ind)
{
  if(test_LVM(disk_car,pv,partition,verbose,dump_ind)!=0)
    return 1;
  set_LVM_info(partition);
  partition->part_type_i386=P_LVM;
  partition->part_type_sun=PSUN_LVM;
  partition->part_type_gpt=GPT_ENT_TYPE_LINUX_LVM;
  partition->part_size=(uint64_t)le32(pv->pv_size)*disk_car->sector_size;
  /* pv_uuid is bigger than part_uuid */
  guid_cpy(&partition->part_uuid, (const efi_guid_t *)&pv->pv_uuid);
  if(verbose>0)
  {
    log_info("part_size %lu\n",(long unsigned)(partition->part_size/disk_car->sector_size));
  }
  return 0;
}
Example #5
0
int recover_xfs(disk_t *disk_car, const struct xfs_sb *sb,partition_t *partition,const int verbose, const int dump_ind)
{
  if(test_xfs(disk_car, sb, partition, verbose)!=0)
    return 1;
  if(verbose>0 || dump_ind!=0)
  {
    log_info("\nrecover_xfs\n");
    if(dump_ind!=0)
    {
      dump_log(sb,DEFAULT_SECTOR_SIZE);
    }
  }
  set_xfs_info(sb, partition);
  partition->part_size = (uint64_t)be64(sb->sb_dblocks) * be32(sb->sb_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->sb_uuid);
  return 0;
}
Example #6
0
void  partition_reset(partition_t *partition, const arch_fnct_t *arch)
{
/* partition->lba=0; Don't reset lba, used by search_part */
  partition->part_size=(uint64_t)0;
  partition->sborg_offset=0;
  partition->sb_offset=0;
  partition->sb_size=0;
  partition->blocksize=0;
  partition->part_type_i386=P_NO_OS;
  partition->part_type_sun=PSUN_UNK;
  partition->part_type_mac=PMAC_UNK;
  partition->part_type_xbox=PXBOX_UNK;
  partition->part_type_gpt=GPT_ENT_TYPE_UNUSED;
  guid_cpy(&partition->part_uuid, &GPT_ENT_TYPE_UNUSED);
  partition->upart_type=UP_UNK;
  partition->status=STATUS_DELETED;
  partition->order=NO_ORDER;
  partition->errcode=BAD_NOERR;
  partition->fsname[0]='\0';
  partition->partname[0]='\0';
  partition->info[0]='\0';
  partition->arch=arch;
}
Example #7
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;
}
Example #8
0
list_part_t *read_part_gpt(disk_t *disk_car, const int verbose, const int saveheader)
{
  struct gpt_hdr *gpt;
  struct gpt_ent* gpt_entries;
  list_part_t *new_list_part=NULL;
  unsigned int i;
  uint32_t gpt_entries_size;
  uint64_t gpt_entries_offset;

  gpt=(struct gpt_hdr*)MALLOC(disk_car->sector_size);
  screen_buffer_reset();
  if((unsigned)disk_car->pread(disk_car, gpt, disk_car->sector_size, disk_car->sector_size) != disk_car->sector_size)
  {
    free(gpt);
    return NULL;
  }
  if(memcmp(gpt->hdr_sig, GPT_HDR_SIG, 8)!=0)
  {
    screen_buffer_add("Bad GPT partition, invalid signature.\n");
    free(gpt);
    return NULL;
  }
  if(verbose>0)
  {
    log_info("hdr_size=%llu\n", (long long unsigned)le32(gpt->hdr_size));
    log_info("hdr_lba_self=%llu\n", (long long unsigned)le64(gpt->hdr_lba_self));
    log_info("hdr_lba_alt=%llu (expected %llu)\n",
	(long long unsigned)le64(gpt->hdr_lba_alt),
	(long long unsigned)((disk_car->disk_size-1)/disk_car->sector_size));
    log_info("hdr_lba_start=%llu\n", (long long unsigned)le64(gpt->hdr_lba_start));
    log_info("hdr_lba_end=%llu\n", (long long unsigned)le64(gpt->hdr_lba_end));
    log_info("hdr_lba_table=%llu\n",
	(long long unsigned)le64(gpt->hdr_lba_table));
    log_info("hdr_entries=%llu\n", (long long unsigned)le32(gpt->hdr_entries));
    log_info("hdr_entsz=%llu\n", (long long unsigned)le32(gpt->hdr_entsz));
  }
  /* Check header size */
  if(le32(gpt->hdr_size)<92 || le32(gpt->hdr_size) > disk_car->sector_size)
  {
    screen_buffer_add("GPT: invalid header size.\n");
    free(gpt);
    return NULL;
  }
  { /* CRC check */
    uint32_t crc;
    uint32_t origcrc;
    origcrc=le32(gpt->hdr_crc_self);
    gpt->hdr_crc_self=le32(0);
    crc=get_crc32(gpt, le32(gpt->hdr_size), 0xFFFFFFFF)^0xFFFFFFFF;
    if(crc!=origcrc)
    {
      screen_buffer_add("Bad GPT partition, invalid header checksum.\n");
      free(gpt);
      return NULL;
    }
    gpt->hdr_crc_self=le32(origcrc);
  }
  if(le64(gpt->hdr_lba_self)!=1)
  {
    screen_buffer_add("Bad GPT partition, invalid LBA self location.\n");
    free(gpt);
    return NULL;
  }
  if(le64(gpt->hdr_lba_start) >= le64(gpt->hdr_lba_end))
  {
    screen_buffer_add("Bad GPT partition, invalid LBA start/end location.\n");
    free(gpt);
    return NULL;
  }
  if(le32(gpt->hdr_revision)!=GPT_HDR_REVISION)
  {
    screen_buffer_add("GPT: Warning - not revision 1.0\n");
  }
  if(le32(gpt->__reserved)!=0)
  {
    screen_buffer_add("GPT: Warning - __reserved!=0\n");
  }
  if(le32(gpt->hdr_entries)==0 || le32(gpt->hdr_entries)>4096)
  {
    screen_buffer_add("GPT: invalid number (%u) of partition entries.\n",
        (unsigned int)le32(gpt->hdr_entries));
    free(gpt);
    return NULL;
  }
  /* le32(gpt->hdr_entsz)==128 */
  if(le32(gpt->hdr_entsz)%8!=0 || le32(gpt->hdr_entsz)<128 || le32(gpt->hdr_entsz)>4096)
  {
    screen_buffer_add("GPT: invalid partition entry size.\n");
    free(gpt);
    return NULL;
  }

  gpt_entries_size=le32(gpt->hdr_entries) * le32(gpt->hdr_entsz);
  if(gpt_entries_size<16384)
  {
    screen_buffer_add("GPT: A minimum of 16,384 bytes of space must be reserved for the GUID Partition Entry array.\n");
    free(gpt);
    return NULL;
  }
  gpt_entries_offset=(uint64_t)le64(gpt->hdr_lba_table) * disk_car->sector_size;
  if((uint64_t) le64(gpt->hdr_lba_self) + le32(gpt->hdr_size) - 1 >= gpt_entries_offset ||
      gpt_entries_offset >= le64(gpt->hdr_lba_start) * disk_car->sector_size)
  {
    screen_buffer_add( "GPT: The primary GUID Partition Entry array must be located after the primary GUID Partition Table Header and end before the FirstUsableLBA.\n");
    free(gpt);
    return NULL;
  }

  gpt_entries=(struct gpt_ent*)MALLOC(gpt_entries_size);
  if((unsigned)disk_car->pread(disk_car, gpt_entries, gpt_entries_size, gpt_entries_offset) != gpt_entries_size)
  {
    free(gpt_entries);
    free(gpt);
    return new_list_part;
  }
  { /* CRC check */
    uint32_t crc;
    crc=get_crc32(gpt_entries, gpt_entries_size, 0xFFFFFFFF)^0xFFFFFFFF;
    if(crc!=le32(gpt->hdr_crc_table))
    {
      screen_buffer_add("Bad GPT partition entries, invalid checksum.\n");
      free(gpt_entries);
      free(gpt);
      return NULL;
    }
  }
  for(i=0;i<le32(gpt->hdr_entries);i++)
  {
    const struct gpt_ent* gpt_entry;
    gpt_entry=(const struct gpt_ent*)((const char*)gpt_entries + (unsigned long)i*le32(gpt->hdr_entsz));
    if(guid_cmp(gpt_entry->ent_type, GPT_ENT_TYPE_UNUSED)!=0 &&
        le64(gpt_entry->ent_lba_start) < le64(gpt_entry->ent_lba_end))
    {
      int insert_error=0;
      partition_t *new_partition=partition_new(&arch_gpt);
      new_partition->order=i+1;
      guid_cpy(&new_partition->part_uuid, &gpt_entry->ent_uuid);
      guid_cpy(&new_partition->part_type_gpt, &gpt_entry->ent_type);
      new_partition->part_offset=(uint64_t)le64(gpt_entry->ent_lba_start)*disk_car->sector_size;
      new_partition->part_size=(uint64_t)(le64(gpt_entry->ent_lba_end) -
          le64(gpt_entry->ent_lba_start)+1) * disk_car->sector_size;
      new_partition->status=STATUS_PRIM;
      UCSle2str(new_partition->partname, (const uint16_t *)&gpt_entry->ent_name, sizeof(gpt_entry->ent_name)/2);
      new_partition->arch->check_part(disk_car,verbose,new_partition,saveheader);
      /* log_debug("%u ent_attr %08llx\n", new_partition->order, (long long unsigned)le64(gpt_entry->ent_attr)); */
      aff_part_buffer(AFF_PART_ORDER|AFF_PART_STATUS,disk_car,new_partition);
      new_list_part=insert_new_partition(new_list_part, new_partition, 0, &insert_error);
      if(insert_error>0)
        free(new_partition);
    }
  }
  /* TODO: The backup GUID Partition Entry array must be
     located after the LastUsableLBA and end before the backup GUID Partition Table Header.
   */
  free(gpt_entries);
  free(gpt);
  return new_list_part;
}
Example #9
0
/*
Primary superblock is at 1024 (SUPERBLOCK_OFFSET)
Group 0 begin at s_first_data_block
*/
int recover_EXT2(disk_t *disk, const struct ext2_super_block *sb,partition_t *partition,const int verbose, const int dump_ind)
{
  if(test_EXT2(sb, partition)!=0)
    return 1;
  if(dump_ind!=0)
  {
    if(partition!=NULL && disk!=NULL)
      log_info("\nEXT2/EXT3 magic value at %u/%u/%u\n",
	  offset2cylinder(disk,partition->part_offset),
	  offset2head(disk,partition->part_offset),
	  offset2sector(disk,partition->part_offset));
    /* There is a little offset ... */
    dump_log(sb,DEFAULT_SECTOR_SIZE);
  }
  if(partition==NULL)
    return 0;
  set_EXT2_info(sb, partition, verbose);
  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=td_ext2fs_blocks_count(sb) * EXT2_MIN_BLOCK_SIZE<<le32(sb->s_log_block_size);
  guid_cpy(&partition->part_uuid, (const efi_guid_t *)&sb->s_uuid);
  if(verbose>0)
  {
    log_info("\n");
  }
  partition->sborg_offset=0x400;
  partition->sb_size=EXT2_SUPERBLOCK_SIZE;
  if(le16(sb->s_block_group_nr)>0)
  {
    const unsigned long int block_nr=(le32(sb->s_first_data_block)+le16(sb->s_block_group_nr)*le32(sb->s_blocks_per_group));
    if(partition->part_offset< (uint64_t)block_nr * (EXT2_MIN_BLOCK_SIZE<<le32(sb->s_log_block_size)))
    {
      log_error("recover_EXT2: part_offset problem\n");
      return 1;
    }
    partition->sb_offset=(uint64_t)block_nr * (EXT2_MIN_BLOCK_SIZE<<le32(sb->s_log_block_size));
    partition->part_offset-=partition->sb_offset;
    log_warning("recover_EXT2: \"e2fsck -b %lu -B %u device\" may be needed\n",
        block_nr, partition->blocksize);
  }
  else
  {
    partition->sb_offset=0;
  }
  if(verbose>0)
  {
    log_info("recover_EXT2: s_block_group_nr=%u/%u, s_mnt_count=%u/%u, s_blocks_per_group=%u, s_inodes_per_group=%u\n",
        le16(sb->s_block_group_nr),
        (unsigned int)(td_ext2fs_blocks_count(sb) /le32(sb->s_blocks_per_group)),
        le16(sb->s_mnt_count), le16(sb->s_max_mnt_count),
        (unsigned int)le32(sb->s_blocks_per_group),
        (unsigned int)le32(sb->s_inodes_per_group));
    log_info("recover_EXT2: s_blocksize=%u\n", partition->blocksize);
    log_info("recover_EXT2: s_blocks_count %lu\n", (long unsigned int)td_ext2fs_blocks_count(sb));
    if(disk==NULL)
      log_info("recover_EXT2: part_size %lu\n", (long unsigned)(partition->part_size / DEFAULT_SECTOR_SIZE));
    else
      log_info("recover_EXT2: part_size %lu\n", (long unsigned)(partition->part_size / disk->sector_size));
  }
  return 0;
}
Example #10
0
static void gpt_change_part_type(const disk_t *disk_car, partition_t *partition)
{
  unsigned int offset=0;
  unsigned int i,j;
  unsigned int current_element_num=0;
  log_info("gpt_change_part_type\n");
  aff_copy(stdscr);
  wmove(stdscr,4,0);
  aff_part(stdscr, AFF_PART_ORDER|AFF_PART_STATUS, disk_car, partition);
  wmove(stdscr,INTER_CHGTYPE_Y, INTER_CHGTYPE_X);
  wattrset(stdscr, A_REVERSE);
  wprintw(stdscr, "[ Proceed ]");
  wattroff(stdscr, A_REVERSE);
  /* By default, select the current type */
  for(i=0;gpt_sys_types[i].name!=NULL;i++)
  {
    if(guid_cmp(partition->part_type_gpt, gpt_sys_types[i].part_type)==0)
    {
      current_element_num=i;
      while(current_element_num >= offset+3*INTER_CHGTYPE)
	offset++;
    }
  }
  while(1)
  {
    wmove(stdscr,5,0);
    wprintw(stdscr, "Please choose the partition type, press Enter when done.");
    wmove(stdscr,5+1,1);
    wclrtoeol(stdscr);
    if(offset>0)
      wprintw(stdscr, "Previous");
    for(i=offset;gpt_sys_types[i].name!=NULL && (i-offset)<3*INTER_CHGTYPE;i++)
    {
      if(i-offset<INTER_CHGTYPE)
	wmove(stdscr,5+2+i-offset,0);
      else if(i-offset<2*INTER_CHGTYPE)
	wmove(stdscr,5+2+i-offset-INTER_CHGTYPE,26);
      else
	wmove(stdscr,5+2+i-offset-2*INTER_CHGTYPE,52);
      wclrtoeol(stdscr);	/* before addstr for BSD compatibility */
      if(i==current_element_num)
      {
	wattrset(stdscr, A_REVERSE);
	wprintw(stdscr,">%s", gpt_sys_types[i].name);
	wattroff(stdscr, A_REVERSE);
      } else
      {
	wprintw(stdscr," %s", gpt_sys_types[i].name);
      }
    }
    if(i-offset<INTER_CHGTYPE)
      wmove(stdscr,5+2+i-offset,1);
    else if(i-offset<2*INTER_CHGTYPE)
      wmove(stdscr,5+2+i-offset-INTER_CHGTYPE,27);
    else
      wmove(stdscr,5+2+i-offset-2*INTER_CHGTYPE,53);
    wclrtoeol(stdscr);
    if(gpt_sys_types[i].name!=NULL)
      wprintw(stdscr, "Next");
    switch(wgetch(stdscr))
    {
      case 'p':
      case 'P':
      case KEY_UP:
	if(current_element_num>0)
	  current_element_num--;
	break;
      case 'n':
      case 'N':
      case KEY_DOWN:
	if(gpt_sys_types[current_element_num].name!=NULL && gpt_sys_types[current_element_num+1].name!=NULL)
	  current_element_num++;
	break;
      case KEY_LEFT:
	if(current_element_num > INTER_CHGTYPE)
	  current_element_num-=INTER_CHGTYPE;
	else
	  current_element_num=0;
	break;
      case KEY_PPAGE:
	if(current_element_num > 3*INTER_CHGTYPE-1)
	  current_element_num-=3*INTER_CHGTYPE-1;
	else
	  current_element_num=0;
	break;
      case KEY_RIGHT:
	for(j=0;j<INTER_CHGTYPE;j++)
	{
	  if(gpt_sys_types[current_element_num].name!=NULL && gpt_sys_types[current_element_num+1].name!=NULL)
	    current_element_num++;
	}
	break;
      case KEY_NPAGE:
	for(j=0;j<3*INTER_CHGTYPE;j++)
	{
	  if(gpt_sys_types[current_element_num].name!=NULL && gpt_sys_types[current_element_num+1].name!=NULL)
	    current_element_num++;
	}
	break;
      case 'Q':
      case 'q':
      case key_CR:
#ifdef PADENTER
      case PADENTER:
#endif
	guid_cpy(&partition->part_type_gpt, &gpt_sys_types[current_element_num].part_type);
	return;
    }
    if(current_element_num<offset)
      offset=current_element_num;
    if(current_element_num >= offset+3*INTER_CHGTYPE)
      offset=current_element_num-3*INTER_CHGTYPE+1;
  }
}