Example #1
0
static void warning_geometry_ncurses(disk_t *disk_car, const unsigned int recommanded_heads_per_cylinder)
{
  aff_copy(stdscr);
  wmove(stdscr,4,0);
  wprintw(stdscr,"%s",disk_car->description(disk_car));
  wmove(stdscr,6,0);
  wprintw(stdscr, "Warning: the current number of heads per cylinder is %u",
      disk_car->geom.heads_per_cylinder);
  wmove(stdscr,7,0);
  wprintw(stdscr,"but the correct value may be %u.",recommanded_heads_per_cylinder);
  wmove(stdscr,8,0);
  wprintw(stdscr,"You can use the Geometry menu to change this value.");
  wmove(stdscr,9,0);
  wprintw(stdscr,"It's something to try if");
  wmove(stdscr,10,0);
  wprintw(stdscr,"- some partitions are not found by TestDisk");
  wmove(stdscr,11,0);
  wprintw(stdscr,"- or the partition table can not be written because partitions overlap.");
  wmove(stdscr,22,0);
  wattrset(stdscr, A_REVERSE);
  wprintw(stdscr,"[ Continue ]");
  wattroff(stdscr, A_REVERSE);
  wrefresh(stdscr);
  while(wgetch(stdscr)==ERR);
}
Example #2
0
static void change_part_type_ncurses(const disk_t *disk_car,partition_t *partition)
{
  partition_t *new_partition;
  char response[100];
  int size=0;
  int i;
  unsigned int last[3], done = 0, next = 0;
  struct part_name_struct part_name[0x100];
  struct MenuItem menuType[]=
  {
    { 'P', "Previous",""},
    { 'N', "Next","" },
    { 'Q', "Proceed","Go set the partition type"},
    { 0, NULL, NULL }
  };
  if(partition->arch->set_part_type==NULL)
    return ;
  /* Create an index of all partition type except Intel extended */
  new_partition=partition_new(NULL);
  dup_partition_t(new_partition,partition);
  for(i=0;i<=0xFF;i++)
  {
    if(partition->arch->set_part_type(new_partition,i)==0)
    {
      part_name[size].name=new_partition->arch->get_partition_typename(new_partition);
      if(part_name[size].name!=NULL)
	part_name[size++].index=i;
    }
  }
  free(new_partition);

  /* Display the list of partition type in 3 columns */
  screen_buffer_reset();
  screen_buffer_add("List of partition type\n");
  for (i = 2; i >= 0; i--)
    last[2 - i] = done += (size + i - done) / (i + 1);
  i = done = 0;
  while (done < last[0])
  {
    screen_buffer_add( "%02x %-20s%c",  part_name[next].index, part_name[next].name,(i==2 ? '\n' : ' '));
    next = last[i++] + done;
    if (i > 2 || next >= last[i]) {
      i = 0;
      next = ++done;
    }
  }

  /* Ask for the new partition type*/
  aff_copy(stdscr);
  wmove(stdscr,4,0);
  aff_part(stdscr,AFF_PART_ORDER|AFF_PART_STATUS,disk_car,partition);
  screen_buffer_display(stdscr,"",menuType);
  wmove(stdscr,LINES-2,0);
  wclrtoeol(stdscr);
  wprintw(stdscr,"New partition type [current %02x] ? ",partition->arch->get_part_type(partition));
  if (get_string(stdscr, response, sizeof(response), NULL) > 0) {
    int tmp_val = strtol(response, NULL, 16);
    partition->arch->set_part_type(partition,tmp_val);
  }
}
Example #3
0
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;
}
Example #4
0
static const char *exFAT_boot_sector_rescan(disk_t *disk, partition_t *partition, unsigned char *buffer_bs, unsigned char *buffer_backup_bs)
{
  const int size_bs=12 * disk->sector_size;
  int opt_B=0;
  int opt_O=0;
#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, size_bs, partition->part_offset) != size_bs)
  {
    screen_buffer_add("Bad: can't read exFAT boot record.\n");
    memset(buffer_bs,0,size_bs);
  }
  else if(test_exFAT((const struct exfat_super_block*)buffer_bs)==0)
  {
    screen_buffer_add("exFAT OK\n");
    opt_O=1;
  }
  else
    screen_buffer_add("Bad\n");
  screen_buffer_add("\nBackup boot record\n");
  if(disk->pread(disk, buffer_backup_bs, size_bs, partition->part_offset + size_bs) != size_bs)
  {
    screen_buffer_add("Bad: can't read exFAT backup boot record.\n");
    memset(buffer_backup_bs,0,size_bs);
  }
  else if(test_exFAT((const struct exfat_super_block*)buffer_backup_bs)==0)
  {
    screen_buffer_add("exFAT OK\n");
    opt_B=1;
  }
  else
    screen_buffer_add("Bad\n");
  screen_buffer_add("\n");
  if(memcmp(buffer_bs, buffer_backup_bs, size_bs)==0)
  {
    screen_buffer_add("Sectors are identical.\n");
    return "D";
  }
  else
  {
    screen_buffer_add("Sectors are not identical.\n");
  }
  if(opt_B!=0 && opt_O!=0)
    return "DOB";
  else if(opt_B!=0)
    return "DB";
  else if(opt_O!=0)
    return "DO";
  return "D";
}
Example #5
0
int intrf_no_disk_ncurses(const char *prog_name)
{
  aff_copy(stdscr);
  wmove(stdscr,4,0);
  wprintw(stdscr,"  %s is free software, and",prog_name);
  wmove(stdscr,5,0);
  wprintw(stdscr,"comes with ABSOLUTELY NO WARRANTY.");
  wmove(stdscr,7,0);
  wprintw(stdscr,"No harddisk found\n");
#if defined(__CYGWIN__) || defined(__MINGW32__)
  wmove(stdscr,8,0);
  wprintw(stdscr,"You need to be administrator to use %s.\n", prog_name);
  wmove(stdscr,9,0);
  wprintw(stdscr,"Under Win9x, use the DOS version instead.\n");
  wmove(stdscr,10,0);
  wprintw(stdscr,"Under Vista or later, select %s, right-click and\n", prog_name);
  wmove(stdscr,11,0);
  wprintw(stdscr,"choose \"Run as administrator\".\n");
#elif defined(DJGPP)
#else
#ifdef HAVE_GETEUID
  if(geteuid()!=0)
  {
    wmove(stdscr,8,0);
    wprintw(stdscr,"You need to be root to use %s.\n", prog_name);
#ifdef SUDO_BIN
    {
      static const struct MenuItem menuSudo[]=
      {
	{'S',"Sudo","Use the sudo command to restart as root"},
	{'Q',"Quit",""},
	{0,NULL,NULL}
      };
      unsigned int menu=0;
      int command;
      command = wmenuSelect_ext(stdscr,23, 20, 0, menuSudo, 8,
	  "SQ", MENU_VERT | MENU_VERT_WARN | MENU_BUTTON, &menu,NULL);
      if(command=='s' || command=='S')
	return 1;
      return 0;
    }
#endif
  }
#endif
#endif
  wmove(stdscr,22,0);
  wattrset(stdscr, A_REVERSE);
  waddstr(stdscr,"[ Quit ]");
  wattroff(stdscr, A_REVERSE);
  wrefresh(stdscr);
  while(wgetch(stdscr)==ERR);
  return 0;
}
Example #6
0
void dump_ncurses(const void *nom_dump, unsigned int lng)
{
  WINDOW *window=newwin(LINES, COLS, 0, 0);	/* full screen */
  keypad(window, TRUE); /* Need it to get arrow key */
  aff_copy(window);
  dump(window, nom_dump, lng);
  dump_log(nom_dump,lng);
  delwin(window);
  (void) clearok(stdscr, TRUE);
#ifdef HAVE_TOUCHWIN
  touchwin(stdscr);
#endif
}
Example #7
0
static void exFAT_dump_ncurses(disk_t *disk, const partition_t *partition, const unsigned char *buffer_bs, const unsigned char *buffer_backup_bs)
{
  WINDOW *window=newwin(LINES, COLS, 0, 0);	/* full screen */
  keypad(window, TRUE); /* Need it to get arrow key */
  aff_copy(window);
  wmove(window,4,0);
  wprintw(window,"%s",disk->description(disk));
  wmove(window,5,0);
  aff_part(window,AFF_PART_ORDER|AFF_PART_STATUS,disk,partition);
  mvwaddstr(window,6,0, "Boot sector                       Backup boot record");
  dump2(window, buffer_bs, buffer_backup_bs, 12 * disk->sector_size);
  delwin(window);
  (void) clearok(stdscr, TRUE);
#ifdef HAVE_TOUCHWIN
  touchwin(stdscr);
#endif
}
Example #8
0
int ask_confirmation(const char*_format, ...)
{
  va_list ap;
  int res;
  WINDOW *window=newwin(LINES, COLS, 0, 0);	/* full screen */
  aff_copy(window);
  va_start(ap,_format);
  vaff_txt(4, window, _format, ap);
  va_end(ap);
  res=ask_YN(window);
  delwin(window);
  (void) clearok(stdscr, TRUE);
#ifdef HAVE_TOUCHWIN
  touchwin(stdscr);
#endif
  return res;
}
Example #9
0
void display_message(const char*msg)
{
  static const struct MenuItem menuGeometry[]=
  {
    { 'Q', "Ok", "" },
    { 0, NULL, NULL }
  };
  WINDOW *window=newwin(LINES, COLS, 0, 0);	/* full screen */
  log_info("%s",msg);
  aff_copy(window);
  mvwaddstr(window,5,0,msg);
  wmenuSimple(window,menuGeometry, 0);
  delwin(window);
  (void) clearok(stdscr, TRUE);
#ifdef HAVE_TOUCHWIN
  touchwin(stdscr);
#endif
}
Example #10
0
void not_implemented(const char *msg)
{
  WINDOW *window=newwin(LINES, COLS, 0, 0);	/* full screen */
  aff_copy(window);
  wmove(window,7,0);
  wprintw(window,"Function %s not implemented",msg);
  log_warning("Function %s not implemented\n",msg);
  wmove(window,22,0);
  wattrset(window, A_REVERSE);
  wprintw(window,"[ Abort ]");
  wattroff(window, A_REVERSE);
  wrefresh(window);
  while(wgetch(window)==ERR);
  delwin(window);
  (void) clearok(stdscr, TRUE);
#ifdef HAVE_TOUCHWIN
  touchwin(stdscr);
#endif
}
Example #11
0
char *ask_log_location(const char*filename, const int errsv)
{
  static char response[128];
  aff_copy(stdscr);
  if(filename!=NULL)
  {
    wmove(stdscr,6,0);
    wprintw(stdscr,"Cannot open %s: %s\n",filename, strerror(errsv));
  }
  wmove(stdscr,8,0);
  wprintw(stdscr,"Please enter the full log filename or press ");
  if(has_colors())
    wbkgdset(stdscr,' ' | A_BOLD | COLOR_PAIR(0));
  wprintw(stdscr,"Enter");
  if(has_colors())
    wbkgdset(stdscr,' ' | COLOR_PAIR(0));
  wmove(stdscr,9,0);
  wprintw(stdscr,"to abort log file creation.\n");
  wclrtoeol(stdscr);
  if (get_string(stdscr, response, sizeof(response), NULL) > 0)
    return response;
  return NULL;
}
Example #12
0
int disk_image(disk_t *disk, const partition_t *partition, const char *image_dd)
{
  int ind_stop=0;
  uint64_t nbr_read_error=0;
  uint64_t src_offset=partition->part_offset;
  uint64_t src_offset_old;
  uint64_t dst_offset=0;
  const uint64_t src_offset_end=partition->part_offset+partition->part_size;
  const uint64_t offset_inc=(src_offset_end-src_offset)/10000;
  uint64_t src_offset_next=src_offset;
  struct stat stat_buf;
  unsigned char *buffer=(unsigned char *)MALLOC(READ_SIZE);
  unsigned int readsize=READ_SIZE;
  int disk_dst;
#ifdef HAVE_NCURSES
  WINDOW *window;
#endif
  if((disk_dst=open(image_dd, O_CREAT|O_LARGEFILE|O_RDWR|O_BINARY, 0644)) < 0)
  {
    log_error("Can't create file %s.\n",image_dd);
    display_message("Can't create file!\n");
    free(buffer);
    return -1;
  }
  if(fstat(disk_dst, &stat_buf)==0)
  {
    int res=1;
#ifdef HAVE_NCURSES
    if(stat_buf.st_size > 0)
      res=ask_confirmation("Append to existing file ? (Y/N)");
#endif
    if(res>0)
    {
      dst_offset=stat_buf.st_size;
      src_offset+=dst_offset;
    }
  }
  src_offset_old=src_offset;
#ifdef HAVE_NCURSES
  window=newwin(LINES, COLS, 0, 0);	/* full screen */
  aff_copy(window);
  wmove(window,5,0);
  wprintw(window,"%s\n",disk->description_short(disk));
  wmove(window,6,0);
  aff_part(window,AFF_PART_ORDER|AFF_PART_STATUS,disk,partition);
  wmove(window,10,0);
  waddstr(window, "Disk images are mainly used ");
  wmove(window,11,0);
  waddstr(window, "- for forensics purpose");
  wmove(window,12,0);
  waddstr(window, "- or to deal with media with bad sectors");
#ifdef WIN32
  wmove(window,14,0);
  waddstr(window, "To use TestDisk or PhotoRec with this disk image, go in command line and run");
  wmove(window,15,0);
  waddstr(window, "   testdisk_win.exe image.dd");
  wmove(window,16,0);
  waddstr(window, "or photorec_win.exe image.dd");
#else
  wmove(window,14,0);
  waddstr(window, "To use TestDisk or PhotoRec with this disk image, start a Terminal and run");
  wmove(window,15,0);
  waddstr(window, "   testdisk image.dd");
  wmove(window,16,0);
  waddstr(window, "or photorec image.dd");
#endif
  wmove(window,22,0);
  wattrset(window, A_REVERSE);
  waddstr(window,"  Stop  ");
  wattroff(window, A_REVERSE);
#endif
  while(ind_stop==0 && src_offset < src_offset_end)
  {
    ssize_t pread_res;
    int update=0;
    if(src_offset_end-src_offset < readsize)
      readsize=src_offset_end-src_offset;
    pread_res=disk->pread(disk, buffer, readsize, src_offset);
    if(pread_res > 0)
    {
#if defined(HAVE_PWRITE)
      if(pwrite(disk_dst, buffer, pread_res, dst_offset)<0)
      {
	ind_stop=2;
      }
#else
      if(lseek(disk_dst, dst_offset, SEEK_SET)<0)
      {
	ind_stop=2;
      }
      if(write(disk_dst, buffer, pread_res) != pread_res)
      {
	ind_stop=2;
      }
#endif
      if(src_offset_old + SKIP_SIZE==src_offset)
      {
	disk_image_backward(disk_dst, disk, src_offset_old, src_offset, dst_offset);
      }
    }
    src_offset_old=src_offset;
    if((unsigned)pread_res == readsize)
    {
      src_offset+=readsize;
      dst_offset+=readsize;
      readsize=READ_SIZE;
    }
    else
    {
      update=1;
      nbr_read_error++;
      readsize=disk->sector_size;
      src_offset+=SKIP_SIZE;
      dst_offset+=SKIP_SIZE;
    }
    if(src_offset>src_offset_next)
    {
      update=1;
      src_offset_next=src_offset+offset_inc;
    }
    if(update)
    {
#ifdef HAVE_NCURSES
      unsigned int i;
      const float percent=(src_offset-partition->part_offset)*100.00/partition->part_size;
      wmove(window,7,0);
      wprintw(window,"%3.2f %% ", percent);
      for(i=0;i<percent*3/5;i++)
	wprintw(window,"=");
      wprintw(window,">");
      wrefresh(window);
      ind_stop=check_enter_key_or_s(window);
#endif
    }
  }
  close(disk_dst);
#ifdef HAVE_NCURSES
  delwin(window);
  (void) clearok(stdscr, TRUE);
#ifdef HAVE_TOUCHWIN
  touchwin(stdscr);
#endif
#endif
  if(ind_stop==2)
  {
    display_message("No space left for the file image.\n");
    free(buffer);
    return -2;
  }
  if(ind_stop)
  {
    if(nbr_read_error==0)
      display_message("Incomplete image created.\n");
    else
      display_message("Incomplete image created: read errors have occured.\n");
    free(buffer);
    return 0;
  }
  if(nbr_read_error==0)
    display_message("Image created successfully.\n");
  else
    display_message("Image created successfully but read errors have occured.\n");
  free(buffer);
  return 0;
}
Example #13
0
int start_ncurses(const char *prog_name, const char *real_prog_name)
{
#if defined(DJGPP) || defined(__MINGW32__)
  if(initscr()==NULL)
  {
    log_critical("initscr() has failed. Exiting\n");
    printf("initscr() has failed. Exiting\n");
    printf("Press Enter key to quit.\n");
    getchar();
    return 1;
  }
#else
  {
    int term_overwrite;
    char *terminfo=filename_to_directory(real_prog_name);
    for(term_overwrite=0;screenp==NULL && term_overwrite<=1;term_overwrite++)
    {
#ifdef HAVE_SETENV
#if defined(TARGET_BSD)
      setenv("TERM","cons25",term_overwrite);
#elif defined(TARGET_LINUX)
      setenv("TERM","linux",term_overwrite);
#elif defined(__CYGWIN__)
      setenv("TERM","cygwin",term_overwrite);
#elif defined(__OS2__)
      setenv("TERM","ansi",term_overwrite);
#elif defined(__APPLE__)
      setenv("TERM","xterm-color",term_overwrite);
#endif
#endif
      screenp=newterm(NULL,stdout,stdin);
#ifdef HAVE_SETENV
      if(screenp==NULL && terminfo!=NULL && terminfo[0]!='\0')
      {
        setenv("TERMINFO", terminfo, 1);
        screenp=newterm(NULL,stdout,stdin);
      }
      if(screenp==NULL)
      {
        setenv("TERMINFO",".",1);
        screenp=newterm(NULL,stdout,stdin);
      }
      if(screenp==NULL)
        unsetenv("TERMINFO");
#endif
    }
    if(screenp==NULL)
    {
      log_critical("Terminfo file is missing.\n");
#if defined(__CYGWIN__)
      printf("The terminfo file '%s\\63\\cygwin' is missing.\n", terminfo);
#else
      printf("Terminfo file is missing.\n");
#endif
      printf("Extract all files and subdirectories before running the program.\n");
      printf("Press Enter key to quit.\n");
      getchar();
      free(terminfo);
      return 1;
    }
    free(terminfo);
  }
#endif
  noecho();
#ifndef DJGPP
  nonl(); /*don't use for Dos version but enter will work with it... dilema */
#endif
  /*  intrflush(stdscr, FALSE); */
  cbreak();
  /* Should solve a problem with users who redefined the colors */
  if(has_colors())
  {
    start_color();
    init_pair(1, COLOR_RED, COLOR_BLACK);
    init_pair(2, COLOR_GREEN, COLOR_BLACK);
  }
  curs_set(0);
  {
    int quit=0;
    while(LINES>=8 && LINES<MINIMUM_LINES && quit==0)
    {
      aff_copy(stdscr);
      wmove(stdscr,4,0);
      wprintw(stdscr,"%s need %d lines to work.", prog_name, MINIMUM_LINES);
      wmove(stdscr,5,0);
      wprintw(stdscr,"Please enlarge the terminal.");
      wmove(stdscr,LINES-2,0);
      wattrset(stdscr, A_REVERSE);
      waddstr(stdscr,"[ Quit ]");
      wattroff(stdscr, A_REVERSE);
      wrefresh(stdscr);
      switch(wgetch(stdscr))
      {
	case 'q':
	case 'Q':
	case KEY_ENTER:
#ifdef PADENTER
	case PADENTER:
#endif
	case '\n':
	case '\r':
	  quit=1;
	  break;
      }
    }
  }
  if(LINES < MINIMUM_LINES)
  {
    end_ncurses();
    printf("%s need %d lines to work.\nPlease enlarge the terminal and restart %s.\n", prog_name, MINIMUM_LINES, prog_name);
    log_critical("Terminal has only %d lines\n",LINES);
    return 1;
  }
  return 0;
}
Example #14
0
unsigned int menu_choose_blocksize(unsigned int blocksize, const unsigned int sector_size, uint64_t *offset)
{
  int command;
  unsigned int menu=0;
  const char *optionsBlocksize="BS51248736";
  static const struct MenuItem menuBlocksize[]=
  {
	{'B',"1",""},
	{'S',"256",""},
	{'5',"512",""},
	{'1',"1024",""},
	{'2',"2048",""},
	{'4',"4096",""},
	{'8',"8192",""},
	{'7',"16384",""},
	{'3',"32768",""},
	{'6',"65536",""},
	{0,NULL,NULL}
  };
  switch(sector_size)
  {
    case 256: optionsBlocksize+=1; break;
    case 512: optionsBlocksize+=2; break;
    case 1024: optionsBlocksize+=3; break;
    case 2048: optionsBlocksize+=4; break;
    case 4096: optionsBlocksize+=5; break;
    case 8192: optionsBlocksize+=6; break;
    case 16384: optionsBlocksize+=7;break;
    case 32768: optionsBlocksize+=8; break;
    case 65536: optionsBlocksize+=9; break;
  }
  switch(blocksize)
  {
    case 1: menu=0; break;
    case 256: menu=1; break;
    case 512: menu=2; break;
    case 1024: menu=3; break;
    case 2048: menu=4; break;
    case 4096: menu=5; break;
    case 8192: menu=6; break;
    case 16384: menu=7; break;
    case 32768: menu=8; break;
    case 65536: menu=9; break;
  }
  aff_copy(stdscr);
  wmove(stdscr,INTER_PARTITION_Y-1,0);
  wprintw(stdscr,"Please select the block size, press Enter when done.");
  command = wmenuSelect_ext(stdscr, 23, INTER_PARTITION_Y, INTER_PARTITION_X, menuBlocksize, 7,
      optionsBlocksize, MENU_VERT| MENU_BUTTON|MENU_VERT_WARN, &menu,NULL);
  switch(command)
  {
    case 'B': blocksize=1; break;
    case 'S': blocksize=256; break;
    case '5': blocksize=512; break;
    case '1': blocksize=1024; break;
    case '2': blocksize=2048; break;
    case '4': blocksize=4096; break;
    case '8': blocksize=8192; break;
    case '7': blocksize=16384; break;
    case '3': blocksize=32768; break;
    case '6': blocksize=65536; break;
  }
  *offset=*offset % blocksize;
  if(*offset%sector_size!=0)
    *offset=0;
  if(sector_size < blocksize)
  {
    unsigned int quit=0;
    aff_copy(stdscr);
    wmove(stdscr,INTER_PARTITION_Y-2,0);
    wprintw(stdscr,"Please select the offset (0 - %u). Press Up/Down to increase/decrease it,",blocksize-sector_size);
    wmove(stdscr,INTER_PARTITION_Y-1,0);
    wprintw(stdscr,"Enter when done.");
    do
    {
      wmove(stdscr,INTER_PARTITION_Y,0);
      wclrtoeol(stdscr);
      wprintw(stdscr,"Offset %u",(unsigned int)(*offset));
      switch(wgetch(stdscr))
      {
	case KEY_ENTER:
#ifdef PADENTER
	case PADENTER:
#endif
	case '\n':
	case '\r':
	  quit=1;
	  break;
	case KEY_PPAGE:
	case KEY_UP:
	case KEY_RIGHT:
	case '+':
	  if(*offset + sector_size < blocksize)
	    *offset+=sector_size;
	  break;
	case KEY_NPAGE:
	case KEY_DOWN:
	case KEY_LEFT:
	case '-':
	  if(*offset >= sector_size)
	    *offset-=sector_size;
	  break;
      }
    } while(quit==0);
  }
  return blocksize;
}
Example #15
0
void menu_photorec(struct ph_param *params, struct ph_options *options, alloc_data_t*list_search_space)
{
  list_part_t *list_part;
#ifdef HAVE_NCURSES
  list_part_t *current_element;
  unsigned int current_element_num;
  int done=0;
  int command;
  unsigned int offset=0;
  unsigned int menu=0;
  static const struct MenuItem menuMain[]=
  {
	{'S',"Search","Start file recovery"},
	{'O',"Options","Modify options"},
	{'F',"File Opt","Modify file options"},
	{'G',"Geometry", "Change disk geometry" },
	{'Q',"Quit","Return to disk selection"},
	{0,NULL,NULL}
  };
#endif
  params->blocksize=0;
  list_part=init_list_part(params->disk, options);
  if(list_part==NULL)
    return;
  log_all_partitions(params->disk, list_part);
  if(params->cmd_run!=NULL)
  {
    if(menu_photorec_cli(list_part, params, options, list_search_space) > 0)
    {
      if(params->recup_dir==NULL)
      {
	char *res;
#ifdef HAVE_NCURSES
	res=ask_location("Please select a destination to save the recovered files.\nDo not choose to write the files to the same partition they were stored on.", "", NULL);
#else
	res=get_default_location();
#endif
	if(res!=NULL)
	{
	  params->recup_dir=(char *)MALLOC(strlen(res)+1+strlen(DEFAULT_RECUP_DIR)+1);
	  strcpy(params->recup_dir,res);
	  strcat(params->recup_dir,"/");
	  strcat(params->recup_dir,DEFAULT_RECUP_DIR);
	  free(res);
	}
      }
      if(params->recup_dir!=NULL)
	photorec(params, options, list_search_space);
    }
  }
  if(params->cmd_run!=NULL)
  {
    part_free_list(list_part);
    return;
  }
#ifdef HAVE_NCURSES
  if(list_part->next!=NULL)
  {
    current_element_num=1;
    current_element=list_part->next;
  }
  else
  {
    current_element_num=0;
    current_element=list_part;
  }
  while(done==0)
  { /* ncurses interface */
    list_part_t *element;
    unsigned int i;
    aff_copy(stdscr);
    wmove(stdscr,4,0);
    wprintw(stdscr,"%s",params->disk->description_short(params->disk));
    mvwaddstr(stdscr,6,0,msg_PART_HEADER_LONG);
#if defined(KEY_MOUSE) && defined(ENABLE_MOUSE)
    mousemask(ALL_MOUSE_EVENTS, NULL);
#endif
    for(i=0,element=list_part; element!=NULL && i<offset+INTER_SELECT;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,params->disk,element->part);
	wattroff(stdscr, A_REVERSE);
      } else
      {
	waddstr(stdscr, " ");
	aff_part(stdscr,AFF_PART_ORDER|AFF_PART_STATUS,params->disk,element->part);
      }
    }
    wmove(stdscr,7+INTER_SELECT,5);
    wclrtoeol(stdscr);
    if(element!=NULL)
      wprintw(stdscr, "Next");
    command = wmenuSelect(stdscr, INTER_SELECT_Y+1, INTER_SELECT_Y, INTER_SELECT_X, menuMain, 8,
	(options->expert==0?"SOFQ":"SOFGQ"), MENU_HORIZ | MENU_BUTTON | MENU_ACCEPT_OTHERS, menu);
