diff options
author | Christophe Grenier <[email protected]> | 2008-08-25 23:15:17 +0200 |
---|---|---|
committer | Christophe Grenier <[email protected]> | 2008-08-25 23:15:17 +0200 |
commit | d5d0a9a74f20ab8288f81ec96be48636dd6e0686 (patch) | |
tree | d9ca34d754825448472b3670afaef7a8d43f38e6 | |
parent | c943ebd716ad2f71d2f73abc821e266be552a36f (diff) |
Split the interface in several files, part 2
Text interface needs 24 lines instead of 25
-rw-r--r-- | src/Makefile.am | 4 | ||||
-rw-r--r-- | src/adv.c | 923 | ||||
-rw-r--r-- | src/adv.h | 5 | ||||
-rw-r--r-- | src/diskacc.c | 38 | ||||
-rw-r--r-- | src/diskcapa.c | 38 | ||||
-rw-r--r-- | src/edit.c | 4 | ||||
-rw-r--r-- | src/fat1x.c | 202 | ||||
-rw-r--r-- | src/fat1x.h | 23 | ||||
-rw-r--r-- | src/fat32.c | 310 | ||||
-rw-r--r-- | src/fat32.h | 22 | ||||
-rw-r--r-- | src/fat_adv.c | 2 | ||||
-rw-r--r-- | src/godmode.c | 12 | ||||
-rw-r--r-- | src/intrf.c | 18 | ||||
-rw-r--r-- | src/intrf.h | 4 | ||||
-rw-r--r-- | src/intrface.c | 31 | ||||
-rw-r--r-- | src/intrface.h | 4 | ||||
-rw-r--r-- | src/ntfs_adv.c | 2 | ||||
-rw-r--r-- | src/ntfs_fix.c | 2 | ||||
-rw-r--r-- | src/parti386.c | 12 | ||||
-rw-r--r-- | src/pblocksize.c | 142 | ||||
-rw-r--r-- | src/pblocksize.h | 22 | ||||
-rw-r--r-- | src/pdisksel.c | 257 | ||||
-rw-r--r-- | src/pdisksel.h | 23 | ||||
-rw-r--r-- | src/pfree_whole.c | 134 | ||||
-rw-r--r-- | src/pfree_whole.h | 24 | ||||
-rw-r--r-- | src/photorec.c | 3 | ||||
-rw-r--r-- | src/photorec.h | 24 | ||||
-rw-r--r-- | src/phrecn.c | 787 | ||||
-rw-r--r-- | src/phrecn.h | 4 | ||||
-rw-r--r-- | src/ppartsel.c | 420 | ||||
-rw-r--r-- | src/ppartsel.h | 24 | ||||
-rw-r--r-- | src/tdelete.c | 1 | ||||
-rw-r--r-- | src/tdiskop.c | 2 | ||||
-rw-r--r-- | src/tdisksel.c | 17 | ||||
-rw-r--r-- | src/thfs.c | 245 | ||||
-rw-r--r-- | src/thfs.h | 22 | ||||
-rw-r--r-- | src/tload.c | 46 | ||||
-rw-r--r-- | src/tlog.c | 2 | ||||
-rw-r--r-- | src/tmbrcode.c | 3 | ||||
-rw-r--r-- | src/tntfs.c | 287 | ||||
-rw-r--r-- | src/tntfs.h | 22 | ||||
-rw-r--r-- | src/toptions.c | 2 |
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 @@ -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; - } - } -} @@ -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; @@ -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, ¤t_cmd)==0) + menu_photorec(disk, verbose, recup_dir, file_enable, ¤t_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(¶noid, &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(¶noid, &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, ¤t_cmd)==0) - menu_photorec(disk, verbose, recup_dir, file_enable, ¤t_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(¶noid, &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(¶noid, &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; } } @@ -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': |