Example #1
0
static int use_backup(disk_t *disk_car, const list_part_t *list_part, const int verbose,const int dump_ind, const unsigned int expert, char**current_cmd)
{
  const list_part_t *element;
  if(verbose>1)
  {
    log_trace("use_backup\n");
  }
  for(element=list_part;element!=NULL;element=element->next)
  {
    if(element->part->sb_offset!=0)
    {
      switch(element->part->upart_type)
      {
	case UP_FAT32:
	  fat32_boot_sector(disk_car, element->part, verbose, dump_ind, expert,current_cmd);
	  break;
	case UP_NTFS:
	  ntfs_boot_sector(disk_car, element->part, verbose, expert, current_cmd);
	  break;
	case UP_HFS:
	case UP_HFSP:
	case UP_HFSX:
	  HFS_HFSP_boot_sector(disk_car, element->part, verbose, current_cmd);
	  break;
	default:
	  log_warning("Need to fix\n");
	  log_partition(disk_car,element->part);
	  break;
      }
    }
  }
  return 0;
}
Example #2
0
File: fatxfc.c Project: HSOFEUP/mm
fx_rtn
fx_init(void) {
    boot_sector_t *bs;
    info_sector_t *info;
    mbr_t *mbr;
    u32_t start, size;

    assert(fx_buf);
    assert(! ms_read_blk(0, fx_buf));

    /* First sector is either an MBR or the boot_sector of the partition.  It
     * had better have the 2 byte signature at the end.  ie.  0xaa55.
     *
     * Start by looking for a boot sector rather than the MBR.
     */
    bs = fx_buf;
    if (bs->sig != CT_LE_16(BOOT_SIG))
	return(FX_BAD_BOOT_SIG);

    start = fx_data_start = 0;
    if ( ! fat32_boot_sector(bs)) {
	/*
	 * something doesn't look right.  Look at the sector as an MBR and see
	 * if it makes sense.  We only look at partition 1.
	 */
	mbr = fx_buf;
	start = (mbr->p1.start4[3] << 24) | (mbr->p1.start4[2] << 16) |
	    (mbr->p1.start4[1] << 8)      | mbr->p1.start4[0];
	size  = (mbr->p1.size4[3] << 24)  | (mbr->p1.size4[2] << 16)  |
	    (mbr->p1.size4[1] << 8      ) | mbr->p1.size4[0];

	/* check for reasonableness, boot_ind can be 0x00 or 0x80 */
	if ((mbr->p1.boot_ind != 0 && mbr->p1.boot_ind != 0x80) ||
	      !fat32_part(mbr->p1.part_type) ||		/* reasonable fat32 partition? */
	      start == 0 ||				/* can't start at 0 */
	      size == 0)				/* zero means nothing, bail */
	    return(FX_NO_PARTITION);
	
	assert(! ms_read_blk(start, fx_buf));
	bs = fx_buf;
	if (CF_LE_16(bs->sig) != BOOT_SIG)
	    return(FX_BAD_BOOT_SIG);
	if (!fat32_boot_sector(bs))			/* make sure what we got is good */
	    return(FX_NO_PARTITION);
	/* check mbr partition size vs. total_sect entry in the file system header
	   only accept if the same or if file system size is one less than the partition header
	*/
	if (size != CF_LE_32(bs->total_sect)) {		/* and partition size should match internal */
	    if (debug)
		printf("*** mbr/fs size mismatch: mbr: %lu (%lx), fs: %lu (%lx)\n",
		       size, size, CF_LE_32(bs->total_sect), CF_LE_32(bs->total_sect));
	    if (size != CF_LE_32(bs->total_sect) + 1)
		return(FX_SIZE_MISMATCH);
	}
	fx_data_start = start;
    }

    if (debug)
	printf("Partition start: %lx, size: %lx\n",
		(u32_t) fx_data_start, CF_LE_32(bs->total_sect));

    /* buf contains the boot_sector.  compute total data sectors and make
       sure that it conforms to FAT32. */

    fx_cluster_size  = bs->cluster_size;	/* u8 */
    fx_reserved      = CF_LE_16(bs->reserved);
    fx_num_fats      = bs->fats;		/* u8 */
    fx_total_sectors = CF_LE_32(bs->total_sect);
    fx_fat_size      = CF_LE_32(bs->fat32_length);
    fx_info_sector   = start + CF_LE_16(bs->info_sector);

    fx_data_end      = fx_data_start + fx_total_sectors - 1;
    fx_fat_start     = fx_data_start + fx_reserved;
    fx_fat_end	     = fx_fat_start + fx_fat_size - 1;
    fx_data_start    = fx_fat_start + fx_fat_size * FX_NUM_FATS;

    size = fx_total_sectors;
    size -= (fx_reserved + (fx_fat_size * fx_num_fats));
    fx_max_cluster = size/fx_cluster_size;		/* last cluster */

    if (debug)
	printf("phys data sectors: %lx, phys clusters: %lx, unused sectors: %lx\n",
		size,
		fx_max_cluster,
		size - fx_max_cluster * fx_cluster_size);

    if (fx_max_cluster < 65525)				/* if less, not FAT32 */
	return(FX_NOT_FAT32);

    fx_max_cluster++;					/* make into cluster id */
    fx_data_end = clu2sec(fx_max_cluster + 1) - 1;	/* get last usable data sector */

    if (fx_cluster_size != FX_CLUSTER_SIZE)
      fprintf(stderr, "*** bad fx_cluster_size (%u) should be (%u)\n", fx_cluster_size, FX_CLUSTER_SIZE);
    if (fx_num_fats != FX_NUM_FATS)
      fprintf(stderr, "*** wrong number of FATS: (%u) should be (%u)\n", fx_num_fats, FX_NUM_FATS);

    f32_get_chain(CF_LE_32(bs->root_cluster), &fx_rdir_start, &fx_rdir_end);
    assert(fx_rdir_start && fx_rdir_end);

    assert(!ms_read_blk(fx_info_sector, fx_buf));
    info = fx_buf;
    if (info->boot_sig == CT_LE_16(BOOT_SIG) && IS_FSINFO(info)) {
	fx_free_clusters = CF_LE_32(info->free_clusters);
	fx_next_cluster = CF_LE_32(info->next_cluster);
    } else {
	fx_info_sector = 0;
	fx_free_clusters = (u32_t) -1;
	fx_next_cluster  = (u32_t) -1;
    }

    if (debug) {
	printf("ts: %lx, r: %x, fat_s: %lx, n: %d, ds: %lx\n",
		fx_total_sectors, fx_reserved,  fx_fat_size, fx_num_fats,
		fx_total_sectors-fx_reserved-(fx_num_fats*fx_fat_size));
	printf("fat_size (secs): %lx, (clus) %lx, %lx bytes\n",
		fx_fat_size, fx_fat_size * SECTOR_SIZE / sizeof(u32_t),
		fx_fat_size * SECTOR_SIZE);
	printf("data_start: %lx, end: %lx, usable sectors: %lx, last phys sector: %lx\n",
		fx_data_start,
		fx_data_end,
		fx_data_end - fx_data_start + 1,	/* usable */
		fx_data_start + (fx_total_sectors - fx_reserved -
				 (fx_num_fats * fx_fat_size))  - 1);
	printf("unused fat entries: %lx,  cluster ids: 2 - %lx\n",
		(fx_fat_end - fx_fat_start + 1) * FAT32_CPB - (fx_max_cluster + 1),
		    fx_max_cluster);
	printf("Last cluster: %lx,  sectors: %lx - %lx, fat sector: %lx, off: %lx\n",
		fx_max_cluster,
		clu2sec(fx_max_cluster),
		clu2sec(fx_max_cluster + 1) - 1,
		FAT_SECTOR(fx_max_cluster) + fx_fat_start,
		FAT_OFFSET(fx_max_cluster));
	printf("  fat_start: %5lx, fat_end: %5lx\n", fx_fat_start, fx_fat_end);
	printf("  info: free %5lx, next:    %5lx\n", fx_free_clusters, fx_next_cluster);
    }

    return(FX_OK);
}
Example #3
0
void interface_adv(disk_t *disk_car, const int verbose,const int dump_ind, const unsigned int expert, char**current_cmd)
{
#ifdef HAVE_NCURSES
    int offset=0;
    int current_element_num=0;
    int old_LINES=LINES;
#endif
    int rewrite=1;
    unsigned int menu=0;
    list_part_t *element;
    list_part_t *list_part;
    list_part_t *current_element;
    log_info("\nInterface Advanced\n");
    list_part=disk_car->arch->read_part(disk_car,verbose,0);
    current_element=list_part;
    log_all_partitions(disk_car, list_part);
    while(1)
    {
        const char *options;
        static struct MenuItem menuAdv[]=
        {
            {'t',"Type","Change type, this setting will not be saved on disk"},
            {'b',"Boot","Boot sector recovery"},
            {'s',"Superblock",NULL},
            {'l',"List", "List and copy files"},
            {'u',"Undelete", "File undelete"},
            {'c',"Image Creation", "Create an image"},
//      {'a',"Add", "Add temporary partition (Expert only)"},
            {'q',"Quit","Return to main menu"},
            {0,NULL,NULL}
        };
        int command;
#ifdef HAVE_NCURSES
        int i;
        if(old_LINES!=LINES)
        {
            old_LINES=LINES;
            rewrite=1;
        }
        if(rewrite!=0)
        {
            aff_copy(stdscr);
            wmove(stdscr,4,0);
            wprintw(stdscr,"%s",disk_car->description(disk_car));
            if(list_part!=NULL)
                mvwaddstr(stdscr,6,0,msg_PART_HEADER_LONG);
            rewrite=0;
        }
        for(i=0,element=list_part; element!=NULL && i<offset+INTER_ADV; element=element->next,i++)
        {
            if(i<offset)
                continue;
            wmove(stdscr,7+i-offset,0);
            wclrtoeol(stdscr);	/* before addstr for BSD compatibility */
            if(element==current_element)
            {
                wattrset(stdscr, A_REVERSE);
                waddstr(stdscr, ">");
                aff_part(stdscr,AFF_PART_ORDER|AFF_PART_STATUS,disk_car,element->part);
                wattroff(stdscr, A_REVERSE);
            } else
            {
                waddstr(stdscr, " ");
                aff_part(stdscr,AFF_PART_ORDER|AFF_PART_STATUS,disk_car,element->part);
            }
        }
        wmove(stdscr,7+INTER_ADV,5);
        wclrtoeol(stdscr);
        if(element!=NULL)
            wprintw(stdscr, "Next");
#endif
        if(current_element==NULL)
        {
            options="q";
#ifdef HAVE_NCURSES
            wmove(stdscr,7,0);
            wattrset(stdscr, A_REVERSE);
            wprintw(stdscr,"No partition available.");
            wattroff(stdscr, A_REVERSE);
#endif
        }
        else
        {
            const partition_t *partition=current_element->part;
            if(menu==0 && (disk_car->arch!=&arch_none || partition->upart_type!=UP_UNK))
                menu=1;
            if(is_part_fat(partition))
            {
                options="tubcq";
                menu=(partition->upart_type==UP_UNK?1:4);
            }
            else if(is_part_ntfs(partition))
                options="tlubcq";
            else if(is_part_linux(partition))
            {
                if(partition->upart_type==UP_EXT2)
                    options="tuscq";
                else
                    options="tlscq";
                menuAdv[2].desc="Locate ext2/ext3/ext4 backup superblock";
            }
            else if(is_part_hfs(partition) || is_part_hfsp(partition))
            {
                options="tscq";
                menuAdv[2].desc="Locate HFS/HFS+ backup volume header";
            }
            else if(is_fat(partition))
                options="tubcq";
            else if(is_ntfs(partition))
                options="tlubcq";
            else if(is_exfat(partition))
                options="tlubcq";
            else if(is_linux(partition))
            {
                if(partition->upart_type==UP_EXT2)
                    options="tluscq";
                else
                    options="tlscq";
                menuAdv[2].desc="Locate ext2/ext3/ext4 backup superblock";
            }
            else if(is_hfs(partition) || is_hfsp(partition))
            {
                options="tscq";
                menuAdv[2].desc="Locate HFS/HFS+ backup volume header";
            }
            else
                options="tcq";
        }
        if(*current_cmd!=NULL)
        {
            int keep_asking;
            command='q';
            do
            {
                keep_asking=0;
                while(*current_cmd[0]==',')
                    (*current_cmd)++;
                if(strncmp(*current_cmd,"type",4)==0)
                {
                    (*current_cmd)+=4;
                    command='t';
                }
                else if(strncmp(*current_cmd,"addpart",7)==0)
                {
                    (*current_cmd)+=7;
                    command='a';
                }
                else if(strncmp(*current_cmd,"boot",4)==0)
                {
                    (*current_cmd)+=4;
                    command='b';
                }
                else if(strncmp(*current_cmd,"copy",4)==0)
                {
                    (*current_cmd)+=4;
                    command='c';
                }
                else if(strncmp(*current_cmd,"list",4)==0)
                {
                    (*current_cmd)+=4;
                    command='l';
                }
                else if(strncmp(*current_cmd,"undelete",8)==0)
                {
                    (*current_cmd)+=8;
                    command='u';
                }
                else if(strncmp(*current_cmd,"superblock",10)==0)
                {
                    (*current_cmd)+=10;
                    command='s';
                }
                else if(isdigit(*current_cmd[0]))
                {
                    const unsigned int order= atoi(*current_cmd);
                    while(*current_cmd[0]!=',' && *current_cmd[0]!='\0')
                        (*current_cmd)++;
                    for(element=list_part; element!=NULL && element->part->order!=order; element=element->next);
                    if(element!=NULL)
                    {
                        current_element=element;
                        keep_asking=1;
                    }
                }
            } while(keep_asking>0);
        }
        else
        {
#ifdef HAVE_NCURSES
            command = wmenuSelect_ext(stdscr, INTER_ADV_Y+1, INTER_ADV_Y, INTER_ADV_X, menuAdv, 8, options,
                                      MENU_HORIZ | MENU_BUTTON | MENU_ACCEPT_OTHERS, &menu, NULL);
#else
            command = 'q';
#endif
        }
        switch(command)
        {
        case 'q':
        case 'Q':
            part_free_list(list_part);
            return;
#ifdef HAVE_NCURSES
        case 'a':
        case 'A':
            if(disk_car->arch!=&arch_none)
            {
                if(*current_cmd!=NULL)
                    list_part=add_partition_cli(disk_car, list_part, current_cmd);
                else
                    list_part=add_partition_ncurses(disk_car, list_part);
                current_element=list_part;
                rewrite=1;
            }
            break;
#endif
        }
#ifdef HAVE_NCURSES
        if(current_element!=NULL)
        {
            switch(command)
            {
            case 'p':
            case 'P':
            case KEY_UP:
                if(current_element->prev!=NULL)
                {
                    current_element=current_element->prev;
                    current_element_num--;
                }
                break;
            case 'n':
            case 'N':
            case KEY_DOWN:
                if(current_element->next!=NULL)
                {
                    current_element=current_element->next;
                    current_element_num++;
                }
                break;
            case KEY_PPAGE:
                for(i=0; i<INTER_ADV-1 && current_element->prev!=NULL; i++)
                {
                    current_element=current_element->prev;
                    current_element_num--;
                }
                break;
            case KEY_NPAGE:
                for(i=0; i<INTER_ADV-1 && current_element->next!=NULL; i++)
                {
                    current_element=current_element->next;
                    current_element_num++;
                }
                break;
            case 'b':
            case 'B':
            {
                partition_t *partition=current_element->part;
                if(is_part_fat32(partition))
                {
                    fat32_boot_sector(disk_car, partition, verbose, dump_ind, expert,current_cmd);
                    rewrite=1;
                }
                else if(is_part_fat12(partition) || is_part_fat16(partition))
                {
                    fat1x_boot_sector(disk_car, partition, verbose, dump_ind,expert,current_cmd);
                    rewrite=1;
                }
                else if(is_part_ntfs(partition))
                {
                    if(partition->upart_type==UP_EXFAT)
                        exFAT_boot_sector(disk_car, partition, verbose, current_cmd);
                    else
                        ntfs_boot_sector(disk_car, partition, verbose, expert, current_cmd);
                    rewrite=1;
                }
                else if(partition->upart_type==UP_FAT32)
                {
                    fat32_boot_sector(disk_car, partition, verbose, dump_ind, expert,current_cmd);
                    rewrite=1;
                }
                else if(partition->upart_type==UP_FAT12 || partition->upart_type==UP_FAT16)
                {
                    fat1x_boot_sector(disk_car, partition, verbose, dump_ind,expert,current_cmd);
                    rewrite=1;
                }
                else if(partition->upart_type==UP_NTFS)
                {
                    ntfs_boot_sector(disk_car, partition, verbose, expert, current_cmd);
                    rewrite=1;
                }
                else if(partition->upart_type==UP_EXFAT)
                {
                    exFAT_boot_sector(disk_car, partition, verbose, current_cmd);
                    rewrite=1;
                }
            }
            break;
            case 'c':
            case 'C':
            {
                char *dst_path;
#ifdef HAVE_NCURSES
                if(*current_cmd!=NULL)
                    dst_path=get_default_location();
                else
                {
                    char msg[256];
                    snprintf(msg, sizeof(msg),
                             "Please select where to store the file image.dd (%u MB), an image of the partition",
                             (unsigned int)(current_element->part->part_size/1000/1000));
                    dst_path=ask_location(msg, "", NULL);
                }
#else
                dst_path=get_default_location();
#endif
                if(dst_path!=NULL)
                {
                    char *filename=(char *)MALLOC(strlen(dst_path) + 1 + strlen(DEFAULT_IMAGE_NAME) + 1);
                    strcpy(filename, dst_path);
                    strcat(filename, "/");
                    strcat(filename, DEFAULT_IMAGE_NAME);
                    disk_image(disk_car, current_element->part, filename);
                    free(filename);
                    free(dst_path);
                }
            }
            rewrite=1;
            break;
            case 'u':
            case 'U':
            {
                partition_t *partition=current_element->part;
                if(partition->sb_offset!=0 && partition->sb_size>0)
                {
                    io_redir_add_redir(disk_car,
                                       partition->part_offset+partition->sborg_offset,
                                       partition->sb_size,
                                       partition->part_offset+partition->sb_offset,
                                       NULL);
                    if(partition->upart_type==UP_NTFS ||
                            (is_part_ntfs(partition) && partition->upart_type!=UP_EXFAT))
                        ntfs_undelete_part(disk_car, partition, verbose, current_cmd);
                    else
                        dir_partition(disk_car, partition, 0, current_cmd);
                    io_redir_del_redir(disk_car, partition->part_offset+partition->sborg_offset);
                }
                else
                {
                    if(partition->upart_type==UP_NTFS ||
                            (is_part_ntfs(partition) && partition->upart_type!=UP_EXFAT))
                        ntfs_undelete_part(disk_car, partition, verbose, current_cmd);
                    else
                        dir_partition(disk_car, partition, 0, current_cmd);
                }
            }
            rewrite=1;
            break;
            case 'l':
            case 'L':
            {
                partition_t *partition=current_element->part;
                if(partition->sb_offset!=0 && partition->sb_size>0)
                {
                    io_redir_add_redir(disk_car,
                                       partition->part_offset+partition->sborg_offset,
                                       partition->sb_size,
                                       partition->part_offset+partition->sb_offset,
                                       NULL);
                    dir_partition(disk_car,partition,verbose, current_cmd);
                    io_redir_del_redir(disk_car, partition->part_offset+partition->sborg_offset);
                }
                else
                    dir_partition(disk_car,partition,verbose, current_cmd);
            }
            rewrite=1;
            break;
            case 's':
            case 'S':
            {
                if(is_linux(current_element->part))
                {
                    list_part_t *list_sb=search_superblock(disk_car,current_element->part,verbose,dump_ind,1);
                    interface_superblock(disk_car,list_sb,current_cmd);
                    part_free_list(list_sb);
                }
                if(is_hfs(current_element->part) || is_hfsp(current_element->part))
                {
                    HFS_HFSP_boot_sector(disk_car, current_element->part, verbose, current_cmd);
                }
                rewrite=1;
            }
            break;
            case 't':
            case 'T':
                if(*current_cmd!=NULL)
                    change_part_type_cli(disk_car, current_element->part, current_cmd);
                else
                    change_part_type_ncurses(disk_car, current_element->part);
                rewrite=1;
                break;
            }
            if(current_element_num<offset)
                offset=current_element_num;
            if(current_element_num>=offset+INTER_ADV)
                offset=current_element_num-INTER_ADV+1;
        }
#endif
    }
}