#if defined(KEY_MOUSE) && defined(ENABLE_MOUSE)
    if(command == KEY_MOUSE)
    {
      MEVENT event;
      if(getmouse(&event) == OK)
      {	/* When the user clicks left mouse button */
	if((event.bstate & BUTTON1_CLICKED) || (event.bstate & BUTTON1_DOUBLE_CLICKED))
	{
	  if(event.y >=7 && event.y<7+INTER_SELECT)
	  {
	    /* Disk selection */
	    while(current_element_num > event.y-(7-offset) && current_element->prev!=NULL)
	    {
	      current_element=current_element->prev;
	      current_element_num--;
	    }
	    while(current_element_num < event.y-(7-offset) && current_element->next!=NULL)
	    {
	      current_element=current_element->next;
	      current_element_num++;
	    }
	    if(event.bstate & BUTTON1_DOUBLE_CLICKED)
	      command='S';
	  }
	  else
	    command = menu_to_command(INTER_SELECT_Y+1, INTER_SELECT_Y, INTER_SELECT_X, menuMain, 8,
		(options->expert==0?"SOFQ":"SOFGQ"), MENU_HORIZ | MENU_BUTTON | MENU_ACCEPT_OTHERS, event.y, event.x);
	}
      }
    }
#endif
    switch(command)
    {
      case KEY_UP:
	if(current_element!=NULL && current_element->prev!=NULL)
	{
	  current_element=current_element->prev;
	  current_element_num--;
	}
	break;
      case KEY_PPAGE:
	for(i=0; (signed)i<INTER_SELECT && current_element->prev!=NULL; i++)
	{
	  current_element=current_element->prev;
	  current_element_num--;
	}
	break;
      case KEY_DOWN:
	if(current_element->next!=NULL)
	{
	  current_element=current_element->next;
	  current_element_num++;
	}
	break;
      case KEY_NPAGE:
	for(i=0; (signed)i<INTER_SELECT && current_element->next!=NULL; i++)
	{
	  current_element=current_element->next;
	  current_element_num++;
	}
	break;
      case 's':
      case 'S':
	if(current_element!=NULL)
	{
	  params->partition=current_element->part;
	  ask_mode_ext2(params->disk, params->partition, &options->mode_ext2, &params->carve_free_space_only);
	  menu=0;
	  if(params->recup_dir==NULL)
	  {
	    char *res;
	    res=ask_location("Please select a destination to save the recovered files.\nDo not choose to write the files to the same partition they were stored on.", "", NULL);
	    if(res!=NULL)
	    {
	      params->recup_dir=(char *)MALLOC(strlen(res)+1+strlen(DEFAULT_RECUP_DIR)+1);
	      strcpy(params->recup_dir,res);
	      strcat(params->recup_dir,"/");
	      strcat(params->recup_dir,DEFAULT_RECUP_DIR);
	      free(res);
	    }
	  }
	  if(params->recup_dir!=NULL)
	  {
	    if(td_list_empty(&list_search_space->list))
	    {
	      init_search_space(list_search_space, params->disk, params->partition);
	    }
	    if(params->carve_free_space_only>0)
	    {
	      aff_copy(stdscr);
	      wmove(stdscr,5,0);
	      wprintw(stdscr, "Filesystem analysis, please wait...\n");
	      wrefresh(stdscr);
	      params->blocksize=remove_used_space(params->disk, params->partition, list_search_space);
	      /* Only free space is carved, list_search_space is modified.
	       * To carve the whole space, need to quit and reselect the params->partition */
	      done = 1;
	    }
	    photorec(params, options, list_search_space);
	  }
	}
	break;
      case 'o':
      case 'O':
	{
	  interface_options_photorec_ncurses(options);
	  menu=1;
	}
	break;
      case 'f':
      case 'F':
	interface_file_select_ncurses(options->list_file_format);
	menu=2;
	break;
      case 'g':
      case 'G':
	if(options->expert!=0)
	  if(change_geometry_ncurses(params->disk))
	    done=1;
	break;
      case 'a':
      case 'A':
	if(params->disk->arch != &arch_none)
	{
	  list_part=add_partition_ncurses(params->disk, list_part);
	  current_element=list_part;
	  current_element_num=0;
	}
	break;
      case 'q':
      case 'Q':
	done = 1;
	break;
    }
    if(current_element_num<offset)
      offset=current_element_num;
    if(current_element_num>=offset+INTER_SELECT)
      offset=current_element_num-INTER_SELECT+1;
  }
