TestDisk: Skip 10MB if a read error occurs during image creation.
This commit is contained in:
parent
10a9142770
commit
e5df74714e
1 changed files with 89 additions and 23 deletions
112
src/dimage.c
112
src/dimage.c
|
@ -2,7 +2,7 @@
|
|||
|
||||
File: dimage.c
|
||||
|
||||
Copyright (C) 2007-2008 Christophe GRENIER <grenier@cgsecurity.org>
|
||||
Copyright (C) 2007-2009 Christophe GRENIER <grenier@cgsecurity.org>
|
||||
|
||||
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
|
||||
|
@ -20,26 +20,29 @@
|
|||
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#ifdef HAVE_STDLIB_H
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#include <sys/types.h>
|
||||
#include <fcntl.h>
|
||||
#include "types.h"
|
||||
#include "common.h"
|
||||
#include "intrf.h"
|
||||
#include "intrfn.h"
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#include "log.h"
|
||||
#include "dimage.h"
|
||||
|
||||
#define READ_SIZE 256*512
|
||||
/* Skip 10Mb when there is a read error */
|
||||
#define SKIP_SIZE 10*1024*1024
|
||||
|
||||
#ifndef O_LARGEFILE
|
||||
#define O_LARGEFILE 0
|
||||
|
@ -48,15 +51,52 @@
|
|||
#define O_BINARY 0
|
||||
#endif
|
||||
|
||||
int disk_image(disk_t *disk_car, const partition_t *partition, const char *image_dd)
|
||||
static void disk_image_backward(int disk_dst, disk_t *disk, const uint64_t offset_start, const uint64_t offset_end)
|
||||
{
|
||||
uint64_t offset;
|
||||
unsigned char *buffer=(unsigned char *)MALLOC(disk->sector_size);
|
||||
for(offset=offset_end-disk->sector_size; offset > offset_start; offset-=disk->sector_size)
|
||||
{
|
||||
ssize_t pread_res;
|
||||
pread_res=disk->pread(disk, buffer, disk->sector_size, offset);
|
||||
if((unsigned)pread_res != disk->sector_size)
|
||||
{
|
||||
free(buffer);
|
||||
return;
|
||||
}
|
||||
#if defined(HAVE_PWRITE)
|
||||
if(pwrite(disk_dst, buffer, pread_res, offset)<0)
|
||||
{
|
||||
free(buffer);
|
||||
return;
|
||||
}
|
||||
#else
|
||||
if(lseek(disk_dst, offset, SEEK_SET)<0)
|
||||
{
|
||||
free(buffer);
|
||||
return;
|
||||
}
|
||||
if(write(disk_dst, buffer, pread_res) != pread_res)
|
||||
{
|
||||
free(buffer);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
free(buffer);
|
||||
}
|
||||
|
||||
int disk_image(disk_t *disk, const partition_t *partition, const char *image_dd)
|
||||
{
|
||||
int ind_stop=0;
|
||||
uint64_t nbr_read_error=0;
|
||||
uint64_t offset=partition->part_offset;
|
||||
uint64_t offset_old=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=(unsigned char *)MALLOC(READ_SIZE);
|
||||
unsigned char *buffer=(unsigned char *)MALLOC(READ_SIZE);
|
||||
unsigned int readsize=READ_SIZE;
|
||||
int disk_dst;
|
||||
#ifdef HAVE_NCURSES
|
||||
WINDOW *window;
|
||||
|
@ -65,16 +105,16 @@ int disk_image(disk_t *disk_car, const partition_t *partition, const char *image
|
|||
{
|
||||
log_error("Can't create file %s.\n",image_dd);
|
||||
display_message("Can't create file!\n");
|
||||
free(buffer_disk);
|
||||
free(buffer);
|
||||
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));
|
||||
wprintw(window,"%s\n",disk->description_short(disk));
|
||||
wmove(window,6,0);
|
||||
aff_part(window,AFF_PART_ORDER|AFF_PART_STATUS,disk_car,partition);
|
||||
aff_part(window,AFF_PART_ORDER|AFF_PART_STATUS,disk,partition);
|
||||
wmove(window,22,0);
|
||||
wattrset(window, A_REVERSE);
|
||||
waddstr(window," Stop ");
|
||||
|
@ -82,26 +122,56 @@ int disk_image(disk_t *disk_car, const partition_t *partition, const char *image
|
|||
#endif
|
||||
while(ind_stop==0 && offset < offset_end)
|
||||
{
|
||||
unsigned int readsize=READ_SIZE;
|
||||
ssize_t pread_res;
|
||||
int update=0;
|
||||
if(offset_end-offset < READ_SIZE)
|
||||
if(offset_end-offset < readsize)
|
||||
readsize=offset_end-offset;
|
||||
if((unsigned)disk_car->pread(disk_car, buffer_disk, readsize, offset) != readsize)
|
||||
pread_res=disk->pread(disk, buffer, readsize, offset);
|
||||
if(pread_res > 0)
|
||||
{
|
||||
#if defined(HAVE_PWRITE)
|
||||
if(pwrite(disk_dst, buffer, pread_res, offset)<0)
|
||||
{
|
||||
ind_stop=2;
|
||||
}
|
||||
#else
|
||||
if(lseek(disk_dst, offset, SEEK_SET)<0)
|
||||
{
|
||||
ind_stop=2;
|
||||
}
|
||||
if(write(disk_dst, buffer, pread_res) != pread_res)
|
||||
{
|
||||
ind_stop=2;
|
||||
}
|
||||
#endif
|
||||
if(offset_old + SKIP_SIZE==offset)
|
||||
{
|
||||
disk_image_backward(disk_dst, disk, offset_old, offset);
|
||||
}
|
||||
}
|
||||
offset_old=offset;
|
||||
if((unsigned)pread_res == readsize)
|
||||
{
|
||||
offset+=readsize;
|
||||
readsize=READ_SIZE;
|
||||
}
|
||||
else
|
||||
{
|
||||
update=1;
|
||||
nbr_read_error++;
|
||||
readsize=disk->sector_size;
|
||||
offset+=SKIP_SIZE;
|
||||
}
|
||||
offset+=READ_SIZE;
|
||||
if(offset>offset_next)
|
||||
{
|
||||
update=1;
|
||||
offset_next+=offset_inc;
|
||||
offset_next=offset+offset_inc;
|
||||
}
|
||||
if(update)
|
||||
{
|
||||
#ifdef HAVE_NCURSES
|
||||
unsigned int i;
|
||||
unsigned int percent=(offset-partition->part_offset)*100/partition->part_size;
|
||||
const unsigned int percent=(offset-partition->part_offset)*100/partition->part_size;
|
||||
wmove(window,7,0);
|
||||
wprintw(window,"%3u %% ", percent);
|
||||
for(i=0;i<percent*3/5;i++)
|
||||
|
@ -111,10 +181,6 @@ int disk_image(disk_t *disk_car, const partition_t *partition, const char *image
|
|||
ind_stop=check_enter_key_or_s(window);
|
||||
#endif
|
||||
}
|
||||
if(write(disk_dst,buffer_disk,readsize)<0)
|
||||
{
|
||||
ind_stop=2;
|
||||
}
|
||||
}
|
||||
close(disk_dst);
|
||||
#ifdef HAVE_NCURSES
|
||||
|
@ -127,7 +193,7 @@ int disk_image(disk_t *disk_car, const partition_t *partition, const char *image
|
|||
if(ind_stop==2)
|
||||
{
|
||||
display_message("No space left for the file image.\n");
|
||||
free(buffer_disk);
|
||||
free(buffer);
|
||||
return -2;
|
||||
}
|
||||
if(ind_stop)
|
||||
|
@ -136,13 +202,13 @@ int disk_image(disk_t *disk_car, const partition_t *partition, const char *image
|
|||
display_message("Incomplete image created.\n");
|
||||
else
|
||||
display_message("Incomplete image created: read errors have occured.\n");
|
||||
free(buffer_disk);
|
||||
free(buffer);
|
||||
return 0;
|
||||
}
|
||||
if(nbr_read_error==0)
|
||||
display_message("Image created successfully.\n");
|
||||
else
|
||||
display_message("Image created successfully but read errors have occured.\n");
|
||||
free(buffer_disk);
|
||||
free(buffer);
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue