From cdb8cbe5fc19346f79922ca25cdc30f7ed88c6d1 Mon Sep 17 00:00:00 2001 From: Christophe Grenier Date: Fri, 21 Dec 2007 08:29:06 +0100 Subject: [PATCH] In expert mode during RepairMFT, user can choose between MFT and MFTmirror if TestDisk can't find the correct one. --- src/adv.c | 2 +- src/intrf.c | 2 +- src/ntfs.h | 2 +- src/ntfs_fix.c | 102 +++++++++++++++++++++++++++++++++++++------------ 4 files changed, 80 insertions(+), 28 deletions(-) diff --git a/src/adv.c b/src/adv.c index 9d622587..c2b3648b 100644 --- a/src/adv.c +++ b/src/adv.c @@ -1068,7 +1068,7 @@ int ntfs_boot_sector(disk_t *disk_car, partition_t *partition, const int verbose dir_partition(disk_car, partition, 0,current_cmd); break; case 'M': - repair_MFT(disk_car, partition, verbose, current_cmd); + repair_MFT(disk_car, partition, verbose, expert, current_cmd); break; case 'R': /* R : rebuild boot sector */ rebuild_NTFS_BS(disk_car,partition,verbose,dump_ind,1,expert,current_cmd); diff --git a/src/intrf.c b/src/intrf.c index a2a342dd..4e89cbf5 100644 --- a/src/intrf.c +++ b/src/intrf.c @@ -402,7 +402,7 @@ int wmenuUpdate(WINDOW *window, int y, int x, const struct MenuItem *menuItems, { log_critical("\nBUG: %s\n",mi); } - if(lenName > itemLength) + if(lenName >= itemLength) { if( menuType & MENU_BUTTON ) snprintf(buff, sizeof(buff),"[%s]",mi); diff --git a/src/ntfs.h b/src/ntfs.h index cc4f6d5e..c828e24c 100644 --- a/src/ntfs.h +++ b/src/ntfs.h @@ -67,5 +67,5 @@ int test_NTFS(const disk_t *disk_car,const struct ntfs_boot_sector*ntfs_header, #define NTFS_GETU64(p) (le64(*(const uint64_t*)(p))) unsigned int ntfs_sector_size(const struct ntfs_boot_sector *ntfs_header); int rebuild_NTFS_BS(disk_t *disk_car,partition_t *partition, const int verbose, const int dump_ind,const int interface, const unsigned int expert, char**current_cmd); -int repair_MFT(disk_t *disk_car, partition_t *partition, const int verbose, char **current_cmd); +int repair_MFT(disk_t *disk_car, partition_t *partition, const int verbose, const unsigned int expert, char **current_cmd); int repair_MFT_Vol(disk_t *disk_car, partition_t *partition, const int verbose); diff --git a/src/ntfs_fix.c b/src/ntfs_fix.c index 85a8b56e..9e61391d 100644 --- a/src/ntfs_fix.c +++ b/src/ntfs_fix.c @@ -42,10 +42,14 @@ #include "ntfs_dir.h" #include "io_redir.h" #include "log.h" +#include "intrfn.h" +#include "lang.h" //#define DEBUG_REPAIR_MFT 1 +#define INTER_MFT_X 0 +#define INTER_MFT_Y 18 -int repair_MFT(disk_t *disk_car, partition_t *partition, const int verbose, char **current_cmd) +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; @@ -54,6 +58,10 @@ int repair_MFT(disk_t *disk_car, partition_t *partition, const int verbose, char unsigned int mft_record_size; unsigned int mftmirr_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"); @@ -192,28 +200,76 @@ int repair_MFT(disk_t *disk_car, partition_t *partition, const int verbose, char { /* Use MFT */ if(ask_confirmation("Fix MFT mirror ? (Y/N)")!=0) + use_MFT=1; + else + log_info("Don't fix MFT mirror.\n"); + } + else if(res1write(disk_car, mftmirr_size_bytes, buffer_mft, mftmirr_pos)!=0) - { - log_error("Failed to fix MFT mirror: write error.\n"); - display_message("Failed to fix MFT mirror: write error.\n"); + /* Use MFT mirror */ + if(ask_confirmation("Fix MFT ? (Y/N)")!=0) + use_MFT=2; + else + log_info("Don't fix MFT.\n"); } else + { /* res1==res2 */ + if(res1<0) + log_error("MFT and MFT mirror are bad. Failed to repair them.\n"); + else + log_error("Both MFT seems ok but they don't match, use chkdsk.\n"); + if(expert==0) { - disk_car->sync(disk_car); - log_info("MFT mirror fixed.\n"); - display_message("MFT mirror fixed.\n"); - } + if(res1<0) + display_message("MFT and MFT mirror are bad. Failed to repair them.\n"); + else + display_message("Both MFT seems ok but they don't match, use chkdsk.\n"); } else { - log_info("Don't fix MFT mirror.\n"); +#ifdef HAVE_NCURSES + unsigned int menu=2; + int real_key; + int command; + static 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) + wprintw(stdscr, "MFT and MFT mirror are bad.\n"); + else + wprintw(stdscr, "Both MFT seems ok but they don't match.\n"); + command=wmenuSelect_ext(stdscr,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 } - else if(res1write(disk_car, mftmirr_size_bytes, buffer_mftmirr, mft_pos)!=0) { @@ -227,22 +283,18 @@ int repair_MFT(disk_t *disk_car, partition_t *partition, const int verbose, char display_message("MFT fixed.\n"); } } - else + else if(use_MFT==1) { - log_info("Don't fix MFT.\n"); - } - } - else if(res1<0) + if(disk_car->write(disk_car, mftmirr_size_bytes, buffer_mft, mftmirr_pos)!=0) { - /* Both are bad */ - log_error("MFT and MFT mirror are bad. Failed to repair them.\n"); - display_message("MFT and MFT mirror are bad. Failed to repair them.\n"); + log_error("Failed to fix MFT mirror: write error.\n"); + display_message("Failed to fix MFT mirror: write error.\n"); } else { - /* Use chkdsk */ - log_error("Both MFT seems ok but they don't match, use chkdsk.\n"); - display_message("Both MFT seems ok but they don't match, use chkdsk.\n"); + disk_car->sync(disk_car); + log_info("MFT mirror fixed.\n"); + display_message("MFT mirror fixed.\n"); } } free(buffer_mftmirr);