#endif
  log_info("\n");
  part_free_list(list_part);
}
Example #16
0
static int testdisk_disk_selection_ncurses(int verbose,int dump_ind, const list_disk_t *list_disk, const int saveheader, char **current_cmd)
{
  int command='Q';
  unsigned int menu=0;
  int offset=0;
  int pos_num=0;
  int use_sudo=0;
  const list_disk_t *element_disk;
  const list_disk_t *current_disk;
  static struct MenuItem menuMain[]=
  {
    { 'P', "Previous", ""},
    { 'N', "Next", "" },
    { 'O', "Proceed", ""},
    { 'S', "Sudo", "Use the sudo command to restart as root"},
    { 'Q', "Quit", "Quit program"},
    {  0,  NULL, NULL}
  };
  if(list_disk==NULL)
  {
    log_critical("No disk found\n");
    return intrf_no_disk_ncurses("TestDisk");
  }
  current_disk=list_disk;
  /* ncurses interface */
  while(1)
  {
    const char *options;
    int i;
#ifdef HAVE_NCURSES
    aff_copy(stdscr);
    wmove(stdscr,4,0);
    wprintw(stdscr,"  TestDisk is free software, and");
    wmove(stdscr,5,0);
    wprintw(stdscr,"comes with ABSOLUTELY NO WARRANTY.");
    wmove(stdscr,7,0);
    wprintw(stdscr,"Select a media (use Arrow keys, then press Enter):");
#endif
    for(i=0,element_disk=list_disk;
	element_disk!=NULL && i<offset+NBR_DISK_MAX;
	i++, element_disk=element_disk->next)
    {
      if(i<offset)
	continue;
      wmove(stdscr,8+i-offset,0);
      if(element_disk!=current_disk)
	wprintw(stdscr," %s\n",element_disk->disk->description_short(element_disk->disk));
      else
      {
	wattrset(stdscr, A_REVERSE);
	wprintw(stdscr,">%s\n",element_disk->disk->description_short(element_disk->disk));
	wattroff(stdscr, A_REVERSE);
      }
    }
    {
      int line=INTER_NOTE_Y;
      mvwaddstr(stdscr,line++,0,"Note: ");
#if defined(__CYGWIN__) || defined(__MINGW32__) || defined(DJGPP)
#else
#ifdef HAVE_GETEUID
      if(geteuid()!=0)
      {
        if(has_colors())
          wbkgdset(stdscr,' ' | A_BOLD | COLOR_PAIR(1));
        waddstr(stdscr,"Some disks won't appear unless you are root user.");
        if(has_colors())
          wbkgdset(stdscr,' ' | COLOR_PAIR(0));
        wmove(stdscr,line++,0);
#ifdef SUDO_BIN
	use_sudo=1;
#endif
      }
#endif
#endif
      waddstr(stdscr,"Disk capacity must be correctly detected for a successful recovery.");
      wmove(stdscr,line++,0);
      wprintw(stdscr,"If a disk listed above has incorrect size, check HD jumper settings, BIOS");
      wmove(stdscr,line,0);
      wprintw(stdscr,"detection, and install the latest OS patches and disk drivers."); 
    }
    if(use_sudo > 0)
    {
      if(i<=NBR_DISK_MAX && element_disk==NULL)
	options="OSQ";
      else
	options="PNOSQ";
    }
    else
    {
      if(i<=NBR_DISK_MAX && element_disk==NULL)
	options="OQ";
      else
	options="PNOQ";
    }
    command = wmenuSelect_ext(stdscr, INTER_NOTE_Y-1, INTER_DISK_Y, INTER_DISK_X, menuMain, 8,
	options, MENU_HORIZ | MENU_BUTTON | MENU_ACCEPT_OTHERS, &menu,NULL);
    switch(command)
    {
      case 'p':
      case 'P':
      case KEY_UP:
	if(current_disk->prev!=NULL)
	{
	  current_disk=current_disk->prev;
	  pos_num--;
	}
	break;
      case 'n':
      case 'N':
      case KEY_DOWN:
	if(current_disk->next!=NULL)
	{
	  current_disk=current_disk->next;
	  pos_num++;
	}
	break;
      case KEY_PPAGE:
	for(i=0;i<NBR_DISK_MAX-1 && current_disk->prev!=NULL;i++)
	{
	  current_disk=current_disk->prev;
	  pos_num--;
	}
	break;
      case KEY_NPAGE:
	for(i=0;i<NBR_DISK_MAX-1 && current_disk->next!=NULL;i++)
	{
	  current_disk=current_disk->next;
	  pos_num++;
	}
	break;
      case 'o':
      case 'O':
	{
	  disk_t *disk=current_disk->disk;
	  const int hpa_dco=is_hpa_or_dco(disk);
	  autodetect_arch(disk, NULL);
	  autoset_unit(disk);
	  if(interface_check_disk_capacity(disk)==0 &&
              interface_check_disk_access(disk, current_cmd)==0 &&
	      (hpa_dco==0 || interface_check_hidden_ncurses(disk, hpa_dco)==0) &&
	      interface_partition_type(disk, verbose, current_cmd)==0)
	  {
	    if(menu_disk(disk, verbose, dump_ind, saveheader, current_cmd))
	      return 0;
	  }
	}
	break;
      case 's':
      case 'S':
	return 1;
      case 'q':
      case 'Q':
	return 0;
    }
    if(pos_num<offset)
      offset=pos_num;
    if(pos_num>=offset+NBR_DISK_MAX)
      offset=pos_num-NBR_DISK_MAX+1;
  }
}
Example #17
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;
  }
}
Example #18
0
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;
}
Example #19
0
int main( int argc, char **argv )
{
  int i;
  int use_sudo=0;
  int create_log=TD_LOG_NONE;
  int run_setlocale=1;
  int testdisk_mode=TESTDISK_O_RDONLY|TESTDISK_O_READAHEAD_32K;
  list_disk_t *list_disk=NULL;
  list_disk_t *element_disk;
  const char *logfile="photorec.log";
  FILE *log_handle=NULL;
  int log_errno=0;
  struct ph_options options={
    .paranoid=1,
    .keep_corrupted_file=0,
    .mode_ext2=0,
    .expert=0,
    .lowmem=0,
    .verbose=0,
    .list_file_format=list_file_enable
  };
  struct ph_param params;
  params.recup_dir=NULL;
  params.cmd_device=NULL;
  params.cmd_run=NULL;
  params.carve_free_space_only=0;
  /* random (weak is ok) is need fot GPT */
  srand(time(NULL));
#ifdef HAVE_SIGACTION
  /* set up the signal handler for SIGINT & SIGHUP */
  sigemptyset(&action.sa_mask);
  sigaddset(&action.sa_mask, SIGINT);
  sigaddset(&action.sa_mask, SIGHUP);
  action.sa_handler  = sighup_hdlr;
  action.sa_flags = 0;
  if(sigaction(SIGINT, &action, NULL)==-1)
  {
    printf("Error on SIGACTION call\n");
    return -1;
  }
  if(sigaction(SIGHUP, &action, NULL)==-1)
  {
    printf("Error on SIGACTION call\n");
    return -1;
  }
#endif
  printf("PhotoRec %s, Data Recovery Utility, %s\nChristophe GRENIER <*****@*****.**>\nhttp://www.cgsecurity.org\n",VERSION,TESTDISKDATE);
  for(i=1;i<argc;i++)
  {
    if((strcmp(argv[i],"/logname")==0) ||(strcmp(argv[i],"-logname")==0))
    {
      if(i+2>=argc)
      {
	display_help();
	free(params.recup_dir);
	return 1;
      }
      logfile=argv[++i];
    }
    else if((strcmp(argv[i],"/log")==0) ||(strcmp(argv[i],"-log")==0))
    {
      if(create_log==TD_LOG_NONE)
        create_log=TD_LOG_APPEND;
    }
    else if((strcmp(argv[i],"/debug")==0) || (strcmp(argv[i],"-debug")==0))
    {
      options.verbose++;
      if(create_log==TD_LOG_NONE)
        create_log=TD_LOG_APPEND;
    }
    else if(((strcmp(argv[i],"/d")==0)||(strcmp(argv[i],"-d")==0)) &&(i+1<argc))
    {
      int len=strlen(argv[i+1]);
      if(argv[i+1][len-1]=='\\' || argv[i+1][len-1]=='/')
      {
        params.recup_dir=(char *)MALLOC(len + strlen(DEFAULT_RECUP_DIR) + 1);
        strcpy(params.recup_dir,argv[i+1]);
        strcat(params.recup_dir,DEFAULT_RECUP_DIR);
      }
      else
        params.recup_dir=strdup(argv[i+1]);
      i++;
    }
    else if((strcmp(argv[i],"/all")==0) || (strcmp(argv[i],"-all")==0))
      testdisk_mode|=TESTDISK_O_ALL;
    else if((strcmp(argv[i],"/direct")==0) || (strcmp(argv[i],"-direct")==0))
      testdisk_mode|=TESTDISK_O_DIRECT;
    else if((strcmp(argv[i],"/help")==0) || (strcmp(argv[i],"-help")==0) || (strcmp(argv[i],"--help")==0) ||
      (strcmp(argv[i],"/h")==0) || (strcmp(argv[i],"-h")==0) ||
      (strcmp(argv[i],"/?")==0) || (strcmp(argv[i],"-?")==0))
    {
      display_help();
      free(params.recup_dir);
      return 0;
    }
    else if((strcmp(argv[i],"/version")==0) || (strcmp(argv[i],"-version")==0) || (strcmp(argv[i],"--version")==0) ||
      (strcmp(argv[i],"/v")==0) || (strcmp(argv[i],"-v")==0))
    {
      display_version();
      free(params.recup_dir);
      return 0;
    }
    else if((strcmp(argv[i],"/nosetlocale")==0) || (strcmp(argv[i],"-nosetlocale")==0))
      run_setlocale=0;
    else if(strcmp(argv[i],"/cmd")==0)
    {
      if(i+2>=argc)
      {
	display_help();
	free(params.recup_dir);
	return 1;
      }
      {
        disk_t *disk_car;
        params.cmd_device=argv[++i];
        params.cmd_run=argv[++i];
        /* There is no log currently */
        disk_car=file_test_availability(params.cmd_device, options.verbose, testdisk_mode);
        if(disk_car==NULL)
        {
          printf("\nUnable to open file or device %s: %s\n", params.cmd_device, strerror(errno));
	  free(params.recup_dir);
	  return 1;
        }
	list_disk=insert_new_disk(list_disk,disk_car);
      }
    }
    else
    {
      disk_t *disk_car=file_test_availability(argv[i], options.verbose, testdisk_mode);
      if(disk_car==NULL)
      {
        printf("\nUnable to open file or device %s: %s\n", argv[i], strerror(errno));
	free(params.recup_dir);
	return 1;
      }
      list_disk=insert_new_disk(list_disk,disk_car);
    }
  }
#ifdef ENABLE_DFXML
  xml_set_command_line(argc, argv);
#endif
  if(create_log!=TD_LOG_NONE)
    log_handle=log_open(logfile, create_log, &log_errno);
#ifdef HAVE_SETLOCALE
  if(run_setlocale>0)
  {
    const char *locale;
    locale = setlocale (LC_ALL, "");
    if (locale==NULL) {
      locale = setlocale (LC_ALL, NULL);
      log_error("Failed to set locale, using default '%s'.\n", locale);
    } else {
      log_info("Using locale '%s'.\n", locale);
    }
  }
#endif
  if(create_log!=TD_LOG_NONE && log_handle==NULL)
    log_handle=log_open_default(logfile, create_log, &log_errno);
#ifdef HAVE_NCURSES
  /* ncurses need locale for correct unicode support */
  if(start_ncurses("PhotoRec", argv[0]))
  {
    free(params.recup_dir);
    return 1;
  }
  {
    const char*filename=logfile;
    while(create_log!=TD_LOG_NONE && log_handle==NULL)
    {
      filename=ask_log_location(filename, log_errno);
      if(filename!=NULL)
	log_handle=log_open(filename, create_log, &log_errno);
      else
	create_log=TD_LOG_NONE;
    }
  }
  aff_copy(stdscr);
  wmove(stdscr,5,0);
  wprintw(stdscr, "Disk identification, please wait...\n");
  wrefresh(stdscr);
#endif
  if(log_handle!=NULL)
  {
    time_t my_time;
#ifdef HAVE_DUP2
    dup2(fileno(log_handle),2);
#endif
    my_time=time(NULL);
    log_info("\n\n%s",ctime(&my_time));
    log_info("Command line: PhotoRec");
    for(i=1;i<argc;i++)
      log_info(" %s", argv[i]);
    log_info("\n\n");
  }
  log_info("PhotoRec %s, Data Recovery Utility, %s\nChristophe GRENIER <*****@*****.**>\nhttp://www.cgsecurity.org\n", VERSION, TESTDISKDATE);
  log_info("OS: %s\n" , get_os());
  log_info("Compiler: %s\n", get_compiler());
  log_info("Compilation date: %s\n", get_compilation_date());
  log_info("ext2fs lib: %s, ntfs lib: %s, ewf lib: %s, libjpeg: %s\n",
      td_ext2fs_version(), td_ntfs_version(), td_ewf_version(), td_jpeg_version());
#if defined(__CYGWIN__) || defined(__MINGW32__) || defined(DJGPP)
#else
#ifdef HAVE_GETEUID
  if(geteuid()!=0)
  {
    log_warning("User is not root!\n");
  }
#endif
#endif
  log_flush();
  screen_buffer_reset();
  /* Scan for available device only if no device or image has been supplied in parameter */
  if(list_disk==NULL)
    list_disk=hd_parse(list_disk, options.verbose, testdisk_mode);
  hd_update_all_geometry(list_disk, options.verbose);
  /* Activate the cache, even if photorec has its own */
  for(element_disk=list_disk;element_disk!=NULL;element_disk=element_disk->next)
  {
    element_disk->disk=new_diskcache(element_disk->disk, testdisk_mode);
  }
  log_disk_list(list_disk);
  reset_list_file_enable(options.list_file_format);
  file_options_load(options.list_file_format);
#ifdef SUDO_BIN
  if(list_disk==NULL)
  {
#if defined(__CYGWIN__) || defined(__MINGW32__) || defined(DJGPP)
#else
#ifdef HAVE_GETEUID
    if(geteuid()!=0)
      use_sudo=2;
#endif
#endif
  }
#endif
  if(use_sudo==0)
    use_sudo=do_curses_photorec(&params, &options, list_disk);
#ifdef HAVE_NCURSES
  end_ncurses();
#endif
  log_info("PhotoRec exited normally.\n");
  if(log_close()!=0)
  {
    printf("PhotoRec: Log file corrupted!\n");
  }
  else if(params.cmd_run!=NULL && params.cmd_run[0]!='\0')
  {
    printf("PhotoRec syntax error: %s\n", params.cmd_run);
  }
#ifdef SUDO_BIN
  if(use_sudo>0)
  {
    printf("\n");
    if(use_sudo>1)
      printf("No disk found.\n");
    printf("PhotoRec will try to restart itself using the sudo command to get\n");
    printf("root (superuser) privileges.\n");
    printf("\n");
    run_sudo(argc, argv);
  }
#endif
  delete_list_disk(list_disk);
  free(params.recup_dir);
#ifdef ENABLE_DFXML
  xml_clear_command_line();
#endif
  return 0;
}
Example #20
0
int start_ncurses(const char *prog_name, const char *real_prog_name)
{
#if defined(DJGPP) || defined(__MINGW32__)
  if(initscr()==NULL)
  {
    log_critical("initscr() has failed. Exiting\n");
    printf("initscr() has failed. Exiting\n");
    printf("Press Enter key to quit.\n");
    (void)getchar();
    return 1;
  }
#else
  get_newterm(real_prog_name);
  if(screenp==NULL)
  {
    log_critical("Terminfo file is missing.\n");
#if defined(__CYGWIN__)
    printf("The terminfo file '63\\cygwin' is missing.\n");
#else
    printf("Terminfo file is missing.\n");
#endif
    printf("Extract all files and subdirectories before running the program.\n");
    printf("Press Enter key to quit.\n");
    (void)getchar();
    return 1;
  }
#endif
  /* Should solve a problem with users who redefined the colors */
  if(has_colors())
  {
    start_color();
#ifdef HAVE_ASSUME_DEFAULT_COLORS
    assume_default_colors(COLOR_WHITE,COLOR_BLACK);
#endif
    init_pair(1, COLOR_RED, COLOR_BLACK);
    init_pair(2, COLOR_GREEN, COLOR_BLACK);
  }
  noecho();
#ifndef DJGPP
  nonl(); /*don't use for Dos version but enter will work with it... dilema */
#endif
  /*  intrflush(stdscr, FALSE); */
  cbreak();
  curs_set(0);
  {
    int quit=0;
    while(LINES>=8 && LINES<MINIMUM_LINES && quit==0)
    {
      aff_copy(stdscr);
      wmove(stdscr,4,0);
      wprintw(stdscr,"%s need %d lines to work.", prog_name, MINIMUM_LINES);
      wmove(stdscr,5,0);
      wprintw(stdscr,"Please enlarge the terminal.");
      wmove(stdscr,LINES-2,0);
      wattrset(stdscr, A_REVERSE);
      waddstr(stdscr,"[ Quit ]");
      wattroff(stdscr, A_REVERSE);
      wrefresh(stdscr);
      switch(wgetch(stdscr))
      {
	case 'q':
	case 'Q':
	case KEY_ENTER:
#ifdef PADENTER
	case PADENTER:
#endif
	case '\n':
	case '\r':
	  quit=1;
	  break;
      }
    }
  }
  if(LINES < MINIMUM_LINES)
  {
    end_ncurses();
    printf("%s need %d lines to work.\nPlease enlarge the terminal and restart %s.\n", prog_name, MINIMUM_LINES, prog_name);
    log_critical("Terminal has only %d lines\n",LINES);
    return 1;
  }
  return 0;
}
Example #21
0
static int photorec_disk_selection_ncurses(struct ph_param *params, struct ph_options *options, const list_disk_t *list_disk, alloc_data_t *list_search_space)
{
  int command;
  int real_key;
  unsigned int menu=0;
  int offset=0;
  int pos_num=0;
  int use_sudo=0;
  const list_disk_t *element_disk;
  const list_disk_t *current_disk=list_disk;
  static const struct MenuItem menuMain[]=
  {
    { 'P', "Previous",""},
    { 'N', "Next","" },
    { 'O',"Proceed",""},
    { 'S', "Sudo", "Use the sudo command to restart as root"},
    { 'Q',"Quit","Quit program"},
    { 0,NULL,NULL}
  };
  if(list_disk==NULL)
  {
    log_critical("No disk found\n");
    return intrf_no_disk_ncurses("PhotoRec");
  }
  /* ncurses interface */
  while(1)
  {
    const char *menu_options;
    int i;
    aff_copy(stdscr);
    wmove(stdscr,4,0);
    wprintw(stdscr,"  PhotoRec is free software, and");
    wmove(stdscr,5,0);
    wprintw(stdscr,"comes with ABSOLUTELY NO WARRANTY.");
    wmove(stdscr,7,0);
    wprintw(stdscr,"Select a media (use Arrow keys, then press Enter):");
#if defined(KEY_MOUSE) && defined(ENABLE_MOUSE)
    mousemask(ALL_MOUSE_EVENTS, NULL);
#endif
    for(i=0,element_disk=list_disk;
	element_disk!=NULL && i<offset+NBR_DISK_MAX;
	i++, element_disk=element_disk->next)
    {
      if(i<offset)
	continue;
      wmove(stdscr,8+i-offset,0);
      if(element_disk!=current_disk)
	wprintw(stdscr," %s\n",element_disk->disk->description_short(element_disk->disk));
      else
      {
	wattrset(stdscr, A_REVERSE);
	wprintw(stdscr,">%s\n",element_disk->disk->description_short(element_disk->disk));
	wattroff(stdscr, A_REVERSE);
      }
    }
    {
      mvwaddstr(stdscr, INTER_NOTE_Y,0,"Note: ");
#if defined(__CYGWIN__) || defined(__MINGW32__)
#else
#ifndef DJGPP
#ifdef HAVE_GETEUID
      if(geteuid()!=0)
      {
	if(has_colors())
	  wbkgdset(stdscr,' ' | A_BOLD | COLOR_PAIR(1));
	wprintw(stdscr,"Some disks won't appear unless you're root user.");
        if(has_colors())
          wbkgdset(stdscr,' ' | COLOR_PAIR(0));
#ifdef SUDO_BIN
	use_sudo=1;
#endif
      }
#endif
#endif
#endif
      wmove(stdscr, INTER_NOTE_Y+1, 0);
      wprintw(stdscr,"Disk capacity must be correctly detected for a successful recovery.");
      wmove(stdscr, INTER_NOTE_Y+2, 0);
      wprintw(stdscr,"If a disk listed above has incorrect size, check HD jumper settings, BIOS");
      wmove(stdscr, INTER_NOTE_Y+3, 0);
      wprintw(stdscr,"detection, and install the latest OS patches and disk drivers."); 
    }
    if(use_sudo > 0)
    {
      if(i<=NBR_DISK_MAX && element_disk==NULL)
	menu_options="OSQ";
      else
	menu_options="PNOSQ";
    }
    else
    {
      if(i<=NBR_DISK_MAX && element_disk==NULL)
	menu_options="OQ";
      else
	menu_options="PNOQ";
    }
    command = wmenuSelect_ext(stdscr, INTER_NOTE_Y-1, INTER_DISK_Y, INTER_DISK_X, menuMain, 8,
	menu_options, MENU_HORIZ | MENU_BUTTON | MENU_ACCEPT_OTHERS, &menu,&real_key);
#if defined(KEY_MOUSE) && defined(ENABLE_MOUSE)
    if(command == KEY_MOUSE)
    {
      MEVENT event;
      if(getmouse(&event) == OK)
      {	/* When the user clicks left mouse button */
	if((event.bstate & BUTTON1_CLICKED) || (event.bstate & BUTTON1_DOUBLE_CLICKED))
	{
	  if(event.y >=8 && event.y<8+NBR_DISK_MAX)
	  {
	    const int pos_num_old=pos_num;
	    /* Disk selection */
	    while(pos_num > event.y-(8-offset) && current_disk->prev!=NULL)
	    {
	      current_disk=current_disk->prev;
	      pos_num--;
	    }
	    while(pos_num < event.y-(8-offset) && current_disk->next!=NULL)
	    {
	      current_disk=current_disk->next;
	      pos_num++;
	    }
	    if(((event.bstate & BUTTON1_CLICKED) && pos_num==pos_num_old) ||
		(event.bstate & BUTTON1_DOUBLE_CLICKED))
	      command='O';
	  }
	  else
	    command = menu_to_command(INTER_NOTE_Y-1, INTER_DISK_Y, INTER_DISK_X, menuMain, 8,
		menu_options, MENU_HORIZ | MENU_BUTTON | MENU_ACCEPT_OTHERS, event.y, event.x);
	}
      }
    }
#endif
    switch(command)
    {
      case KEY_UP:
      case 'P':
	if(current_disk->prev!=NULL)
	{
	  current_disk=current_disk->prev;
	  pos_num--;
	}
	break;
      case KEY_DOWN:
      case 'N':
	if(current_disk->next!=NULL)
	{
	  current_disk=current_disk->next;
	  pos_num++;
	}
	break;
      case KEY_PPAGE:
	for(i=0;i<NBR_DISK_MAX-1 && current_disk->prev!=NULL;i++)
	{
	  current_disk=current_disk->prev;
	  pos_num--;
	}
	break;
      case KEY_NPAGE:
	for(i=0;i<NBR_DISK_MAX-1 && current_disk->next!=NULL;i++)
	{
	  current_disk=current_disk->next;
	  pos_num++;
	}
	break;
      case 'o':
      case 'O':
	{
	  disk_t *disk=current_disk->disk;
	  const int hpa_dco=is_hpa_or_dco(disk);
	  autodetect_arch(disk, &arch_none);
	  params->disk=disk;
	  if((hpa_dco==0 || interface_check_hidden_ncurses(disk, hpa_dco)==0) &&
	      (options->expert == 0 ||
	       change_arch_type_ncurses(disk, options->verbose)==0))
	    menu_photorec(params, options, list_search_space);
	}
	break;
      case 's':
      case 'S':
	return 1;
      case 'q':
      case 'Q':
	return 0;
    }
    if(pos_num<offset)
      offset=pos_num;
    if(pos_num>=offset+NBR_DISK_MAX)
      offset=pos_num-NBR_DISK_MAX+1;
  }
}
Example #22
0
static void interface_editor_ncurses(disk_t *disk)
{
  int done = 0;
  uint64_t hd_offset=0;
  unsigned char *buffer=(unsigned char *)MALLOC(disk->sector_size);
  log_info("%s\n",disk->description(disk));
  aff_copy(stdscr);
  wmove(stdscr,4,0);
  wprintw(stdscr,"%s", disk->description_short(disk));
  while (done==0)
  {
    static const struct MenuItem menuEditor[]=
    {
      { 'C', "Change location", "" },
      { 'D', "Dump", "Dump sector" },
      { 'Q', "Quit",""},
      { 0, NULL, NULL }
    };
    switch ( wmenuSelect(stdscr, INTER_EDIT_Y+1, INTER_EDIT_Y, INTER_EDIT_X, menuEditor, 8, "CDQ", MENU_HORIZ | MENU_BUTTON, 0))
    {
      case 'c':
      case 'C':
	interface_editor_location(disk,&hd_offset);
	break;
      case 'd':
      case 'D':
	{
	  int menu_pos=KEY_DOWN;
	  while(done==0)
	  {
	    wmove(stdscr,5,0);
	    wclrtoeol(stdscr);
	    wprintw(stdscr,"%lu ", (unsigned long)(hd_offset/disk->sector_size));
	    aff_LBA2CHS(disk, hd_offset/disk->sector_size);
	    if((unsigned)disk->pread(disk, buffer, disk->sector_size, hd_offset) != disk->sector_size)
	    {
	      wprintw(stdscr,msg_PART_RD_ERR);
	    }
	    {
	      menu_pos=dump_editor(buffer, disk->sector_size, menu_pos);
	      switch(menu_pos)
	      {
		case KEY_UP:
		  if(hd_offset>0)
		    hd_offset-=disk->sector_size;
		  else
		    menu_pos=KEY_DOWN;
		  break;
		case KEY_DOWN:
		  if(hd_offset<disk->disk_size)
		    hd_offset+=disk->sector_size;
		  else
		    menu_pos=KEY_UP;
		  break;
		default:
		  done = 1;
		  break;
	      }
	    }
	  }
	  done = 0;
	}
	break;
      case key_ESC:
      case 'q':
      case 'Q':
	done = 1;
	break;
    }
  }
  free(buffer);
}
Example #23
0
static void ask_mbr_order_i386(disk_t *disk_car,list_part_t *list_part)
{
  partition_t *table[4];
  int nbr_prim=0;
  int i,pos=0;
  int res;
  int quit=0;
  list_part_t *element;
  /* Initialisation */
  aff_copy(stdscr);
  wmove(stdscr,4,0);
  wprintw(stdscr,"%s",disk_car->description(disk_car));
  mvwaddstr(stdscr,5,0,msg_MBR_ORDER);
  mvwaddstr(stdscr,6,0,msg_PART_HEADER_LONG);
  for(element=list_part;element!=NULL;element=element->next)
  {
    if((element->part->order>0) && (element->part->order<5))
      table[nbr_prim++]=element->part;
  }
  /* */
  log_info("\nSelect primary partition\n");
  for(i=0;i<nbr_prim;i++)
      log_partition(disk_car,table[i]);
  /* */
  do
  {
    partition_t *table2[4];
    int car;
    unsigned int order;
    /* sort table into table2 */
    int part=0;
    res=0;
    for(order=1;order<=4;order++)
    {
      int nbr=0;
      for(i=0;i<nbr_prim;i++)
	if(table[i]->order==order)
	{
	  table2[part++]=table[i];
	  nbr++;
	}
      res|=(nbr>1);
    }
    if(part!=nbr_prim)
    {
      log_critical("\nBUG part %d, nbr_prim %d\n", part, nbr_prim);
    }
    for(i=0;i<nbr_prim;i++)
    {
      wmove(stdscr,5+2+i,0);
      wclrtoeol(stdscr);
      if(i==pos)
	standout();
      aff_part(stdscr,AFF_PART_ORDER|AFF_PART_STATUS,disk_car,table2[i]);
      if(i==pos)
	standend();
    }
    wmove(stdscr,20,0);
    if(res)
      wprintw(stdscr,msg_MBR_ORDER_BAD);
    else
      wprintw(stdscr,msg_MBR_ORDER_GOOD);
    wrefresh(stdscr);
    car=wgetch(stdscr);
    quit=0;
    switch(car)
    {
      case KEY_UP:
	if(--pos<0)
	  pos=nbr_prim-1;
	break;
      case KEY_DOWN:
	if(++pos>=nbr_prim)
	  pos=0;
	break;
      case KEY_PPAGE:
	pos=0;
	break;
      case KEY_NPAGE:
	pos=nbr_prim-1;
	break;
      case '1':
      case '2':
      case '3':
      case '4':
	table2[pos]->order=car-'0';
	break;
      case KEY_RIGHT:
      case ' ':
      case '+':
	if(++table2[pos]->order>4)
	  table2[pos]->order=1;
	break;
      case KEY_LEFT:
      case '-':
	if(--table2[pos]->order<1)
	  table2[pos]->order=4;
	break;
      case 'q':
      case '\r':
      case '\n':
      case KEY_ENTER:
#ifdef PADENTER
      case PADENTER:
#endif
      case 'M':
	quit=1;
	break;
    }
    wrefresh(stdscr);
  } while(res!=0 || quit==0);
}
Example #24
0
static void change_part_type_ncurses2(const disk_t *disk_car, partition_t *partition)
{
  partition_t *new_partition;
  unsigned int intr_nbr_line=0;
  unsigned int offset=0;
  unsigned int i;
  unsigned int current_element_num=0;
  struct part_name_struct part_name[0x100];
  if(partition->arch->set_part_type==NULL)
    return ;
  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);
  /* Create an index of all partition type except Intel extended */
  new_partition=partition_new(NULL);
  dup_partition_t(new_partition,partition);
  for(i=0;i<=0xFF;i++)
  {
    if(partition->arch->set_part_type(new_partition,i)==0)
    {
      part_name[intr_nbr_line].name=new_partition->arch->get_partition_typename(new_partition);
      if(part_name[intr_nbr_line].name!=NULL)
      {
	if(partition->arch->get_part_type(partition)==i)
	  current_element_num=intr_nbr_line;
	part_name[intr_nbr_line++].index=i;
      }
    }
  }
  free(new_partition);
  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;i<intr_nbr_line && (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", part_name[i].name);
	wattroff(stdscr, A_REVERSE);
      } else
      {
	wprintw(stdscr," %s", part_name[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(i<intr_nbr_line)
      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(current_element_num < intr_nbr_line-1)
	  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:
	if(current_element_num+INTER_CHGTYPE < intr_nbr_line-1)
	  current_element_num+=INTER_CHGTYPE;
	else
	  current_element_num=intr_nbr_line-1;
	break;
      case KEY_NPAGE:
	if(current_element_num+3*INTER_CHGTYPE-1 < intr_nbr_line-1)
	  current_element_num+=3*INTER_CHGTYPE-1;
	else
	  current_element_num=intr_nbr_line-1;
	break;
      case 'Q':
      case 'q':
      case key_CR:
#ifdef PADENTER
      case PADENTER:
#endif
	partition->arch->set_part_type(partition, part_name[current_element_num].index);
	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;
  }
}
Example #25
0
list_part_t *search_superblock(disk_t *disk_car, partition_t *partition, const int verbose, const int dump_ind, const int interface)
{
  unsigned char *buffer=(unsigned char *)MALLOC(2*0x200);
  uint64_t hd_offset;
  int nbr_sb=0;
  list_part_t *list_part=NULL;
  int ind_stop=0;
#ifdef HAVE_NCURSES
  unsigned long int old_percent=0;
#endif
  struct ext2_super_block *sb=(struct ext2_super_block *)buffer;
  partition_t *new_partition=partition_new(disk_car->arch);
  log_trace("search_superblock\n");
#ifdef HAVE_NCURSES
  if(interface>0)
  {
    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);
    wmove(stdscr,22,0);
    wattrset(stdscr, A_REVERSE);
    waddstr(stdscr,"  Stop  ");
    wattroff(stdscr, A_REVERSE);
  }
#endif
  for(hd_offset=0;hd_offset<partition->part_size && nbr_sb<10 && ind_stop==0;hd_offset=next_sb(hd_offset))
  {
#ifdef HAVE_NCURSES
    unsigned long int percent;
    percent=hd_offset*100/partition->part_size;
    if(interface>0 && percent!=old_percent)
    {
      wmove(stdscr,9,0);
      wclrtoeol(stdscr);
      wprintw(stdscr,"Search ext2/ext3/ext4 superblock %10lu/%lu %lu%%", (long unsigned)(hd_offset/disk_car->sector_size),
	  (long unsigned)(partition->part_size/disk_car->sector_size),percent);
      wrefresh(stdscr);
      ind_stop|=check_enter_key_or_s(stdscr);
      old_percent=percent;
    }
#endif
    if(disk_car->pread(disk_car, buffer, 1024, partition->part_offset + hd_offset) == 1024)
    {
      /* ext2/ext3/ext4 */
      if(le16(sb->s_magic)==EXT2_SUPER_MAGIC)
      {
	dup_partition_t(new_partition,partition);
	new_partition->part_offset+=hd_offset;
	if(recover_EXT2(disk_car,sb,new_partition,verbose,dump_ind)==0)
	{
	  int insert_error=0;
	  if(hd_offset<=(EXT2_MIN_BLOCK_SIZE<<2))
	    new_partition->part_offset-=hd_offset;
	  if(partition->blocksize==0)
	  {
	    partition->sborg_offset=new_partition->sborg_offset;
	    partition->sb_offset   =new_partition->sb_offset;
	    partition->sb_size     =new_partition->sb_size;
	    partition->blocksize   =new_partition->blocksize;
	  }
	  log_info("Ext2 superblock found at sector %llu (block=%llu, blocksize=%u)\n",
	      (long long unsigned) hd_offset/DEFAULT_SECTOR_SIZE,
	      (long long unsigned) hd_offset>>(EXT2_MIN_BLOCK_LOG_SIZE+le32(sb->s_log_block_size)),
	      EXT2_MIN_BLOCK_SIZE<<le32(sb->s_log_block_size));
#ifdef HAVE_NCURSES
	  wmove(stdscr,10+nbr_sb,0);
	  wprintw(stdscr,"Ext2 superblock found at sector %llu (block=%llu, blocksize=%u)        \n",
	      (long long unsigned) hd_offset/DEFAULT_SECTOR_SIZE,
	      (long long unsigned) hd_offset>>(EXT2_MIN_BLOCK_LOG_SIZE+le32(sb->s_log_block_size)),
	      EXT2_MIN_BLOCK_SIZE<<le32(sb->s_log_block_size));
#endif
	  list_part=insert_new_partition(list_part, new_partition, 1, &insert_error);
	  new_partition=partition_new(disk_car->arch);
	  nbr_sb++;
	}
      }
    }
Example #26
0
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;
}
Example #27
0
static list_part_t *ask_structure_ncurses(disk_t *disk_car,list_part_t *list_part, const int verbose, char **current_cmd)
{
  int offset=0;
  int pos_num=0;
  list_part_t *pos=list_part;
  int rewrite=1;
  int old_LINES=LINES;
  while(1)
  {
    int i;
    int command;
    list_part_t *parts;
    int structure_status;
    if(old_LINES!=LINES)
    {
      rewrite=1;
      old_LINES=LINES;
    }
    if(rewrite)
    {
      aff_copy(stdscr);
      wmove(stdscr,4,0);
      wprintw(stdscr,"%s",disk_car->description(disk_car));
      mvwaddstr(stdscr,5,0,msg_PART_HEADER);
      rewrite=0;
    }
    structure_status=disk_car->arch->test_structure(list_part);
    for(i=0,parts=list_part;
	parts!=NULL && i<offset+INTER_STRUCTURE;
	i++, parts=parts->next)
    {
      if(i<offset)
	continue;
      wmove(stdscr,6+i-offset,0);
      wclrtoeol(stdscr);	/* before addstr for BSD compatibility */
      if(parts==pos)
	wattrset(stdscr, A_REVERSE);
      if(structure_status==0 && parts->part->status!=STATUS_DELETED && has_colors())
	wbkgdset(stdscr,' ' | COLOR_PAIR(2));
      if(parts==pos)
	waddstr(stdscr, ">");
      else
	waddstr(stdscr, " ");
      aff_part(stdscr, AFF_PART_STATUS, disk_car, parts->part);
      if(structure_status==0 && parts->part->status!=STATUS_DELETED && has_colors())
	wbkgdset(stdscr,' ' | COLOR_PAIR(0));
      if(parts==pos)
      {
	char buffer_part_size[100];
	wattroff(stdscr, A_REVERSE);
	wmove(stdscr,LINES-1,0);
	wclrtoeol(stdscr);	/* before addstr for BSD compatibility */
	if(parts->part->info[0]!='\0')
	{
	  wprintw(stdscr,"%s, ",parts->part->info);
	}
	size_to_unit(parts->part->part_size, buffer_part_size);
	wprintw(stdscr,"%s", buffer_part_size);
      }
    }
    if(structure_status==0)
    {
      if(list_part!=NULL)
	mvwaddstr(stdscr,LINES-6,0,msg_STRUCT_OK);
    }
    else
    {
      if(has_colors())
	wbkgdset(stdscr,' ' | A_BOLD | COLOR_PAIR(1));
      mvwaddstr(stdscr,LINES-6,0,msg_STRUCT_BAD);
      if(has_colors())
	wbkgdset(stdscr,' ' | COLOR_PAIR(0));
    }
    if(list_part!=NULL && disk_car->arch->msg_part_type!=NULL)
    {
      mvwaddstr(stdscr,LINES-6,16,"Use ");
      if(has_colors())
	wbkgdset(stdscr,' ' | A_BOLD | COLOR_PAIR(0));
      waddstr(stdscr,"Up");
      if(has_colors())
	wbkgdset(stdscr,' ' | COLOR_PAIR(0));
      waddstr(stdscr,"/");
      if(has_colors())
	wbkgdset(stdscr,' ' | A_BOLD | COLOR_PAIR(0));
      waddstr(stdscr,"Down");
      if(has_colors())
	wbkgdset(stdscr,' ' | COLOR_PAIR(0));
      waddstr(stdscr," Arrow keys to select partition.");
      mvwaddstr(stdscr,LINES-5,0,"Use ");
      if(has_colors())
	wbkgdset(stdscr,' ' | A_BOLD | COLOR_PAIR(0));
      waddstr(stdscr,"Left");
      if(has_colors())
	wbkgdset(stdscr,' ' | COLOR_PAIR(0));
      waddstr(stdscr,"/");
      if(has_colors())
	wbkgdset(stdscr,' ' | A_BOLD | COLOR_PAIR(0));
      waddstr(stdscr,"Right");
      if(has_colors())
	wbkgdset(stdscr,' ' | COLOR_PAIR(0));
      waddstr(stdscr," Arrow keys to CHANGE partition characteristics:");
      mvwaddstr(stdscr,LINES-4,0,disk_car->arch->msg_part_type);
    }
    wmove(stdscr,LINES-3,0);
    wclrtoeol(stdscr);	/* before addstr for BSD compatibility */
    waddstr(stdscr,"Keys ");
    /* If the disk can't be partionned, there is no partition to add and no partition to save */
    if(disk_car->arch != &arch_none)
    {
      if(has_colors())
	wbkgdset(stdscr,' ' | A_BOLD | COLOR_PAIR(0));
      waddstr(stdscr,"A");
      if(has_colors())
	wbkgdset(stdscr,' ' | COLOR_PAIR(0));
      waddstr(stdscr,": add partition, ");
      if(has_colors())
	wbkgdset(stdscr,' ' | A_BOLD | COLOR_PAIR(0));
      waddstr(stdscr,"L");
      if(has_colors())
	wbkgdset(stdscr,' ' | COLOR_PAIR(0));
      waddstr(stdscr,": load backup, ");
    }
    if(list_part==NULL)
    {
      waddstr(stdscr,"Enter: to continue");
    }
    else
    {
      if(pos->part->arch==NULL || pos->part->arch==disk_car->arch)
      {
	if(has_colors())
	  wbkgdset(stdscr,' ' | A_BOLD | COLOR_PAIR(0));
	waddstr(stdscr,"T");
	if(has_colors())
	  wbkgdset(stdscr,' ' | COLOR_PAIR(0));
	waddstr(stdscr,": change type, ");
      }
      switch(pos->part->upart_type)
      {
	case UP_EXFAT:
	case UP_EXT2:
	case UP_EXT3:
	case UP_EXT4:
	case UP_RFS:
	case UP_RFS2:
	case UP_RFS3:
	case UP_FAT12:
	case UP_FAT16:
	case UP_FAT32:
	case UP_NTFS:
	  if(has_colors())
	    wbkgdset(stdscr,' ' | A_BOLD | COLOR_PAIR(0));
	  waddstr(stdscr,"P");
	  if(has_colors())
	    wbkgdset(stdscr,' ' | COLOR_PAIR(0));
	  waddstr(stdscr,": list files, ");
	  break;
	default:
	  break;
      }
      if(has_colors())
	wbkgdset(stdscr,' ' | A_BOLD | COLOR_PAIR(0));
      mvwaddstr(stdscr,LINES-2,5, "Enter");
      if(has_colors())
	wbkgdset(stdscr,' ' | COLOR_PAIR(0));
      waddstr(stdscr,": to continue");
    }
    wrefresh(stdscr);
    command=wgetch(stdscr);
    switch(command)
    {
      case KEY_UP:
	if(list_part!=NULL)
	{
	  only_one_bootable(list_part,pos);
	  if(pos->prev!=NULL)
	  {
	    pos=pos->prev;
	    pos_num--;
	  }
	}
	break;
      case KEY_DOWN:
	if(list_part!=NULL)
	{
	  only_one_bootable(list_part,pos);
	  if(pos->next!=NULL)
	  {
	    pos=pos->next;
	    pos_num++;
	  }
	}
	break;
      case KEY_PPAGE:
	if(list_part!=NULL)
	{
	  only_one_bootable(list_part,pos);
	  for(i=0; i<INTER_STRUCTURE && pos->prev!=NULL; i++)
	  {
	    pos=pos->prev;
	    pos_num--;
	  }
	}
	break;
      case KEY_NPAGE:
	if(list_part!=NULL)
	{
	  only_one_bootable(list_part,pos);
	  for(i=0; i<INTER_STRUCTURE && pos->next!=NULL; i++)
	  {
	    pos=pos->next;
	    pos_num++;
	  }
	}
	break;
      case KEY_RIGHT:
      case '+':
      case ' ':
	if(list_part!=NULL)
	{
	  if(pos->part->arch==NULL || pos->part->arch==disk_car->arch)
	    disk_car->arch->set_next_status(disk_car,pos->part);
	}
	break;
      case KEY_LEFT:
      case '-':
	if(list_part!=NULL)
	{
	  if(pos->part->arch==NULL || pos->part->arch==disk_car->arch)
	    disk_car->arch->set_prev_status(disk_car,pos->part);
	}
	break;
      case 'a':
      case 'A':
	if(disk_car->arch != &arch_none)
	{
	  list_part=add_partition_ncurses(disk_car, list_part);
	  rewrite=1;
	  offset=0;
	  pos_num=0;
	  pos=list_part;
	}
	break;
      case 't':
      case 'T':
	if(list_part!=NULL)
	{
	  rewrite=1;
	  change_part_type_ncurses(disk_car, pos->part);
	}
	break;
      case 'p':
      case 'P':
	if(list_part!=NULL)
        {
          const partition_t *partition=pos->part;
          if(partition->sb_offset==0 || partition->sb_size==0)
            dir_partition(disk_car,partition,verbose, current_cmd);
          else
          {
            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);
          }
	  rewrite=1;
        }
	break;
      case 'b':
      case 'B':
	if(partition_save(disk_car,list_part,verbose)<0)
	  display_message("Can't create backup.log.\n");
	else
	  display_message("Results saved in backup.log.\n");
	rewrite=1;
        break;
      case 'l':
      case 'L':
	if(disk_car->arch != &arch_none)
	{
	  list_part=interface_load(disk_car,list_part,verbose);
	  rewrite=1;
	  offset=0;
	  pos_num=0;
	  pos=list_part;
	}
        break;
      case 'q':
      case '\r':
      case '\n':
      case KEY_ENTER:
#ifdef PADENTER
      case PADENTER:
#endif
      case 'M':
	return list_part;
      default:
/*	log_trace("ask_structure command=%x\n",command); */
	break;
    }
    if(pos_num<offset)
      offset=pos_num;
    if(pos_num>=offset+INTER_STRUCTURE)
      offset=pos_num-INTER_STRUCTURE+1;
  }
}
Example #28
0
int repair_MFT(disk_t *disk_car, partition_t *partition, const int verbose, const unsigned int expert, char **current_cmd)
{
  struct ntfs_boot_sector *ntfs_header;
  unsigned char *buffer_mft;
  unsigned char *buffer_mftmirr;
  unsigned int cluster_size;
  unsigned int mft_record_size;
  unsigned int mftmirr_size_bytes;
  unsigned int use_MFT=0;
  /* 0: do nothing
   * 1: fix MFT mirror using MFT
   * 2: fix MFT using MFT mirror */
  uint64_t mft_pos;
  uint64_t mftmirr_pos;
  log_trace("repair_MFT\n");
  if(check_NTFS(disk_car, partition, verbose, 0)!=0)
  {
    display_message("Boot sector not valid, can't repair MFT.\n");
    return -1;
  }
  ntfs_header=(struct ntfs_boot_sector *)MALLOC(DEFAULT_SECTOR_SIZE);
  if(disk_car->pread(disk_car, ntfs_header, DEFAULT_SECTOR_SIZE, partition->part_offset) != DEFAULT_SECTOR_SIZE)
  {
    free(ntfs_header);
    display_message("Can't read NTFS boot sector.\n");
    return -1;
  }
  mft_pos=partition->part_offset+(uint64_t)(le16(ntfs_header->reserved)+le64(ntfs_header->mft_lcn)*ntfs_header->sectors_per_cluster)*ntfs_sector_size(ntfs_header);
  mftmirr_pos=partition->part_offset+(uint64_t)(le16(ntfs_header->reserved)+le64(ntfs_header->mftmirr_lcn)*ntfs_header->sectors_per_cluster)*ntfs_sector_size(ntfs_header);
  if(ntfs_header->clusters_per_mft_record>0)
    mft_record_size=ntfs_header->sectors_per_cluster*ntfs_header->clusters_per_mft_record;
  else
    mft_record_size=1<<(-ntfs_header->clusters_per_mft_record);

  cluster_size=ntfs_header->sectors_per_cluster;

  mftmirr_size_bytes = (cluster_size <= 4 * mft_record_size ? 4 * mft_record_size : cluster_size) * ntfs_sector_size(ntfs_header);
#ifdef DEBUG_REPAIR_MFT
  log_debug("mft_pos %lu\n",(unsigned long)(mft_pos/disk_car->sector_size));
  log_debug("mftmirr_pos %lu\n",(unsigned long)(mftmirr_pos/disk_car->sector_size));
  log_debug("cluster_size %u\n", cluster_size);
  log_debug("mft_record_size    %u\n", mft_record_size);
  log_debug("ntfs_sector_size   %u\n", ntfs_sector_size(ntfs_header));
  log_debug("mftmirr_size_bytes %u\n", mftmirr_size_bytes);
#endif
  if(mftmirr_size_bytes==0)
  {
    display_message("Invalid NTFS MFT size.\n");
    log_error("Invalid NTFS MFT size.\n");
    free(ntfs_header);
    return -1;
  }
  /* Check if MFT mirror is identical to the beginning of MFT */
  buffer_mft=(unsigned char *)MALLOC(mftmirr_size_bytes);
  if((unsigned)disk_car->pread(disk_car, buffer_mft, mftmirr_size_bytes, mft_pos) != mftmirr_size_bytes)
  {
    display_message("Can't read NTFS MFT.\n");
    log_error("Can't read NTFS MFT.\n");
    free(buffer_mft);
    free(ntfs_header);
    return -1;
  }
  buffer_mftmirr=(unsigned char *)MALLOC(mftmirr_size_bytes);
  if((unsigned)disk_car->pread(disk_car, buffer_mftmirr, mftmirr_size_bytes, mftmirr_pos) != mftmirr_size_bytes)
  {
    display_message("Can't read NTFS MFT mirror.\n");
    log_error("Can't read NTFS MFT mirror.\n");
    free(buffer_mftmirr);
    free(buffer_mft);
    free(ntfs_header);
    return -1;
  }
  if(memcmp(buffer_mft, buffer_mftmirr, mftmirr_size_bytes)==0)
  {
    log_info("MFT and MFT mirror match perfectly.\n");
    if(*current_cmd==NULL)
      display_message("MFT and MFT mirror match perfectly.\n");
    free(buffer_mftmirr);
    free(buffer_mft);
    free(ntfs_header);
    return 0;
  }
  if(partition->sb_offset!=0)
  {
    log_info("Please quit TestDisk and reboot your computer before trying to fix the MFT.\n");
    display_message("Please quit TestDisk and reboot your computer before trying to fix the MFT.\n");
    free(buffer_mftmirr);
    free(buffer_mft);
    free(ntfs_header);
    return -1;
  }
/*
  log_debug("MFT\n");
  dump_log(buffer_mft, mftmirr_size_bytes);
  log_debug("MFT mirror\n");
  dump_log(buffer_mftmirr, mftmirr_size_bytes);
  */
  /*
  The idea is to use the internal IO redirector built-in TestDisk
  to redirect read access to the MFT to the MFT backup instead (or
  vice-versa) when listing the NTFS files. If TestDisk can get
  a file listing, it also knows which MFT to use.
  */
  {
    int res1,res2;
    dir_data_t dir_data;
    /* Use MFT */
    io_redir_add_redir(disk_car, mftmirr_pos, mftmirr_size_bytes, 0, buffer_mft);
    res1=dir_partition_ntfs_init(disk_car,partition,&dir_data,verbose);
    if(res1==DIR_PART_ENOSYS)
    {
	display_message("Can't determine which MFT is correct, ntfslib is missing.\n");
	log_error("Can't determine which MFT is correct, ntfslib is missing.\n");
	free(buffer_mftmirr);
	free(buffer_mft);
	free(ntfs_header);
	io_redir_del_redir(disk_car,mftmirr_pos);
	return 0;
    }
    if(res1==DIR_PART_OK)
    {
      file_info_t dir_list;
      TD_INIT_LIST_HEAD(&dir_list.list);
      dir_data.get_dir(disk_car,partition,&dir_data,dir_data.current_inode, &dir_list);
      if(!td_list_empty(&dir_list.list))
      {
	log_info("NTFS listing using MFT:\n");
	dir_aff_log(&dir_data, &dir_list);
	if(delete_list_file(&dir_list)>2)
	  res1++;
      }
      dir_data.close(&dir_data);
    }
    io_redir_del_redir(disk_car,mftmirr_pos);
    /* Use MFT mirror */
    io_redir_add_redir(disk_car, mft_pos, mftmirr_size_bytes, 0, buffer_mftmirr);
    res2=dir_partition_ntfs_init(disk_car,partition,&dir_data,verbose);
    if(res2==DIR_PART_OK)
    {
      file_info_t dir_list;
      TD_INIT_LIST_HEAD(&dir_list.list);
      dir_data.get_dir(disk_car,partition,&dir_data,dir_data.current_inode, &dir_list);
      if(!td_list_empty(&dir_list.list))
      {
	log_info("NTFS listing using MFT mirror:\n");
	dir_aff_log(&dir_data, &dir_list);
	if(delete_list_file(&dir_list)>2)
	  res2++;
      }
      dir_data.close(&dir_data);
    }
    io_redir_del_redir(disk_car,mft_pos);
    /* */
    if(res1>res2 && res1>DIR_PART_OK)
    {
      /* Use MFT */
#ifdef HAVE_NCURSES
      if(ask_confirmation("Fix MFT mirror using MFT ? (Y/N)")!=0)
	use_MFT=1;
      else
#endif
	log_info("Don't fix MFT mirror.\n");
    }
    else if(res1<res2 && res2>DIR_PART_OK)
    {
      /* Use MFT mirror */
#ifdef HAVE_NCURSES
      if(ask_confirmation("Fix MFT using its mirror ? (Y/N) - DANGEROUS NON REVERSIBLE OPERATION\nUse it ONLY IF Windows failed to access this filesystem.")!=0)
	use_MFT=2;
      else
#endif
	log_info("Don't fix MFT.\n");
    }
    else
    { /* res1==res2 */
      if(res1>DIR_PART_OK && res2>DIR_PART_OK)
	log_error("Both MFT seems ok but they don't match, use chkdsk.\n");
      else
	log_error("MFT and MFT mirror are bad. Failed to repair them.\n");
      if(expert==0)
      {
	if(res1>DIR_PART_OK && res2>DIR_PART_OK)
	  display_message("Both MFT seems ok but they don't match, use chkdsk.\n");
	else
	  display_message("MFT and MFT mirror are bad. Failed to repair them.\n");
      }
      else
      {
#ifdef HAVE_NCURSES
	unsigned int menu=2;
	int real_key;
	int command;
	static const struct MenuItem menuMFT[]=
	{
	  {'B',"MFT",		"Fix MFT using MFT mirror"},
	  {'M',"MFT Mirror",	"Fix MFT mirror using MFT"},
	  {'Q',"Quit","Return to NTFS functions"},
	  {0,NULL,NULL}
	};
	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);
	wmove(stdscr,8,0);
	if(res1>0 && res2>0)
	  wprintw(stdscr, "Both MFT seem ok but they don't match.\n");
	else
	  wprintw(stdscr, "MFT and MFT mirror are bad.\n");
	command=wmenuSelect_ext(stdscr, 23, INTER_MFT_Y, INTER_MFT_X, menuMFT, 10, "MBQ",
	    MENU_VERT | MENU_VERT_WARN | MENU_BUTTON, &menu, &real_key);
	switch(command)
	{
	  case 'b':
	  case 'B':
	    use_MFT=2;
	    break;
	  case 'm':
	  case 'M':
	    use_MFT=1;
	    break;
	  default:
	    use_MFT=0;
	    break;
	}
#endif
      }
    }
  }
  if(use_MFT==2)
  {
    if((unsigned)disk_car->pwrite(disk_car, buffer_mftmirr, mftmirr_size_bytes, mft_pos) != mftmirr_size_bytes)
    {
      display_message("Failed to fix MFT: write error.\n");
    }
    else
    {
      disk_car->sync(disk_car);
      display_message("MFT fixed.\n");
    }
  }
  else if(use_MFT==1)
  {
    if((unsigned)disk_car->pwrite(disk_car, buffer_mft, mftmirr_size_bytes, mftmirr_pos) != mftmirr_size_bytes)
    {
      display_message("Failed to fix MFT mirror: write error.\n");
    }
    else
    {
      disk_car->sync(disk_car);
      display_message("MFT mirror fixed.\n");
    }
  }
  free(buffer_mftmirr);
  free(buffer_mft);
  free(ntfs_header);
  return 0;
}
Example #29
0
void menu_photorec(struct ph_param *params, struct ph_options *options, alloc_data_t*list_search_space)
{
  list_part_t *list_part;
  list_part_t *current_element;
  unsigned int current_element_num;
  unsigned int user_blocksize=0;
  int done=0;
  init_mode_t mode_init_space=(td_list_empty(&list_search_space->list)?INIT_SPACE_WHOLE:INIT_SPACE_PREINIT);
#ifdef HAVE_NCURSES
  int command;
  unsigned int offset=0;
  unsigned int menu=0;
  static const struct MenuItem menuMain[]=
  {
	{'S',"Search","Start file recovery"},
	{'O',"Options","Modify options"},
	{'F',"File Opt","Modify file options"},
	{'G',"Geometry", "Change disk geometry" },
	{'Q',"Quit","Return to disk selection"},
	{0,NULL,NULL}
  };
#endif
  params->blocksize=0;
  list_part=init_list_part(params->disk, options);
  if(list_part==NULL)
    return;
  log_all_partitions(params->disk, list_part);
  if(list_part->next!=NULL)
  {
    current_element_num=1;
    current_element=list_part->next;
  }
  else
  {
    current_element_num=0;
    current_element=list_part;
  }
  while(done==0)
  {
    if(params->cmd_run!=NULL)
    {
      while(params->cmd_run[0]==',')
	params->cmd_run++;
      if(params->cmd_run[0]=='\0')
      {
	part_free_list(list_part);
	return;
      }
      if(strncmp(params->cmd_run,"search",6)==0)
      {
	params->cmd_run+=6;
	if(params->recup_dir==NULL)
	{
	  char *res;
#ifdef HAVE_NCURSES
	  res=ask_location("Please select a destination to save the recovered files.\nDo not choose to write the files to the same partition they were stored on.", "", NULL);
#else
	  res=get_default_location();
#endif
	  if(res!=NULL)
	  {
	    params->recup_dir=(char *)MALLOC(strlen(res)+1+strlen(DEFAULT_RECUP_DIR)+1);
	    strcpy(params->recup_dir,res);
	    strcat(params->recup_dir,"/");
	    strcat(params->recup_dir,DEFAULT_RECUP_DIR);
	    free(res);
	  }
	}
	if(params->recup_dir!=NULL)
	{
	  params->partition=current_element->part;
	  if(mode_init_space==INIT_SPACE_EXT2_GROUP)
	  {
	    params->blocksize=ext2_fix_group(list_search_space, params->disk, params->partition);
	    if(params->blocksize==0)
	      display_message("Not a valid ext2/ext3/ext4 filesystem");
	  }
	  else if(mode_init_space==INIT_SPACE_EXT2_INODE)
	  {
	    params->blocksize=ext2_fix_inode(list_search_space, params->disk, params->partition);
	    if(params->blocksize==0)
	      display_message("Not a valid ext2/ext3/ext4 filesystem");
	  }
	  if(td_list_empty(&list_search_space->list))
	  {
	    init_search_space(list_search_space, params->disk, params->partition);
	  }
	  if(params->carve_free_space_only>0)
	  {
	    params->blocksize=remove_used_space(params->disk, params->partition, list_search_space);
	  }
	  if(user_blocksize > 0)
	    params->blocksize=user_blocksize;
	  photorec(params, options, list_search_space);
	}
      }
      else if(strncmp(params->cmd_run,"options",7)==0)
      {
	params->cmd_run+=7;
	interface_options_photorec_cli(options, &params->cmd_run);
      }
      else if(strncmp(params->cmd_run,"fileopt",7)==0)
      {
	params->cmd_run+=7;
	interface_file_select(options->list_file_format, &params->cmd_run);
      }
      else if(strncmp(params->cmd_run,"blocksize,",10)==0)
      {
	params->cmd_run+=10;
	user_blocksize=atoi(params->cmd_run);
	while(params->cmd_run[0]!=',' && params->cmd_run[0]!='\0')
	  params->cmd_run++;
      }
      else if(strncmp(params->cmd_run,"geometry,",9)==0)
      {
	params->cmd_run+=9;
	change_geometry_cli(params->disk, &params->cmd_run);
      }
      else if(strncmp(params->cmd_run,"inter",5)==0)
      {	/* Start interactive mode */
	params->cmd_run=NULL;
      }
      else if(strncmp(params->cmd_run,"wholespace",10)==0)
      {
	params->cmd_run+=10;
	params->carve_free_space_only=0;
      }
      else if(strncmp(params->cmd_run,"freespace",9)==0)
      {
	params->cmd_run+=9;
	params->carve_free_space_only=1;
      }
      else if(strncmp(params->cmd_run,"ext2_group,",11)==0)
      {
	unsigned int groupnr;
	params->cmd_run+=11;
	options->mode_ext2=1;
	groupnr=atoi(params->cmd_run);
	while(params->cmd_run[0]!=',' && params->cmd_run[0]!='\0')
	  params->cmd_run++;
	if(mode_init_space==INIT_SPACE_WHOLE)
	  mode_init_space=INIT_SPACE_EXT2_GROUP;
	if(mode_init_space==INIT_SPACE_EXT2_GROUP)
	{
          alloc_data_t *new_free_space;
          new_free_space=(alloc_data_t*)MALLOC(sizeof(*new_free_space));
          /* Temporary storage, values need to be multiplied by group size and aligned */
          new_free_space->start=groupnr;
          new_free_space->end=groupnr;
          new_free_space->file_stat=NULL;
	  new_free_space->data=1;
          if(td_list_add_sorted_uniq(&new_free_space->list, &list_search_space->list, spacerange_cmp))
	    free(new_free_space);
        }
      }
      else if(strncmp(params->cmd_run,"ext2_inode,",11)==0)
      {
	unsigned int inodenr;
	params->cmd_run+=11;
	options->mode_ext2=1;
	inodenr=atoi(params->cmd_run);
	while(params->cmd_run[0]!=',' && params->cmd_run[0]!='\0')
	  params->cmd_run++;
	if(mode_init_space==INIT_SPACE_WHOLE)
	  mode_init_space=INIT_SPACE_EXT2_INODE;
	if(mode_init_space==INIT_SPACE_EXT2_INODE)
	{
          alloc_data_t *new_free_space;
          new_free_space=(alloc_data_t*)MALLOC(sizeof(*new_free_space));
          /* Temporary storage, values need to be multiplied by group size and aligned */
          new_free_space->start=inodenr;
          new_free_space->end=inodenr;
          new_free_space->file_stat=NULL;
	  new_free_space->data=1;
          if(td_list_add_sorted_uniq(&new_free_space->list, &list_search_space->list, spacerange_cmp))
	    free(new_free_space);
        }
      }
      else if(isdigit(params->cmd_run[0]))
      {
	list_part_t *element;
	unsigned int order;
	order= atoi(params->cmd_run);
	while(params->cmd_run[0]!=',' && params->cmd_run[0]!='\0')
	  params->cmd_run++;
	for(element=list_part;element!=NULL && element->part->order!=order;element=element->next);
	if(element!=NULL)
	  current_element=element;
      }
      else
      {
	log_critical("Syntax error in command line: %s\n", params->cmd_run);
	part_free_list(list_part);
	return;
      }
    }
#ifdef HAVE_NCURSES
    else
    { /* ncurses interface */
      list_part_t *element;
      unsigned int i;
      aff_copy(stdscr);
      wmove(stdscr,4,0);
      wprintw(stdscr,"%s",params->disk->description_short(params->disk));
      mvwaddstr(stdscr,6,0,msg_PART_HEADER_LONG);
#if defined(KEY_MOUSE) && defined(ENABLE_MOUSE)
      mousemask(ALL_MOUSE_EVENTS, NULL);
#endif
      for(i=0,element=list_part; element!=NULL && i<offset+INTER_SELECT;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,params->disk,element->part);
	  wattroff(stdscr, A_REVERSE);
	} else
	{
	  waddstr(stdscr, " ");
	  aff_part(stdscr,AFF_PART_ORDER|AFF_PART_STATUS,params->disk,element->part);
	}
      }
      wmove(stdscr,7+INTER_SELECT,5);
      wclrtoeol(stdscr);
      if(element!=NULL)
	wprintw(stdscr, "Next");
      command = wmenuSelect(stdscr, INTER_SELECT_Y+1, INTER_SELECT_Y, INTER_SELECT_X, menuMain, 8,
	  (options->expert==0?"SOFQ":"SOFGQ"), MENU_HORIZ | MENU_BUTTON | MENU_ACCEPT_OTHERS, menu);
#if defined(KEY_MOUSE) && defined(ENABLE_MOUSE)
      if(command == KEY_MOUSE)
      {
	MEVENT event;
	if(getmouse(&event) == OK)
	{	/* When the user clicks left mouse button */
	  if((event.bstate & BUTTON1_CLICKED) || (event.bstate & BUTTON1_DOUBLE_CLICKED))
	  {
	    if(event.y >=7 && event.y<7+INTER_SELECT)
	    {
	      /* Disk selection */
	      while(current_element_num > event.y-(7-offset) && current_element->prev!=NULL)
	      {
		current_element=current_element->prev;
		current_element_num--;
	      }
	      while(current_element_num < event.y-(7-offset) && current_element->next!=NULL)
	      {
		current_element=current_element->next;
		current_element_num++;
	      }
	      if(event.bstate & BUTTON1_DOUBLE_CLICKED)
		command='S';
	    }
	    else
	      command = menu_to_command(INTER_SELECT_Y+1, INTER_SELECT_Y, INTER_SELECT_X, menuMain, 8,
		  (options->expert==0?"SOFQ":"SOFGQ"), MENU_HORIZ | MENU_BUTTON | MENU_ACCEPT_OTHERS, event.y, event.x);
	  }
	}
      }
#endif
      switch(command)
      {
	case KEY_UP:
	  if(current_element!=NULL && current_element->prev!=NULL)
	  {
	    current_element=current_element->prev;
	    current_element_num--;
	  }
	  break;
	case KEY_PPAGE:
	  for(i=0; (signed)i<INTER_SELECT && current_element->prev!=NULL; i++)
	  {
	    current_element=current_element->prev;
	    current_element_num--;
	  }
	  break;
	case KEY_DOWN:
	  if(current_element->next!=NULL)
	  {
	    current_element=current_element->next;
	    current_element_num++;
	  }
	  break;
	case KEY_NPAGE:
	  for(i=0; (signed)i<INTER_SELECT && current_element->next!=NULL; i++)
	  {
	    current_element=current_element->next;
	    current_element_num++;
	  }
	  break;
	case 's':
	case 'S':
	  if(current_element!=NULL)
	  {
	    params->partition=current_element->part;
	    ask_mode_ext2(params->disk, params->partition, &options->mode_ext2, &params->carve_free_space_only);
	    menu=0;
	    if(params->recup_dir==NULL)
	    {
	      char *res;
	      res=ask_location("Please select a destination to save the recovered files.\nDo not choose to write the files to the same partition they were stored on.", "", NULL);
	      if(res!=NULL)
	      {
		params->recup_dir=(char *)MALLOC(strlen(res)+1+strlen(DEFAULT_RECUP_DIR)+1);
		strcpy(params->recup_dir,res);
		strcat(params->recup_dir,"/");
		strcat(params->recup_dir,DEFAULT_RECUP_DIR);
		free(res);
	      }
	    }
	    if(params->recup_dir!=NULL)
	    {
	      if(td_list_empty(&list_search_space->list))
	      {
		init_search_space(list_search_space, params->disk, params->partition);
	      }
	      if(params->carve_free_space_only>0)
	      {
		aff_copy(stdscr);
		wmove(stdscr,5,0);
		wprintw(stdscr, "Filesystem analysis, please wait...\n");
		wrefresh(stdscr);
		params->blocksize=remove_used_space(params->disk, params->partition, list_search_space);
		/* Only free space is carved, list_search_space is modified.
		 * To carve the whole space, need to quit and reselect the params->partition */
		done = 1;
	      }
	      photorec(params, options, list_search_space);
	    }
	  }
	  break;
	case 'o':
	case 'O':
	  {
	    interface_options_photorec_ncurses(options);
	    menu=1;
	  }
	  break;
	case 'f':
	case 'F':
	  interface_file_select(options->list_file_format, &params->cmd_run);
	  menu=2;
	  break;
	case 'g':
	case 'G':
	  if(options->expert!=0)
	    if(change_geometry_ncurses(params->disk))
	      done=1;
	  break;
      case 'a':
      case 'A':
	if(params->disk->arch != &arch_none)
	{
	  list_part=add_partition_ncurses(params->disk, list_part);
	  current_element=list_part;
	  current_element_num=0;
	}
	break;
	case 'q':
	case 'Q':
	  done = 1;
	  break;
      }
      if(current_element_num<offset)
	offset=current_element_num;
      if(current_element_num>=offset+INTER_SELECT)
	offset=current_element_num-INTER_SELECT+1;
    }
