コード例 #1
0
ファイル: ext2_sb.c プロジェクト: Tom9X/TestDisk
int interface_superblock(disk_t *disk_car,list_part_t *list_part, char**current_cmd)
{
  const list_part_t *parts;
  const partition_t *old_part=NULL;
#ifdef HAVE_NCURSES
  struct MenuItem menuSuperblock[]=
  {
    { 'P', "Previous",""},
    { 'N', "Next","" },
    { 'Q',"Quit","Return to Advanced menu"},
    { 0, NULL, NULL }
  };
#endif
  screen_buffer_reset();
#ifdef HAVE_NCURSES
  aff_copy(stdscr);
  wmove(stdscr,4,0);
  wprintw(stdscr,"%s",disk_car->description(disk_car));
  wmove(stdscr,5,0);
  mvwaddstr(stdscr,6,0,msg_PART_HEADER_LONG);
#endif
  for(parts=list_part;parts!=NULL;parts=parts->next)
  {
    const partition_t *partition=parts->part;
    if(old_part==NULL ||
      old_part->part_offset!=partition->part_offset ||
      old_part->part_size!=partition->part_size ||
      guid_cmp(old_part->part_type_gpt, partition->part_type_gpt)!=0	||
      old_part->part_type_i386!=partition->part_type_i386 	||
      old_part->part_type_sun!=partition->part_type_sun 	||
      old_part->part_type_mac!=partition->part_type_mac 	||
      old_part->upart_type!=partition->upart_type)
    {
      aff_part_buffer(AFF_PART_BASE, disk_car, partition);
      old_part=partition;
    }
    if(partition->blocksize!=0)
      screen_buffer_add("superblock %lu, blocksize=%u [%s]\n",
          (long unsigned)(partition->sb_offset/partition->blocksize),
          partition->blocksize, partition->fsname);
  }
  if(list_part!=NULL)
  {
    const partition_t *partition=list_part->part;
    screen_buffer_add("\n");
    screen_buffer_add("To repair the filesystem using alternate superblock, run\n");
    screen_buffer_add("fsck.ext%u -p -b superblock -B blocksize device\n",
	(partition->upart_type==UP_EXT2?2:
	 (partition->upart_type==UP_EXT3?3:4)));
  }
  screen_buffer_to_log();
  if(*current_cmd==NULL)
  {
    log_flush();
#ifdef HAVE_NCURSES
    screen_buffer_display(stdscr,"",menuSuperblock);
#endif
  }
  return 0;
}
コード例 #2
0
ファイル: partgpt.c プロジェクト: AndrewSmart/testdisk
list_part_t *read_part_gpt(disk_t *disk, const int verbose, const int saveheader)
{
  list_part_t *list_part;
  screen_buffer_reset();
  if((list_part=read_part_gpt_aux(disk, verbose, saveheader, 1))!=NULL)
    return list_part;
  screen_buffer_add( "Trying alternate GPT\n");
  list_part=read_part_gpt_aux(disk, verbose, saveheader, 
      (disk->disk_size-1)/disk->sector_size);
  screen_buffer_to_log();
  return list_part;
}
コード例 #3
0
ファイル: texfat.c プロジェクト: cgsecurity/testdisk
int exFAT_boot_sector(disk_t *disk, partition_t *partition, char **current_cmd)
{
  unsigned char *buffer_bs;
  unsigned char *buffer_backup_bs;
  int rescan=1;
  const int size_bs=12 * disk->sector_size;
  const char *options;
#ifdef HAVE_NCURSES
  const struct MenuItem menu_exFAT[]=
  {
    { 'P', "Previous",""},
    { 'N', "Next","" },
    { 'Q', "Quit","Return to Advanced menu"},
    { 'O', "Org. BS","Copy superblock over backup sector"},
    { 'B', "Backup BS","Copy backup superblock over superblock"},
    { 'D', "Dump","Dump superblock and backup superblock"},
    { 0, NULL, NULL }
  };
#endif
  buffer_bs=(unsigned char*)MALLOC(size_bs);
  buffer_backup_bs=(unsigned char*)MALLOC(size_bs);
  while(1)
  {
    int command;
    screen_buffer_reset();
    if(rescan==1)
    {
      options=exFAT_boot_sector_rescan(disk, partition, buffer_bs, buffer_backup_bs);
      rescan=0;
    }
    screen_buffer_to_log();
    if(*current_cmd!=NULL)
    {
      command=exFAT_boot_sector_command(current_cmd, options);
    }
    else
    {
#ifdef HAVE_NCURSES
      unsigned int menu=0;
#endif
      log_flush();
#ifdef HAVE_NCURSES
      command=screen_buffer_display_ext(stdscr, options, menu_exFAT, &menu);
#else
      command=0;
#endif
    }
    switch(command)
    {
      case 0:
        free(buffer_bs);
        free(buffer_backup_bs);
	return 0;
      case 'O': /* O : copy original superblock over backup boot */
#ifdef HAVE_NCURSES
	if(ask_confirmation("Copy original exFAT boot record over backup, confirm ? (Y/N)")!=0)
#endif
	{
	  log_info("copy original superblock over backup boot\n");
	  if(disk->pwrite(disk, buffer_bs, size_bs, partition->part_offset + size_bs) != size_bs)
	  {
	    display_message("Write error: Can't overwrite exFAT backup boot record\n");
	  }
          disk->sync(disk);
	  rescan=1;
	}
	break;
      case 'B': /* B : copy backup superblock over main superblock */
#ifdef HAVE_NCURSES
	if(ask_confirmation("Copy backup exFAT boot record over main boot record, confirm ? (Y/N)")!=0)
#endif
	{
	  log_info("copy backup superblock over main superblock\n");
	  /* Reset information about backup boot record */
	  partition->sb_offset=0;
	  if(disk->pwrite(disk, buffer_backup_bs, size_bs, partition->part_offset) != size_bs)
	  {
	    display_message("Write error: Can't overwrite exFAT main boot record\n");
	  }
          disk->sync(disk);
	  rescan=1;
	}
	break;
      case 'D':
	exFAT_dump(disk, partition, buffer_bs, buffer_backup_bs, current_cmd);
	break;
    }
  }
}
コード例 #4
0
ファイル: dirpart.c プロジェクト: AndychenCL/TestDisk
dir_partition_t dir_partition(disk_t *disk, const partition_t *partition, const int verbose, char **current_cmd)
{
  dir_data_t dir_data;
#ifdef HAVE_NCURSES
  WINDOW *window;
#endif
  dir_partition_t res;
  fflush(stderr);
  dir_data.local_dir=NULL;
  res=dir_partition_init(disk, partition, verbose, &dir_data);
#ifdef HAVE_NCURSES
  window=newwin(LINES, COLS, 0, 0);	/* full screen */
  dir_data.display=window;
  aff_copy(window);
#else
  dir_data.display=NULL;
#endif
  log_info("\n");
  switch(res)
  {
    case DIR_PART_ENOSYS:
      screen_buffer_reset();
#ifdef HAVE_NCURSES
      aff_copy(window);
      wmove(window,4,0);
      aff_part(window,AFF_PART_ORDER|AFF_PART_STATUS,disk,partition);
#endif
      log_partition(disk,partition);
      screen_buffer_add("Support for this filesystem hasn't been enable during compilation.\n");
      screen_buffer_to_log();
      if(*current_cmd==NULL)
      {
#ifdef HAVE_NCURSES
	screen_buffer_display(window,"",NULL);
#endif
      }
      break;
    case DIR_PART_EIO:
      screen_buffer_reset();
#ifdef HAVE_NCURSES
      aff_copy(window);
      wmove(window,4,0);
      aff_part(window,AFF_PART_ORDER|AFF_PART_STATUS,disk,partition);
#endif
      log_partition(disk,partition);
      screen_buffer_add("Can't open filesystem. Filesystem seems damaged.\n");
      screen_buffer_to_log();
      if(*current_cmd==NULL)
      {
#ifdef HAVE_NCURSES
	screen_buffer_display(window,"",NULL);
#endif
      }
      break;
    case DIR_PART_OK:
      {
	int recursive=0;
	if(*current_cmd!=NULL)
	{
	  int do_continue;
	  do
	  {
	    do_continue=0;
	    while(*current_cmd[0]==',')
	      (*current_cmd)++;
	    if(strncmp(*current_cmd,"recursive",9)==0)
	    {
	      (*current_cmd)+=9;
	      recursive=1;
	      do_continue=1;
	    }
	    else if(strncmp(*current_cmd,"fullpathname",12)==0)
	    {
	      (*current_cmd)+=12;
	      dir_data.param|=FLAG_LIST_PATHNAME;
	      do_continue=1;
	    }
	  } while(do_continue==1);
	}
	if(recursive>0)
	  dir_whole_partition_log(disk,partition,&dir_data,dir_data.current_inode);
	else
	{
#ifdef HAVE_NCURSES
	  dir_partition_aff(disk, partition, &dir_data, dir_data.current_inode, current_cmd);
#else
	  {
	    file_info_t dir_list = {
	      .list = TD_LIST_HEAD_INIT(dir_list.list),
	      .name = NULL
	    };
	    dir_data.get_dir(disk, partition, &dir_data, dir_data.current_inode, &dir_list);
	    dir_aff_log(&dir_data, &dir_list);
	    delete_list_file(&dir_list);
	  }
#endif
	}
	dir_data.close(&dir_data);
      }
      break;
  }
#ifdef HAVE_NCURSES
  delwin(window);
  (void) clearok(stdscr, TRUE);
#ifdef HAVE_TOUCHWIN
  touchwin(stdscr);
#endif
  wrefresh(stdscr);
#endif
  fflush(stderr);
  free(dir_data.local_dir);
  return res;
}
コード例 #5
0
ファイル: tanalyse.c プロジェクト: AndrewSmart/testdisk
static list_part_t *interface_analyse_ncurses(disk_t *disk_car, const int verbose, const int saveheader, char**current_cmd)
{
  list_part_t *list_part;
  int command;
#ifdef HAVE_NCURSES
  const struct MenuItem menuAnalyse[]=
  {
    { 'P', "Previous",""},
    { 'N', "Next","" },
    { 'Q',"Quick Search","Try to locate partition"},
    { 'B', "Backup","Save current partition list to backup.log file and proceed"},
    { 0, NULL, NULL }
  };
#endif
  screen_buffer_reset();
  /* ncurses interface */
#ifdef HAVE_NCURSES
  aff_copy(stdscr);
  wmove(stdscr,4,0);
  wprintw(stdscr,"%s\n",disk_car->description(disk_car));
  mvwaddstr(stdscr,5,0,"Checking current partition structure");
  wrefresh(stdscr);
#endif
  list_part=disk_car->arch->read_part(disk_car,verbose,saveheader);
  log_info("Current partition structure:\n");
  screen_buffer_to_log();
#ifdef HAVE_NCURSES
  wmove(stdscr,5,0);
  wclrtoeol(stdscr);	/* before addstr for BSD compatibility */
  waddstr(stdscr,"Current partition structure:");
  wmove(stdscr,6,0);
  wprintw(stdscr,msg_PART_HEADER_LONG);
  if(disk_car->arch->msg_part_type!=NULL)
    mvwaddstr(stdscr,LINES-3,0,disk_car->arch->msg_part_type);
#endif
  command='Q';
  if(*current_cmd!=NULL)
  {
    while(*current_cmd[0]==',')
      (*current_cmd)++;
    if(strncmp(*current_cmd,"backup",6)==0)
    {
      (*current_cmd)+=6;
      if(list_part!=NULL)
	command='B';
    }
  }
  else
  {
    log_flush();
#ifdef HAVE_NCURSES
    command=screen_buffer_display(stdscr,
	(list_part!=NULL && disk_car->arch != &arch_none?"QB":"Q"),
	menuAnalyse);
#endif
  }
  if(command=='B')
  {
    log_info("Backup partition structure\n");
    if(partition_save(disk_car,list_part,verbose)<0)
    {
      display_message("Can't create backup.log.\n");
    }
  }
  return list_part;
}
コード例 #6
0
ファイル: texfat.c プロジェクト: Tom9X/TestDisk
int exFAT_boot_sector(disk_t *disk, partition_t *partition, const int verbose, char **current_cmd)
{
  unsigned char *buffer_bs;
  unsigned char *buffer_backup_bs;
  const char *options="";
  int rescan=1;
#ifdef HAVE_NCURSES
  struct MenuItem menu_exFAT[]=
  {
    { 'P', "Previous",""},
    { 'N', "Next","" },
    { 'Q', "Quit","Return to Advanced menu"},
    { 'O', "Org. BS","Copy superblock over backup sector"},
    { 'B', "Backup BS","Copy backup superblock over superblock"},
    { 'D', "Dump","Dump superblock and backup superblock"},
    { 0, NULL, NULL }
  };
#endif
  buffer_bs=(unsigned char*)MALLOC(12 * disk->sector_size);
  buffer_backup_bs=(unsigned char*)MALLOC(12 * disk->sector_size);

  while(1)
  {
#ifdef HAVE_NCURSES
    unsigned int menu=0;
#endif
    int command;
    screen_buffer_reset();
    if(rescan==1)
    {
      int opt_over=0;
      int opt_B=0;
      int opt_O=0;
      options="D";
#ifdef HAVE_NCURSES
      aff_copy(stdscr);
      wmove(stdscr,4,0);
      wprintw(stdscr,"%s",disk->description(disk));
      mvwaddstr(stdscr,5,0,msg_PART_HEADER_LONG);
      wmove(stdscr,6,0);
      aff_part(stdscr,AFF_PART_ORDER|AFF_PART_STATUS,disk,partition);
#endif
      log_info("\nexFAT_boot_sector\n");
      log_partition(disk,partition);
      screen_buffer_add("Boot sector\n");
      if(disk->pread(disk, buffer_bs, 12 * disk->sector_size, partition->part_offset) != 12 * disk->sector_size)
      {
	screen_buffer_add("Bad: can't read exFAT boot record.\n");
	memset(buffer_bs,0,12 * disk->sector_size);
      }
      else if(test_EXFAT((const struct exfat_super_block*)buffer_bs, partition)==0)
      {
	screen_buffer_add("exFAT OK\n");
	opt_O=1;
	opt_over=1;
      }
      else
	screen_buffer_add("Bad\n");
      screen_buffer_add("\nBackup boot record\n");
      if(disk->pread(disk, buffer_backup_bs, 12 * disk->sector_size, partition->part_offset + 12 * disk->sector_size) != 12 * disk->sector_size)
      {
	screen_buffer_add("Bad: can't read exFAT backup boot record.\n");
	memset(buffer_backup_bs,0,12 * disk->sector_size);
      }
      else if(test_EXFAT((const struct exfat_super_block*)buffer_backup_bs, partition)==0)
      {
	screen_buffer_add("exFAT OK\n");
	opt_B=1;
	opt_over=1;
      }
      else
	screen_buffer_add("Bad\n");
      screen_buffer_add("\n");
      if(memcmp(buffer_bs,buffer_backup_bs,12 * disk->sector_size)==0)
      {
	screen_buffer_add("Sectors are identical.\n");
	opt_over=0;
      }
      else
      {
	screen_buffer_add("Sectors are not identical.\n");
      }
      if(opt_over!=0)
      {
	if(opt_B!=0 && opt_O!=0)
	  options="DOB";
	else if(opt_B!=0)
	  options="DB";
	else if(opt_O!=0)
	  options="DO";
      }
      rescan=0;
    }
    screen_buffer_to_log();
    if(*current_cmd!=NULL)
    {
      command=0;
      while(*current_cmd[0]==',')
	(*current_cmd)++;
      if(strncmp(*current_cmd,"dump",4)==0)
      {
	(*current_cmd)+=4;
	command='D';
      }
      else if(strncmp(*current_cmd,"originalexFAT",11)==0)
      {
	(*current_cmd)+=11;
	if(strchr(options,'O')!=NULL)
	    command='O';
      }
      else if(strncmp(*current_cmd,"backupexFAT",9)==0)
      {
	(*current_cmd)+=9;
	if(strchr(options,'B')!=NULL)
	    command='B';
      }
    }
    else
    {
      log_flush();
#ifdef HAVE_NCURSES
      command=screen_buffer_display_ext(stdscr, options, menu_exFAT, &menu);
#else
      command=0;
#endif
    }
    switch(command)
    {
      case 0:
        free(buffer_bs);
        free(buffer_backup_bs);
	return 0;
      case 'O': /* O : copy original superblock over backup boot */
#ifdef HAVE_NCURSES
	if(ask_confirmation("Copy original exFAT boot record over backup, confirm ? (Y/N)")!=0)
	{
	  log_info("copy original superblock over backup boot\n");
	  if(disk->pwrite(disk, buffer_bs, 12 * disk->sector_size, partition->part_offset + 12 * disk->sector_size) != 12 * disk->sector_size)
	  {
	    display_message("Write error: Can't overwrite exFAT backup boot record\n");
	  }
          disk->sync(disk);
	  rescan=1;
	}
#endif
	break;
      case 'B': /* B : copy backup superblock over main superblock */
#ifdef HAVE_NCURSES
	if(ask_confirmation("Copy backup exFAT boot record over main boot record, confirm ? (Y/N)")!=0)
	{
	  log_info("copy backup superblock over main superblock\n");
	  /* Reset information about backup boot record */
	  partition->sb_offset=0;
	  if(disk->pwrite(disk, buffer_backup_bs, 12 * disk->sector_size, partition->part_offset) != 12 * disk->sector_size)
	  {
	    display_message("Write error: Can't overwrite exFAT main boot record\n");
	  }
          disk->sync(disk);
	  rescan=1;
	}
#endif
	break;
      case 'D':
	exFAT_dump(disk, partition, buffer_bs, buffer_backup_bs, current_cmd);
	break;
    }
  }
}
コード例 #7
0
ファイル: dirpart.c プロジェクト: Tom9X/TestDisk
int dir_partition(disk_t *disk_car, const partition_t *partition, const int verbose, char **current_cmd)
{
  dir_data_t dir_data;
#ifdef HAVE_NCURSES
  WINDOW *window;
#endif
  int res=-3;
  fflush(stderr);
  dir_data.local_dir=NULL;
  if(is_part_fat(partition))
    res=dir_partition_fat_init(disk_car,partition,&dir_data,verbose);
  else if(is_part_ntfs(partition))
  {
    res=dir_partition_ntfs_init(disk_car,partition,&dir_data,verbose);
    if(res!=0)
      res=dir_partition_exfat_init(disk_car, partition, &dir_data, verbose);
  }
  else if(is_part_linux(partition))
  {
    res=dir_partition_ext2_init(disk_car,partition,&dir_data,verbose);
    if(res!=0)
      res=dir_partition_reiser_init(disk_car,partition,&dir_data,verbose);
  }
  if(res!=0)
  {
    switch(partition->upart_type)
    {
      case UP_FAT12:
      case UP_FAT16:
      case UP_FAT32:
	res=dir_partition_fat_init(disk_car,partition,&dir_data,verbose);
	break;
      case UP_EXT4:
      case UP_EXT3:
      case UP_EXT2:
	res=dir_partition_ext2_init(disk_car,partition,&dir_data,verbose);
	break;
      case UP_RFS:
      case UP_RFS2:
      case UP_RFS3:
	res=dir_partition_reiser_init(disk_car,partition,&dir_data,verbose);
	break;
      case UP_NTFS:
	res=dir_partition_ntfs_init(disk_car,partition,&dir_data,verbose);
	break;
      case UP_EXFAT:
	res=dir_partition_exfat_init(disk_car, partition, &dir_data, verbose);
	break;
      default:
	return res;
    }
  }
#ifdef HAVE_NCURSES
  window=newwin(LINES, COLS, 0, 0);	/* full screen */
  dir_data.display=window;
  aff_copy(window);
#else
  dir_data.display=NULL;
#endif
  log_info("\n");
  switch(res)
  {
    case -2:
      screen_buffer_reset();
#ifdef HAVE_NCURSES
      aff_copy(window);
      wmove(window,4,0);
      aff_part(window,AFF_PART_ORDER|AFF_PART_STATUS,disk_car,partition);
#endif
      log_partition(disk_car,partition);
      screen_buffer_add("Support for this filesystem hasn't been enable during compilation.\n");
      screen_buffer_to_log();
      if(*current_cmd==NULL)
      {
#ifdef HAVE_NCURSES
	screen_buffer_display(window,"",NULL);
#endif
      }
      break;
    case -1:
      screen_buffer_reset();
#ifdef HAVE_NCURSES
      aff_copy(window);
      wmove(window,4,0);
      aff_part(window,AFF_PART_ORDER|AFF_PART_STATUS,disk_car,partition);
#endif
      log_partition(disk_car,partition);
      screen_buffer_add("Can't open filesystem. Filesystem seems damaged.\n");
      screen_buffer_to_log();
      if(*current_cmd==NULL)
      {
#ifdef HAVE_NCURSES
	screen_buffer_display(window,"",NULL);
#endif
      }
      break;
    default:
      {
	int recursive=0;
	if(*current_cmd!=NULL)
	{
	  int do_continue;
	  do
	  {
	    do_continue=0;
	    while(*current_cmd[0]==',')
	      (*current_cmd)++;
	    if(strncmp(*current_cmd,"recursive",9)==0)
	    {
	      (*current_cmd)+=9;
	      recursive=1;
	      do_continue=1;
	    }
	    else if(strncmp(*current_cmd,"fullpathname",12)==0)
	    {
	      (*current_cmd)+=12;
	      dir_data.param|=FLAG_LIST_PATHNAME;
	      do_continue=1;
	    }
	  } while(do_continue==1);
	}
	if(recursive>0)
	  dir_whole_partition_log(disk_car,partition,&dir_data,dir_data.current_inode);
	else
	{
#ifdef HAVE_NCURSES
	  dir_partition_aff(disk_car, partition, &dir_data, dir_data.current_inode, current_cmd);
#else
	  {
	    file_data_t *dir_list;
	    dir_list=dir_data.get_dir(disk_car, partition, &dir_data, dir_data.current_inode);
	    dir_aff_log(&dir_data, dir_list);
	    delete_list_file(dir_list);
	  }
#endif
	}
	dir_data.close(&dir_data);
      }
      break;
  }
#ifdef HAVE_NCURSES
  delwin(window);
  (void) clearok(stdscr, TRUE);
#ifdef HAVE_TOUCHWIN
  touchwin(stdscr);
#endif
  wrefresh(stdscr);
#endif
  fflush(stderr);
  free(dir_data.local_dir);
  return res;
}
コード例 #8
0
ファイル: tntfs.c プロジェクト: Tom9X/TestDisk
int ntfs_boot_sector(disk_t *disk_car, partition_t *partition, const int verbose, const unsigned int expert, char **current_cmd)
{
  unsigned char *buffer_bs;
  unsigned char *buffer_backup_bs;
  const char *options="";
#ifdef HAVE_NCURSES
  struct MenuItem menu_ntfs[]=
  {
    { 'P', "Previous",""},
    { 'N', "Next","" },
    { 'Q', "Quit","Return to Advanced menu"},
    { 'L', "List", "List directories and files, copy data from NTFS" },
    { 'O', "Org. BS","Copy boot sector over backup sector"},
    { 'B', "Backup BS","Copy backup boot sector over boot sector"},
    { 'R', "Rebuild BS","Rebuild boot sector"},
    { 'M', "Repair MFT","Check MFT"},
    { 'D', "Dump","Dump boot sector and backup boot sector"},
    { 0, NULL, NULL }
  };
#endif
  buffer_bs=(unsigned char*)MALLOC(NTFS_BOOT_SECTOR_SIZE);
  buffer_backup_bs=(unsigned char*)MALLOC(NTFS_BOOT_SECTOR_SIZE);

  while(1)
  {
    unsigned int menu=0;
    int command;
    screen_buffer_reset();
    {
      int identical_sectors=0;
      int opt_B=0;
      int opt_O=0;
#ifdef HAVE_NCURSES
      aff_copy(stdscr);
      wmove(stdscr,4,0);
      wprintw(stdscr,"%s",disk_car->description(disk_car));
      mvwaddstr(stdscr,5,0,msg_PART_HEADER_LONG);
      wmove(stdscr,6,0);
      aff_part(stdscr,AFF_PART_ORDER|AFF_PART_STATUS,disk_car,partition);
#endif
      log_info("\nntfs_boot_sector\n");
      log_partition(disk_car,partition);
      screen_buffer_add("Boot sector\n");
      if(disk_car->pread(disk_car, buffer_bs, NTFS_BOOT_SECTOR_SIZE, partition->part_offset) != NTFS_BOOT_SECTOR_SIZE)
      {
	screen_buffer_add("ntfs_boot_sector: Can't read boot sector.\n");
	memset(buffer_bs,0,NTFS_BOOT_SECTOR_SIZE);
      }
      if(test_NTFS(disk_car,(struct ntfs_boot_sector*)buffer_bs,partition,verbose,0)==0)
      {
	screen_buffer_add("Status: OK\n");
	opt_O=1;
      }
      else
      {
	screen_buffer_add("Status: Bad\n");
      }
      screen_buffer_add("\nBackup boot sector\n");
      if(disk_car->pread(disk_car, buffer_backup_bs, NTFS_BOOT_SECTOR_SIZE, partition->part_offset + partition->part_size - disk_car->sector_size) != NTFS_BOOT_SECTOR_SIZE)
      {
	screen_buffer_add("ntfs_boot_sector: Can't read backup boot sector.\n");
	memset(buffer_backup_bs,0,NTFS_BOOT_SECTOR_SIZE);
      }
      if(test_NTFS(disk_car,(struct ntfs_boot_sector*)buffer_backup_bs,partition,verbose,0)==0)
      {
	screen_buffer_add("Status: OK\n");
	opt_B=1;
      }
      else
      {
	screen_buffer_add("Status: Bad\n");
      }
      screen_buffer_add("\n");
      if(memcmp(buffer_bs,buffer_backup_bs,NTFS_BOOT_SECTOR_SIZE)==0)
      {
	log_ntfs_info((const struct ntfs_boot_sector *)buffer_bs);
	screen_buffer_add("Sectors are identical.\n");
	identical_sectors=1;
      }
      else
      {
	log_ntfs2_info((const struct ntfs_boot_sector *)buffer_bs, (const struct ntfs_boot_sector *)buffer_backup_bs);
	screen_buffer_add("Sectors are not identical.\n");
	identical_sectors=0;
      }
      screen_buffer_add("\n");
      screen_buffer_add("A valid NTFS Boot sector must be present in order to access\n");
      screen_buffer_add("any data; even if the partition is not bootable.\n");
      if(opt_B!=0 && opt_O!=0)
      {
	if(identical_sectors==0)
	  options="DOBRL";
	else
	  options="DRML";
      }
      else if(opt_B!=0)
      {
	menu=5;
	if(expert>0)
	  options="DBRML";
	else
	  options="DBRL";
      }
      else if(opt_O!=0)
      {
	menu=4;
	options="DORL";
      }
      else
	options="DR";
    }
    screen_buffer_to_log();
    if(*current_cmd!=NULL)
    {
      command=0;
      while(*current_cmd[0]==',')
	(*current_cmd)++;
      if(strncmp(*current_cmd,"rebuildbs",9)==0)
      {
	(*current_cmd)+=9;
	command='R';
      }
      else if(strncmp(*current_cmd,"dump",4)==0)
      {
	(*current_cmd)+=4;
	command='D';
      }
      else if(strncmp(*current_cmd,"list",4)==0)
      {
	(*current_cmd)+=4;
	command='L';
      }
      else if(strncmp(*current_cmd,"originalntfs",11)==0)
      {
	(*current_cmd)+=11;
	if(strchr(options,'O')!=NULL)
	    command='O';
      }
      else if(strncmp(*current_cmd,"backupntfs",9)==0)
      {
	(*current_cmd)+=9;
	if(strchr(options,'B')!=NULL)
	    command='B';
      }
      else if(strncmp(*current_cmd,"repairmft",9)==0)
      {
	(*current_cmd)+=9;
	if(strchr(options,'M')!=NULL)
	    command='M';
      }
    }
    else
    {
      log_flush();
#ifdef HAVE_NCURSES
      command=screen_buffer_display_ext(stdscr, options, menu_ntfs, &menu);
#else
      command=0;
#endif
    }
    switch(command)
    {
      case 0:
        free(buffer_bs);
        free(buffer_backup_bs);
	return 0;
      case 'O': /* O : copy original boot sector over backup boot */
#ifdef HAVE_NCURSES
	if(ask_confirmation("Copy original NTFS boot sector over backup boot, confirm ? (Y/N)")!=0)
	{
	  log_info("copy original boot sector over backup boot\n");
	  if(disk_car->pwrite(disk_car, buffer_bs, NTFS_BOOT_SECTOR_SIZE, partition->part_offset + partition->part_size - disk_car->sector_size) != NTFS_BOOT_SECTOR_SIZE)
	  {
	    display_message("Write error: Can't overwrite NTFS backup boot sector\n");
	  }
          disk_car->sync(disk_car);
	}
#endif
	break;
      case 'B': /* B : copy backup boot sector over boot sector */
#ifdef HAVE_NCURSES
	if(ask_confirmation("Copy backup NTFS boot sector over boot sector, confirm ? (Y/N)")!=0)
	{
	  log_info("copy backup boot sector over boot sector\n");
	  /* Reset information about backup boot sector */
	  partition->sb_offset=0;
	  if(disk_car->pwrite(disk_car, buffer_backup_bs, NTFS_BOOT_SECTOR_SIZE, partition->part_offset) != NTFS_BOOT_SECTOR_SIZE)
	  {
	    display_message("Write error: Can't overwrite NTFS boot sector\n");
	  }
          disk_car->sync(disk_car);
	}
#endif
	break;
      case 'L':
	if(strchr(options,'O')==NULL && strchr(options,'B')!=NULL)
	{
	  io_redir_add_redir(disk_car,partition->part_offset,NTFS_BOOT_SECTOR_SIZE,0,buffer_backup_bs);
	  dir_partition(disk_car, partition, 0,current_cmd);
	  io_redir_del_redir(disk_car,partition->part_offset);
	}
	else
	  dir_partition(disk_car, partition, 0,current_cmd);
	break;
      case 'M':
        repair_MFT(disk_car, partition, verbose, expert, current_cmd);
	break;
      case 'R': /* R : rebuild boot sector */
	rebuild_NTFS_BS(disk_car, partition, verbose, 1, expert, current_cmd);
	break;
      case 'D':
	dump_NTFS(disk_car, partition, buffer_bs, buffer_backup_bs);
	break;
    }
  }
}