From 8aad5d9eebdd59fb28ce8fd24edaad84ecb47648 Mon Sep 17 00:00:00 2001 From: Christophe Grenier Date: Tue, 29 Apr 2008 20:24:12 +0200 Subject: [PATCH] Bugfix: add missing fewf_sync() function to EWF Fix reported size (2048 TB instead of 0) for some broken USB device under Windows --- src/ewf.c | 56 ++++++++++++++++++++++++++------------------------ src/hdaccess.c | 52 ++++++++++++++++++++++++++++++---------------- src/hdaccess.h | 1 + src/win32.c | 43 +++++++++++++++----------------------- 4 files changed, 80 insertions(+), 72 deletions(-) diff --git a/src/ewf.c b/src/ewf.c index 3212404e..babe9e13 100644 --- a/src/ewf.c +++ b/src/ewf.c @@ -53,14 +53,14 @@ #include #include "log.h" +#include "hdaccess.h" static const char *fewf_description(disk_t *disk_car); static const char *fewf_description_short(disk_t *disk_car); static int fewf_clean(disk_t *disk_car); static int fewf_read(disk_t *disk_car, const unsigned int count, void *nom_buffer, const uint64_t offset); -static int fewf_write(disk_t *disk_car, const unsigned int count, const void *nom_buffer, const uint64_t offset); static int fewf_nowrite(disk_t *disk_car, const unsigned int count, const void *nom_buffer, const uint64_t offset); - +static int fewf_sync(disk_t *disk_car); struct info_fewf_struct { @@ -89,7 +89,6 @@ disk_t *fewf_init(const char *device, const int verbose, const arch_fnct_t *arch data->buffer_size=0; data->mode=mode; data->handle=NULL; -// data->handle=libewf_open(filenames, 1, ((mode&O_RDWR)==O_RDWR?LIBEWF_OPEN_WRITE:LIBEWF_OPEN_READ)); #ifdef HAVE_GLOB_H { globbuf.gl_offs = 0; @@ -111,6 +110,7 @@ disk_t *fewf_init(const char *device, const int verbose, const arch_fnct_t *arch data->handle=libewf_open(filenames, num_files, LIBEWF_OPEN_READ); if(data->handle==NULL) { + log_error("libewf_open(%s) failed\n", device); #ifdef HAVE_GLOB_H globfree(&globbuf); #endif @@ -120,10 +120,20 @@ disk_t *fewf_init(const char *device, const int verbose, const arch_fnct_t *arch } if( libewf_parse_header_values( data->handle, LIBEWF_DATE_FORMAT_DAYMONTH) != 1 ) { - fprintf( stderr, "Unable to parse header values.\n" ); + log_error("%s Unable to parse EWF header values\n", device); } disk_car=(disk_t *)MALLOC(sizeof(*disk_car)); + init_disk(disk_car); disk_car->arch=arch; + disk_car->device=strdup(device); + disk_car->data=data; + disk_car->description=fewf_description; + disk_car->description_short=fewf_description_short; + disk_car->read=fewf_read; + disk_car->write=fewf_nowrite; + disk_car->sync=fewf_sync; + disk_car->access_mode=TESTDISK_O_RDONLY; + disk_car->clean=fewf_clean; #ifdef LIBEWF_GET_BYTES_PER_SECTOR_HAVE_TWO_ARGUMENTS { uint32_t bytes_per_sector; @@ -138,31 +148,23 @@ disk_t *fewf_init(const char *device, const int verbose, const arch_fnct_t *arch // printf("libewf_get_bytes_per_sector %u\n",disk_car->sector_size); if(disk_car->sector_size==0) disk_car->sector_size=DEFAULT_SECTOR_SIZE; + /* Set geometry */ + disk_car->CHS.cylinder=0; + disk_car->CHS.head=0; + disk_car->CHS.sector=1; + /* Get disk_real_size */ #ifdef LIBEWF_GET_MEDIA_SIZE_HAVE_TWO_ARGUMENTS { size64_t media_size; if(libewf_get_media_size(data->handle, &media_size)<0) - disk_car->disk_size=0; + disk_car->disk_real_size=0; else - disk_car->disk_size=media_size; + disk_car->disk_real_size=media_size; } #else - disk_car->disk_size=libewf_get_media_size(data->handle); + disk_car->disk_real_size=libewf_get_media_size(data->handle); #endif -// printf("libewf_get_media_size %llu\n",(long long unsigned) (disk_car->sector_size/disk_car->sector_size)); - disk_car->disk_real_size=disk_car->disk_size; - disk_car->CHS.head=255-1; - disk_car->CHS.sector=63; - disk_car->CHS.cylinder=(disk_car->disk_size/(disk_car->CHS.head+1))/disk_car->CHS.sector/disk_car->sector_size-1; - disk_car->device=strdup(device); - disk_car->write_used=0; - disk_car->description_txt[0]='\0'; - disk_car->description=fewf_description; - disk_car->description_short=fewf_description_short; - disk_car->read=fewf_read; - disk_car->write=((mode&O_RDWR)==O_RDWR?fewf_write:fewf_nowrite); - disk_car->clean=fewf_clean; - disk_car->data=data; + update_disk_car_fields(disk_car); #ifdef HAVE_GLOB_H globfree(&globbuf); #endif @@ -207,6 +209,12 @@ static int fewf_clean(disk_t *disk_car) return 0; } +static int fewf_sync(disk_t *disk_car) +{ + errno=EINVAL; + return -1; +} + static int fewf_read(disk_t *disk_car,const unsigned int count, void *nom_buffer, const uint64_t offset) { struct info_fewf_struct *data=(struct info_fewf_struct *)disk_car->data; @@ -229,12 +237,6 @@ static int fewf_read(disk_t *disk_car,const unsigned int count, void *nom_buffer return 0; } -static int fewf_write(disk_t *disk_car,const unsigned int count, const void *nom_buffer, const uint64_t offset) -{ - struct info_fewf_struct *data=(struct info_fewf_struct *)disk_car->data; - return -1; -} - static int fewf_nowrite(disk_t *disk_car,const unsigned int count, const void *nom_buffer, const uint64_t offset) { struct info_fewf_struct *data=(struct info_fewf_struct *)disk_car->data; diff --git a/src/hdaccess.c b/src/hdaccess.c index 9a1d2d34..6cee16db 100644 --- a/src/hdaccess.c +++ b/src/hdaccess.c @@ -1299,30 +1299,27 @@ disk_t *file_test_availability(const char *device, const int verbose, const arch dos_nr = 0x87; if(dos_nr>0) disk_car = hd_identify(verbose, dos_nr, arch, testdisk_mode); + if(disk_car!=NULL) + return disk_car; } #endif + /* Handle 'testdisk disk.E*' or 'photorec "disk.E*"' case */ + if(strncmp(device,"/dev/",5)!=0) + { +#if defined(HAVE_LIBEWF_H) && defined(HAVE_LIBEWF) && defined(HAVE_GLOB_H) + return fewf_init(device,verbose,arch,testdisk_mode); +#endif + } return disk_car; } disk_car=(disk_t *)MALLOC(sizeof(*disk_car)); disk_car->arch=arch; - disk_car->autodetect=0; - disk_car->disk_size=0; - /* Note, some Raid reserves the first 1024 512-sectors */ - disk_car->offset=0; + init_disk(disk_car); + disk_car->device=strdup(device); data=MALLOC(sizeof(*data)); data->handle=hd_h; -#if defined(POSIX_FADV_SEQUENTIAL) && defined(HAVE_POSIX_FADVISE) - posix_fadvise(hd_h,0,0,POSIX_FADV_SEQUENTIAL); -#endif data->mode=mode; - disk_car->rbuffer=NULL; - disk_car->wbuffer=NULL; - disk_car->rbuffer_size=0; - disk_car->wbuffer_size=0; - disk_car->device=strdup(device); - disk_car->model=NULL; - disk_car->write_used=0; - disk_car->description_txt[0]='\0'; + disk_car->data=data; disk_car->description=file_description; disk_car->description_short=file_description_short; disk_car->read=file_read; @@ -1334,8 +1331,6 @@ disk_t *file_test_availability(const char *device, const int verbose, const arch disk_car->access_mode|=TESTDISK_O_DIRECT; #endif disk_car->clean=file_clean; - disk_car->data=data; - disk_car->unit=UNIT_CHS; if(fstat(hd_h,&stat_rec)>=0) { if(S_ISREG(stat_rec.st_mode) && stat_rec.st_size > 0) @@ -1387,8 +1382,11 @@ disk_t *file_test_availability(const char *device, const int verbose, const arch else if(memcmp(buffer, evf_file_signature, 8)==0) { free(buffer); - close(hd_h); + free(data); + free(disk_car->device); + free(disk_car->model); free(disk_car); + close(hd_h); #if defined(HAVE_LIBEWF_H) && defined(HAVE_LIBEWF) return fewf_init(device,verbose,arch,testdisk_mode); #else @@ -1418,6 +1416,9 @@ disk_t *file_test_availability(const char *device, const int verbose, const arch free(buffer); } update_disk_car_fields(disk_car); +#if defined(POSIX_FADV_SEQUENTIAL) && defined(HAVE_POSIX_FADVISE) + posix_fadvise(hd_h,0,0,POSIX_FADV_SEQUENTIAL); +#endif if(disk_car->disk_real_size!=0) return disk_car; log_warning("Warning: can't get size for %s\n", device); @@ -1505,3 +1506,18 @@ void autoset_unit(disk_t *disk_car) disk_car->unit=UNIT_CHS; } +void init_disk(disk_t *disk) +{ + disk->autodetect=0; + disk->disk_size=0; + /* Note, some Raid reserve the first 1024 512-sectors */ + disk->offset=0; + disk->rbuffer=NULL; + disk->wbuffer=NULL; + disk->rbuffer_size=0; + disk->wbuffer_size=0; + disk->model=NULL; + disk->write_used=0; + disk->description_txt[0]='\0'; + disk->unit=UNIT_CHS; +} diff --git a/src/hdaccess.h b/src/hdaccess.h index 459b2f69..9a06ffea 100644 --- a/src/hdaccess.h +++ b/src/hdaccess.h @@ -5,3 +5,4 @@ disk_t *file_test_availability(const char *device, const int verbose, const arch void autoset_unit(disk_t *disk_car); void update_disk_car_fields(disk_t *disk_car); int generic_clean(disk_t *disk_car); +void init_disk(disk_t *disk); diff --git a/src/win32.c b/src/win32.c index 0972f1b8..9e1173a3 100644 --- a/src/win32.c +++ b/src/win32.c @@ -307,22 +307,13 @@ disk_t *file_test_availability_win32(const char *device, const int verbose, cons { struct info_file_win32_struct *data; disk_car=(disk_t *)MALLOC(sizeof(*disk_car)); - disk_car->sector_size=disk_get_sector_size_win32(handle, device, verbose); - disk_get_geometry_win32(&disk_car->CHS, handle, device, verbose); - disk_car->disk_real_size=disk_get_size_win32(handle, device, verbose); - update_disk_car_fields(disk_car); + init_disk(disk_car); disk_car->arch=arch; + disk_car->device=strdup(device); data=MALLOC(sizeof(*data)); data->handle=handle; data->mode=mode; - disk_car->rbuffer=NULL; - disk_car->wbuffer=NULL; - disk_car->rbuffer_size=0; - disk_car->wbuffer_size=0; - disk_car->device=strdup(device); - disk_car->model=NULL; - disk_car->write_used=0; - disk_car->description_txt[0]='\0'; + disk_car->data=data; disk_car->description=file_win32_description; disk_car->description_short=file_win32_description_short; disk_car->read=file_win32_read; @@ -330,23 +321,21 @@ disk_t *file_test_availability_win32(const char *device, const int verbose, cons disk_car->sync=file_win32_sync; disk_car->access_mode=testdisk_mode; disk_car->clean=file_win32_clean; - disk_car->data=data; - disk_car->offset=0; + disk_car->sector_size=disk_get_sector_size_win32(handle, device, verbose); + disk_get_geometry_win32(&disk_car->CHS, handle, device, verbose); + disk_car->disk_real_size=disk_get_size_win32(handle, device, verbose); file_win32_disk_get_model(handle, disk_car, verbose); - if(disk_car->disk_real_size==0) - { - log_warning("Warning: can't get size for %s\n",device); - free(data); - free(disk_car->device); - free(disk_car->model); - free(disk_car); - CloseHandle(handle); - return NULL; - } - disk_car->CHS.cylinder=(disk_car->disk_size/(disk_car->CHS.head+1))/disk_car->CHS.sector/disk_car->sector_size-1; - disk_car->unit=UNIT_CHS; - return disk_car; + update_disk_car_fields(disk_car); + if(disk_car->disk_real_size!=0) + return disk_car; + log_warning("Warning: can't get size for %s\n",device); + free(data); + free(disk_car->device); + free(disk_car->model); + free(disk_car); + CloseHandle(handle); } + return NULL; } static const char *file_win32_description(disk_t *disk_car)