#endif
  }
  log_info("\n");
  part_free_list(list_part);
}
Example #30
0
static int interface_part_bad_ncurses(disk_t *disk_car, list_part_t *list_part)
{
  int quit=0;
  int offset=0;
  int pos_num=0;
  uint64_t disk_size=disk_car->disk_size;
  list_part_t *pos=list_part;
  if(list_part==NULL)
    return 1;
  {
    list_part_t *parts;
    for(parts=list_part;parts!=NULL;parts=parts->next)
    {
      if(disk_size<parts->part->part_offset+parts->part->part_size-1)
	disk_size=parts->part->part_offset+parts->part->part_size-1;
    }
  }
  aff_copy(stdscr);
  wmove(stdscr,4,0);
  wprintw(stdscr,"%s",disk_car->description(disk_car));
  wmove(stdscr,6,0);
  {
    char buffer_disk_size[100];
    char buffer_disk_size_found[100];
    size_to_unit(disk_car->disk_size, buffer_disk_size);
    size_to_unit(disk_size, buffer_disk_size_found);
    wprintw(stdscr,"The harddisk (%s) seems too small! (< %s)",
	buffer_disk_size, buffer_disk_size_found);
  }
  wmove(stdscr,7,0);
  wprintw(stdscr,"Check the harddisk size: HD jumper settings, BIOS detection...");
#if defined(__CYGWIN__) || defined(__MINGW32__)
  if(disk_car->disk_size<=((uint64_t)1<<(28-1)) && disk_size>=((uint64_t)1<<(28-1)))
  {
    wmove(stdscr,8,0);
    wprintw(stdscr,"Hint: update Windows to support LBA48 (minimum: W2K SP4 or XP SP1)");
  }
#endif
  wmove(stdscr,9,0);
  if(list_part->next==NULL)
  {
    wprintw(stdscr,"The following partition can't be recovered:");
  } else {
    wprintw(stdscr,"The following partitions can't be recovered:");
  }
  mvwaddstr(stdscr,10,0,msg_PART_HEADER);
  wmove(stdscr,22,0);
  wattrset(stdscr, A_REVERSE);
  wprintw(stdscr,"[ Continue ]");
  wattroff(stdscr, A_REVERSE);
  do
  {
    int i;
    int car;
    list_part_t *parts;
    for(i=0,parts=list_part;(parts!=NULL) && (i<offset);parts=parts->next,i++);
    for(i=offset;(parts!=NULL) &&((i-offset)<INTER_BAD_PART);i++,parts=parts->next)
    {
      wmove(stdscr,11+i-offset,0);
      wclrtoeol(stdscr);	/* before addstr for BSD compatibility */
      if(parts==pos)
      {
	char buffer_part_size[100];
	wattrset(stdscr, A_REVERSE);
	waddstr(stdscr, ">");
	aff_part(stdscr, AFF_PART_BASE, disk_car, parts->part);
	wattroff(stdscr, A_REVERSE);
	wmove(stdscr,23,0);
	wclrtoeol(stdscr);	/* before addstr for BSD compatibility */
	if(parts->part->info[0]!='\0')
	{
	  wprintw(stdscr,"%s, ",parts->part->info);
	}
	size_to_unit(parts->part->part_size, buffer_part_size);
	wprintw(stdscr,"%s", buffer_part_size);
      } else
      {
	waddstr(stdscr, " ");
	aff_part(stdscr, AFF_PART_BASE, disk_car, parts->part);
      }
    }
    wrefresh(stdscr);
    car=wgetch(stdscr);
    switch(car)
    {
      case 'q':
      case '\r':
      case '\n':
      case KEY_ENTER:
#ifdef PADENTER
      case PADENTER:
#endif
      case 'M':
	quit=1;
	break;
      case KEY_UP:
	if(pos->prev!=NULL)
	{
	  pos=pos->prev;
	  pos_num--;
	}
	break;
      case KEY_DOWN:
	if(pos->next!=NULL)
	{
	  pos=pos->next;
	  pos_num++;
	}
	break;
      case KEY_PPAGE:
	for(i=0; i<INTER_BAD_PART && pos->prev!=NULL; i++)
	{
	  pos=pos->prev;
	  pos_num--;
	}
	break;
      case KEY_NPAGE:
	for(i=0; i<INTER_BAD_PART && pos->next!=NULL; i++)
	{
	  pos=pos->next;
	  pos_num++;
	}
	break;
      default:
	break;
    }
    if(pos_num<offset)
      offset=pos_num;
    if(pos_num>=offset+INTER_BAD_PART)
      offset=pos_num-INTER_BAD_PART+1;
  } while(quit==0);
  return 0;
}