diff --git a/src/Makefile.am b/src/Makefile.am index 46d2f72d..62b88817 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -16,7 +16,7 @@ base_H = common.h crc.h ewf.h fnctdsk.h hdaccess.h guid_cmp.h guid_cpy.h hdcac 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 edit.c edit.h ext2_dir.c ext2_dir.h ext2_inc.h fat_adv.c fat_dir.c fat_dir.h geometry.c godmode.c godmode.h intrface.c 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 +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 edit.c edit.h ext2_dir.c ext2_dir.h ext2_inc.h fat_adv.c fat_dir.c fat_dir.h geometry.c godmode.c godmode.h intrface.c 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 photorec_SOURCES = photorec.c photorec.h phrecn.c phrecn.h dir.c dir.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_aif.c file_all.c file_asf.c file_au.c file_bkf.c file_bld.c file_bmp.c file_bz2.c file_cab.c file_cam.c file_cm.c file_crw.c file_ctg.c file_cwk.c file_dat.c file_dbf.c file_dir.c file_djv.c file_doc.c file_dpx.c file_dsc.c file_dta.c file_dv.c file_dwg.c file_elf.c file_evt.c file_exe.c pe.h file_ext.c file_fh10.c file_fh5.c file_flac.c file_flv.c file_fs.c file_gif.c file_gz.c file_imb.c file_indd.c file_dump.c file_itu.c file_jpg.c file_jpg.h file_kdb.c file_max.c file_mb.c file_mdb.c file_mdf.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_pap.c file_pcx.c file_pdf.c file_png.c file_prc.c file_ps.c file_psd.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_sit.c file_skp.c file_spe.c file_spss.c file_stu.c file_swf.c file_tar.c file_tar.h file_tib.c file_tiff.c file_txt.c file_vmdk.c file_wpd.c file_wmf.c file_x3f.c file_xcf.c file_xm.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) diff --git a/src/adv.c b/src/adv.c index db2b3d56..c395fcab 100644 --- a/src/adv.c +++ b/src/adv.c @@ -50,6 +50,7 @@ #include "io_redir.h" #include "log.h" #include "guid_cmp.h" +#include "dimage.h" extern const arch_fnct_t arch_gpt; extern const arch_fnct_t arch_i386; @@ -61,6 +62,7 @@ extern const arch_fnct_t arch_xbox; #define INTER_ADV_X 0 #define INTER_ADV_Y 23 #define INTER_ADV 15 +#define DEFAULT_IMAGE_NAME "image.dd" static int is_hfs(const partition_t *partition); static int is_hfsp(const partition_t *partition); @@ -188,6 +190,7 @@ void interface_adv(disk_t *disk_car, const int verbose,const int dump_ind, const {'t',"Type","Change type, this setting will not be saved on disk"}, {'b',"Boot","Boot sector recovery"}, {'s',"Superblock",NULL}, + {'c',"Copy", "Create an image"}, // {'a',"Add", "Add temporary partition (Expert only)"}, {'q',"Quit","Return to main menu"}, {0,NULL,NULL} @@ -237,41 +240,41 @@ void interface_adv(disk_t *disk_car, const int verbose,const int dump_ind, const if(is_part_fat(current_element->part) || is_part_ntfs(current_element->part)) { - options="tbq"; + options="tbcq"; menu=1; } else if(is_part_linux(current_element->part)) { - options="tsq"; + options="tscq"; menuAdv[2].desc="Locate EXT2/EXT3 backup superblock"; menu=1; } else if(is_part_hfs(current_element->part) || is_part_hfsp(current_element->part)) { - options="tsq"; + options="tscq"; menuAdv[2].desc="Locate HFS/HFS+ backup superblock"; menu=1; } else if(is_fat(current_element->part) || is_ntfs(current_element->part)) { - options="tbq"; + options="tbcq"; menu=1; } else if(is_linux(current_element->part)) { - options="tsq"; + options="tscq"; menuAdv[2].desc="Locate EXT2/EXT3 backup superblock"; menu=1; } else if(is_hfs(current_element->part) || is_hfsp(current_element->part)) { - options="tsq"; + options="tscq"; menuAdv[2].desc="Locate HFS/HFS+ backup superblock"; menu=1; } else - options="tq"; + options="tcq"; } quit=0; if(*current_cmd!=NULL) @@ -293,6 +296,11 @@ void interface_adv(disk_t *disk_car, const int verbose,const int dump_ind, const (*current_cmd)+=4; command='b'; } + else if(strncmp(*current_cmd,"copy",4)==0) + { + (*current_cmd)+=4; + command='c'; + } else if(strncmp(*current_cmd,"superblock",10)==0) { (*current_cmd)+=10; @@ -399,6 +407,29 @@ void interface_adv(disk_t *disk_car, const int verbose,const int dump_ind, const } } break; + case 'c': + case 'C': + if(current_element!=NULL) + { + char *image_dd; + menu=0; + image_dd=ask_location("Do you want to save disk file image.dd in %s%s ? [Y/N]",""); + if(image_dd!=NULL) + { + char *new_recup_dir=MALLOC(strlen(image_dd)+1+strlen(DEFAULT_IMAGE_NAME)+1); + strcpy(new_recup_dir,image_dd); + strcat(new_recup_dir,"/"); + strcat(new_recup_dir,DEFAULT_IMAGE_NAME); + free(image_dd); + image_dd=new_recup_dir; + } + if(image_dd!=NULL) + { + disk_image(disk_car, current_element->part, image_dd); + free(image_dd); + } + } + break; case 's': case 'S': if(current_element!=NULL) diff --git a/src/dimage.c b/src/dimage.c new file mode 100644 index 00000000..5292738a --- /dev/null +++ b/src/dimage.c @@ -0,0 +1,153 @@ +/* + + File: dimage.c + + Copyright (C) 2007 Christophe GRENIER + + 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 +#endif +#ifdef HAVE_STDLIB_H +#include +#endif +#ifdef HAVE_STRING_H +#include +#endif +#ifdef HAVE_LOCALE_H +#include /* setlocale */ +#endif +#ifdef HAVE_SIGNAL_H +#include +#endif +#ifdef HAVE_TIME_H +#include +#endif +#include +#include +#include +#include "types.h" +#include "common.h" +#include "testdisk.h" +#include "intrf.h" +#ifdef HAVE_NCURSES +#include "intrfn.h" +#else +#include +#endif +#ifdef HAVE_UNISTD_H +#include +#endif +#include "intrface.h" +#include "fnctdsk.h" +#include "log.h" +#include "dimage.h" + +#define READ_SIZE 256*512 + +#ifndef O_LARGEFILE +#define O_LARGEFILE 0 +#endif +#ifndef O_BINARY +#define O_BINARY 0 +#endif + +int disk_image(disk_t *disk_car, const partition_t *partition, const char *image_dd) +{ + int ind_stop=0; + uint64_t nbr_read_error=0; + uint64_t offset=partition->part_offset; + const uint64_t offset_end=partition->part_offset+partition->part_size; + const uint64_t offset_inc=(offset_end-offset)/100; + uint64_t offset_next=offset; + unsigned char *buffer_disk=MALLOC(READ_SIZE); + int disk_dst; +#ifdef HAVE_NCURSES + WINDOW *window; +#endif + if((disk_dst=open(image_dd,O_LARGEFILE|O_RDWR|O_BINARY|O_CREAT,0644))<0) + { + log_error("Can't create file %s.\n",image_dd); + display_message("Can't create file!\n"); + return -1; + } +#ifdef HAVE_NCURSES + window=newwin(0,0,0,0); /* full screen */ + aff_copy(window); + wmove(window,5,0); + wprintw(window,"%s\n",disk_car->description_short(disk_car)); + wmove(window,6,0); + aff_part(window,AFF_PART_ORDER|AFF_PART_STATUS,disk_car,partition); + wmove(window,22,0); + wattrset(window, A_REVERSE); + waddstr(window," Stop "); + wattroff(window, A_REVERSE); +#endif + while(ind_stop==0 && offset < offset_end) + { + unsigned int readsize=READ_SIZE; + int update=0; + if(offset_end-offset < READ_SIZE) + readsize=offset_end-offset; + if(disk_car->read(disk_car, readsize, buffer_disk, offset)<0) + { + update=1; + nbr_read_error++; + } + offset+=READ_SIZE; + if(offset>offset_next) + { + update=1; + offset_next+=offset_inc; + } + if(update) + { +#ifdef HAVE_NCURSES + unsigned int i; + unsigned int percent=(offset-partition->part_offset)*100/partition->part_size; + wmove(window,7,0); + wprintw(window,"%3u %% ", percent); + for(i=0;i"); + wrefresh(window); + ind_stop=check_enter_key_or_s(window); +#endif + } + if(write(disk_dst,buffer_disk,readsize)<0) + { + ind_stop=2; + } + } + close(disk_dst); + delwin(window); + (void) clearok(window, TRUE); +#ifdef HAVE_TOUCHWIN + touchwin(window); +#endif + if(ind_stop==2) + { + display_message("No space left for the file image.\n"); + return -2; + } + if(nbr_read_error==0) + display_message("Image created successfully.\n"); + else + display_message("Image created successfully but read errors have occured.\n"); + return 0; +} diff --git a/src/dimage.h b/src/dimage.h new file mode 100644 index 00000000..bac6056d --- /dev/null +++ b/src/dimage.h @@ -0,0 +1,22 @@ +/* + + File: dimage.h + + Copyright (C) 2007 Christophe GRENIER + + 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 disk_image(disk_t *disk_car, const partition_t *partition, const char *image_dd);