summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristophe Grenier <[email protected]>2008-08-25 23:15:17 +0200
committerChristophe Grenier <[email protected]>2008-08-25 23:15:17 +0200
commitd5d0a9a74f20ab8288f81ec96be48636dd6e0686 (patch)
treed9ca34d754825448472b3670afaef7a8d43f38e6
parentc943ebd716ad2f71d2f73abc821e266be552a36f (diff)
Split the interface in several files, part 2
Text interface needs 24 lines instead of 25
-rw-r--r--src/Makefile.am4
-rw-r--r--src/adv.c923
-rw-r--r--src/adv.h5
-rw-r--r--src/diskacc.c38
-rw-r--r--src/diskcapa.c38
-rw-r--r--src/edit.c4
-rw-r--r--src/fat1x.c202
-rw-r--r--src/fat1x.h23
-rw-r--r--src/fat32.c310
-rw-r--r--src/fat32.h22
-rw-r--r--src/fat_adv.c2
-rw-r--r--src/godmode.c12
-rw-r--r--src/intrf.c18
-rw-r--r--src/intrf.h4
-rw-r--r--src/intrface.c31
-rw-r--r--src/intrface.h4
-rw-r--r--src/ntfs_adv.c2
-rw-r--r--src/ntfs_fix.c2
-rw-r--r--src/parti386.c12
-rw-r--r--src/pblocksize.c142
-rw-r--r--src/pblocksize.h22
-rw-r--r--src/pdisksel.c257
-rw-r--r--src/pdisksel.h23
-rw-r--r--src/pfree_whole.c134
-rw-r--r--src/pfree_whole.h24
-rw-r--r--src/photorec.c3
-rw-r--r--src/photorec.h24
-rw-r--r--src/phrecn.c787
-rw-r--r--src/phrecn.h4
-rw-r--r--src/ppartsel.c420
-rw-r--r--src/ppartsel.h24
-rw-r--r--src/tdelete.c1
-rw-r--r--src/tdiskop.c2
-rw-r--r--src/tdisksel.c17
-rw-r--r--src/thfs.c245
-rw-r--r--src/thfs.h22
-rw-r--r--src/tload.c46
-rw-r--r--src/tlog.c2
-rw-r--r--src/tmbrcode.c3
-rw-r--r--src/tntfs.c287
-rw-r--r--src/tntfs.h22
-rw-r--r--src/toptions.c2
42 files changed, 2338 insertions, 1831 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index 9128f75e..bf9a182f 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -16,9 +16,9 @@ base_H = alignio.h common.h crc.h ewf.h fnctdsk.h hdaccess.h hdwin32.h guid_cm
fs_C = analyse.c bfs.c bsd.c cramfs.c fat.c fatx.c ext2.c jfs.c hfs.c hfsp.c luks.c lvm.c md.c netware.c ntfs.c rfs.c savehdr.c sun.c swap.c sysv.c ufs.c xfs.c
fs_H = analyse.h bfs.h bsd.h cramfs.h fat.h fatx.h ext2.h jfs_superblock.h jfs.h hfs.h hfsp.h luks.h lvm.h md.h netware.h ntfs.h rfs.h savehdr.h sun.h swap.h sysv.h ufs.h xfs.h
-testdisk_SOURCES = testdisk.c $(base_C) $(base_H) $(fs_C) $(fs_H) testdisk.h adv.c adv.h dir.c dir.h dirpart.c dirpart.h diskacc.c diskacc.h edit.c edit.h ext2_dir.c ext2_dir.h ext2_inc.h ext2_sb.c ext2_sb.h fat_adv.c fat_adv.h fat_dir.c fat_dir.h geometry.c godmode.c godmode.h intrface.c diskcapa.c diskcapa.h intrface.h ntfs_adv.c ntfs_dir.c ntfs_dir.h ntfs_fix.c ntfs_inc.h rfs_dir.c rfs_dir.h $(ICON_TESTDISK) next.c next.h dimage.c dimage.h ntfs_udl.c ntfs_udl.h tanalyse.c tanalyse.h tdelete.c tdelete.h tdisksel.c tdisksel.h tdiskop.c tdiskop.h tload.c tload.h tlog.c tlog.h tmbrcode.c tmbrcode.h toptions.c toptions.h tpartwr.c tpartwr.h
+testdisk_SOURCES = testdisk.c $(base_C) $(base_H) $(fs_C) $(fs_H) testdisk.h adv.c adv.h dir.c dir.h dirpart.c dirpart.h diskacc.c diskacc.h edit.c edit.h ext2_dir.c ext2_dir.h ext2_inc.h ext2_sb.c ext2_sb.h fat1x.c fat1x.h fat32.c fat32.h fat_adv.c fat_adv.h fat_dir.c fat_dir.h geometry.c godmode.c godmode.h intrface.c diskcapa.c diskcapa.h intrface.h ntfs_adv.c ntfs_dir.c ntfs_dir.h ntfs_fix.c ntfs_inc.h rfs_dir.c rfs_dir.h $(ICON_TESTDISK) next.c next.h dimage.c dimage.h ntfs_udl.c ntfs_udl.h tanalyse.c tanalyse.h tdelete.c tdelete.h tdisksel.c tdisksel.h tdiskop.c tdiskop.h thfs.c thfs.h tload.c tload.h tlog.c tlog.h tmbrcode.c tmbrcode.h tntfs.c tntfs.h toptions.c toptions.h tpartwr.c tpartwr.h
-photorec_SOURCES = photorec.c photorec.h phcfg.c phcfg.h phrecn.c phrecn.h dir.c dir.h ext2grp.c ext2grp.h ext2p.c ext2p.h ext2_dir.c ext2_dir.h ext2_inc.h fat_dir.c fat_dir.h fatp.c fatp.h filegen.c filegen.h file_7z.c file_a.c file_ab.c file_ace.c file_ahn.c file_aif.c file_all.c file_als.c file_amd.c file_amr.c file_arj.c file_asf.c file_asm.c file_au.c file_bkf.c file_bld.c file_bmp.c file_bz2.c file_cab.c file_cam.c file_chm.c file_cm.c file_compress.c file_crw.c file_ctg.c file_cwk.c file_dat.c file_dbf.c file_dim.c file_dir.c file_djv.c file_doc.c file_dpx.c file_drw.c file_ds2.c file_dsc.c file_dss.c file_dta.c file_dump.c file_dv.c file_dwg.c file_elf.c file_emf.c file_evt.c file_exe.c pe.h file_ext.c file_fcp.c file_fcs.c file_fbk.c file_fdb.c file_fh10.c file_fh5.c file_fits.c file_flac.c file_flv.c file_fob.c file_frm.c file_fs.c file_gho.c file_gif.c file_gpg.c file_gz.c file_ifo.c file_imb.c file_indd.c file_iso.c file_itu.c file_jpg.c file_jpg.h file_kdb.c file_lnk.c file_m2ts.c file_max.c file_mb.c file_mcd.c file_mdb.c file_mdf.c file_mfg.c file_mid.c file_mkv.c file_mov.c file_mp3.c file_mpg.c file_mrw.c file_mus.c file_mysql.c file_njx.c file_ogg.c file_one.c file_orf.c file_paf.c file_pap.c file_pcap.c file_pct.c file_pcx.c file_pdf.c file_pfx.c file_png.c file_prc.c file_prt.c file_ps.c file_psd.c file_psp.c file_pst.c file_ptb.c file_qbb.c file_qdf.c file_qxd.c file_ra.c file_raf.c file_rar.c file_raw.c file_rdc.c file_reg.c file_res.c file_riff.c file_rm.c file_rns.c file_rpm.c file_sib.c file_sit.c file_skp.c file_spe.c file_spss.c file_sql.c file_stl.c file_stu.c file_swf.c file_tar.c file_tar.h file_tib.c file_tiff.c file_tph.c file_txt.c file_veg.c file_vmdk.c file_wks.c file_wmf.c file_wnk.c file_wpd.c file_x3f.c file_xcf.c file_xm.c file_xsv.c file_zip.c memmem.h geometry.c list.c list.h ole.h ntfs_dir.c ntfs_dir.h ntfsp.c ntfsp.h ntfs_inc.h sessionp.c sessionp.h $(base_C) $(base_H) $(fs_C) $(fs_H) $(ICON_PHOTOREC)
+photorec_SOURCES = photorec.c photorec.h phcfg.c phcfg.h phrecn.c phrecn.h dir.c dir.h ext2grp.c ext2grp.h ext2p.c ext2p.h ext2_dir.c ext2_dir.h ext2_inc.h fat_dir.c fat_dir.h fatp.c fatp.h filegen.c filegen.h file_7z.c file_a.c file_ab.c file_ace.c file_ahn.c file_aif.c file_all.c file_als.c file_amd.c file_amr.c file_arj.c file_asf.c file_asm.c file_au.c file_bkf.c file_bld.c file_bmp.c file_bz2.c file_cab.c file_cam.c file_chm.c file_cm.c file_compress.c file_crw.c file_ctg.c file_cwk.c file_dat.c file_dbf.c file_dim.c file_dir.c file_djv.c file_doc.c file_dpx.c file_drw.c file_ds2.c file_dsc.c file_dss.c file_dta.c file_dump.c file_dv.c file_dwg.c file_elf.c file_emf.c file_evt.c file_exe.c pe.h file_ext.c file_fcp.c file_fcs.c file_fbk.c file_fdb.c file_fh10.c file_fh5.c file_fits.c file_flac.c file_flv.c file_fob.c file_frm.c file_fs.c file_gho.c file_gif.c file_gpg.c file_gz.c file_ifo.c file_imb.c file_indd.c file_iso.c file_itu.c file_jpg.c file_jpg.h file_kdb.c file_lnk.c file_m2ts.c file_max.c file_mb.c file_mcd.c file_mdb.c file_mdf.c file_mfg.c file_mid.c file_mkv.c file_mov.c file_mp3.c file_mpg.c file_mrw.c file_mus.c file_mysql.c file_njx.c file_ogg.c file_one.c file_orf.c file_paf.c file_pap.c file_pcap.c file_pct.c file_pcx.c file_pdf.c file_pfx.c file_png.c file_prc.c file_prt.c file_ps.c file_psd.c file_psp.c file_pst.c file_ptb.c file_qbb.c file_qdf.c file_qxd.c file_ra.c file_raf.c file_rar.c file_raw.c file_rdc.c file_reg.c file_res.c file_riff.c file_rm.c file_rns.c file_rpm.c file_sib.c file_sit.c file_skp.c file_spe.c file_spss.c file_sql.c file_stl.c file_stu.c file_swf.c file_tar.c file_tar.h file_tib.c file_tiff.c file_tph.c file_txt.c file_veg.c file_vmdk.c file_wks.c file_wmf.c file_wnk.c file_wpd.c file_x3f.c file_xcf.c file_xm.c file_xsv.c file_zip.c memmem.h geometry.c list.c list.h ole.h ntfs_dir.c ntfs_dir.h ntfsp.c ntfsp.h ntfs_inc.h pblocksize.c pblocksize.h pdisksel.c pdisksel.h pfree_whole.c pfree_whole.h ppartsel.c ppartsel.h sessionp.c sessionp.h $(base_C) $(base_H) $(fs_C) $(fs_H) $(ICON_PHOTOREC)
#diskcp_SOURCES = diskcp.c types.h
diff --git a/src/adv.c b/src/adv.c
index 0f9dcaad..497710b1 100644
--- a/src/adv.c
+++ b/src/adv.c
@@ -2,7 +2,7 @@
File: adv.c
- Copyright (C) 1998-2007 Christophe GRENIER <[email protected]>
+ Copyright (C) 1998-2008 Christophe GRENIER <[email protected]>
This software is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -23,14 +23,12 @@
#include <config.h>
#endif
-#include <stdarg.h>
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
#ifdef HAVE_STRING_H
#include <string.h>
#endif
-#include <ctype.h>
#include "types.h"
#include "common.h"
#include "lang.h"
@@ -38,21 +36,20 @@
#include "intrfn.h"
#include "fnctdsk.h"
#include "chgtype.h"
-#include "testdisk.h"
#include "dirpart.h"
#include "fat.h"
#include "ntfs.h"
-#include "hfs.h"
-#include "hfsp.h"
#include "adv.h"
#include "analyse.h"
-#include "io_redir.h"
#include "log.h"
#include "guid_cmp.h"
#include "dimage.h"
-#include "fat_adv.h"
#include "ntfs_udl.h"
#include "ext2_sb.h"
+#include "fat1x.h"
+#include "fat32.h"
+#include "tntfs.h"
+#include "thfs.h"
extern const arch_fnct_t arch_gpt;
extern const arch_fnct_t arch_i386;
@@ -61,9 +58,12 @@ extern const arch_fnct_t arch_none;
extern const arch_fnct_t arch_sun;
extern const arch_fnct_t arch_xbox;
+#ifdef HAVE_NCURSES
#define INTER_ADV_X 0
-#define INTER_ADV_Y 23
-#define INTER_ADV 15
+#define INTER_ADV_Y (LINES-2)
+#define INTER_ADV (LINES-2-7-1)
+#endif
+
#define DEFAULT_IMAGE_NAME "image.dd"
static int is_hfs(const partition_t *partition);
@@ -175,6 +175,7 @@ void interface_adv(disk_t *disk_car, const int verbose,const int dump_ind, const
#ifdef HAVE_NCURSES
int offset=0;
int current_element_num=0;
+ unsigned int old_LINES=LINES;
#endif
int rewrite=1;
const char *options;
@@ -205,6 +206,11 @@ void interface_adv(disk_t *disk_car, const int verbose,const int dump_ind, const
int command;
#ifdef HAVE_NCURSES
int i;
+ if(old_LINES!=LINES)
+ {
+ old_LINES=LINES;
+ rewrite=1;
+ }
if(rewrite!=0)
{
aff_copy(stdscr);
@@ -214,10 +220,11 @@ void interface_adv(disk_t *disk_car, const int verbose,const int dump_ind, const
mvwaddstr(stdscr,6,0,msg_PART_HEADER_LONG);
rewrite=0;
}
- for(i=0,element=list_part;(element!=NULL) && (i<offset);element=element->next,i++);
- for(i=offset;(element!=NULL) && ((i-offset)<INTER_ADV);element=element->next,i++)
+ for(i=0,element=list_part; element!=NULL && i<offset+INTER_ADV;element=element->next,i++)
{
- wmove(stdscr,5+2+i-offset,0);
+ if(i<offset)
+ continue;
+ wmove(stdscr,7+i-offset,0);
wclrtoeol(stdscr); /* before addstr for BSD compatibility */
if(element==current_element)
{
@@ -229,13 +236,17 @@ void interface_adv(disk_t *disk_car, const int verbose,const int dump_ind, const
aff_part(stdscr,AFF_PART_ORDER|AFF_PART_STATUS,disk_car,element->part);
}
}
+ wmove(stdscr,7+INTER_ADV,5);
+ wclrtoeol(stdscr);
+ if(element!=NULL)
+ wprintw(stdscr, "Next");
#endif
menu=0;
if(current_element==NULL)
{
options="q";
#ifdef HAVE_NCURSES
- wmove(stdscr,5+2,0);
+ wmove(stdscr,7,0);
wattrset(stdscr, A_REVERSE);
wprintw(stdscr,"No partition available.");
wattroff(stdscr, A_REVERSE);
@@ -349,7 +360,7 @@ void interface_adv(disk_t *disk_car, const int verbose,const int dump_ind, const
else
{
#ifdef HAVE_NCURSES
- command = wmenuSelect(stdscr, 24, INTER_ADV_Y, INTER_ADV_X, menuAdv, 8, options,
+ command = wmenuSelect(stdscr, INTER_ADV_Y+1, INTER_ADV_Y, INTER_ADV_X, menuAdv, 8, options,
MENU_HORIZ | MENU_BUTTON | MENU_ACCEPT_OTHERS, menu);
#else
command = 'q';
@@ -371,11 +382,11 @@ void interface_adv(disk_t *disk_car, const int verbose,const int dump_ind, const
}
break;
}
+#ifdef HAVE_NCURSES
if(current_element!=NULL)
{
switch(command)
{
-#ifdef HAVE_NCURSES
case 'p':
case 'P':
case KEY_UP:
@@ -408,7 +419,6 @@ void interface_adv(disk_t *disk_car, const int verbose,const int dump_ind, const
current_element_num++;
}
break;
-#endif
case 'b':
case 'B':
{
@@ -506,884 +516,7 @@ void interface_adv(disk_t *disk_car, const int verbose,const int dump_ind, const
if(current_element_num>=offset+INTER_ADV)
offset=current_element_num-INTER_ADV+1;
}
+#endif
} while(quit==0);
part_free_list(list_part);
}
-
-#ifdef HAVE_NCURSES
-static void dump_fat1x_ncurses(disk_t *disk_car, partition_t *partition, const unsigned char *buffer_bs)
-{
- WINDOW *window=newwin(0,0,0,0); /* full screen */
- keypad(window, TRUE); /* Need it to get arrow key */
- aff_copy(window);
- wmove(window,4,0);
- wprintw(window,"%s",disk_car->description(disk_car));
- wmove(window,5,0);
- aff_part(window,AFF_PART_ORDER|AFF_PART_STATUS,disk_car,partition);
- mvwaddstr(window,6,0, "Boot sector");
- dump(window,buffer_bs,FAT1x_BOOT_SECTOR_SIZE);
- delwin(window);
- (void) clearok(stdscr, TRUE);
-#ifdef HAVE_TOUCHWIN
- touchwin(stdscr);
-#endif
-}
-#endif
-
-static void dump_fat1x(disk_t *disk_car, partition_t *partition, const unsigned char *buffer_bs)
-{
- log_info("Boot sector\n");
- dump_log(buffer_bs, FAT1x_BOOT_SECTOR_SIZE);
-#ifdef HAVE_NCURSES
- dump_fat1x_ncurses(disk_car, partition, buffer_bs);
-#endif
-}
-
-int fat1x_boot_sector(disk_t *disk_car, partition_t *partition, const int verbose, const int dump_ind, const unsigned int expert, char **current_cmd)
-{
- unsigned char *buffer_bs;
- const char *options="DR";
- int rescan=1;
-#ifdef HAVE_NCURSES
- struct MenuItem menu_fat1x[]=
- {
- { 'P', "Previous",""},
- { 'N', "Next","" },
- { 'Q', "Quit","Return to Advanced menu"},
- { 'L', "List", "List directories and files, copy and undelete data from FAT" },
- { 'R', "Rebuild BS","Rebuild boot sector"},
- { 'D', "Dump","Dump boot sector and backup boot sector"},
- { 'C', "Repair FAT","Very Dangerous! Expert only"},
- { 'I', "Init Root","Init root directory: Very Dangerous! Expert only"},
- { 0, NULL, NULL }
- };
-#endif
- buffer_bs=(unsigned char*)MALLOC(FAT1x_BOOT_SECTOR_SIZE);
- while(1)
- {
-#ifdef HAVE_NCURSES
- unsigned int menu=0;
-#endif
- int command;
- screen_buffer_reset();
- if(rescan==1)
- {
-#ifdef HAVE_NCURSES
- aff_copy(stdscr);
- wmove(stdscr,4,0);
- wprintw(stdscr,"%s",disk_car->description(disk_car));
- mvwaddstr(stdscr,5,0,msg_PART_HEADER_LONG);
- wmove(stdscr,6,0);
- aff_part(stdscr,AFF_PART_ORDER|AFF_PART_STATUS,disk_car,partition);
-#endif
- log_info("\nfat1x_boot_sector\n");
- log_partition(disk_car,partition);
- screen_buffer_add("Boot sector\n");
- if(disk_car->read(disk_car,FAT1x_BOOT_SECTOR_SIZE, buffer_bs, partition->part_offset)!=0)
- {
- screen_buffer_add("fat1x_boot_sector: Can't read boot sector.\n");
- memset(buffer_bs,0,FAT1x_BOOT_SECTOR_SIZE);
- }
- if(test_FAT(disk_car,(const struct fat_boot_sector *)buffer_bs,partition,verbose,0)==0)
- {
- screen_buffer_add("OK\n");
- if(expert==0)
- options="DRCL";
- else
- options="DRCIL";
- }
- else
- {
- screen_buffer_add("Bad\n");
- options="DRC";
- }
- screen_buffer_add("\n");
- screen_buffer_add("A valid FAT Boot sector must be present in order to access\n");
- screen_buffer_add("any data; even if the partition is not bootable.\n");
- rescan=0;
- }
- screen_buffer_to_log();
- if(*current_cmd!=NULL)
- {
- command=0;
- while(*current_cmd[0]==',')
- (*current_cmd)++;
- if(strncmp(*current_cmd,"rebuildbs",9)==0)
- {
- (*current_cmd)+=9;
- command='R';
- }
- else if(strncmp(*current_cmd,"dump",4)==0)
- {
- (*current_cmd)+=4;
- command='D';
- }
- else if(strncmp(*current_cmd,"list",4)==0)
- {
- (*current_cmd)+=4;
- if(strchr(options,'L')!=NULL)
- command='L';
- }
- else if(strncmp(*current_cmd,"repairfat",8)==0)
- {
- (*current_cmd)+=8;
- if(strchr(options,'C')!=NULL)
- command='C';
- }
- else if(strncmp(*current_cmd,"initroot",8)==0)
- {
- (*current_cmd)+=8;
- if(strchr(options,'I')!=NULL)
- command='I';
- }
- }
- else
- {
- log_flush();
-#ifdef HAVE_NCURSES
- command=screen_buffer_display_ext(stdscr, options, menu_fat1x, &menu);
-#else
- command=0;
-#endif
- }
- switch(command)
- {
- case 0:
- free(buffer_bs);
- return 0;
- case 'R': /* R : rebuild boot sector */
- rebuild_FAT_BS(disk_car,partition,verbose,dump_ind,1,expert,current_cmd);
- rescan=1;
- break;
- case 'D':
- dump_fat1x(disk_car, partition, buffer_bs);
- break;
- case 'C':
- repair_FAT_table(disk_car,partition,verbose);
- break;
- case 'I':
- FAT_init_rootdir(disk_car,partition,verbose);
- break;
- case 'L':
- dir_partition(disk_car, partition, 0,current_cmd);
- break;
- }
- }
-}
-
-#ifdef HAVE_NCURSES
-static void dump_fat32_ncurses(disk_t *disk_car, const partition_t *partition, const unsigned char *buffer_bs, const unsigned char *buffer_backup_bs)
-{
- WINDOW *window=newwin(0,0,0,0); /* full screen */
- keypad(window, TRUE); /* Need it to get arrow key */
- aff_copy(window);
- wmove(window,4,0);
- wprintw(window,"%s",disk_car->description(disk_car));
- wmove(window,5,0);
- aff_part(window,AFF_PART_ORDER|AFF_PART_STATUS,disk_car,partition);
- mvwaddstr(window,6,0, "Boot sector Backup boot sector");
- dump2(window, buffer_bs, buffer_backup_bs, 3*disk_car->sector_size);
- delwin(window);
- (void) clearok(stdscr, TRUE);
-#ifdef HAVE_TOUCHWIN
- touchwin(stdscr);
-#endif
-}
-#endif
-
-static void dump_fat32(disk_t *disk_car, const partition_t *partition, const unsigned char *buffer_bs, const unsigned char *buffer_backup_bs)
-{
- log_info("Boot sector Backup boot sector\n");
- dump2_log(buffer_bs, buffer_backup_bs, 3*disk_car->sector_size);
- log_fat2_info((const struct fat_boot_sector*)buffer_bs,(const struct fat_boot_sector*)buffer_backup_bs,UP_FAT32,disk_car->sector_size);
-#ifdef HAVE_NCURSES
- dump_fat32_ncurses(disk_car, partition, buffer_bs, buffer_backup_bs);
-#endif
-}
-
-int fat32_boot_sector(disk_t *disk_car, partition_t *partition, const int verbose, const int dump_ind, const unsigned int expert, char **current_cmd)
-{
- unsigned char *buffer_bs;
- unsigned char *buffer_backup_bs;
- const char *options="DRC";
- int rescan=1;
-#ifdef HAVE_NCURSES
- struct MenuItem menu_fat32[]=
- {
- { 'P', "Previous",""},
- { 'N', "Next","" },
- { 'Q', "Quit","Return to Advanced menu"},
- { 'L', "List", "List directories and files, copy and undelete data from FAT" },
- { 'O', "Org. BS","Copy boot sector over backup sector"},
- { 'B', "Backup BS","Copy backup boot sector over boot sector"},
- { 'R', "Rebuild BS","Rebuild boot sector"},
- { 'D', "Dump","Dump boot sector and backup boot sector"},
- { 'C', "Repair FAT","Very Dangerous! Expert only"},
- { 0, NULL, NULL }
- };
-#endif
- buffer_bs=(unsigned char*)MALLOC(3*disk_car->sector_size);
- buffer_backup_bs=(unsigned char*)MALLOC(3*disk_car->sector_size);
- while(1)
- {
- unsigned int menu=0;
- int command;
- screen_buffer_reset();
- if(rescan==1)
- {
- int opt_over=0;
- int opt_B=0;
- int opt_O=0;
- options="DRC";
-#ifdef HAVE_NCURSES
- aff_copy(stdscr);
- wmove(stdscr,4,0);
- wprintw(stdscr,"%s",disk_car->description(disk_car));
- mvwaddstr(stdscr,5,0,msg_PART_HEADER_LONG);
- wmove(stdscr,6,0);
- aff_part(stdscr,AFF_PART_ORDER|AFF_PART_STATUS,disk_car,partition);
-#endif
- log_info("\nfat32_boot_sector\n");
- log_partition(disk_car,partition);
- screen_buffer_add("Boot sector\n");
- if(disk_car->read(disk_car,3*disk_car->sector_size, buffer_bs, partition->part_offset)!=0)
- {
- screen_buffer_add("fat32_boot_sector: Can't read boot sector.\n");
- memset(buffer_bs,0,3*disk_car->sector_size);
- }
- if(test_FAT(disk_car,(struct fat_boot_sector *)buffer_bs,partition,verbose,0)==0)
- {
- screen_buffer_add("OK\n");
- if(partition->upart_type==UP_FAT32)
- {
- opt_O=1;
- opt_over=1;
- }
- else
- {
- screen_buffer_add("Warning: valid FAT bootsector but not a FAT32 one!");
- }
- }
- else
- {
- screen_buffer_add("Bad\n");
- }
- screen_buffer_add("\nBackup boot sector\n");
- if(disk_car->read(disk_car,3*disk_car->sector_size, buffer_backup_bs, partition->part_offset+6*disk_car->sector_size)!=0)
- {
- screen_buffer_add("fat32_boot_sector: Can't read backup boot sector.\n");
- memset(buffer_backup_bs,0,3*disk_car->sector_size);
- }
- if(test_FAT(disk_car,(struct fat_boot_sector *)buffer_backup_bs,partition,verbose,0)==0)
- {
- screen_buffer_add("OK\n");
- if(partition->upart_type==UP_FAT32)
- {
- opt_B=1;
- opt_over=1;
- }
- else
- {
- screen_buffer_add("Warning: valid FAT backup bootsector but not a FAT32 one!");
- }
- }
- else
- {
- screen_buffer_add("Bad\n");
- }
- screen_buffer_add("\n");
- if((memcmp(buffer_bs,buffer_backup_bs,0x3E8)==0)&&(memcmp(buffer_bs+0x3F0,buffer_backup_bs+0x3F0,0x600-0x3F0))==0)
- {
- screen_buffer_add("Sectors are identical.\n");
- opt_over=0;
- }
- else
- {
- if(memcmp(buffer_bs,buffer_backup_bs,0x200)!=0)
- screen_buffer_add("First sectors (Boot code and partition information) are not identical.\n");
- if((memcmp(buffer_bs+disk_car->sector_size, buffer_backup_bs+disk_car->sector_size,0x1E8)!=0)||
- (memcmp(buffer_bs+disk_car->sector_size+0x1F0, buffer_backup_bs+disk_car->sector_size+0x1F0,0x200-0x1F0)!=0))
- screen_buffer_add("Second sectors (cluster information) are not identical.\n");
- if(memcmp(buffer_bs+2*disk_car->sector_size, buffer_backup_bs+2*disk_car->sector_size,0x200)!=0)
- screen_buffer_add("Third sectors (Second part of boot code) are not identical.\n");
- }
- screen_buffer_add("\n");
- screen_buffer_add("A valid FAT Boot sector must be present in order to access\n");
- screen_buffer_add("any data; even if the partition is not bootable.\n");
- if(opt_over!=0)
- {
- if(opt_B!=0 && opt_O!=0)
- options="DOBRL";
- else if(opt_B!=0)
- {
- menu=5;
- options="DBRL";
- }
- else if(opt_O!=0)
- {
- menu=4;
- options="DORL";
- }
- }
- else
- {
- if(opt_B!=0)
- options="DRCL";
- else
- options="DR";
- }
- rescan=0;
- }
- screen_buffer_to_log();
- if(*current_cmd!=NULL)
- {
- command=0;
- while(*current_cmd[0]==',')
- (*current_cmd)++;
- if(strncmp(*current_cmd,"rebuildbs",9)==0)
- {
- (*current_cmd)+=9;
- command='R';
- }
- else if(strncmp(*current_cmd,"dump",4)==0)
- {
- (*current_cmd)+=4;
- command='D';
- }
- else if(strncmp(*current_cmd,"list",4)==0)
- {
- (*current_cmd)+=4;
- if(strchr(options,'L')!=NULL)
- command='L';
- }
- else if(strncmp(*current_cmd,"repairfat",8)==0)
- {
- (*current_cmd)+=8;
- if(strchr(options,'C')!=NULL)
- command='C';
- }
- else if(strncmp(*current_cmd,"originalfat",11)==0)
- {
- (*current_cmd)+=11;
- if(strchr(options,'O')!=NULL)
- command='O';
- }
- else if(strncmp(*current_cmd,"backupfat",9)==0)
- {
- (*current_cmd)+=9;
- if(strchr(options,'B')!=NULL)
- command='B';
- }
- }
- else
- {
- log_flush();
-#ifdef HAVE_NCURSES
- command=screen_buffer_display_ext(stdscr, options, menu_fat32, &menu);
-#else
- command=0;
-#endif
- }
- switch(command)
- {
- case 0:
- free(buffer_bs);
- free(buffer_backup_bs);
- return 0;
- case 'O': /* O : copy original boot sector over backup boot */
- if(ask_confirmation("Copy original FAT32 boot sector over backup boot, confirm ? (Y/N)")!=0)
- {
- log_info("copy original boot sector over backup boot\n");
- if(disk_car->write(disk_car,3*disk_car->sector_size, buffer_bs, partition->part_offset+6*disk_car->sector_size)!=0)
- {
- display_message("Write error: Can't overwrite FAT32 backup boot sector\n");
- }
- disk_car->sync(disk_car);
- rescan=1;
- }
- break;
- case 'B': /* B : copy backup boot sector over boot sector */
- if(ask_confirmation("Copy backup FAT32 boot sector over boot sector, confirm ? (Y/N)")!=0)
- {
- log_info("copy backup boot sector over boot sector\n");
- if(disk_car->write(disk_car,3*disk_car->sector_size, buffer_backup_bs, partition->part_offset)!=0)
- {
- display_message("Write error: Can't overwrite FAT32 boot sector\n");
- }
- disk_car->sync(disk_car);
- rescan=1;
- }
- break;
- case 'C':
- repair_FAT_table(disk_car,partition,verbose);
- break;
- case 'D':
- dump_fat32(disk_car, partition, buffer_bs, buffer_backup_bs);
- break;
- case 'L':
- if(strchr(options,'O')==NULL && strchr(options,'B')!=NULL)
- {
- io_redir_add_redir(disk_car,partition->part_offset,3*disk_car->sector_size,0,buffer_backup_bs);
- dir_partition(disk_car, partition, 0,current_cmd);
- io_redir_del_redir(disk_car,partition->part_offset);
- }
- else
- dir_partition(disk_car, partition, 0,current_cmd);
- break;
- case 'R': /* R : rebuild boot sector */
- rebuild_FAT_BS(disk_car,partition,verbose,dump_ind,1,expert,current_cmd);
- rescan=1;
- break;
- }
- }
-}
-
-#ifdef HAVE_NCURSES
-static void dump_NTFS_ncurses(disk_t *disk_car, const partition_t *partition, const unsigned char *buffer_bs, const unsigned char *buffer_backup_bs)
-{
- WINDOW *window=newwin(0,0,0,0); /* full screen */
- keypad(window, TRUE); /* Need it to get arrow key */
- aff_copy(window);
- wmove(window,4,0);
- wprintw(window,"%s",disk_car->description(disk_car));
- wmove(window,5,0);
- aff_part(window,AFF_PART_ORDER|AFF_PART_STATUS,disk_car,partition);
- mvwaddstr(window,6,0, "Boot sector Backup boot sector");
- dump2(window, buffer_bs, buffer_backup_bs, NTFS_BOOT_SECTOR_SIZE);
- delwin(window);
- (void) clearok(stdscr, TRUE);
-#ifdef HAVE_TOUCHWIN
- touchwin(stdscr);
-#endif
-}
-#endif
-
-static void dump_NTFS(disk_t *disk_car, const partition_t *partition, const unsigned char *buffer_bs, const unsigned char *buffer_backup_bs)
-{
- log_info("Boot sector Backup boot sector\n");
- dump2_log(buffer_bs, buffer_backup_bs, NTFS_BOOT_SECTOR_SIZE);
-#ifdef HAVE_NCURSES
- dump_NTFS_ncurses(disk_car, partition, buffer_bs, buffer_backup_bs);
-#endif
-}
-
-int ntfs_boot_sector(disk_t *disk_car, partition_t *partition, const int verbose, const int dump_ind, const unsigned int expert, char **current_cmd)
-{
- unsigned char *buffer_bs;
- unsigned char *buffer_backup_bs;
- const char *options="";
- int rescan=1;
-#ifdef HAVE_NCURSES
- struct MenuItem menu_ntfs[]=
- {
- { 'P', "Previous",""},
- { 'N', "Next","" },
- { 'Q', "Quit","Return to Advanced menu"},
- { 'L', "List", "List directories and files, copy data from NTFS" },
- { 'O', "Org. BS","Copy boot sector over backup sector"},
- { 'B', "Backup BS","Copy backup boot sector over boot sector"},
- { 'R', "Rebuild BS","Rebuild boot sector"},
- { 'M', "Repair MFT","Check MFT"},
- { 'D', "Dump","Dump boot sector and backup boot sector"},
- { 0, NULL, NULL }
- };
-#endif
- buffer_bs=(unsigned char*)MALLOC(NTFS_BOOT_SECTOR_SIZE);
- buffer_backup_bs=(unsigned char*)MALLOC(NTFS_BOOT_SECTOR_SIZE);
-
- while(1)
- {
- unsigned int menu=0;
- int command;
- screen_buffer_reset();
- if(rescan==1)
- {
- int identical_sectors=0;
- int opt_B=0;
- int opt_O=0;
-#ifdef HAVE_NCURSES
- aff_copy(stdscr);
- wmove(stdscr,4,0);
- wprintw(stdscr,"%s",disk_car->description(disk_car));
- mvwaddstr(stdscr,5,0,msg_PART_HEADER_LONG);
- wmove(stdscr,6,0);
- aff_part(stdscr,AFF_PART_ORDER|AFF_PART_STATUS,disk_car,partition);
-#endif
- log_info("\nntfs_boot_sector\n");
- log_partition(disk_car,partition);
- screen_buffer_add("Boot sector\n");
- if(disk_car->read(disk_car,NTFS_BOOT_SECTOR_SIZE, buffer_bs, partition->part_offset)!=0)
- {
- screen_buffer_add("ntfs_boot_sector: Can't read boot sector.\n");
- memset(buffer_bs,0,NTFS_BOOT_SECTOR_SIZE);
- }
- if(test_NTFS(disk_car,(struct ntfs_boot_sector*)buffer_bs,partition,verbose,0)==0)
- {
- screen_buffer_add("Status: OK\n");
- opt_O=1;
- }
- else
- {
- screen_buffer_add("Status: Bad\n");
- }
- screen_buffer_add("\nBackup boot sector\n");
- if(disk_car->read(disk_car,NTFS_BOOT_SECTOR_SIZE, buffer_backup_bs, partition->part_offset+partition->part_size-disk_car->sector_size)!=0)
- {
- screen_buffer_add("ntfs_boot_sector: Can't read backup boot sector.\n");
- memset(buffer_backup_bs,0,NTFS_BOOT_SECTOR_SIZE);
- }
- if(test_NTFS(disk_car,(struct ntfs_boot_sector*)buffer_backup_bs,partition,verbose,0)==0)
- {
- screen_buffer_add("Status: OK\n");
- opt_B=1;
- }
- else
- {
- screen_buffer_add("Status: Bad\n");
- }
- screen_buffer_add("\n");
- if(memcmp(buffer_bs,buffer_backup_bs,NTFS_BOOT_SECTOR_SIZE)==0)
- {
- log_ntfs_info((const struct ntfs_boot_sector *)buffer_bs);
- screen_buffer_add("Sectors are identical.\n");
- identical_sectors=1;
- }
- else
- {
- log_ntfs2_info((const struct ntfs_boot_sector *)buffer_bs, (const struct ntfs_boot_sector *)buffer_backup_bs);
- screen_buffer_add("Sectors are not identical.\n");
- identical_sectors=0;
- }
- screen_buffer_add("\n");
- screen_buffer_add("A valid NTFS Boot sector must be present in order to access\n");
- screen_buffer_add("any data; even if the partition is not bootable.\n");
- if(opt_B!=0 && opt_O!=0)
- {
- if(identical_sectors==0)
- options="DOBRL";
- else
- options="DRML";
- }
- else if(opt_B!=0)
- {
- menu=5;
- if(expert>0)
- options="DBRML";
- else
- options="DBRL";
- }
- else if(opt_O!=0)
- {
- menu=4;
- options="DORL";
- }
- else
- options="DR";
- rescan=0;
- }
- screen_buffer_to_log();
- if(*current_cmd!=NULL)
- {
- command=0;
- while(*current_cmd[0]==',')
- (*current_cmd)++;
- if(strncmp(*current_cmd,"rebuildbs",9)==0)
- {
- (*current_cmd)+=9;
- command='R';
- }
- else if(strncmp(*current_cmd,"dump",4)==0)
- {
- (*current_cmd)+=4;
- command='D';
- }
- else if(strncmp(*current_cmd,"list",4)==0)
- {
- (*current_cmd)+=4;
- command='L';
- }
- else if(strncmp(*current_cmd,"originalntfs",11)==0)
- {
- (*current_cmd)+=11;
- if(strchr(options,'O')!=NULL)
- command='O';
- }
- else if(strncmp(*current_cmd,"backupntfs",9)==0)
- {
- (*current_cmd)+=9;
- if(strchr(options,'B')!=NULL)
- command='B';
- }
- else if(strncmp(*current_cmd,"repairmft",9)==0)
- {
- (*current_cmd)+=9;
- if(strchr(options,'M')!=NULL)
- command='M';
- }
- }
- else
- {
- log_flush();
-#ifdef HAVE_NCURSES
- command=screen_buffer_display_ext(stdscr, options, menu_ntfs, &menu);
-#else
- command=0;
-#endif
- }
- switch(command)
- {
- case 0:
- free(buffer_bs);
- free(buffer_backup_bs);
- return 0;
- case 'O': /* O : copy original boot sector over backup boot */
- if(ask_confirmation("Copy original NTFS boot sector over backup boot, confirm ? (Y/N)")!=0)
- {
- log_info("copy original boot sector over backup boot\n");
- if(disk_car->write(disk_car,NTFS_BOOT_SECTOR_SIZE, buffer_bs, partition->part_offset+partition->part_size-disk_car->sector_size)!=0)
- {
- display_message("Write error: Can't overwrite NTFS backup boot sector\n");
- }
- disk_car->sync(disk_car);
- rescan=1;
- }
- break;
- case 'B': /* B : copy backup boot sector over boot sector */
- if(ask_confirmation("Copy backup NTFS boot sector over boot sector, confirm ? (Y/N)")!=0)
- {
- log_info("copy backup boot sector over boot sector\n");
- if(disk_car->write(disk_car,NTFS_BOOT_SECTOR_SIZE, buffer_backup_bs, partition->part_offset)!=0)
- {
- display_message("Write error: Can't overwrite NTFS boot sector\n");
- }
- disk_car->sync(disk_car);
- rescan=1;
- }
- break;
- case 'L':
- if(strchr(options,'O')==NULL && strchr(options,'B')!=NULL)
- {
- io_redir_add_redir(disk_car,partition->part_offset,NTFS_BOOT_SECTOR_SIZE,0,buffer_backup_bs);
- dir_partition(disk_car, partition, 0,current_cmd);
- io_redir_del_redir(disk_car,partition->part_offset);
- }
- else
- dir_partition(disk_car, partition, 0,current_cmd);
- break;
- case 'M':
- repair_MFT(disk_car, partition, verbose, expert, current_cmd);
- break;
- case 'R': /* R : rebuild boot sector */
- rebuild_NTFS_BS(disk_car,partition,verbose,dump_ind,1,expert,current_cmd);
- rescan=1;
- break;
- case 'D':
- dump_NTFS(disk_car, partition, buffer_bs, buffer_backup_bs);
- break;
- }
- }
-}
-
-#ifdef HAVE_NCURSES
-static void hfs_dump_ncurses(disk_t *disk_car, const partition_t *partition, const unsigned char *buffer_bs, const unsigned char *buffer_backup_bs)
-{
- WINDOW *window=newwin(0,0,0,0); /* full screen */
- keypad(window, TRUE); /* Need it to get arrow key */
- aff_copy(window);
- wmove(window,4,0);
- wprintw(window,"%s",disk_car->description(disk_car));
- wmove(window,5,0);
- aff_part(window,AFF_PART_ORDER|AFF_PART_STATUS,disk_car,partition);
- mvwaddstr(window,6,0, "Superblock Backup superblock");
- dump2(window, buffer_bs, buffer_backup_bs, HFSP_BOOT_SECTOR_SIZE);
- delwin(window);
- (void) clearok(stdscr, TRUE);
-#ifdef HAVE_TOUCHWIN
- touchwin(stdscr);
-#endif
-}
-#endif
-
-static void hfs_dump(disk_t *disk_car, const partition_t *partition, const unsigned char *buffer_bs, const unsigned char *buffer_backup_bs)
-{
- log_info("Superblock Backup superblock\n");
- dump2_log(buffer_bs, buffer_backup_bs, HFSP_BOOT_SECTOR_SIZE);
-#ifdef HAVE_NCURSES
- hfs_dump_ncurses(disk_car, partition, buffer_bs, buffer_backup_bs);
-#endif
-}
-
-int HFS_HFSP_boot_sector(disk_t *disk_car, partition_t *partition, const int verbose, const int dump_ind, const unsigned int expert, char **current_cmd)
-{
- unsigned char *buffer_bs;
- unsigned char *buffer_backup_bs;
- const char *options="";
- int rescan=1;
-#ifdef HAVE_NCURSES
- struct MenuItem menu_hfsp[]=
- {
- { 'P', "Previous",""},
- { 'N', "Next","" },
- { 'Q', "Quit","Return to Advanced menu"},
- { 'O', "Org. BS","Copy superblock over backup sector"},
- { 'B', "Backup BS","Copy backup superblock over superblock"},
- { 'D', "Dump","Dump superblock and backup superblock"},
- { 0, NULL, NULL }
- };
-#endif
- buffer_bs=(unsigned char*)MALLOC(HFSP_BOOT_SECTOR_SIZE);
- buffer_backup_bs=(unsigned char*)MALLOC(HFSP_BOOT_SECTOR_SIZE);
-
- while(1)
- {
-#ifdef HAVE_NCURSES
- unsigned int menu=0;
-#endif
- int command;
- screen_buffer_reset();
- if(rescan==1)
- {
- int opt_over=0;
- int opt_B=0;
- int opt_O=0;
- options="D";
-#ifdef HAVE_NCURSES
- aff_copy(stdscr);
- wmove(stdscr,4,0);
- wprintw(stdscr,"%s",disk_car->description(disk_car));
- mvwaddstr(stdscr,5,0,msg_PART_HEADER_LONG);
- wmove(stdscr,6,0);
- aff_part(stdscr,AFF_PART_ORDER|AFF_PART_STATUS,disk_car,partition);
-#endif
- log_info("\nHFS_HFSP_boot_sector\n");
- log_partition(disk_car,partition);
- screen_buffer_add("Volume header\n");
- if(disk_car->read(disk_car,HFSP_BOOT_SECTOR_SIZE, buffer_bs, partition->part_offset+0x400)!=0)
- {
- screen_buffer_add("Bad: can't read HFS/HFS+ volume header.\n");
- memset(buffer_bs,0,HFSP_BOOT_SECTOR_SIZE);
- }
- else if(test_HFSP(disk_car,(const struct hfsp_vh*)buffer_bs,partition,verbose,0)==0)
- {
- screen_buffer_add("HFS+ OK\n");
- opt_O=1;
- opt_over=1;
- }
- else if(test_HFS(disk_car,(const hfs_mdb_t*)buffer_bs,partition,verbose,0)==0)
- {
- screen_buffer_add("HFS Ok\n");
- opt_O=1;
- opt_over=1;
- }
- else
- screen_buffer_add("Bad\n");
- screen_buffer_add("\nBackup volume header\n");
- if(disk_car->read(disk_car,HFSP_BOOT_SECTOR_SIZE, buffer_backup_bs, partition->part_offset+partition->part_size-0x400)!=0)
- {
- screen_buffer_add("Bad: can't read HFS/HFS+ backup volume header.\n");
- memset(buffer_backup_bs,0,HFSP_BOOT_SECTOR_SIZE);
- }
- else if(test_HFSP(disk_car,(const struct hfsp_vh*)buffer_backup_bs,partition,verbose,0)==0)
- {
- screen_buffer_add("HFS+ OK\n");
- opt_B=1;
- opt_over=1;
- }
- else if(test_HFS(disk_car,(const hfs_mdb_t*)buffer_backup_bs,partition,verbose,0)==0)
- {
- screen_buffer_add("HFS Ok\n");
- opt_B=1;
- opt_over=1;
- }
- else
- screen_buffer_add("Bad\n");
- screen_buffer_add("\n");
- if(memcmp(buffer_bs,buffer_backup_bs,HFSP_BOOT_SECTOR_SIZE)==0)
- {
- screen_buffer_add("Sectors are identical.\n");
- opt_over=0;
- }
- else
- {
- screen_buffer_add("Sectors are not identical.\n");
- }
- if(opt_over!=0)
- {
- if(opt_B!=0 && opt_O!=0)
- options="DOB";
- else if(opt_B!=0)
- options="DB";
- else if(opt_O!=0)
- options="DO";
- }
- rescan=0;
- }
- screen_buffer_to_log();
- if(*current_cmd!=NULL)
- {
- command=0;
- while(*current_cmd[0]==',')
- (*current_cmd)++;
- if(strncmp(*current_cmd,"dump",4)==0)
- {
- (*current_cmd)+=4;
- command='D';
- }
- else if(strncmp(*current_cmd,"originalhfsp",11)==0)
- {
- (*current_cmd)+=11;
- if(strchr(options,'O')!=NULL)
- command='O';
- }
- else if(strncmp(*current_cmd,"backuphfsp",9)==0)
- {
- (*current_cmd)+=9;
- if(strchr(options,'B')!=NULL)
- command='B';
- }
- }
- else
- {
- log_flush();
-#ifdef HAVE_NCURSES
- command=screen_buffer_display_ext(stdscr, options, menu_hfsp, &menu);
-#else
- command=0;
-#endif
- }
- switch(command)
- {
- case 0:
- free(buffer_bs);
- free(buffer_backup_bs);
- return 0;
- case 'O': /* O : copy original superblock over backup boot */
- if(ask_confirmation("Copy original HFS/HFS+ volume header over backup, confirm ? (Y/N)")!=0)
- {
- log_info("copy original superblock over backup boot\n");
- if(disk_car->write(disk_car,HFSP_BOOT_SECTOR_SIZE, buffer_bs, partition->part_offset+partition->part_size-0x400)!=0)
- {
- display_message("Write error: Can't overwrite HFS/HFS+ backup volume header\n");
- }
- disk_car->sync(disk_car);
- rescan=1;
- }
- break;
- case 'B': /* B : copy backup superblock over main superblock */
- if(ask_confirmation("Copy backup HFS/HFS+ volume header over main volume header, confirm ? (Y/N)")!=0)
- {
- log_info("copy backup superblock over main superblock\n");
- if(disk_car->write(disk_car,HFSP_BOOT_SECTOR_SIZE, buffer_backup_bs, partition->part_offset+0x400)!=0)
- {
- display_message("Write error: Can't overwrite HFS/HFS+ main volume header\n");
- }
- disk_car->sync(disk_car);
- rescan=1;
- }
- break;
- case 'D':
- hfs_dump(disk_car, partition, buffer_bs, buffer_backup_bs);
- break;
- }
- }
-}
diff --git a/src/adv.h b/src/adv.h
index 6dcce337..120c3c76 100644
--- a/src/adv.h
+++ b/src/adv.h
@@ -20,9 +20,4 @@
*/
void interface_adv(disk_t *disk_car, const int verbose,const int dump_ind, const unsigned int expert, char**current_cmd);
-int fat1x_boot_sector(disk_t *disk_car, partition_t *partition, const int verbose, const int dump_ind, const unsigned int expert, char **current_cmd);
-int fat32_boot_sector(disk_t *disk_car, partition_t *partition, const int verbose, const int dump_ind, const unsigned int expert, char **current_cmd);
-int ntfs_boot_sector(disk_t *disk_car, partition_t *partition, const int verbose, const int dump_ind, const unsigned int expert, char **current_cmd);
int is_part_linux(const partition_t *partition);
-int HFS_HFSP_boot_sector(disk_t *disk_car, partition_t *partition, const int verbose, const int dump_ind, const unsigned int expert, char **current_cmd);
-
diff --git a/src/diskacc.c b/src/diskacc.c
index 90b70881..6cb078c0 100644
--- a/src/diskacc.c
+++ b/src/diskacc.c
@@ -23,53 +23,23 @@
#include <config.h>
#endif
-#include <stdarg.h>
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
-#ifdef HAVE_STRING_H
-#include <string.h>
-#endif
-#include <ctype.h>
-#ifdef HAVE_TIME_H
-#include <time.h>
-#endif
-#ifdef HAVE_SYS_TIME_H
-#include <sys/time.h>
-#endif
-#ifdef HAVE_SYS_STAT_H
-#include <sys/stat.h>
-#endif
#include "types.h"
#include "common.h"
-#include "lang.h"
#include "intrf.h"
#ifdef HAVE_NCURSES
#include "intrfn.h"
#else
#include <stdio.h>
#endif
-#include "intrface.h"
-#include "godmode.h"
-#include "fnctdsk.h"
-#include "testdisk.h"
-#include "adv.h"
-#include "analyse.h"
-#include "chgtype.h"
-#include "edit.h"
-#include "savehdr.h"
-#include "dirpart.h"
-#include "fat.h"
-#include "partauto.h"
#include "log.h"
-#include "guid_cmp.h"
-#include "hdaccess.h"
-#include "io_redir.h"
#include "diskacc.h"
+#define INTER_DISK_X 0
+#define INTER_DISK_Y 18
+
#ifdef HAVE_NCURSES
static int interface_check_disk_access_ncurses(disk_t *disk_car)
{
@@ -118,7 +88,7 @@ static int interface_check_disk_access_ncurses(disk_t *disk_car)
#endif
wmove(stdscr,line++,0);
wprintw(stdscr,"- This media may be physically write-protected, check the jumpers.\n");
- car= wmenuSelect_ext(stdscr, 24, INTER_MAIN_Y, INTER_MAIN_X, menuDiskAccess, 10,
+ car= wmenuSelect_ext(stdscr, 23, INTER_DISK_Y, INTER_DISK_X, menuDiskAccess, 10,
"CQ", MENU_VERT | MENU_VERT_WARN | MENU_BUTTON, &menu,NULL);
if(car=='c' || car=='C')
return 0;
diff --git a/src/diskcapa.c b/src/diskcapa.c
index 7d020481..4b4d2c4a 100644
--- a/src/diskcapa.c
+++ b/src/diskcapa.c
@@ -23,26 +23,6 @@
#include <config.h>
#endif
-#include <stdarg.h>
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-#ifdef HAVE_STRING_H
-#include <string.h>
-#endif
-#include <ctype.h>
-#ifdef HAVE_TIME_H
-#include <time.h>
-#endif
-#ifdef HAVE_SYS_TIME_H
-#include <sys/time.h>
-#endif
-#ifdef HAVE_SYS_STAT_H
-#include <sys/stat.h>
-#endif
#include "types.h"
#include "common.h"
#include "lang.h"
@@ -52,23 +32,7 @@
#else
#include <stdio.h>
#endif
-#include "intrface.h"
-#include "godmode.h"
-#include "fnctdsk.h"
-#include "testdisk.h"
-#include "adv.h"
-#include "analyse.h"
-#include "chgtype.h"
-#include "edit.h"
-#include "savehdr.h"
-#include "dirpart.h"
-#include "fat.h"
-#include "partauto.h"
#include "log.h"
-#include "guid_cmp.h"
-#include "hdaccess.h"
-#include "io_redir.h"
-
#include "diskcapa.h"
#ifdef HAVE_NCURSES
@@ -95,7 +59,7 @@ static int interface_check_disk_capacity_ncurses(disk_t *disk_car)
#if defined(__CYGWIN__) || defined(__MINGW32__)
wprintw(stdscr,"Update Windows to support LBA48 (minimum: W2K SP4 or XP SP1)");
#endif
- car= wmenuSelect_ext(stdscr, 24, INTER_MAIN_Y, INTER_MAIN_X, menuMain, 10,
+ car= wmenuSelect_ext(stdscr, 23, INTER_MAIN_Y, INTER_MAIN_X, menuMain, 10,
"CQ", MENU_VERT | MENU_VERT_WARN | MENU_BUTTON, &menu,NULL);
if(car=='c' || car=='C')
return 0;
diff --git a/src/edit.c b/src/edit.c
index be53ad29..8b2e5c81 100644
--- a/src/edit.c
+++ b/src/edit.c
@@ -63,7 +63,7 @@ static void interface_editor_ncurses(disk_t *disk_car)
{ 'Q', "Quit",""},
{ 0, NULL, NULL }
};
- switch ( wmenuSelect(stdscr, 24, INTER_DUMP_Y, INTER_DUMP_X, menuEditor, 8, "CDQ", MENU_HORIZ | MENU_BUTTON, 0))
+ switch ( wmenuSelect(stdscr, INTER_DUMP_Y+1, INTER_DUMP_Y, INTER_DUMP_X, menuEditor, 8, "CDQ", MENU_HORIZ | MENU_BUTTON, 0))
{
case 'c':
case 'C':
@@ -233,7 +233,7 @@ static int dump_editor(const unsigned char *nom_dump,const unsigned int lng, con
wprintw(stdscr,"%c", car);
}
}
- switch (wmenuSelect(stdscr, 24, INTER_DUMP_Y, INTER_DUMP_X, menuDump, 8, "PNQ", MENU_HORIZ | MENU_BUTTON | MENU_ACCEPT_OTHERS, menu))
+ switch (wmenuSelect(stdscr, INTER_DUMP_Y+1, INTER_DUMP_Y, INTER_DUMP_X, menuDump, 8, "PNQ", MENU_HORIZ | MENU_BUTTON | MENU_ACCEPT_OTHERS, menu))
{
case 'p':
case 'P':
diff --git a/src/fat1x.c b/src/fat1x.c
new file mode 100644
index 00000000..7432c6d0
--- /dev/null
+++ b/src/fat1x.c
@@ -0,0 +1,202 @@
+/*
+
+ File: fat1x.c
+
+ Copyright (C) 2008 Christophe GRENIER <[email protected]>
+
+ This software is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write the Free Software Foundation, Inc., 51
+ Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+ */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+#include "types.h"
+#include "common.h"
+#include "lang.h"
+#include "intrf.h"
+#include "intrfn.h"
+#include "dirpart.h"
+#include "fat.h"
+#include "log.h"
+#include "fat_adv.h"
+#include "fat1x.h"
+
+#ifdef HAVE_NCURSES
+static void dump_fat1x_ncurses(disk_t *disk_car, partition_t *partition, const unsigned char *buffer_bs)
+{
+ WINDOW *window=newwin(0,0,0,0); /* full screen */
+ keypad(window, TRUE); /* Need it to get arrow key */
+ aff_copy(window);
+ wmove(window,4,0);
+ wprintw(window,"%s",disk_car->description(disk_car));
+ wmove(window,5,0);
+ aff_part(window,AFF_PART_ORDER|AFF_PART_STATUS,disk_car,partition);
+ mvwaddstr(window,6,0, "Boot sector");
+ dump(window,buffer_bs,FAT1x_BOOT_SECTOR_SIZE);
+ delwin(window);
+ (void) clearok(stdscr, TRUE);
+#ifdef HAVE_TOUCHWIN
+ touchwin(stdscr);
+#endif
+}
+#endif
+
+static void dump_fat1x(disk_t *disk_car, partition_t *partition, const unsigned char *buffer_bs)
+{
+ log_info("Boot sector\n");
+ dump_log(buffer_bs, FAT1x_BOOT_SECTOR_SIZE);
+#ifdef HAVE_NCURSES
+ dump_fat1x_ncurses(disk_car, partition, buffer_bs);
+#endif
+}
+
+int fat1x_boot_sector(disk_t *disk_car, partition_t *partition, const int verbose, const int dump_ind, const unsigned int expert, char **current_cmd)
+{
+ unsigned char *buffer_bs;
+ const char *options="DR";
+ int rescan=1;
+#ifdef HAVE_NCURSES
+ struct MenuItem menu_fat1x[]=
+ {
+ { 'P', "Previous",""},
+ { 'N', "Next","" },
+ { 'Q', "Quit","Return to Advanced menu"},
+ { 'L', "List", "List directories and files, copy and undelete data from FAT" },
+ { 'R', "Rebuild BS","Rebuild boot sector"},
+ { 'D', "Dump","Dump boot sector and backup boot sector"},
+ { 'C', "Repair FAT","Very Dangerous! Expert only"},
+ { 'I', "Init Root","Init root directory: Very Dangerous! Expert only"},
+ { 0, NULL, NULL }
+ };
+#endif
+ buffer_bs=(unsigned char*)MALLOC(FAT1x_BOOT_SECTOR_SIZE);
+ while(1)
+ {
+#ifdef HAVE_NCURSES
+ unsigned int menu=0;
+#endif
+ int command;
+ screen_buffer_reset();
+ if(rescan==1)
+ {
+#ifdef HAVE_NCURSES
+ aff_copy(stdscr);
+ wmove(stdscr,4,0);
+ wprintw(stdscr,"%s",disk_car->description(disk_car));
+ mvwaddstr(stdscr,5,0,msg_PART_HEADER_LONG);
+ wmove(stdscr,6,0);
+ aff_part(stdscr,AFF_PART_ORDER|AFF_PART_STATUS,disk_car,partition);
+#endif
+ log_info("\nfat1x_boot_sector\n");
+ log_partition(disk_car,partition);
+ screen_buffer_add("Boot sector\n");
+ if(disk_car->read(disk_car,FAT1x_BOOT_SECTOR_SIZE, buffer_bs, partition->part_offset)!=0)
+ {
+ screen_buffer_add("fat1x_boot_sector: Can't read boot sector.\n");
+ memset(buffer_bs,0,FAT1x_BOOT_SECTOR_SIZE);
+ }
+ if(test_FAT(disk_car,(const struct fat_boot_sector *)buffer_bs,partition,verbose,0)==0)
+ {
+ screen_buffer_add("OK\n");
+ if(expert==0)
+ options="DRCL";
+ else
+ options="DRCIL";
+ }
+ else
+ {
+ screen_buffer_add("Bad\n");
+ options="DRC";
+ }
+ screen_buffer_add("\n");
+ screen_buffer_add("A valid FAT Boot sector must be present in order to access\n");
+ screen_buffer_add("any data; even if the partition is not bootable.\n");
+ rescan=0;
+ }
+ screen_buffer_to_log();
+ if(*current_cmd!=NULL)
+ {
+ command=0;
+ while(*current_cmd[0]==',')
+ (*current_cmd)++;
+ if(strncmp(*current_cmd,"rebuildbs",9)==0)
+ {
+ (*current_cmd)+=9;
+ command='R';
+ }
+ else if(strncmp(*current_cmd,"dump",4)==0)
+ {
+ (*current_cmd)+=4;
+ command='D';
+ }
+ else if(strncmp(*current_cmd,"list",4)==0)
+ {
+ (*current_cmd)+=4;
+ if(strchr(options,'L')!=NULL)
+ command='L';
+ }
+ else if(strncmp(*current_cmd,"repairfat",8)==0)
+ {
+ (*current_cmd)+=8;
+ if(strchr(options,'C')!=NULL)
+ command='C';
+ }
+ else if(strncmp(*current_cmd,"initroot",8)==0)
+ {
+ (*current_cmd)+=8;
+ if(strchr(options,'I')!=NULL)
+ command='I';
+ }
+ }
+ else
+ {
+ log_flush();
+#ifdef HAVE_NCURSES
+ command=screen_buffer_display_ext(stdscr, options, menu_fat1x, &menu);
+#else
+ command=0;
+#endif
+ }
+ switch(command)
+ {
+ case 0:
+ free(buffer_bs);
+ return 0;
+ case 'R': /* R : rebuild boot sector */
+ rebuild_FAT_BS(disk_car,partition,verbose,dump_ind,1,expert,current_cmd);
+ rescan=1;
+ break;
+ case 'D':
+ dump_fat1x(disk_car, partition, buffer_bs);
+ break;
+ case 'C':
+ repair_FAT_table(disk_car,partition,verbose);
+ break;
+ case 'I':
+ FAT_init_rootdir(disk_car,partition,verbose);
+ break;
+ case 'L':
+ dir_partition(disk_car, partition, 0,current_cmd);
+ break;
+ }
+ }
+}
diff --git a/src/fat1x.h b/src/fat1x.h
new file mode 100644
index 00000000..998d20cf
--- /dev/null
+++ b/src/fat1x.h
@@ -0,0 +1,23 @@
+/*
+
+ File: fat1x.h
+
+ Copyright (C) 2008 Christophe GRENIER <[email protected]>
+
+ This software is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write the Free Software Foundation, Inc., 51
+ Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+ */
+int fat1x_boot_sector(disk_t *disk_car, partition_t *partition, const int verbose, const int dump_ind, const unsigned int expert, char **current_cmd);
+
diff --git a/src/fat32.c b/src/fat32.c
new file mode 100644
index 00000000..d06582f6
--- /dev/null
+++ b/src/fat32.c
@@ -0,0 +1,310 @@
+/*
+
+ File: fat32.c
+
+ Copyright (C) 2008 Christophe GRENIER <[email protected]>
+
+ This software is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write the Free Software Foundation, Inc., 51
+ Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+ */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+#include <ctype.h>
+#include "types.h"
+#include "common.h"
+#include "lang.h"
+#include "intrf.h"
+#include "intrfn.h"
+#include "dirpart.h"
+#include "fat.h"
+#include "io_redir.h"
+#include "log.h"
+#include "fat_adv.h"
+#include "fat32.h"
+
+#ifdef HAVE_NCURSES
+static void dump_fat32_ncurses(disk_t *disk_car, const partition_t *partition, const unsigned char *buffer_bs, const unsigned char *buffer_backup_bs)
+{
+ WINDOW *window=newwin(0,0,0,0); /* full screen */
+ keypad(window, TRUE); /* Need it to get arrow key */
+ aff_copy(window);
+ wmove(window,4,0);
+ wprintw(window,"%s",disk_car->description(disk_car));
+ wmove(window,5,0);
+ aff_part(window,AFF_PART_ORDER|AFF_PART_STATUS,disk_car,partition);
+ mvwaddstr(window,6,0, "Boot sector Backup boot sector");
+ dump2(window, buffer_bs, buffer_backup_bs, 3*disk_car->sector_size);
+ delwin(window);
+ (void) clearok(stdscr, TRUE);
+#ifdef HAVE_TOUCHWIN
+ touchwin(stdscr);
+#endif
+}
+#endif
+
+static void dump_fat32(disk_t *disk_car, const partition_t *partition, const unsigned char *buffer_bs, const unsigned char *buffer_backup_bs)
+{
+ log_info("Boot sector Backup boot sector\n");
+ dump2_log(buffer_bs, buffer_backup_bs, 3*disk_car->sector_size);
+ log_fat2_info((const struct fat_boot_sector*)buffer_bs,(const struct fat_boot_sector*)buffer_backup_bs,UP_FAT32,disk_car->sector_size);
+#ifdef HAVE_NCURSES
+ dump_fat32_ncurses(disk_car, partition, buffer_bs, buffer_backup_bs);
+#endif
+}
+
+int fat32_boot_sector(disk_t *disk_car, partition_t *partition, const int verbose, const int dump_ind, const unsigned int expert, char **current_cmd)
+{
+ unsigned char *buffer_bs;
+ unsigned char *buffer_backup_bs;
+ const char *options="DRC";
+ int rescan=1;
+#ifdef HAVE_NCURSES
+ struct MenuItem menu_fat32[]=
+ {
+ { 'P', "Previous",""},
+ { 'N', "Next","" },
+ { 'Q', "Quit","Return to Advanced menu"},
+ { 'L', "List", "List directories and files, copy and undelete data from FAT" },
+ { 'O', "Org. BS","Copy boot sector over backup sector"},
+ { 'B', "Backup BS","Copy backup boot sector over boot sector"},
+ { 'R', "Rebuild BS","Rebuild boot sector"},
+ { 'D', "Dump","Dump boot sector and backup boot sector"},
+ { 'C', "Repair FAT","Very Dangerous! Expert only"},
+ { 0, NULL, NULL }
+ };
+#endif
+ buffer_bs=(unsigned char*)MALLOC(3*disk_car->sector_size);
+ buffer_backup_bs=(unsigned char*)MALLOC(3*disk_car->sector_size);
+ while(1)
+ {
+ unsigned int menu=0;
+ int command;
+ screen_buffer_reset();
+ if(rescan==1)
+ {
+ int opt_over=0;
+ int opt_B=0;
+ int opt_O=0;
+ options="DRC";
+#ifdef HAVE_NCURSES
+ aff_copy(stdscr);
+ wmove(stdscr,4,0);
+ wprintw(stdscr,"%s",disk_car->description(disk_car));
+ mvwaddstr(stdscr,5,0,msg_PART_HEADER_LONG);
+ wmove(stdscr,6,0);
+ aff_part(stdscr,AFF_PART_ORDER|AFF_PART_STATUS,disk_car,partition);
+#endif
+ log_info("\nfat32_boot_sector\n");
+ log_partition(disk_car,partition);
+ screen_buffer_add("Boot sector\n");
+ if(disk_car->read(disk_car,3*disk_car->sector_size, buffer_bs, partition->part_offset)!=0)
+ {
+ screen_buffer_add("fat32_boot_sector: Can't read boot sector.\n");
+ memset(buffer_bs,0,3*disk_car->sector_size);
+ }
+ if(test_FAT(disk_car,(struct fat_boot_sector *)buffer_bs,partition,verbose,0)==0)
+ {
+ screen_buffer_add("OK\n");
+ if(partition->upart_type==UP_FAT32)
+ {
+ opt_O=1;
+ opt_over=1;
+ }
+ else
+ {
+ screen_buffer_add("Warning: valid FAT bootsector but not a FAT32 one!");
+ }
+ }
+ else
+ {
+ screen_buffer_add("Bad\n");
+ }
+ screen_buffer_add("\nBackup boot sector\n");
+ if(disk_car->read(disk_car,3*disk_car->sector_size, buffer_backup_bs, partition->part_offset+6*disk_car->sector_size)!=0)
+ {
+ screen_buffer_add("fat32_boot_sector: Can't read backup boot sector.\n");
+ memset(buffer_backup_bs,0,3*disk_car->sector_size);
+ }
+ if(test_FAT(disk_car,(struct fat_boot_sector *)buffer_backup_bs,partition,verbose,0)==0)
+ {
+ screen_buffer_add("OK\n");
+ if(partition->upart_type==UP_FAT32)
+ {
+ opt_B=1;
+ opt_over=1;
+ }
+ else
+ {
+ screen_buffer_add("Warning: valid FAT backup bootsector but not a FAT32 one!");
+ }
+ }
+ else
+ {
+ screen_buffer_add("Bad\n");
+ }
+ screen_buffer_add("\n");
+ if((memcmp(buffer_bs,buffer_backup_bs,0x3E8)==0)&&(memcmp(buffer_bs+0x3F0,buffer_backup_bs+0x3F0,0x600-0x3F0))==0)
+ {
+ screen_buffer_add("Sectors are identical.\n");
+ opt_over=0;
+ }
+ else
+ {
+ if(memcmp(buffer_bs,buffer_backup_bs,0x200)!=0)
+ screen_buffer_add("First sectors (Boot code and partition information) are not identical.\n");
+ if((memcmp(buffer_bs+disk_car->sector_size, buffer_backup_bs+disk_car->sector_size,0x1E8)!=0)||
+ (memcmp(buffer_bs+disk_car->sector_size+0x1F0, buffer_backup_bs+disk_car->sector_size+0x1F0,0x200-0x1F0)!=0))
+ screen_buffer_add("Second sectors (cluster information) are not identical.\n");
+ if(memcmp(buffer_bs+2*disk_car->sector_size, buffer_backup_bs+2*disk_car->sector_size,0x200)!=0)
+ screen_buffer_add("Third sectors (Second part of boot code) are not identical.\n");
+ }
+ screen_buffer_add("\n");
+ screen_buffer_add("A valid FAT Boot sector must be present in order to access\n");
+ screen_buffer_add("any data; even if the partition is not bootable.\n");
+ if(opt_over!=0)
+ {
+ if(opt_B!=0 && opt_O!=0)
+ options="DOBRL";
+ else if(opt_B!=0)
+ {
+ menu=5;
+ options="DBRL";
+ }
+ else if(opt_O!=0)
+ {
+ menu=4;
+ options="DORL";
+ }
+ }
+ else
+ {
+ if(opt_B!=0)
+ options="DRCL";
+ else
+ options="DR";
+ }
+ rescan=0;
+ }
+ screen_buffer_to_log();
+ if(*current_cmd!=NULL)
+ {
+ command=0;
+ while(*current_cmd[0]==',')
+ (*current_cmd)++;
+ if(strncmp(*current_cmd,"rebuildbs",9)==0)
+ {
+ (*current_cmd)+=9;
+ command='R';
+ }
+ else if(strncmp(*current_cmd,"dump",4)==0)
+ {
+ (*current_cmd)+=4;
+ command='D';
+ }
+ else if(strncmp(*current_cmd,"list",4)==0)
+ {
+ (*current_cmd)+=4;
+ if(strchr(options,'L')!=NULL)
+ command='L';
+ }
+ else if(strncmp(*current_cmd,"repairfat",8)==0)
+ {
+ (*current_cmd)+=8;
+ if(strchr(options,'C')!=NULL)
+ command='C';
+ }
+ else if(strncmp(*current_cmd,"originalfat",11)==0)
+ {
+ (*current_cmd)+=11;
+ if(strchr(options,'O')!=NULL)
+ command='O';
+ }
+ else if(strncmp(*current_cmd,"backupfat",9)==0)
+ {
+ (*current_cmd)+=9;
+ if(strchr(options,'B')!=NULL)
+ command='B';
+ }
+ }
+ else
+ {
+ log_flush();
+#ifdef HAVE_NCURSES
+ command=screen_buffer_display_ext(stdscr, options, menu_fat32, &menu);
+#else
+ command=0;
+#endif
+ }
+ switch(command)
+ {
+ case 0:
+ free(buffer_bs);
+ free(buffer_backup_bs);
+ return 0;
+ case 'O': /* O : copy original boot sector over backup boot */
+ if(ask_confirmation("Copy original FAT32 boot sector over backup boot, confirm ? (Y/N)")!=0)
+ {
+ log_info("copy original boot sector over backup boot\n");
+ if(disk_car->write(disk_car,3*disk_car->sector_size, buffer_bs, partition->part_offset+6*disk_car->sector_size)!=0)
+ {
+ display_message("Write error: Can't overwrite FAT32 backup boot sector\n");
+ }
+ disk_car->sync(disk_car);
+ rescan=1;
+ }
+ break;
+ case 'B': /* B : copy backup boot sector over boot sector */
+ if(ask_confirmation("Copy backup FAT32 boot sector over boot sector, confirm ? (Y/N)")!=0)
+ {
+ log_info("copy backup boot sector over boot sector\n");
+ if(disk_car->write(disk_car,3*disk_car->sector_size, buffer_backup_bs, partition->part_offset)!=0)
+ {
+ display_message("Write error: Can't overwrite FAT32 boot sector\n");
+ }
+ disk_car->sync(disk_car);
+ rescan=1;
+ }
+ break;
+ case 'C':
+ repair_FAT_table(disk_car,partition,verbose);
+ break;
+ case 'D':
+ dump_fat32(disk_car, partition, buffer_bs, buffer_backup_bs);
+ break;
+ case 'L':
+ if(strchr(options,'O')==NULL && strchr(options,'B')!=NULL)
+ {
+ io_redir_add_redir(disk_car,partition->part_offset,3*disk_car->sector_size,0,buffer_backup_bs);
+ dir_partition(disk_car, partition, 0,current_cmd);
+ io_redir_del_redir(disk_car,partition->part_offset);
+ }
+ else
+ dir_partition(disk_car, partition, 0,current_cmd);
+ break;
+ case 'R': /* R : rebuild boot sector */
+ rebuild_FAT_BS(disk_car,partition,verbose,dump_ind,1,expert,current_cmd);
+ rescan=1;
+ break;
+ }
+ }
+}
diff --git a/src/fat32.h b/src/fat32.h
new file mode 100644
index 00000000..a004354a
--- /dev/null
+++ b/src/fat32.h
@@ -0,0 +1,22 @@
+/*
+
+ File: fat32.h
+
+ Copyright (C) 2008 Christophe GRENIER <[email protected]>
+
+ This software is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write the Free Software Foundation, Inc., 51
+ Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+ */
+int fat32_boot_sector(disk_t *disk_car, partition_t *partition, const int verbose, const int dump_ind, const unsigned int expert, char **current_cmd);
diff --git a/src/fat_adv.c b/src/fat_adv.c
index 6135feac..f0866ba3 100644
--- a/src/fat_adv.c
+++ b/src/fat_adv.c
@@ -979,7 +979,7 @@ static void menu_write_fat_boot_sector(disk_t *disk_car, partition_t *partition,
else
{
#ifdef HAVE_NCURSES
- command=wmenuSelect(stdscr, 24, INTER_DUMP_Y, INTER_DUMP_X, menuSaveBoot,8,options,MENU_HORIZ|MENU_BUTTON, 1);
+ command=wmenuSelect(stdscr, INTER_DUMP_Y+1, INTER_DUMP_Y, INTER_DUMP_X, menuSaveBoot,8,options,MENU_HORIZ|MENU_BUTTON, 1);
#else
command=0;
#endif
diff --git a/src/godmode.c b/src/godmode.c
index 74960d4a..7dd76994 100644
--- a/src/godmode.c
+++ b/src/godmode.c
@@ -2,7 +2,7 @@
File: godmode.c
- Copyright (C) 1998-2007 Christophe GRENIER <[email protected]>
+ Copyright (C) 1998-2008 Christophe GRENIER <[email protected]>
This software is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -37,17 +37,20 @@
#include "lang.h"
#include "godmode.h"
#include "testdisk.h"
+#include "intrface.h"
#include "fat.h"
#include "ext2.h"
#include "intrf.h"
#include "intrfn.h"
-#include "intrface.h"
#include "md.h"
#include "adv.h"
#include "ntfs.h"
#include "next.h"
#include "tpartwr.h"
#include "log.h"
+#include "fat32.h"
+#include "tntfs.h"
+#include "thfs.h"
#define RO 1
#define RW 0
@@ -66,6 +69,9 @@ static int interface_part_bad_log(disk_t *disk_car,list_part_t *list_part_bad);
static int interface_part_bad_ncurses(disk_t *disk_car, list_part_t *list_part_bad);
static void warning_geometry_ncurses(disk_t *disk_car, const unsigned int recommanded_heads_per_cylinder);
static void ask_mbr_order_i386(disk_t *disk_car,list_part_t *list_part);
+#define ANALYSE_X 0
+#define ANALYSE_Y 5
+#define INTER_BAD_PART 10
#endif
static list_part_t *add_ext_part_i386(disk_t *disk_car, list_part_t *list_part, const int max_ext, const int align,const int verbose);
static unsigned int tab_insert(uint64_t *tab, const uint64_t offset, unsigned int tab_nbr);
@@ -176,7 +182,7 @@ static int interface_part_bad_ncurses(disk_t *disk_car, list_part_t *list_part)
wattrset(stdscr, A_REVERSE);
aff_part(stdscr, AFF_PART_BASE, disk_car, parts->part);
wattroff(stdscr, A_REVERSE);
- wmove(stdscr,24,0);
+ wmove(stdscr,23,0);
wclrtoeol(stdscr); /* before addstr for BSD compatibility */
if(parts->part->info[0]!='\0')
{
diff --git a/src/intrf.c b/src/intrf.c
index 25fb1c28..1b953b6f 100644
--- a/src/intrf.c
+++ b/src/intrf.c
@@ -647,7 +647,7 @@ int wmenuSimple(WINDOW *window,const struct MenuItem *menuItems, unsigned int me
available[i] = menuItems[i].key;
}
available[i] = 0;
- return wmenuSelect(window, 24, 18, 0, menuItems, itemLength, available, MENU_HORIZ | MENU_BUTTON, menuDefault);
+ return wmenuSelect(window, 23, 18, 0, menuItems, itemLength, available, MENU_HORIZ | MENU_BUTTON, menuDefault);
}
/* End of command menu support code */
@@ -755,7 +755,7 @@ void dump(WINDOW *window, const void *nom_dump,unsigned int lng)
wprintw(window," ");
}
}
- switch (wmenuSelect(window, 24, INTER_DUMP_Y, INTER_DUMP_X, menuDump, 8, options, MENU_HORIZ | MENU_BUTTON | MENU_ACCEPT_OTHERS, menu))
+ switch (wmenuSelect(window, INTER_DUMP_Y+1, INTER_DUMP_Y, INTER_DUMP_X, menuDump, 8, options, MENU_HORIZ | MENU_BUTTON | MENU_ACCEPT_OTHERS, menu))
{
case 'p':
case 'P':
@@ -908,7 +908,7 @@ void dump2(WINDOW *window, const void *dump_1, const void *dump_2, const unsigne
wprintw(window," ");
}
}
- switch (wmenuSelect(window, 24, INTER_DUMP_Y, INTER_DUMP_X, menuDump, 8, options, MENU_HORIZ | MENU_BUTTON | MENU_ACCEPT_OTHERS, menu))
+ switch (wmenuSelect(window, INTER_DUMP_Y+1, INTER_DUMP_Y, INTER_DUMP_X, menuDump, 8, options, MENU_HORIZ | MENU_BUTTON | MENU_ACCEPT_OTHERS, menu))
{
case 'p':
case 'P':
@@ -1294,11 +1294,11 @@ int start_ncurses(const char *prog_name, const char *real_prog_name)
curs_set(0);
{
int quit=0;
- while(LINES>=8 && LINES<25 && quit==0)
+ while(LINES>=8 && LINES<24 && quit==0)
{
aff_copy(stdscr);
wmove(stdscr,4,0);
- wprintw(stdscr,"%s need 25 lines to work.", prog_name);
+ wprintw(stdscr,"%s need 24 lines to work.", prog_name);
wmove(stdscr,5,0);
wprintw(stdscr,"Please enlarge the terminal.");
wmove(stdscr,LINES-2,0);
@@ -1321,10 +1321,10 @@ int start_ncurses(const char *prog_name, const char *real_prog_name)
}
}
}
- if(LINES<25)
+ if(LINES<24)
{
end_ncurses();
- printf("%s need 25 lines to work.\nPlease enlarge the terminal and restart %s.\n",prog_name,prog_name);
+ printf("%s need 24 lines to work.\nPlease enlarge the terminal and restart %s.\n",prog_name,prog_name);
log_critical("Terminal has only %u lines\n",LINES);
return 1;
}
@@ -1399,7 +1399,7 @@ static int intrf_no_disk_ncurses(const char *prog_name)
};
unsigned int menu=0;
int command;
- command = wmenuSelect_ext(stdscr,24, 21, 0, menuSudo, 8,
+ 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;
@@ -1470,7 +1470,7 @@ static int interface_partition_type_ncurses(disk_t *disk_car)
wprintw(stdscr,"Note: Do NOT select 'None' for media with only a single partition. It's very");
wmove(stdscr,21,0);
wprintw(stdscr,"rare for a drive to be 'Non-partitioned'.");
- car=wmenuSelect_ext(stdscr, 24, INTER_PARTITION_Y, INTER_PARTITION_X, menuOptions, 7, "IGMNSXQ", MENU_BUTTON | MENU_VERT | MENU_VERT_WARN, &menu,&real_key);
+ car=wmenuSelect_ext(stdscr, 23, INTER_PARTITION_Y, INTER_PARTITION_X, menuOptions, 7, "IGMNSXQ", MENU_BUTTON | MENU_VERT | MENU_VERT_WARN, &menu,&real_key);
switch(car)
{
case 'i':
diff --git a/src/intrf.h b/src/intrf.h
index 1a5a7a5a..4a05fd42 100644
--- a/src/intrf.h
+++ b/src/intrf.h
@@ -34,10 +34,10 @@ struct MenuItem
#define COLUMNS 80
#define DUMP_X 0
-#define DUMP_Y 5 + 2
+#define DUMP_Y 7
#define DUMP_MAX_LINES 14
#define INTER_DUMP_X DUMP_X
-#define INTER_DUMP_Y DUMP_Y+DUMP_MAX_LINES+1
+#define INTER_DUMP_Y 22
#define INTER_OPTION_X 0
#define INTER_OPTION_Y 10
#define INTER_PARTITION_X 0
diff --git a/src/intrface.c b/src/intrface.c
index 0867860e..305c51cb 100644
--- a/src/intrface.c
+++ b/src/intrface.c
@@ -93,19 +93,25 @@ static list_part_t *ask_structure_cli(disk_t *disk_car,list_part_t *list_part, c
}
#ifdef HAVE_NCURSES
-#define INTER_STRUCTURE 13
+#define INTER_STRUCTURE (LINES-12)
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);
@@ -115,9 +121,12 @@ static list_part_t *ask_structure_ncurses(disk_t *disk_car,list_part_t *list_par
rewrite=0;
}
structure_status=disk_car->arch->test_structure(list_part);
- for(i=0,parts=list_part;(parts!=NULL) && (i<offset);parts=parts->next,i++);
- for(i=offset;(parts!=NULL) &&((i-offset)<INTER_STRUCTURE);i++,parts=parts->next)
+ 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)
@@ -133,7 +142,7 @@ static list_part_t *ask_structure_ncurses(disk_t *disk_car,list_part_t *list_par
{
char buffer_part_size[100];
wattroff(stdscr, A_REVERSE);
- wmove(stdscr,24,0);
+ wmove(stdscr,LINES-1,0);
wclrtoeol(stdscr); /* before addstr for BSD compatibility */
if(parts->part->info[0]!='\0')
{
@@ -143,18 +152,18 @@ static list_part_t *ask_structure_ncurses(disk_t *disk_car,list_part_t *list_par
}
}
if(structure_status==0)
- mvwaddstr(stdscr,19,0,msg_STRUCT_OK);
+ mvwaddstr(stdscr,LINES-6,0,msg_STRUCT_OK);
else
{
if(has_colors())
wbkgdset(stdscr,' ' | A_BOLD | COLOR_PAIR(1));
- mvwaddstr(stdscr,19,0,msg_STRUCT_BAD);
+ 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,19,16,"Use ");
+ mvwaddstr(stdscr,LINES-6,16,"Use ");
if(has_colors())
wbkgdset(stdscr,' ' | A_BOLD | COLOR_PAIR(0));
waddstr(stdscr,"Up");
@@ -167,7 +176,7 @@ static list_part_t *ask_structure_ncurses(disk_t *disk_car,list_part_t *list_par
if(has_colors())
wbkgdset(stdscr,' ' | COLOR_PAIR(0));
waddstr(stdscr," Arrow keys to select partition.");
- mvwaddstr(stdscr,20,0,"Use ");
+ mvwaddstr(stdscr,LINES-5,0,"Use ");
if(has_colors())
wbkgdset(stdscr,' ' | A_BOLD | COLOR_PAIR(0));
waddstr(stdscr,"Left");
@@ -180,9 +189,9 @@ static list_part_t *ask_structure_ncurses(disk_t *disk_car,list_part_t *list_par
if(has_colors())
wbkgdset(stdscr,' ' | COLOR_PAIR(0));
waddstr(stdscr," Arrow keys to CHANGE partition characteristics:");
- mvwaddstr(stdscr,21,0,disk_car->arch->msg_part_type);
+ mvwaddstr(stdscr,LINES-4,0,disk_car->arch->msg_part_type);
}
- wmove(stdscr,22,0);
+ 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 */
@@ -240,7 +249,7 @@ static list_part_t *ask_structure_ncurses(disk_t *disk_car,list_part_t *list_par
}
if(has_colors())
wbkgdset(stdscr,' ' | A_BOLD | COLOR_PAIR(0));
- mvwaddstr(stdscr,23,5, "Enter");
+ mvwaddstr(stdscr,LINES-2,5, "Enter");
if(has_colors())
wbkgdset(stdscr,' ' | COLOR_PAIR(0));
waddstr(stdscr,": to continue");
diff --git a/src/intrface.h b/src/intrface.h
index 104c8bfe..a2eff2d0 100644
--- a/src/intrface.h
+++ b/src/intrface.h
@@ -20,9 +20,5 @@
*/
-#define ANALYSE_X 0
-#define ANALYSE_Y 5
-#define INTER_BAD_PART 10
-
list_part_t *ask_structure(disk_t *disk_car,list_part_t *list_part, const int verbose, char **current_cmd);
void interface_list(disk_t *disk_car, const int verbose, const int saveheader, const int backup, char **current_cmd);
diff --git a/src/ntfs_adv.c b/src/ntfs_adv.c
index 31d91183..d04ec2a0 100644
--- a/src/ntfs_adv.c
+++ b/src/ntfs_adv.c
@@ -194,7 +194,7 @@ static void menu_write_ntfs_boot_sector_ncurses(disk_t *disk_car, partition_t *p
ncurses_ntfs_info(ntfs_header);
wprintw(stdscr,"Extrapolated boot sector and current boot sector are identical.\n");
}
- command=wmenuSelect(stdscr, 24, INTER_DUMP_Y, INTER_DUMP_X, menuSaveBoot,8,options,MENU_HORIZ | MENU_BUTTON, 1);
+ command=wmenuSelect(stdscr, INTER_DUMP_Y+1, INTER_DUMP_Y, INTER_DUMP_X, menuSaveBoot,8,options,MENU_HORIZ | MENU_BUTTON, 1);
switch(command)
{
case 'w':
diff --git a/src/ntfs_fix.c b/src/ntfs_fix.c
index 7dd0bca7..d322b0a9 100644
--- a/src/ntfs_fix.c
+++ b/src/ntfs_fix.c
@@ -258,7 +258,7 @@ int repair_MFT(disk_t *disk_car, partition_t *partition, const int verbose, cons
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, 24, INTER_MFT_Y, INTER_MFT_X, menuMFT, 10, "MBQ",
+ 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)
{
diff --git a/src/parti386.c b/src/parti386.c
index 17abd529..74f352da 100644
--- a/src/parti386.c
+++ b/src/parti386.c
@@ -1285,7 +1285,8 @@ static list_part_t *add_partition_i386_ncurses(disk_t *disk_car,list_part_t *lis
end.sector=disk_car->geom.sectors_per_head;
{
int done = 0;
- while (done==0) {
+ while (done==0)
+ {
int command;
static struct MenuItem menuGeometry[]=
{
@@ -1311,17 +1312,18 @@ static list_part_t *add_partition_i386_ncurses(disk_t *disk_car,list_part_t *lis
wclrtoeol(stdscr);
wrefresh(stdscr);
command=wmenuSimple(stdscr,menuGeometry, position);
- switch (command) {
+ switch (command)
+ {
case 'c':
wmove(stdscr, INTER_GEOM_Y, INTER_GEOM_X);
start.cylinder=ask_number(start.cylinder,
- 0, disk_car->geom.cylinders, "Enter the starting cylinder ");
+ 0, disk_car->geom.cylinders-1, "Enter the starting cylinder ");
position=1;
break;
case 'h':
wmove(stdscr, INTER_GEOM_Y, INTER_GEOM_X);
start.head=ask_number(start.head,
- 0, disk_car->geom.heads_per_cylinder, "Enter the starting head ");
+ 0, disk_car->geom.heads_per_cylinder-1, "Enter the starting head ");
position=2;
break;
case 's':
@@ -1339,7 +1341,7 @@ static list_part_t *add_partition_i386_ncurses(disk_t *disk_car,list_part_t *lis
case 'H':
wmove(stdscr, INTER_GEOM_Y, INTER_GEOM_X);
end.head=ask_number(end.head,
- 0, disk_car->geom.heads_per_cylinder, "Enter the ending head ");
+ 0, disk_car->geom.heads_per_cylinder-1, "Enter the ending head ");
position=5;
break;
case 'S':
diff --git a/src/pblocksize.c b/src/pblocksize.c
new file mode 100644
index 00000000..9c9a4afe
--- /dev/null
+++ b/src/pblocksize.c
@@ -0,0 +1,142 @@
+/*
+
+ File: pblocksize.c
+
+ Copyright (C) 1998-2008 Christophe GRENIER <[email protected]>
+
+ This software is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write the Free Software Foundation, Inc., 51
+ Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "types.h"
+#include "common.h"
+#include "intrf.h"
+#ifdef HAVE_NCURSES
+#include "intrfn.h"
+#else
+#include <stdio.h>
+#endif
+#include "log.h"
+#include "pblocksize.h"
+
+#ifdef HAVE_NCURSES
+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="S51248736";
+ static const struct MenuItem menuBlocksize[]=
+ {
+ {'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 512: optionsBlocksize+=1; break;
+ case 1024: optionsBlocksize+=2; break;
+ case 2048: optionsBlocksize+=3; break;
+ case 4096: optionsBlocksize+=4; break;
+ case 8192: optionsBlocksize+=5; break;
+ case 16384: optionsBlocksize+=6;break;
+ case 32768: optionsBlocksize+=7; break;
+ case 65536: optionsBlocksize+=8; break;
+ }
+ switch(blocksize)
+ {
+ case 256: menu=0; break;
+ case 512: menu=1; break;
+ case 1024: menu=2; break;
+ case 2048: menu=3; break;
+ case 4096: menu=4; break;
+ case 8192: menu=5; break;
+ case 16384: menu=6; break;
+ case 32768: menu=7; break;
+ case 65536: menu=8; 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 '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;
+ }
+ if(*offset%sector_size!=0 || *offset>=blocksize)
+ *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);
+ }
+ log_info("blocksize=%u,offset=%u\n",blocksize,(unsigned int)*offset);
+ return blocksize;
+}
+#endif
diff --git a/src/pblocksize.h b/src/pblocksize.h
new file mode 100644
index 00000000..711496e4
--- /dev/null
+++ b/src/pblocksize.h
@@ -0,0 +1,22 @@
+/*
+
+ File: pblocksize.h
+
+ Copyright (C) 1998-2008 Christophe GRENIER <[email protected]>
+
+ This software is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write the Free Software Foundation, Inc., 51
+ Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+ */
+unsigned int menu_choose_blocksize(unsigned int blocksize, const unsigned int sector_size, uint64_t *offset);
diff --git a/src/pdisksel.c b/src/pdisksel.c
new file mode 100644
index 00000000..bccbb35d
--- /dev/null
+++ b/src/pdisksel.c
@@ -0,0 +1,257 @@
+/*
+
+ File: pdisksel.c
+
+ Copyright (C) 1998-2008 Christophe GRENIER <[email protected]>
+
+ This software is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write the Free Software Foundation, Inc., 51
+ Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h> /* geteuid */
+#endif
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+#include "types.h"
+#include "common.h"
+#include "intrf.h"
+#ifdef HAVE_NCURSES
+#include "intrfn.h"
+#else
+#include <stdio.h>
+#endif
+#include "dir.h"
+#include "list.h"
+#include "filegen.h"
+#include "photorec.h"
+#include "sessionp.h"
+#include "partauto.h"
+#include "log.h"
+#include "pdisksel.h"
+#include "ppartsel.h"
+
+#ifdef HAVE_NCURSES
+#define NBR_DISK_MAX (LINES-6-8)
+#define INTER_DISK_X 0
+#define INTER_DISK_Y (8+NBR_DISK_MAX)
+#define INTER_NOTE_Y (LINES-4)
+
+static void photorec_disk_selection_ncurses(int verbose, const char *recup_dir, const list_disk_t *list_disk, file_enable_t *file_enable)
+{
+ char * current_cmd=NULL;
+ int command;
+ int real_key;
+ int done=0;
+ unsigned int menu=0;
+ int offset=0;
+ int pos_num=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",""},
+ { 'Q',"Quit","Quit program"},
+ { 0,NULL,NULL}
+ };
+ static alloc_data_t list_search_space={
+ .list = TD_LIST_HEAD_INIT(list_search_space.list)
+ };
+ /* ncurses interface */
+ while(done==0)
+ {
+ const char *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):");
+ 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);
+ }
+ }
+ if(i<=NBR_DISK_MAX && element_disk==NULL)
+ options="OQ";
+ else
+ options="PNOQ";
+ {
+ int line=INTER_NOTE_Y;
+ mvwaddstr(stdscr,line++,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));
+ }
+#endif
+#endif
+#endif
+ wmove(stdscr,line++,0);
+ wprintw(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.");
+ }
+ 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,&real_key);
+ 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;
+ autodetect_arch(disk);
+ if(interface_partition_type(disk, verbose, &current_cmd)==0)
+ menu_photorec(disk, verbose, recup_dir, file_enable, &current_cmd, &list_search_space);
+ }
+ break;
+ case 'q':
+ case 'Q':
+ done=1;
+ break;
+ }
+ if(pos_num<offset)
+ offset=pos_num;
+ if(pos_num>=offset+NBR_DISK_MAX)
+ offset=pos_num-NBR_DISK_MAX+1;
+ }
+}
+#endif
+
+int do_curses_photorec(int verbose, const char *recup_dir, const list_disk_t *list_disk, file_enable_t *file_enable, char *cmd_device, char **current_cmd)
+{
+ static alloc_data_t list_search_space={
+ .list = TD_LIST_HEAD_INIT(list_search_space.list)
+ };
+ if(list_disk==NULL)
+ {
+ return intrf_no_disk("PhotoRec");
+ }
+ if(cmd_device==NULL)
+ {
+ char *saved_device=NULL;
+ char *saved_cmd=NULL;
+ session_load(&saved_device, &saved_cmd,&list_search_space);
+ if(saved_device!=NULL && saved_cmd!=NULL && !td_list_empty(&list_search_space.list) && ask_confirmation("Continue previous session ? (Y/N)")!=0)
+ {
+ /* yes */
+ *current_cmd=saved_cmd;
+ cmd_device=saved_device;
+ }
+ else
+ {
+ free(saved_device);
+ free(saved_cmd);
+ free_list_search_space(&list_search_space);
+ }
+ }
+ if(cmd_device!=NULL && *current_cmd!=NULL)
+ {
+ const list_disk_t *element_disk;
+ disk_t *disk=NULL;
+ for(element_disk=list_disk;element_disk!=NULL;element_disk=element_disk->next)
+ {
+ if(strcmp(element_disk->disk->device,cmd_device)==0)
+ disk=element_disk->disk;
+ }
+ if(disk==NULL)
+ {
+ return intrf_no_disk("PhotoRec");
+ }
+ {
+ /* disk sector size is now known, fix the sector ranges */
+ struct td_list_head *search_walker = NULL;
+ td_list_for_each(search_walker, &list_search_space.list)
+ {
+ alloc_data_t *current_search_space;
+ current_search_space=td_list_entry(search_walker, alloc_data_t, list);
+ current_search_space->start=current_search_space->start*disk->sector_size;
+ current_search_space->end=current_search_space->end*disk->sector_size+disk->sector_size-1;
+ }
+ }
+ autodetect_arch(disk);
+ if(interface_partition_type(disk, verbose, current_cmd)==0)
+ menu_photorec(disk, verbose, recup_dir, file_enable, current_cmd, &list_search_space);
+ }
+ else
+ {
+#ifdef HAVE_NCURSES
+ photorec_disk_selection_ncurses(verbose, recup_dir, list_disk, file_enable);
+#endif
+ }
+ log_info("\n");
+ return 0;
+}
diff --git a/src/pdisksel.h b/src/pdisksel.h
new file mode 100644
index 00000000..f78d49f0
--- /dev/null
+++ b/src/pdisksel.h
@@ -0,0 +1,23 @@
+/*
+
+ File: pdisksel.h
+
+ Copyright (C) 2008 Christophe GRENIER <[email protected]>
+
+ This software is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write the Free Software Foundation, Inc., 51
+ Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+ */
+
+int do_curses_photorec(int verbose, const char *recup_dir, const list_disk_t *list_disk, file_enable_t *file_enable, char *cmd_device, char**cmd_run);
diff --git a/src/pfree_whole.c b/src/pfree_whole.c
new file mode 100644
index 00000000..cb22e0e7
--- /dev/null
+++ b/src/pfree_whole.c
@@ -0,0 +1,134 @@
+/*
+
+ File: pfree_whole.c
+
+ Copyright (C) 1998-2008 Christophe GRENIER <[email protected]>
+
+ This software is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write the Free Software Foundation, Inc., 51
+ Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "types.h"
+#include "common.h"
+#include "intrf.h"
+#ifdef HAVE_NCURSES
+#include "intrfn.h"
+#else
+#include <stdio.h>
+#endif
+#include "log.h"
+#include "pfree_whole.h"
+
+#ifdef HAVE_NCURSES
+int ask_mode_ext2(const disk_t *disk_car, const partition_t *partition, unsigned int *mode_ext2, unsigned int *carve_free_space_only)
+{
+ static const struct MenuItem menuMode[]=
+ {
+ {'E',"ext2/ext3","ext2/ext3/ext4 filesystem"},
+ {'O',"Other","FAT/NTFS/HFS+/ReiserFS/..."},
+ {0,NULL,NULL}
+ };
+ static const struct MenuItem menuFAT16[]=
+ {
+ {'F',"Free", "Scan for files from FAT16 unallocated space only"},
+ {'W',"Whole","Extract files from whole partition"},
+ {0,NULL,NULL}
+ };
+ static const struct MenuItem menuFAT32[]=
+ {
+ {'F',"Free", "Scan for file from FAT32 unallocated space only"},
+ {'W',"Whole","Extract files from whole partition"},
+ {0,NULL,NULL}
+ };
+#ifdef HAVE_LIBNTFS
+ static const struct MenuItem menuNTFS[]=
+ {
+ {'F',"Free", "Scan for file from NTFS unallocated space only"},
+ {'W',"Whole","Extract files from whole partition"},
+ {0,NULL,NULL}
+ };
+#endif
+#ifdef HAVE_LIBEXT2FS
+ static const struct MenuItem menuEXT2[]=
+ {
+ {'F',"Free", "Scan for file from ext2/ext3 unallocated space only"},
+ {'W',"Whole","Extract files from whole partition"},
+ {0,NULL,NULL}
+ };
+#endif
+ const char *options="EO";
+ WINDOW *window;
+ unsigned int menu;
+ int command;
+ if(partition->upart_type==UP_EXT2 ||
+ partition->upart_type==UP_EXT3 ||
+ partition->upart_type==UP_EXT4)
+ menu=0;
+ else
+ menu=1;
+ window=newwin(0,0,0,0); /* full screen */
+ aff_copy(window);
+ wmove(window,4,0);
+ aff_part(window, AFF_PART_ORDER|AFF_PART_STATUS,disk_car,partition);
+ wmove(window,6,0);
+ waddstr(window,"To recover lost files, PhotoRec need to know the filesystem type where the");
+ wmove(window,7,0);
+ waddstr(window,"file were stored:");
+ command = wmenuSelect_ext(window, 23, 8, 0, menuMode, 11,
+ options, MENU_VERT | MENU_VERT_WARN | MENU_BUTTON, &menu,NULL);
+ *mode_ext2=(command=='E' || command=='e');
+ if(*mode_ext2>0)
+ {
+ log_info("ext2/ext3/ext4 mode activated.\n");
+ }
+ {
+ menu=0;
+ options="FW";
+ wmove(window,6,0);
+ wclrtoeol(window);
+ wmove(window,7,0);
+ wclrtoeol(window);
+ waddstr(window,"Please choose if all space need to be analysed:");
+ if(partition->upart_type==UP_FAT16)
+ command = wmenuSelect_ext(window, 23, 8, 0, menuFAT16, 11,
+ options, MENU_VERT | MENU_VERT_WARN | MENU_BUTTON, &menu,NULL);
+ else if(partition->upart_type==UP_FAT32)
+ command = wmenuSelect_ext(window, 23, 8, 0, menuFAT32, 11,
+ options, MENU_VERT | MENU_VERT_WARN | MENU_BUTTON, &menu,NULL);
+#ifdef HAVE_LIBNTFS
+ else if(partition->upart_type==UP_NTFS)
+ command = wmenuSelect_ext(window, 23, 8, 0, menuNTFS, 11,
+ options, MENU_VERT | MENU_VERT_WARN | MENU_BUTTON, &menu,NULL);
+#endif
+#ifdef HAVE_LIBEXT2FS
+ else if(partition->upart_type==UP_EXT2 || partition->upart_type==UP_EXT3 || partition->upart_type==UP_EXT4)
+ command = wmenuSelect_ext(window, 23, 8, 0, menuEXT2, 11,
+ options, MENU_VERT | MENU_VERT_WARN | MENU_BUTTON, &menu,NULL);
+#endif
+ else
+ command='W';
+ *carve_free_space_only=(command=='F' || command=='f')?1:0;
+ if(*carve_free_space_only>0)
+ {
+ log_info("Carve free space only.\n");
+ }
+ }
+ delwin(window);
+ return 0;
+}
+#endif
diff --git a/src/pfree_whole.h b/src/pfree_whole.h
new file mode 100644
index 00000000..fba16c95
--- /dev/null
+++ b/src/pfree_whole.h
@@ -0,0 +1,24 @@
+/*
+
+ File: pfree_whole.h
+
+ Copyright (C) 2008 Christophe GRENIER <[email protected]>
+
+ This software is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write the Free Software Foundation, Inc., 51
+ Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+ */
+#ifdef HAVE_NCURSES
+int ask_mode_ext2(const disk_t *disk_car, const partition_t *partition, unsigned int *mode_ext2, unsigned int *carve_free_space_only);
+#endif
diff --git a/src/photorec.c b/src/photorec.c
index 9bf7f9d7..8ab7214b 100644
--- a/src/photorec.c
+++ b/src/photorec.c
@@ -74,9 +74,9 @@
#include "photorec.h"
#include "fat.h"
#include "hdcache.h"
+#include "ext2p.h"
#include "fatp.h"
#include "ntfsp.h"
-#include "ext2p.h"
#include "ewf.h"
#include "log.h"
#include "phrecn.h"
@@ -86,6 +86,7 @@
#include "misc.h"
#include "ext2_dir.h"
#include "ntfs_dir.h"
+#include "pdisksel.h"
/* #define DEBUG_FILE_FINISH */
/* #define DEBUG_UPDATE_SEARCH_SPACE */
diff --git a/src/photorec.h b/src/photorec.h
index 88968ec4..ea11a68c 100644
--- a/src/photorec.h
+++ b/src/photorec.h
@@ -1,6 +1,24 @@
-#define INTER_SELECT_X 0
-#define INTER_SELECT_Y 23
-#define INTER_SELECT 15
+/*
+
+ File: photorec.h
+
+ Copyright (C) 1998-2008 Christophe GRENIER <[email protected]>
+
+ This software is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write the Free Software Foundation, Inc., 51
+ Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+ */
#define MAX_FILES_PER_DIR 500
#define DEFAULT_RECUP_DIR "recup_dir"
diff --git a/src/phrecn.c b/src/phrecn.c
index 11fda234..1c0f1861 100644
--- a/src/phrecn.c
+++ b/src/phrecn.c
@@ -64,12 +64,14 @@
#include "file_tar.h"
#include "phcfg.h"
#include "ext2grp.h"
+#include "pdisksel.h"
+#include "pblocksize.h"
+#include "pfree_whole.h"
/* #define DEBUG */
/* #define DEBUG_GET_NEXT_SECTOR */
/* #define DEBUG_BF */
#define READ_SIZE 1024*512
-#define INTER_MENU_DISK 10
extern const file_hint_t file_hint_tar;
extern const file_hint_t file_hint_dir;
@@ -78,15 +80,11 @@ extern file_check_list_t file_check_list;
#ifdef HAVE_NCURSES
static int photorec_progressbar(WINDOW *window, const unsigned int pass, const photorec_status_t status, const uint64_t offset, disk_t *disk_car, partition_t *partition, const unsigned int file_nbr, const time_t elapsed_time, const file_stat_t *file_stats);
static void recovery_finished(const unsigned int file_nbr, const char *recup_dir, const int ind_stop, char **current_cmd);
-static int ask_mode_ext2(const disk_t *disk_car, const partition_t *partition, unsigned int *mode_ext2, unsigned int *carve_free_space_only);
#endif
static int photorec_bf(disk_t *disk_car, partition_t *partition, const int verbose, const int paranoid, const char *recup_dir, const int interface, file_stat_t *file_stats, unsigned int *file_nbr, unsigned int *blocksize, alloc_data_t *list_search_space, const time_t real_start_time, unsigned int *dir_num, const photorec_status_t status, const unsigned int pass);
static int photorec_aux(disk_t *disk_car, partition_t *partition, const int verbose, const int paranoid, const char *recup_dir, const int interface, file_stat_t *file_stats, unsigned int *file_nbr, const unsigned int blocksize, alloc_data_t *list_search_space, const time_t real_start_time, unsigned int *dir_num, const photorec_status_t status, const unsigned int pass, const unsigned int lowmem);
-static int photorec(disk_t *disk_car, partition_t *partition, const int verbose, const int paranoid, char *recup_dir, const int keep_corrupted_file, const int interface, file_enable_t *file_enable, const unsigned int mode_ext2, char **current_cmd, alloc_data_t *list_search_space, unsigned int blocksize, const unsigned int expert, const unsigned int lowmem, const unsigned int carve_free_space_only);
-static void interface_options_photorec(int *paranoid, int *allow_partial_last_cylinder, int *keep_corrupted_file, unsigned int *mode_ext2, unsigned int *expert, unsigned int *lowmem, char**current_cmd);
static int photorec_bf_aux(disk_t *disk_car, partition_t *partition, const int paranoid, const char *recup_dir, const int interface, file_stat_t *file_stats, unsigned int *file_nbr, file_recovery_t *file_recovery, unsigned int blocksize, alloc_data_t *list_search_space, alloc_data_t *current_search_space, const time_t real_start_time, unsigned int *dir_num, const photorec_status_t status);
-static void interface_file_select(file_enable_t *files_enable, char**current_cmd);
static int interface_cannot_create_file(void);
/* ==================== INLINE FUNCTIONS ========================= */
@@ -298,211 +296,6 @@ void aff_copy(WINDOW *window)
wmove(window,2,0);
wprintw(window, "http://www.cgsecurity.org");
}
-
-static int ask_mode_ext2(const disk_t *disk_car, const partition_t *partition, unsigned int *mode_ext2, unsigned int *carve_free_space_only)
-{
- static const struct MenuItem menuMode[]=
- {
- {'E',"ext2/ext3","ext2/ext3/ext4 filesystem"},
- {'O',"Other","FAT/NTFS/HFS+/ReiserFS/..."},
- {0,NULL,NULL}
- };
- static const struct MenuItem menuFAT16[]=
- {
- {'F',"Free", "Scan for files from FAT16 unallocated space only"},
- {'W',"Whole","Extract files from whole partition"},
- {0,NULL,NULL}
- };
- static const struct MenuItem menuFAT32[]=
- {
- {'F',"Free", "Scan for file from FAT32 unallocated space only"},
- {'W',"Whole","Extract files from whole partition"},
- {0,NULL,NULL}
- };
-#ifdef HAVE_LIBNTFS
- static const struct MenuItem menuNTFS[]=
- {
- {'F',"Free", "Scan for file from NTFS unallocated space only"},
- {'W',"Whole","Extract files from whole partition"},
- {0,NULL,NULL}
- };
-#endif
-#ifdef HAVE_LIBEXT2FS
- static const struct MenuItem menuEXT2[]=
- {
- {'F',"Free", "Scan for file from ext2/ext3 unallocated space only"},
- {'W',"Whole","Extract files from whole partition"},
- {0,NULL,NULL}
- };
-#endif
- const char *options="EO";
- WINDOW *window;
- unsigned int menu;
- int command;
- if(partition->upart_type==UP_EXT2 ||
- partition->upart_type==UP_EXT3 ||
- partition->upart_type==UP_EXT4)
- menu=0;
- else
- menu=1;
- window=newwin(0,0,0,0); /* full screen */
- aff_copy(window);
- wmove(window,4,0);
- aff_part(window, AFF_PART_ORDER|AFF_PART_STATUS,disk_car,partition);
- wmove(window,6,0);
- waddstr(window,"To recover lost files, PhotoRec need to know the filesystem type where the");
- wmove(window,7,0);
- waddstr(window,"file were stored:");
- command = wmenuSelect_ext(window, 24, 8, 0, menuMode, 11,
- options, MENU_VERT | MENU_VERT_WARN | MENU_BUTTON, &menu,NULL);
- *mode_ext2=(command=='E' || command=='e');
- if(*mode_ext2>0)
- {
- log_info("ext2/ext3/ext4 mode activated.\n");
- }
- /*
- if((*mode_ext2)!=0)
- return 0;
- */
- {
- menu=0;
- options="FW";
- wmove(window,6,0);
- wclrtoeol(window);
- wmove(window,7,0);
- wclrtoeol(window);
- waddstr(window,"Please choose if all space need to be analysed:");
- if(partition->upart_type==UP_FAT16)
- command = wmenuSelect_ext(window, 24, 8, 0, menuFAT16, 11,
- options, MENU_VERT | MENU_VERT_WARN | MENU_BUTTON, &menu,NULL);
- else if(partition->upart_type==UP_FAT32)
- command = wmenuSelect_ext(window, 24, 8, 0, menuFAT32, 11,
- options, MENU_VERT | MENU_VERT_WARN | MENU_BUTTON, &menu,NULL);
-#ifdef HAVE_LIBNTFS
- else if(partition->upart_type==UP_NTFS)
- command = wmenuSelect_ext(window, 24, 8, 0, menuNTFS, 11,
- options, MENU_VERT | MENU_VERT_WARN | MENU_BUTTON, &menu,NULL);
-#endif
-#ifdef HAVE_LIBEXT2FS
- else if(partition->upart_type==UP_EXT2 || partition->upart_type==UP_EXT3 || partition->upart_type==UP_EXT4)
- command = wmenuSelect_ext(window, 24, 8, 0, menuEXT2, 11,
- options, MENU_VERT | MENU_VERT_WARN | MENU_BUTTON, &menu,NULL);
-#endif
- else
- command='W';
- *carve_free_space_only=(command=='F' || command=='f')?1:0;
- if(*carve_free_space_only>0)
- {
- log_info("Carve free space only.\n");
- }
- }
- delwin(window);
- return 0;
-}
-
-static 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="S51248736";
- static const struct MenuItem menuBlocksize[]=
- {
- {'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 512: optionsBlocksize+=1; break;
- case 1024: optionsBlocksize+=2; break;
- case 2048: optionsBlocksize+=3; break;
- case 4096: optionsBlocksize+=4; break;
- case 8192: optionsBlocksize+=5; break;
- case 16384: optionsBlocksize+=6;break;
- case 32768: optionsBlocksize+=7; break;
- case 65536: optionsBlocksize+=8; break;
- }
- switch(blocksize)
- {
- case 256: menu=0; break;
- case 512: menu=1; break;
- case 1024: menu=2; break;
- case 2048: menu=3; break;
- case 4096: menu=4; break;
- case 8192: menu=5; break;
- case 16384: menu=6; break;
- case 32768: menu=7; break;
- case 65536: menu=8; 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, 24, INTER_PARTITION_Y, INTER_PARTITION_X, menuBlocksize, 7,
- optionsBlocksize, MENU_VERT| MENU_BUTTON|MENU_VERT_WARN, &menu,NULL);
- switch(command)
- {
- 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;
- }
- if(*offset%sector_size!=0 || *offset>=blocksize)
- *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);
- }
- log_info("blocksize=%u,offset=%u\n",blocksize,(unsigned int)*offset);
- return blocksize;
-}
#endif
static void set_filename(file_recovery_t *file_recovery, const char *recup_dir, const unsigned int dir_num, const disk_t *disk, const partition_t *partition, const int broken)
@@ -1403,7 +1196,7 @@ static int interface_cannot_create_file(void)
{ 'Q', "Quit", "Abort the recovery."},
{ 0,NULL,NULL}
};
- unsigned int menu=1;
+ unsigned int menu=0;
int car;
aff_copy(stdscr);
wmove(stdscr,4,0);
@@ -1412,7 +1205,7 @@ static int interface_cannot_create_file(void)
wprintw(stdscr,"This problem may be due to antivirus blocking write access while scanning files created by PhotoRec.");
wmove(stdscr,6,0);
wprintw(stdscr,"If possible, temporary disable your antivirus live protection.");
- car= wmenuSelect_ext(stdscr, 24, INTER_MAIN_Y, INTER_MAIN_X, menuMain, 10,
+ car= wmenuSelect_ext(stdscr, 23, INTER_MAIN_Y, INTER_MAIN_X, menuMain, 10,
"CQ", MENU_VERT | MENU_VERT_WARN | MENU_BUTTON, &menu,NULL);
if(car=='c' || car=='C')
return 0;
@@ -1456,7 +1249,7 @@ static file_stat_t * init_file_stats(file_enable_t *files_enable)
return file_stats;
}
-static int photorec(disk_t *disk_car, partition_t *partition, const int verbose, const int paranoid, char *recup_dir, const int keep_corrupted_file, const int interface, file_enable_t *files_enable, unsigned int mode_ext2, char **current_cmd, alloc_data_t *list_search_space, unsigned int blocksize, const unsigned int expert, const unsigned int lowmem, const unsigned int carve_free_space_only)
+int photorec(disk_t *disk_car, partition_t *partition, const int verbose, const int paranoid, char *recup_dir, const int keep_corrupted_file, const int interface, file_enable_t *files_enable, unsigned int mode_ext2, char **current_cmd, alloc_data_t *list_search_space, unsigned int blocksize, const unsigned int expert, const unsigned int lowmem, const unsigned int carve_free_space_only)
{
char *new_recup_dir=NULL;
file_stat_t *file_stats;
@@ -1667,559 +1460,6 @@ static int photorec(disk_t *disk_car, partition_t *partition, const int verbose,
return 0;
}
-static int spacerange_cmp(const struct td_list_head *a, const struct td_list_head *b)
-{
- const alloc_data_t *space_a=td_list_entry(a, const alloc_data_t, list);
- const alloc_data_t *space_b=td_list_entry(b, const alloc_data_t, list);
- if(space_a->start < space_b->start)
- return -1;
- if(space_a->start > space_b->start)
- return 1;
- return space_a->end - space_b->end;
-}
-
-enum { INIT_SPACE_WHOLE, INIT_SPACE_PREINIT, INIT_SPACE_EXT2_GROUP, INIT_SPACE_EXT2_INODE };
-
-static void menu_photorec(disk_t *disk_car, const int verbose, const char *recup_dir, file_enable_t *file_enable, char **current_cmd, alloc_data_t*list_search_space)
-{
- int insert_error=0;
- list_part_t *list_part;
- list_part_t *element;
- partition_t *partition_wd;
- list_part_t *current_element;
- int allow_partial_last_cylinder=0;
- int paranoid=1;
- int keep_corrupted_file=0;
- int current_element_num;
- unsigned int mode_ext2=0;
- unsigned int blocksize=0;
- unsigned int expert=0;
- unsigned int lowmem=0;
- unsigned int carve_free_space_only=0;
- int done=0;
- int mode_init_space=(td_list_empty(&list_search_space->list)?INIT_SPACE_WHOLE:INIT_SPACE_PREINIT);
-#ifdef HAVE_NCURSES
- int command;
- 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
- list_part=disk_car->arch->read_part(disk_car,verbose,0);
- partition_wd=new_whole_disk(disk_car);
- list_part=insert_new_partition(list_part, partition_wd, 0, &insert_error);
- if(insert_error>0)
- {
- free(partition_wd);
- }
- for(element=list_part;element!=NULL;element=element->next)
- {
- log_partition(disk_car,element->part);
- }
- if(list_part!=NULL && 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(*current_cmd!=NULL)
- {
- while(*current_cmd[0]==',')
- (*current_cmd)++;
- if(*current_cmd[0]=='\0')
- {
- part_free_list(list_part);
- return;
- }
- if(strncmp(*current_cmd,"search",6)==0)
- {
- char *res;
- (*current_cmd)+=6;
- if(recup_dir!=NULL)
- res=recup_dir;
- else
- {
- res=ask_location("Do you want to save recovered files in %s%s ? [Y/N]\nDo not choose to write the files to the same partition they were stored on.","");
- if(res!=NULL)
- {
- char *new_recup_dir=(char *)MALLOC(strlen(res)+1+strlen(DEFAULT_RECUP_DIR)+1);
- strcpy(new_recup_dir,res);
- strcat(new_recup_dir,"/");
- strcat(new_recup_dir,DEFAULT_RECUP_DIR);
- if(res!=recup_dir)
- free(res);
- res=new_recup_dir;
- }
- }
- if(res!=NULL)
- {
- partition_t *partition=current_element->part;
- if(mode_init_space==INIT_SPACE_EXT2_GROUP)
- {
- blocksize=ext2_fix_group(list_search_space, disk_car, partition);
- }
- else if(mode_init_space==INIT_SPACE_EXT2_INODE)
- {
- blocksize=ext2_fix_inode(list_search_space, disk_car, partition);
- }
- if(td_list_empty(&list_search_space->list))
- {
- init_search_space(list_search_space, disk_car, partition);
- }
- if(carve_free_space_only>0)
- {
- blocksize=remove_used_space(disk_car, partition, list_search_space);
- }
- photorec(disk_car, partition, verbose, paranoid, res, keep_corrupted_file,1,file_enable,mode_ext2,current_cmd,list_search_space,blocksize,expert, lowmem, carve_free_space_only);
- }
- if(res!=recup_dir)
- free(res);
- }
- else if(strncmp(*current_cmd,"options",7)==0)
- {
- int old_allow_partial_last_cylinder=allow_partial_last_cylinder;
- (*current_cmd)+=7;
- interface_options_photorec(&paranoid, &allow_partial_last_cylinder,
- &keep_corrupted_file, &mode_ext2, &expert, &lowmem, current_cmd);
- if(old_allow_partial_last_cylinder!=allow_partial_last_cylinder)
- hd_update_geometry(disk_car,allow_partial_last_cylinder,verbose);
- }
- else if(strncmp(*current_cmd,"fileopt",7)==0)
- {
- (*current_cmd)+=7;
- interface_file_select(file_enable,current_cmd);
- }
- else if(strncmp(*current_cmd,"blocksize,",10)==0)
- {
- (*current_cmd)+=10;
- blocksize=atoi(*current_cmd);
- while(*current_cmd[0]!=',' && *current_cmd[0]!='\0')
- (*current_cmd)++;
- }
- else if(strncmp(*current_cmd,"geometry,",9)==0)
- {
- (*current_cmd)+=9;
- change_geometry(disk_car,current_cmd);
- }
- else if(strncmp(*current_cmd,"inter",5)==0)
- { /* Start interactive mode */
- *current_cmd=NULL;
- }
- else if(strncmp(*current_cmd,"wholespace",10)==0)
- {
- (*current_cmd)+=10;
- carve_free_space_only=0;
- }
- else if(strncmp(*current_cmd,"freespace",9)==0)
- {
- (*current_cmd)+=9;
- carve_free_space_only=1;
- }
- else if(strncmp(*current_cmd,"ext2_group,",11)==0)
- {
- unsigned int groupnr;
- (*current_cmd)+=11;
- mode_ext2=1;
- groupnr=atoi(*current_cmd);
- while(*current_cmd[0]!=',' && *current_cmd[0]!='\0')
- (*current_cmd)++;
- 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;
- if(td_list_add_sorted_uniq(&new_free_space->list, &list_search_space->list, spacerange_cmp))
- free(new_free_space);
- }
- }
- else if(strncmp(*current_cmd,"ext2_inode,",11)==0)
- {
- unsigned int inodenr;
- (*current_cmd)+=11;
- mode_ext2=1;
- inodenr=atoi(*current_cmd);
- while(*current_cmd[0]!=',' && *current_cmd[0]!='\0')
- (*current_cmd)++;
- 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;
- if(td_list_add_sorted_uniq(&new_free_space->list, &list_search_space->list, spacerange_cmp))
- free(new_free_space);
- }
- }
- else if(isdigit(*current_cmd[0]))
- {
- unsigned int order;
- order= atoi(*current_cmd);
- while(*current_cmd[0]!=',' && *current_cmd[0]!='\0')
- (*current_cmd)++;
- for(element=list_part;element!=NULL && element->part->order!=order;element=element->next);
- if(element!=NULL)
- current_element=element;
- }
- else
- {
- log_critical("error >%s<\n",*current_cmd);
- while(*current_cmd[0]!='\0')
- (*current_cmd)++;
- part_free_list(list_part);
- return;
- }
- }
-#ifdef HAVE_NCURSES
- else
- { /* ncurses interface */
- unsigned int i;
- aff_copy(stdscr);
- wmove(stdscr,4,0);
- wprintw(stdscr,"%s",disk_car->description_short(disk_car));
- mvwaddstr(stdscr,6,0,msg_PART_HEADER_LONG);
- for(i=0,element=list_part;(element!=NULL) && (i<offset);element=element->next,i++);
- for(i=offset;(element!=NULL) && ((i-offset)<INTER_SELECT);i++,element=element->next)
- {
- wmove(stdscr,5+2+i-offset,0);
- wclrtoeol(stdscr); /* before addstr for BSD compatibility */
- if(element==current_element)
- {
- wattrset(stdscr, A_REVERSE);
- aff_part(stdscr,AFF_PART_ORDER|AFF_PART_STATUS,disk_car,element->part);
- wattroff(stdscr, A_REVERSE);
- } else
- {
- aff_part(stdscr,AFF_PART_ORDER|AFF_PART_STATUS,disk_car,element->part);
- }
- }
- command = wmenuSelect(stdscr, 24, INTER_SELECT_Y, INTER_SELECT_X, menuMain, 8,
- (expert==0?"SOFQ":"SOFGQ"), MENU_HORIZ | MENU_BUTTON | MENU_ACCEPT_OTHERS, menu);
- 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; 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; 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)
- {
- char *res;
- partition_t *partition=current_element->part;
- ask_mode_ext2(disk_car, partition, &mode_ext2, &carve_free_space_only);
- menu=0;
- if(recup_dir!=NULL)
- res=recup_dir;
- else
- {
- res=ask_location("Do you want to save recovered files in %s%s ? [Y/N]\nDo not choose to write the files to the same partition they were stored on.","");
- if(res!=NULL)
- {
- char *new_recup_dir=(char *)MALLOC(strlen(res)+1+strlen(DEFAULT_RECUP_DIR)+1);
- strcpy(new_recup_dir,res);
- strcat(new_recup_dir,"/");
- strcat(new_recup_dir,DEFAULT_RECUP_DIR);
- if(res!=recup_dir)
- free(res);
- res=new_recup_dir;
- }
- }
- if(res!=NULL)
- {
- if(td_list_empty(&list_search_space->list))
- {
- init_search_space(list_search_space, disk_car, partition);
- }
- if(carve_free_space_only>0)
- {
- blocksize=remove_used_space(disk_car, partition, list_search_space);
- }
- photorec(disk_car, partition, verbose, paranoid, res, keep_corrupted_file,1,file_enable,mode_ext2, current_cmd, list_search_space,blocksize,expert, lowmem, carve_free_space_only);
- }
- if(res!=recup_dir)
- free(res);
- }
- break;
- case 'o':
- case 'O':
- {
- int old_allow_partial_last_cylinder=allow_partial_last_cylinder;
- interface_options_photorec(&paranoid, &allow_partial_last_cylinder,
- &keep_corrupted_file, &mode_ext2, &expert, &lowmem, current_cmd);
- if(old_allow_partial_last_cylinder!=allow_partial_last_cylinder)
- hd_update_geometry(disk_car,allow_partial_last_cylinder,verbose);
- menu=1;
- }
- break;
- case 'f':
- case 'F':
- interface_file_select(file_enable, current_cmd);
- menu=2;
- break;
- case 'g':
- case 'G':
- if(expert!=0)
- change_geometry(disk_car, current_cmd);
- 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);
-}
-
-#ifdef HAVE_NCURSES
-static void photorec_disk_selection_ncurses(int verbose, const char *recup_dir, const list_disk_t *list_disk, file_enable_t *file_enable)
-{
- char * current_cmd=NULL;
- int command;
- int real_key;
- int done=0;
- unsigned int menu=0;
- int offset=0;
- int pos_num=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",""},
- { 'Q',"Quit","Quit program"},
- { 0,NULL,NULL}
- };
- static alloc_data_t list_search_space={
- .list = TD_LIST_HEAD_INIT(list_search_space.list)
- };
- /* ncurses interface */
- while(done==0)
- {
- const char *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):");
- for(i=0,element_disk=list_disk;(element_disk!=NULL) && (i<offset);element_disk=element_disk->next,i++);
- for(;element_disk!=NULL && (i-offset)<10;i++,element_disk=element_disk->next)
- {
- 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);
- }
- }
- if(i<=10 && element_disk==NULL)
- options="OQ";
- else
- options="PNOQ";
- {
- int line=20;
-#if defined(__CYGWIN__) || defined(__MINGW32__)
-#else
-#ifndef DJGPP
-#ifdef HAVE_GETEUID
- if(geteuid()!=0)
- {
- wmove(stdscr,line++,0);
- wprintw(stdscr,"Note: Some disks won't appear unless you're root user.");
- }
-#endif
-#endif
-#endif
- wmove(stdscr,line++,0);
- if(line==22)
- wprintw(stdscr,"Disk capacity must be correctly detected for a successful recovery.");
- else
- wprintw(stdscr,"Note: 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.");
- }
- command = wmenuSelect_ext(stdscr, 24, INTER_MAIN_Y, INTER_MAIN_X, menuMain, 8,
- options, MENU_HORIZ | MENU_BUTTON | MENU_ACCEPT_OTHERS, &menu,&real_key);
- 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<INTER_MENU_DISK && current_disk->prev!=NULL;i++)
- {
- current_disk=current_disk->prev;
- pos_num--;
- }
- break;
- case KEY_NPAGE:
- for(i=0;i<INTER_MENU_DISK && current_disk->next!=NULL;i++)
- {
- current_disk=current_disk->next;
- pos_num++;
- }
- break;
- case 'o':
- case 'O':
- {
- disk_t *disk=current_disk->disk;
- autodetect_arch(disk);
- if(interface_partition_type(disk, verbose, &current_cmd)==0)
- menu_photorec(disk, verbose, recup_dir, file_enable, &current_cmd, &list_search_space);
- }
- break;
- case 'q':
- case 'Q':
- done=1;
- break;
- }
- if(pos_num<offset)
- offset=pos_num;
- if(pos_num>=offset+INTER_MENU_DISK)
- offset=pos_num-INTER_MENU_DISK+1;
- }
-}
-#endif
-
-int do_curses_photorec(int verbose, const char *recup_dir, const list_disk_t *list_disk, file_enable_t *file_enable, char *cmd_device, char **current_cmd)
-{
- static alloc_data_t list_search_space={
- .list = TD_LIST_HEAD_INIT(list_search_space.list)
- };
- if(list_disk==NULL)
- {
- return intrf_no_disk("PhotoRec");
- }
- if(cmd_device==NULL)
- {
- char *saved_device=NULL;
- char *saved_cmd=NULL;
- session_load(&saved_device, &saved_cmd,&list_search_space);
- if(saved_device!=NULL && saved_cmd!=NULL && !td_list_empty(&list_search_space.list) && ask_confirmation("Continue previous session ? (Y/N)")!=0)
- {
- /* yes */
- *current_cmd=saved_cmd;
- cmd_device=saved_device;
- }
- else
- {
- free(saved_device);
- free(saved_cmd);
- free_list_search_space(&list_search_space);
- }
- }
- if(cmd_device!=NULL && *current_cmd!=NULL)
- {
- const list_disk_t *element_disk;
- disk_t *disk=NULL;
- for(element_disk=list_disk;element_disk!=NULL;element_disk=element_disk->next)
- {
- if(strcmp(element_disk->disk->device,cmd_device)==0)
- disk=element_disk->disk;
- }
- if(disk==NULL)
- {
- return intrf_no_disk("PhotoRec");
- }
- {
- /* disk sector size is now known, fix the sector ranges */
- struct td_list_head *search_walker = NULL;
- td_list_for_each(search_walker, &list_search_space.list)
- {
- alloc_data_t *current_search_space;
- current_search_space=td_list_entry(search_walker, alloc_data_t, list);
- current_search_space->start=current_search_space->start*disk->sector_size;
- current_search_space->end=current_search_space->end*disk->sector_size+disk->sector_size-1;
- }
- }
- autodetect_arch(disk);
- if(interface_partition_type(disk, verbose, current_cmd)==0)
- menu_photorec(disk, verbose, recup_dir, file_enable, current_cmd, &list_search_space);
- }
- else
- {
-#ifdef HAVE_NCURSES
- photorec_disk_selection_ncurses(verbose, recup_dir, list_disk, file_enable);
-#endif
- }
- log_info("\n");
- return 0;
-}
-
#ifdef HAVE_NCURSES
static void interface_options_photorec_ncurses(int *paranoid, int *allow_partial_last_cylinder, int *keep_corrupted_file, unsigned int *mode_ext2, unsigned int *expert, unsigned int *lowmem)
{
@@ -2268,7 +1508,7 @@ static void interface_options_photorec_ncurses(int *paranoid, int *allow_partial
*/
aff_copy(stdscr);
- car=wmenuSelect_ext(stdscr, 24, INTER_OPTION_Y, INTER_OPTION_X, menuOptions, 0, "PAKELQ", MENU_VERT|MENU_VERT_ARROW2VALID, &menu,&real_key);
+ car=wmenuSelect_ext(stdscr, 23, INTER_OPTION_Y, INTER_OPTION_X, menuOptions, 0, "PAKELQ", MENU_VERT|MENU_VERT_ARROW2VALID, &menu,&real_key);
switch(car)
{
case 'p':
@@ -2307,7 +1547,7 @@ static void interface_options_photorec_ncurses(int *paranoid, int *allow_partial
}
#endif
-static void interface_options_photorec(int *paranoid, int *allow_partial_last_cylinder, int *keep_corrupted_file, unsigned int *mode_ext2, unsigned int *expert, unsigned int *lowmem, char **current_cmd)
+void interface_options_photorec(int *paranoid, int *allow_partial_last_cylinder, int *keep_corrupted_file, unsigned int *mode_ext2, unsigned int *expert, unsigned int *lowmem, char **current_cmd)
{
if(*current_cmd!=NULL)
{
@@ -2385,8 +1625,8 @@ static void interface_options_photorec(int *paranoid, int *allow_partial_last_cy
#ifdef HAVE_NCURSES
#define INTER_FSELECT_X 0
-#define INTER_FSELECT_Y LINES-2
-#define INTER_FSELECT LINES-10
+#define INTER_FSELECT_Y (LINES-2)
+#define INTER_FSELECT (LINES-10)
static void interface_file_select_ncurses(file_enable_t *files_enable)
{
@@ -2429,7 +1669,8 @@ static void interface_file_select_ncurses(file_enable_t *files_enable)
files_enable[i].file_hint->extension:""),
files_enable[i].file_hint->description);
wattroff(stdscr, A_REVERSE);
- } else
+ }
+ else
{
wprintw(stdscr,"[%c] %-4s %s", (files_enable[i].enable==0?' ':'X'),
(files_enable[i].file_hint->extension!=NULL?
@@ -2532,7 +1773,7 @@ static void interface_file_select_ncurses(file_enable_t *files_enable)
}
#endif
-static void interface_file_select(file_enable_t *files_enable, char**current_cmd)
+void interface_file_select(file_enable_t *files_enable, char**current_cmd)
{
log_info("\nInterface File Select\n");
if(*current_cmd!=NULL)
@@ -2616,5 +1857,3 @@ void bug(void)
log_critical("bug\n");
}
#endif
-
-
diff --git a/src/phrecn.h b/src/phrecn.h
index 67cc1c28..acb2e43a 100644
--- a/src/phrecn.h
+++ b/src/phrecn.h
@@ -19,5 +19,7 @@
Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
-int do_curses_photorec(int verbose, const char *recup_dir, const list_disk_t *list_disk, file_enable_t *file_enable, char *cmd_device, char**cmd_run);
+int photorec(disk_t *disk_car, partition_t *partition, const int verbose, const int paranoid, char *recup_dir, const int keep_corrupted_file, const int interface, file_enable_t *file_enable, const unsigned int mode_ext2, char **current_cmd, alloc_data_t *list_search_space, unsigned int blocksize, const unsigned int expert, const unsigned int lowmem, const unsigned int carve_free_space_only);
+void interface_file_select(file_enable_t *files_enable, char**current_cmd);
+void interface_options_photorec(int *paranoid, int *allow_partial_last_cylinder, int *keep_corrupted_file, unsigned int *mode_ext2, unsigned int *expert, unsigned int *lowmem, char**current_cmd);
void free_search_space(alloc_data_t *list_search_space);
diff --git a/src/ppartsel.c b/src/ppartsel.c
new file mode 100644
index 00000000..56d3d2af
--- /dev/null
+++ b/src/ppartsel.c
@@ -0,0 +1,420 @@
+/*
+
+ File: ppartsel.c
+
+ Copyright (C) 1998-2008 Christophe GRENIER <[email protected]>
+
+ This software is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write the Free Software Foundation, Inc., 51
+ Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+#include <ctype.h> /* isdigit */
+#include "types.h"
+#include "common.h"
+#include "intrf.h"
+#ifdef HAVE_NCURSES
+#include "intrfn.h"
+#else
+#include <stdio.h>
+#endif
+#include "fnctdsk.h"
+#include "dir.h"
+#include "list.h"
+#include "chgtype.h"
+#include "lang.h"
+#include "filegen.h"
+#include "photorec.h"
+#include "phrecn.h"
+#include "log.h"
+#include "hdaccess.h"
+#include "ext2grp.h"
+#include "pfree_whole.h"
+#include "ppartsel.h"
+
+enum { INIT_SPACE_WHOLE, INIT_SPACE_PREINIT, INIT_SPACE_EXT2_GROUP, INIT_SPACE_EXT2_INODE };
+
+static int spacerange_cmp(const struct td_list_head *a, const struct td_list_head *b)
+{
+ const alloc_data_t *space_a=td_list_entry(a, const alloc_data_t, list);
+ const alloc_data_t *space_b=td_list_entry(b, const alloc_data_t, list);
+ if(space_a->start < space_b->start)
+ return -1;
+ if(space_a->start > space_b->start)
+ return 1;
+ return space_a->end - space_b->end;
+}
+
+#ifdef HAVE_NCURSES
+#define INTER_SELECT_X 0
+#define INTER_SELECT_Y (LINES-2)
+#define INTER_SELECT (LINES-2-7-1)
+#endif
+
+void menu_photorec(disk_t *disk_car, const int verbose, const char *recup_dir, file_enable_t *file_enable, char **current_cmd, alloc_data_t*list_search_space)
+{
+ int insert_error=0;
+ list_part_t *list_part;
+ list_part_t *element;
+ partition_t *partition_wd;
+ list_part_t *current_element;
+ int allow_partial_last_cylinder=0;
+ int paranoid=1;
+ int keep_corrupted_file=0;
+ int current_element_num;
+ unsigned int mode_ext2=0;
+ unsigned int blocksize=0;
+ unsigned int expert=0;
+ unsigned int lowmem=0;
+ unsigned int carve_free_space_only=0;
+ int done=0;
+ int mode_init_space=(td_list_empty(&list_search_space->list)?INIT_SPACE_WHOLE:INIT_SPACE_PREINIT);
+#ifdef HAVE_NCURSES
+ int command;
+ 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
+ list_part=disk_car->arch->read_part(disk_car,verbose,0);
+ partition_wd=new_whole_disk(disk_car);
+ list_part=insert_new_partition(list_part, partition_wd, 0, &insert_error);
+ if(insert_error>0)
+ {
+ free(partition_wd);
+ }
+ for(element=list_part;element!=NULL;element=element->next)
+ {
+ log_partition(disk_car,element->part);
+ }
+ if(list_part!=NULL && 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(*current_cmd!=NULL)
+ {
+ while(*current_cmd[0]==',')
+ (*current_cmd)++;
+ if(*current_cmd[0]=='\0')
+ {
+ part_free_list(list_part);
+ return;
+ }
+ if(strncmp(*current_cmd,"search",6)==0)
+ {
+ char *res;
+ (*current_cmd)+=6;
+ if(recup_dir!=NULL)
+ res=recup_dir;
+ else
+ {
+ res=ask_location("Do you want to save recovered files in %s%s ? [Y/N]\nDo not choose to write the files to the same partition they were stored on.","");
+ if(res!=NULL)
+ {
+ char *new_recup_dir=(char *)MALLOC(strlen(res)+1+strlen(DEFAULT_RECUP_DIR)+1);
+ strcpy(new_recup_dir,res);
+ strcat(new_recup_dir,"/");
+ strcat(new_recup_dir,DEFAULT_RECUP_DIR);
+ if(res!=recup_dir)
+ free(res);
+ res=new_recup_dir;
+ }
+ }
+ if(res!=NULL)
+ {
+ partition_t *partition=current_element->part;
+ if(mode_init_space==INIT_SPACE_EXT2_GROUP)
+ {
+ blocksize=ext2_fix_group(list_search_space, disk_car, partition);
+ }
+ else if(mode_init_space==INIT_SPACE_EXT2_INODE)
+ {
+ blocksize=ext2_fix_inode(list_search_space, disk_car, partition);
+ }
+ if(td_list_empty(&list_search_space->list))
+ {
+ init_search_space(list_search_space, disk_car, partition);
+ }
+ if(carve_free_space_only>0)
+ {
+ blocksize=remove_used_space(disk_car, partition, list_search_space);
+ }
+ photorec(disk_car, partition, verbose, paranoid, res, keep_corrupted_file,1,file_enable,mode_ext2,current_cmd,list_search_space,blocksize,expert, lowmem, carve_free_space_only);
+ }
+ if(res!=recup_dir)
+ free(res);
+ }
+ else if(strncmp(*current_cmd,"options",7)==0)
+ {
+ int old_allow_partial_last_cylinder=allow_partial_last_cylinder;
+ (*current_cmd)+=7;
+ interface_options_photorec(&paranoid, &allow_partial_last_cylinder,
+ &keep_corrupted_file, &mode_ext2, &expert, &lowmem, current_cmd);
+ if(old_allow_partial_last_cylinder!=allow_partial_last_cylinder)
+ hd_update_geometry(disk_car,allow_partial_last_cylinder,verbose);
+ }
+ else if(strncmp(*current_cmd,"fileopt",7)==0)
+ {
+ (*current_cmd)+=7;
+ interface_file_select(file_enable,current_cmd);
+ }
+ else if(strncmp(*current_cmd,"blocksize,",10)==0)
+ {
+ (*current_cmd)+=10;
+ blocksize=atoi(*current_cmd);
+ while(*current_cmd[0]!=',' && *current_cmd[0]!='\0')
+ (*current_cmd)++;
+ }
+ else if(strncmp(*current_cmd,"geometry,",9)==0)
+ {
+ (*current_cmd)+=9;
+ change_geometry(disk_car,current_cmd);
+ }
+ else if(strncmp(*current_cmd,"inter",5)==0)
+ { /* Start interactive mode */
+ *current_cmd=NULL;
+ }
+ else if(strncmp(*current_cmd,"wholespace",10)==0)
+ {
+ (*current_cmd)+=10;
+ carve_free_space_only=0;
+ }
+ else if(strncmp(*current_cmd,"freespace",9)==0)
+ {
+ (*current_cmd)+=9;
+ carve_free_space_only=1;
+ }
+ else if(strncmp(*current_cmd,"ext2_group,",11)==0)
+ {
+ unsigned int groupnr;
+ (*current_cmd)+=11;
+ mode_ext2=1;
+ groupnr=atoi(*current_cmd);
+ while(*current_cmd[0]!=',' && *current_cmd[0]!='\0')
+ (*current_cmd)++;
+ 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;
+ if(td_list_add_sorted_uniq(&new_free_space->list, &list_search_space->list, spacerange_cmp))
+ free(new_free_space);
+ }
+ }
+ else if(strncmp(*current_cmd,"ext2_inode,",11)==0)
+ {
+ unsigned int inodenr;
+ (*current_cmd)+=11;
+ mode_ext2=1;
+ inodenr=atoi(*current_cmd);
+ while(*current_cmd[0]!=',' && *current_cmd[0]!='\0')
+ (*current_cmd)++;
+ 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;
+ if(td_list_add_sorted_uniq(&new_free_space->list, &list_search_space->list, spacerange_cmp))
+ free(new_free_space);
+ }
+ }
+ else if(isdigit(*current_cmd[0]))
+ {
+ unsigned int order;
+ order= atoi(*current_cmd);
+ while(*current_cmd[0]!=',' && *current_cmd[0]!='\0')
+ (*current_cmd)++;
+ for(element=list_part;element!=NULL && element->part->order!=order;element=element->next);
+ if(element!=NULL)
+ current_element=element;
+ }
+ else
+ {
+ log_critical("error >%s<\n",*current_cmd);
+ while(*current_cmd[0]!='\0')
+ (*current_cmd)++;
+ part_free_list(list_part);
+ return;
+ }
+ }
+#ifdef HAVE_NCURSES
+ else
+ { /* ncurses interface */
+ unsigned int i;
+ aff_copy(stdscr);
+ wmove(stdscr,4,0);
+ wprintw(stdscr,"%s",disk_car->description_short(disk_car));
+ mvwaddstr(stdscr,6,0,msg_PART_HEADER_LONG);
+ 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);
+ aff_part(stdscr,AFF_PART_ORDER|AFF_PART_STATUS,disk_car,element->part);
+ wattroff(stdscr, A_REVERSE);
+ } else
+ {
+ aff_part(stdscr,AFF_PART_ORDER|AFF_PART_STATUS,disk_car,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,
+ (expert==0?"SOFQ":"SOFGQ"), MENU_HORIZ | MENU_BUTTON | MENU_ACCEPT_OTHERS, menu);
+ 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; 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; 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)
+ {
+ char *res;
+ partition_t *partition=current_element->part;
+ ask_mode_ext2(disk_car, partition, &mode_ext2, &carve_free_space_only);
+ menu=0;
+ if(recup_dir!=NULL)
+ res=recup_dir;
+ else
+ {
+ res=ask_location("Do you want to save recovered files in %s%s ? [Y/N]\nDo not choose to write the files to the same partition they were stored on.","");
+ if(res!=NULL)
+ {
+ char *new_recup_dir=(char *)MALLOC(strlen(res)+1+strlen(DEFAULT_RECUP_DIR)+1);
+ strcpy(new_recup_dir,res);
+ strcat(new_recup_dir,"/");
+ strcat(new_recup_dir,DEFAULT_RECUP_DIR);
+ if(res!=recup_dir)
+ free(res);
+ res=new_recup_dir;
+ }
+ }
+ if(res!=NULL)
+ {
+ if(td_list_empty(&list_search_space->list))
+ {
+ init_search_space(list_search_space, disk_car, partition);
+ }
+ if(carve_free_space_only>0)
+ {
+ blocksize=remove_used_space(disk_car, partition, list_search_space);
+ }
+ photorec(disk_car, partition, verbose, paranoid, res, keep_corrupted_file,1,file_enable,mode_ext2, current_cmd, list_search_space,blocksize,expert, lowmem, carve_free_space_only);
+ }
+ if(res!=recup_dir)
+ free(res);
+ }
+ break;
+ case 'o':
+ case 'O':
+ {
+ int old_allow_partial_last_cylinder=allow_partial_last_cylinder;
+ interface_options_photorec(&paranoid, &allow_partial_last_cylinder,
+ &keep_corrupted_file, &mode_ext2, &expert, &lowmem, current_cmd);
+ if(old_allow_partial_last_cylinder!=allow_partial_last_cylinder)
+ hd_update_geometry(disk_car,allow_partial_last_cylinder,verbose);
+ menu=1;
+ }
+ break;
+ case 'f':
+ case 'F':
+ interface_file_select(file_enable, current_cmd);
+ menu=2;
+ break;
+ case 'g':
+ case 'G':
+ if(expert!=0)
+ change_geometry(disk_car, current_cmd);
+ 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);
+}
diff --git a/src/ppartsel.h b/src/ppartsel.h
new file mode 100644
index 00000000..0ece3d2a
--- /dev/null
+++ b/src/ppartsel.h
@@ -0,0 +1,24 @@
+/*
+
+ File: ppartsel.h
+
+ Copyright (C) 2008 Christophe GRENIER <[email protected]>
+
+ This software is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write the Free Software Foundation, Inc., 51
+ Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+ */
+void menu_photorec(disk_t *disk_car, const int verbose, const char *recup_dir, file_enable_t *file_enable, char **current_cmd, alloc_data_t*list_search_space);
+
+
diff --git a/src/tdelete.c b/src/tdelete.c
index 20197802..26d99f21 100644
--- a/src/tdelete.c
+++ b/src/tdelete.c
@@ -32,6 +32,7 @@
#else
#include <stdio.h>
#endif
+#include "log.h"
#include "tdelete.h"
#ifdef HAVE_NCURSES
diff --git a/src/tdiskop.c b/src/tdiskop.c
index 939637c6..e6662b73 100644
--- a/src/tdiskop.c
+++ b/src/tdiskop.c
@@ -171,7 +171,7 @@ static int menu_disk_ncurses(disk_t *disk_car, const int verbose,int dump_ind, c
wprintw(stdscr,"Note: Correct disk geometry is required for a successful recovery. 'Analyse'");
wmove(stdscr,21,0);
wprintw(stdscr,"process may give some warnings if it thinks the logical geometry is mismatched.");
- command = wmenuSelect_ext(stdscr, 24, INTER_DISK_Y, INTER_DISK_X, menuMain, 10,
+ command = wmenuSelect_ext(stdscr, 23, INTER_DISK_Y, INTER_DISK_X, menuMain, 10,
options, MENU_VERT | MENU_VERT_WARN | MENU_BUTTON | MENU_ACCEPT_OTHERS, &menu,&real_key);
/* e for editor will be added when the editor will be better */
switch(command)
diff --git a/src/tdisksel.c b/src/tdisksel.c
index eddf12d1..528dba1e 100644
--- a/src/tdisksel.c
+++ b/src/tdisksel.c
@@ -48,7 +48,11 @@
#include "tdisksel.h"
#ifdef HAVE_NCURSES
-#define NBR_DISK_MAX 10
+#define NBR_DISK_MAX (LINES-6-8)
+#define INTER_DISK_X 0
+#define INTER_DISK_Y (8+NBR_DISK_MAX)
+#define INTER_NOTE_Y (LINES-4)
+
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';
@@ -84,9 +88,12 @@ static int testdisk_disk_selection_ncurses(int verbose,int dump_ind, const list_
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);element_disk=element_disk->next,i++);
- for(;element_disk!=NULL && (i-offset)<NBR_DISK_MAX;i++,element_disk=element_disk->next)
+ 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));
@@ -102,7 +109,7 @@ static int testdisk_disk_selection_ncurses(int verbose,int dump_ind, const list_
else
options="PNOQ";
{
- int line=20;
+ int line=INTER_NOTE_Y;
mvwaddstr(stdscr,line++,0,"Note: ");
#if defined(__CYGWIN__) || defined(__MINGW32__) || defined(DJGPP)
#else
@@ -124,7 +131,7 @@ static int testdisk_disk_selection_ncurses(int verbose,int dump_ind, const list_
wmove(stdscr,line++,0);
wprintw(stdscr,"detection, and install the latest OS patches and disk drivers.");
}
- command = wmenuSelect_ext(stdscr, LINES-1, INTER_MAIN_Y, INTER_MAIN_X, menuMain, 8,
+ 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)
{
diff --git a/src/thfs.c b/src/thfs.c
new file mode 100644
index 00000000..4d0485ed
--- /dev/null
+++ b/src/thfs.c
@@ -0,0 +1,245 @@
+/*
+
+ File: thfs.c
+
+ Copyright (C) 2008 Christophe GRENIER <[email protected]>
+
+ This software is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write the Free Software Foundation, Inc., 51
+ Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+ */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+#include <ctype.h>
+#include "types.h"
+#include "common.h"
+#include "lang.h"
+#include "intrf.h"
+#include "intrfn.h"
+#include "hfs.h"
+#include "hfsp.h"
+#include "log.h"
+#include "thfs.h"
+
+#ifdef HAVE_NCURSES
+static void hfs_dump_ncurses(disk_t *disk_car, const partition_t *partition, const unsigned char *buffer_bs, const unsigned char *buffer_backup_bs)
+{
+ WINDOW *window=newwin(0,0,0,0); /* full screen */
+ keypad(window, TRUE); /* Need it to get arrow key */
+ aff_copy(window);
+ wmove(window,4,0);
+ wprintw(window,"%s",disk_car->description(disk_car));
+ wmove(window,5,0);
+ aff_part(window,AFF_PART_ORDER|AFF_PART_STATUS,disk_car,partition);
+ mvwaddstr(window,6,0, "Superblock Backup superblock");
+ dump2(window, buffer_bs, buffer_backup_bs, HFSP_BOOT_SECTOR_SIZE);
+ delwin(window);
+ (void) clearok(stdscr, TRUE);
+#ifdef HAVE_TOUCHWIN
+ touchwin(stdscr);
+#endif
+}
+#endif
+
+static void hfs_dump(disk_t *disk_car, const partition_t *partition, const unsigned char *buffer_bs, const unsigned char *buffer_backup_bs)
+{
+ log_info("Superblock Backup superblock\n");
+ dump2_log(buffer_bs, buffer_backup_bs, HFSP_BOOT_SECTOR_SIZE);
+#ifdef HAVE_NCURSES
+ hfs_dump_ncurses(disk_car, partition, buffer_bs, buffer_backup_bs);
+#endif
+}
+
+int HFS_HFSP_boot_sector(disk_t *disk_car, partition_t *partition, const int verbose, const int dump_ind, const unsigned int expert, char **current_cmd)
+{
+ unsigned char *buffer_bs;
+ unsigned char *buffer_backup_bs;
+ const char *options="";
+ int rescan=1;
+#ifdef HAVE_NCURSES
+ struct MenuItem menu_hfsp[]=
+ {
+ { 'P', "Previous",""},
+ { 'N', "Next","" },
+ { 'Q', "Quit","Return to Advanced menu"},
+ { 'O', "Org. BS","Copy superblock over backup sector"},
+ { 'B', "Backup BS","Copy backup superblock over superblock"},
+ { 'D', "Dump","Dump superblock and backup superblock"},
+ { 0, NULL, NULL }
+ };
+#endif
+ buffer_bs=(unsigned char*)MALLOC(HFSP_BOOT_SECTOR_SIZE);
+ buffer_backup_bs=(unsigned char*)MALLOC(HFSP_BOOT_SECTOR_SIZE);
+
+ while(1)
+ {
+#ifdef HAVE_NCURSES
+ unsigned int menu=0;
+#endif
+ int command;
+ screen_buffer_reset();
+ if(rescan==1)
+ {
+ int opt_over=0;
+ int opt_B=0;
+ int opt_O=0;
+ options="D";
+#ifdef HAVE_NCURSES
+ aff_copy(stdscr);
+ wmove(stdscr,4,0);
+ wprintw(stdscr,"%s",disk_car->description(disk_car));
+ mvwaddstr(stdscr,5,0,msg_PART_HEADER_LONG);
+ wmove(stdscr,6,0);
+ aff_part(stdscr,AFF_PART_ORDER|AFF_PART_STATUS,disk_car,partition);
+#endif
+ log_info("\nHFS_HFSP_boot_sector\n");
+ log_partition(disk_car,partition);
+ screen_buffer_add("Volume header\n");
+ if(disk_car->read(disk_car,HFSP_BOOT_SECTOR_SIZE, buffer_bs, partition->part_offset+0x400)!=0)
+ {
+ screen_buffer_add("Bad: can't read HFS/HFS+ volume header.\n");
+ memset(buffer_bs,0,HFSP_BOOT_SECTOR_SIZE);
+ }
+ else if(test_HFSP(disk_car,(const struct hfsp_vh*)buffer_bs,partition,verbose,0)==0)
+ {
+ screen_buffer_add("HFS+ OK\n");
+ opt_O=1;
+ opt_over=1;
+ }
+ else if(test_HFS(disk_car,(const hfs_mdb_t*)buffer_bs,partition,verbose,0)==0)
+ {
+ screen_buffer_add("HFS Ok\n");
+ opt_O=1;
+ opt_over=1;
+ }
+ else
+ screen_buffer_add("Bad\n");
+ screen_buffer_add("\nBackup volume header\n");
+ if(disk_car->read(disk_car,HFSP_BOOT_SECTOR_SIZE, buffer_backup_bs, partition->part_offset+partition->part_size-0x400)!=0)
+ {
+ screen_buffer_add("Bad: can't read HFS/HFS+ backup volume header.\n");
+ memset(buffer_backup_bs,0,HFSP_BOOT_SECTOR_SIZE);
+ }
+ else if(test_HFSP(disk_car,(const struct hfsp_vh*)buffer_backup_bs,partition,verbose,0)==0)
+ {
+ screen_buffer_add("HFS+ OK\n");
+ opt_B=1;
+ opt_over=1;
+ }
+ else if(test_HFS(disk_car,(const hfs_mdb_t*)buffer_backup_bs,partition,verbose,0)==0)
+ {
+ screen_buffer_add("HFS Ok\n");
+ opt_B=1;
+ opt_over=1;
+ }
+ else
+ screen_buffer_add("Bad\n");
+ screen_buffer_add("\n");
+ if(memcmp(buffer_bs,buffer_backup_bs,HFSP_BOOT_SECTOR_SIZE)==0)
+ {
+ screen_buffer_add("Sectors are identical.\n");
+ opt_over=0;
+ }
+ else
+ {
+ screen_buffer_add("Sectors are not identical.\n");
+ }
+ if(opt_over!=0)
+ {
+ if(opt_B!=0 && opt_O!=0)
+ options="DOB";
+ else if(opt_B!=0)
+ options="DB";
+ else if(opt_O!=0)
+ options="DO";
+ }
+ rescan=0;
+ }
+ screen_buffer_to_log();
+ if(*current_cmd!=NULL)
+ {
+ command=0;
+ while(*current_cmd[0]==',')
+ (*current_cmd)++;
+ if(strncmp(*current_cmd,"dump",4)==0)
+ {
+ (*current_cmd)+=4;
+ command='D';
+ }
+ else if(strncmp(*current_cmd,"originalhfsp",11)==0)
+ {
+ (*current_cmd)+=11;
+ if(strchr(options,'O')!=NULL)
+ command='O';
+ }
+ else if(strncmp(*current_cmd,"backuphfsp",9)==0)
+ {
+ (*current_cmd)+=9;
+ if(strchr(options,'B')!=NULL)
+ command='B';
+ }
+ }
+ else
+ {
+ log_flush();
+#ifdef HAVE_NCURSES
+ command=screen_buffer_display_ext(stdscr, options, menu_hfsp, &menu);
+#else
+ command=0;
+#endif
+ }
+ switch(command)
+ {
+ case 0:
+ free(buffer_bs);
+ free(buffer_backup_bs);
+ return 0;
+ case 'O': /* O : copy original superblock over backup boot */
+ if(ask_confirmation("Copy original HFS/HFS+ volume header over backup, confirm ? (Y/N)")!=0)
+ {
+ log_info("copy original superblock over backup boot\n");
+ if(disk_car->write(disk_car,HFSP_BOOT_SECTOR_SIZE, buffer_bs, partition->part_offset+partition->part_size-0x400)!=0)
+ {
+ display_message("Write error: Can't overwrite HFS/HFS+ backup volume header\n");
+ }
+ disk_car->sync(disk_car);
+ rescan=1;
+ }
+ break;
+ case 'B': /* B : copy backup superblock over main superblock */
+ if(ask_confirmation("Copy backup HFS/HFS+ volume header over main volume header, confirm ? (Y/N)")!=0)
+ {
+ log_info("copy backup superblock over main superblock\n");
+ if(disk_car->write(disk_car,HFSP_BOOT_SECTOR_SIZE, buffer_backup_bs, partition->part_offset+0x400)!=0)
+ {
+ display_message("Write error: Can't overwrite HFS/HFS+ main volume header\n");
+ }
+ disk_car->sync(disk_car);
+ rescan=1;
+ }
+ break;
+ case 'D':
+ hfs_dump(disk_car, partition, buffer_bs, buffer_backup_bs);
+ break;
+ }
+ }
+}
diff --git a/src/thfs.h b/src/thfs.h
new file mode 100644
index 00000000..18d42f1b
--- /dev/null
+++ b/src/thfs.h
@@ -0,0 +1,22 @@
+/*
+
+ File: thfs.h
+
+ Copyright (C) 2008 Christophe GRENIER <[email protected]>
+
+ This software is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write the Free Software Foundation, Inc., 51
+ Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+ */
+int HFS_HFSP_boot_sector(disk_t *disk_car, partition_t *partition, const int verbose, const int dump_ind, const unsigned int expert, char **current_cmd);
diff --git a/src/tload.c b/src/tload.c
index efb139b6..29b4480c 100644
--- a/src/tload.c
+++ b/src/tload.c
@@ -23,57 +23,38 @@
#include <config.h>
#endif
-#include <stdarg.h>
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
#ifdef HAVE_STRING_H
#include <string.h>
#endif
-#include <ctype.h>
#ifdef HAVE_TIME_H
#include <time.h>
#endif
#ifdef HAVE_SYS_TIME_H
#include <sys/time.h>
#endif
-#ifdef HAVE_SYS_STAT_H
-#include <sys/stat.h>
-#endif
#include "types.h"
#include "common.h"
-#include "lang.h"
#include "intrf.h"
#ifdef HAVE_NCURSES
#include "intrfn.h"
#else
#include <stdio.h>
#endif
-#include "intrface.h"
-#include "godmode.h"
#include "fnctdsk.h"
-#include "testdisk.h"
-#include "adv.h"
-#include "analyse.h"
-#include "chgtype.h"
-#include "edit.h"
#include "savehdr.h"
-#include "dirpart.h"
-#include "fat.h"
-#include "partauto.h"
#include "log.h"
-#include "guid_cmp.h"
-#include "hdaccess.h"
-#include "io_redir.h"
#include "tload.h"
#ifdef HAVE_NCURSES
static list_part_t *merge_partition_list(list_part_t *list_part,list_part_t *backup_part, const int verbose);
-#define INTER_STRUCTURE 13
+#define INTER_LOAD 13
+#define INTER_LOAD_X 0
+#define INTER_LOAD_Y 22
+
static struct td_list_head *interface_load_ncurses(disk_t *disk_car, backup_disk_t *backup_list, const int verbose)
{
int offset=0;
@@ -112,9 +93,12 @@ static struct td_list_head *interface_load_ncurses(disk_t *disk_car, backup_disk
if(backup_list!=NULL)
{
backup_disk_t *backup=NULL;
- for(i=0,backup_walker=backup_list->list.next;(backup_walker!=&backup_list->list) && (i<offset);backup_walker=backup_walker->next,i++);
- for(i=offset;(backup_walker!=&backup_list->list) &&((i-offset)<INTER_STRUCTURE);i++,backup_walker=backup_walker->next)
+ for(i=0,backup_walker=backup_list->list.next;
+ backup_walker!=&backup_list->list && i<offset+INTER_LOAD;
+ backup_walker=backup_walker->next,i++)
{
+ if(i<offset)
+ continue;
backup=td_list_entry(backup_walker, backup_disk_t, list);
wmove(stdscr,8+i-offset,0);
wclrtoeol(stdscr); /* before addstr for BSD compatibility */
@@ -128,7 +112,7 @@ static struct td_list_head *interface_load_ncurses(disk_t *disk_car, backup_disk
wprintw(stdscr,"%s %s",backup->description,ctime(&backup->my_time));
}
}
- if(i<=INTER_STRUCTURE && backup==NULL)
+ if(i<=INTER_LOAD && backup==NULL)
{
strncpy(options,"LQ",sizeof(options));
menu=0;
@@ -144,7 +128,7 @@ static struct td_list_head *interface_load_ncurses(disk_t *disk_car, backup_disk
menu=0;
strncpy(options,"Q",sizeof(options));
}
- switch(wmenuSelect(stdscr, 24, INTER_DUMP_Y,INTER_DUMP_X, menuLoadBackup, 8, options, MENU_HORIZ| MENU_BUTTON | MENU_ACCEPT_OTHERS, menu))
+ switch(wmenuSelect(stdscr, INTER_LOAD_Y+1, INTER_LOAD_Y,INTER_LOAD_X, menuLoadBackup, 8, options, MENU_HORIZ| MENU_BUTTON | MENU_ACCEPT_OTHERS, menu))
{
case 'q':
case 'Q':
@@ -169,14 +153,14 @@ static struct td_list_head *interface_load_ncurses(disk_t *disk_car, backup_disk
}
break;
case KEY_PPAGE:
- for(i=0;(i<INTER_STRUCTURE) && (backup_current->prev!=&backup_list->list);i++)
+ for(i=0;(i<INTER_LOAD) && (backup_current->prev!=&backup_list->list);i++)
{
backup_current=backup_current->prev;
backup_current_num--;
}
break;
case KEY_NPAGE:
- for(i=0;(i<INTER_STRUCTURE) && (backup_current->next!=&backup_list->list);i++)
+ for(i=0;(i<INTER_LOAD) && (backup_current->next!=&backup_list->list);i++)
{
backup_current=backup_current->next;
backup_current_num++;
@@ -188,8 +172,8 @@ static struct td_list_head *interface_load_ncurses(disk_t *disk_car, backup_disk
}
if(backup_current_num<offset)
offset=backup_current_num;
- if(backup_current_num>=offset+INTER_STRUCTURE)
- offset=backup_current_num-INTER_STRUCTURE+1;
+ if(backup_current_num>=offset+INTER_LOAD)
+ offset=backup_current_num-INTER_LOAD+1;
}
}
diff --git a/src/tlog.c b/src/tlog.c
index 90a4e4a4..3f45ac82 100644
--- a/src/tlog.c
+++ b/src/tlog.c
@@ -75,7 +75,7 @@ int ask_testdisk_log_creation()
while(1)
{
int command;
- command = wmenuSelect_ext(stdscr, 24, 17, 0, menuLogCreation, 8,
+ command = wmenuSelect_ext(stdscr, 23, 17, 0, menuLogCreation, 8,
"CAQ", MENU_VERT | MENU_VERT_WARN | MENU_BUTTON, &menu,NULL);
switch(command)
{
diff --git a/src/tmbrcode.c b/src/tmbrcode.c
index 440b5a77..81685a13 100644
--- a/src/tmbrcode.c
+++ b/src/tmbrcode.c
@@ -35,6 +35,7 @@
#else
#include <stdio.h>
#endif
+#include "log.h"
#include "tmbrcode.h"
#ifdef HAVE_NCURSES
@@ -65,7 +66,7 @@ int write_MBR_code(disk_t *disk_car)
return 0;
}
#else
-static int write_MBR_code(disk_t *disk_car)
+int write_MBR_code(disk_t *disk_car)
{
if(disk_car->arch->write_MBR_code==NULL)
{
diff --git a/src/tntfs.c b/src/tntfs.c
new file mode 100644
index 00000000..88095a09
--- /dev/null
+++ b/src/tntfs.c
@@ -0,0 +1,287 @@
+/*
+
+ File: tntfs.c
+
+ Copyright (C) 2008 Christophe GRENIER <[email protected]>
+
+ This software is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write the Free Software Foundation, Inc., 51
+ Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+ */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+#include "types.h"
+#include "common.h"
+#include "lang.h"
+#include "intrf.h"
+#include "intrfn.h"
+#include "dirpart.h"
+#include "ntfs.h"
+#include "io_redir.h"
+#include "log.h"
+#include "tntfs.h"
+
+#ifdef HAVE_NCURSES
+static void dump_NTFS_ncurses(disk_t *disk_car, const partition_t *partition, const unsigned char *buffer_bs, const unsigned char *buffer_backup_bs)
+{
+ WINDOW *window=newwin(0,0,0,0); /* full screen */
+ keypad(window, TRUE); /* Need it to get arrow key */
+ aff_copy(window);
+ wmove(window,4,0);
+ wprintw(window,"%s",disk_car->description(disk_car));
+ wmove(window,5,0);
+ aff_part(window,AFF_PART_ORDER|AFF_PART_STATUS,disk_car,partition);
+ mvwaddstr(window,6,0, "Boot sector Backup boot sector");
+ dump2(window, buffer_bs, buffer_backup_bs, NTFS_BOOT_SECTOR_SIZE);
+ delwin(window);
+ (void) clearok(stdscr, TRUE);
+#ifdef HAVE_TOUCHWIN
+ touchwin(stdscr);
+#endif
+}
+#endif
+
+static void dump_NTFS(disk_t *disk_car, const partition_t *partition, const unsigned char *buffer_bs, const unsigned char *buffer_backup_bs)
+{
+ log_info("Boot sector Backup boot sector\n");
+ dump2_log(buffer_bs, buffer_backup_bs, NTFS_BOOT_SECTOR_SIZE);
+#ifdef HAVE_NCURSES
+ dump_NTFS_ncurses(disk_car, partition, buffer_bs, buffer_backup_bs);
+#endif
+}
+
+int ntfs_boot_sector(disk_t *disk_car, partition_t *partition, const int verbose, const int dump_ind, const unsigned int expert, char **current_cmd)
+{
+ unsigned char *buffer_bs;
+ unsigned char *buffer_backup_bs;
+ const char *options="";
+ int rescan=1;
+#ifdef HAVE_NCURSES
+ struct MenuItem menu_ntfs[]=
+ {
+ { 'P', "Previous",""},
+ { 'N', "Next","" },
+ { 'Q', "Quit","Return to Advanced menu"},
+ { 'L', "List", "List directories and files, copy data from NTFS" },
+ { 'O', "Org. BS","Copy boot sector over backup sector"},
+ { 'B', "Backup BS","Copy backup boot sector over boot sector"},
+ { 'R', "Rebuild BS","Rebuild boot sector"},
+ { 'M', "Repair MFT","Check MFT"},
+ { 'D', "Dump","Dump boot sector and backup boot sector"},
+ { 0, NULL, NULL }
+ };
+#endif
+ buffer_bs=(unsigned char*)MALLOC(NTFS_BOOT_SECTOR_SIZE);
+ buffer_backup_bs=(unsigned char*)MALLOC(NTFS_BOOT_SECTOR_SIZE);
+
+ while(1)
+ {
+ unsigned int menu=0;
+ int command;
+ screen_buffer_reset();
+ if(rescan==1)
+ {
+ int identical_sectors=0;
+ int opt_B=0;
+ int opt_O=0;
+#ifdef HAVE_NCURSES
+ aff_copy(stdscr);
+ wmove(stdscr,4,0);
+ wprintw(stdscr,"%s",disk_car->description(disk_car));
+ mvwaddstr(stdscr,5,0,msg_PART_HEADER_LONG);
+ wmove(stdscr,6,0);
+ aff_part(stdscr,AFF_PART_ORDER|AFF_PART_STATUS,disk_car,partition);
+#endif
+ log_info("\nntfs_boot_sector\n");
+ log_partition(disk_car,partition);
+ screen_buffer_add("Boot sector\n");
+ if(disk_car->read(disk_car,NTFS_BOOT_SECTOR_SIZE, buffer_bs, partition->part_offset)!=0)
+ {
+ screen_buffer_add("ntfs_boot_sector: Can't read boot sector.\n");
+ memset(buffer_bs,0,NTFS_BOOT_SECTOR_SIZE);
+ }
+ if(test_NTFS(disk_car,(struct ntfs_boot_sector*)buffer_bs,partition,verbose,0)==0)
+ {
+ screen_buffer_add("Status: OK\n");
+ opt_O=1;
+ }
+ else
+ {
+ screen_buffer_add("Status: Bad\n");
+ }
+ screen_buffer_add("\nBackup boot sector\n");
+ if(disk_car->read(disk_car,NTFS_BOOT_SECTOR_SIZE, buffer_backup_bs, partition->part_offset+partition->part_size-disk_car->sector_size)!=0)
+ {
+ screen_buffer_add("ntfs_boot_sector: Can't read backup boot sector.\n");
+ memset(buffer_backup_bs,0,NTFS_BOOT_SECTOR_SIZE);
+ }
+ if(test_NTFS(disk_car,(struct ntfs_boot_sector*)buffer_backup_bs,partition,verbose,0)==0)
+ {
+ screen_buffer_add("Status: OK\n");
+ opt_B=1;
+ }
+ else
+ {
+ screen_buffer_add("Status: Bad\n");
+ }
+ screen_buffer_add("\n");
+ if(memcmp(buffer_bs,buffer_backup_bs,NTFS_BOOT_SECTOR_SIZE)==0)
+ {
+ log_ntfs_info((const struct ntfs_boot_sector *)buffer_bs);
+ screen_buffer_add("Sectors are identical.\n");
+ identical_sectors=1;
+ }
+ else
+ {
+ log_ntfs2_info((const struct ntfs_boot_sector *)buffer_bs, (const struct ntfs_boot_sector *)buffer_backup_bs);
+ screen_buffer_add("Sectors are not identical.\n");
+ identical_sectors=0;
+ }
+ screen_buffer_add("\n");
+ screen_buffer_add("A valid NTFS Boot sector must be present in order to access\n");
+ screen_buffer_add("any data; even if the partition is not bootable.\n");
+ if(opt_B!=0 && opt_O!=0)
+ {
+ if(identical_sectors==0)
+ options="DOBRL";
+ else
+ options="DRML";
+ }
+ else if(opt_B!=0)
+ {
+ menu=5;
+ if(expert>0)
+ options="DBRML";
+ else
+ options="DBRL";
+ }
+ else if(opt_O!=0)
+ {
+ menu=4;
+ options="DORL";
+ }
+ else
+ options="DR";
+ rescan=0;
+ }
+ screen_buffer_to_log();
+ if(*current_cmd!=NULL)
+ {
+ command=0;
+ while(*current_cmd[0]==',')
+ (*current_cmd)++;
+ if(strncmp(*current_cmd,"rebuildbs",9)==0)
+ {
+ (*current_cmd)+=9;
+ command='R';
+ }
+ else if(strncmp(*current_cmd,"dump",4)==0)
+ {
+ (*current_cmd)+=4;
+ command='D';
+ }
+ else if(strncmp(*current_cmd,"list",4)==0)
+ {
+ (*current_cmd)+=4;
+ command='L';
+ }
+ else if(strncmp(*current_cmd,"originalntfs",11)==0)
+ {
+ (*current_cmd)+=11;
+ if(strchr(options,'O')!=NULL)
+ command='O';
+ }
+ else if(strncmp(*current_cmd,"backupntfs",9)==0)
+ {
+ (*current_cmd)+=9;
+ if(strchr(options,'B')!=NULL)
+ command='B';
+ }
+ else if(strncmp(*current_cmd,"repairmft",9)==0)
+ {
+ (*current_cmd)+=9;
+ if(strchr(options,'M')!=NULL)
+ command='M';
+ }
+ }
+ else
+ {
+ log_flush();
+#ifdef HAVE_NCURSES
+ command=screen_buffer_display_ext(stdscr, options, menu_ntfs, &menu);
+#else
+ command=0;
+#endif
+ }
+ switch(command)
+ {
+ case 0:
+ free(buffer_bs);
+ free(buffer_backup_bs);
+ return 0;
+ case 'O': /* O : copy original boot sector over backup boot */
+ if(ask_confirmation("Copy original NTFS boot sector over backup boot, confirm ? (Y/N)")!=0)
+ {
+ log_info("copy original boot sector over backup boot\n");
+ if(disk_car->write(disk_car,NTFS_BOOT_SECTOR_SIZE, buffer_bs, partition->part_offset+partition->part_size-disk_car->sector_size)!=0)
+ {
+ display_message("Write error: Can't overwrite NTFS backup boot sector\n");
+ }
+ disk_car->sync(disk_car);
+ rescan=1;
+ }
+ break;
+ case 'B': /* B : copy backup boot sector over boot sector */
+ if(ask_confirmation("Copy backup NTFS boot sector over boot sector, confirm ? (Y/N)")!=0)
+ {
+ log_info("copy backup boot sector over boot sector\n");
+ if(disk_car->write(disk_car,NTFS_BOOT_SECTOR_SIZE, buffer_backup_bs, partition->part_offset)!=0)
+ {
+ display_message("Write error: Can't overwrite NTFS boot sector\n");
+ }
+ disk_car->sync(disk_car);
+ rescan=1;
+ }
+ break;
+ case 'L':
+ if(strchr(options,'O')==NULL && strchr(options,'B')!=NULL)
+ {
+ io_redir_add_redir(disk_car,partition->part_offset,NTFS_BOOT_SECTOR_SIZE,0,buffer_backup_bs);
+ dir_partition(disk_car, partition, 0,current_cmd);
+ io_redir_del_redir(disk_car,partition->part_offset);
+ }
+ else
+ dir_partition(disk_car, partition, 0,current_cmd);
+ break;
+ case 'M':
+ repair_MFT(disk_car, partition, verbose, expert, current_cmd);
+ break;
+ case 'R': /* R : rebuild boot sector */
+ rebuild_NTFS_BS(disk_car,partition,verbose,dump_ind,1,expert,current_cmd);
+ rescan=1;
+ break;
+ case 'D':
+ dump_NTFS(disk_car, partition, buffer_bs, buffer_backup_bs);
+ break;
+ }
+ }
+}
diff --git a/src/tntfs.h b/src/tntfs.h
new file mode 100644
index 00000000..1151babe
--- /dev/null
+++ b/src/tntfs.h
@@ -0,0 +1,22 @@
+/*
+
+ File: tntfs.h
+
+ Copyright (C) 2008 Christophe GRENIER <[email protected]>
+
+ This software is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write the Free Software Foundation, Inc., 51
+ Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+ */
+int ntfs_boot_sector(disk_t *disk_car, partition_t *partition, const int verbose, const int dump_ind, const unsigned int expert, char **current_cmd);
diff --git a/src/toptions.c b/src/toptions.c
index 64aa12de..70af73e6 100644
--- a/src/toptions.c
+++ b/src/toptions.c
@@ -68,7 +68,7 @@ static void interface_options_ncurses(int *dump_ind, int *align, int *allow_part
menuOptions[2].name=*allow_partial_last_cylinder?"Allow partial last cylinder : Yes":"Allow partial last cylinder : No";
menuOptions[3].name=*dump_ind?"Dump : Yes":"Dump : No";
aff_copy(stdscr);
- car=wmenuSelect_ext(stdscr, 24, INTER_OPTION_Y, INTER_OPTION_X, menuOptions, 0, "ECADQ", MENU_VERT|MENU_VERT_ARROW2VALID, &menu,&real_key);
+ car=wmenuSelect_ext(stdscr, 23, INTER_OPTION_Y, INTER_OPTION_X, menuOptions, 0, "ECADQ", MENU_VERT|MENU_VERT_ARROW2VALID, &menu,&real_key);
switch(car)
{
case 'd':