summaryrefslogtreecommitdiffstats
path: root/src/ewf.c
diff options
context:
space:
mode:
authorChristophe Grenier <grenier@cgsecurity.org>2007-10-29 22:38:52 +0100
committerChristophe Grenier <grenier@cgsecurity.org>2007-10-29 22:38:52 +0100
commit9928d99936105b4653d2d1b8ca74dc3ffba5c71e (patch)
tree06aa4f5e9f0055027c6fb54dd47a8414cf2fba32 /src/ewf.c
First version in git
Diffstat (limited to 'src/ewf.c')
-rw-r--r--src/ewf.c241
1 files changed, 241 insertions, 0 deletions
diff --git a/src/ewf.c b/src/ewf.c
new file mode 100644
index 0000000..4152f73
--- /dev/null
+++ b/src/ewf.c
@@ -0,0 +1,241 @@
+/*
+
+ File: ewf.c
+
+ Copyright (C) 2006-2007 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
+ 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_STRING_H
+#include <string.h>
+#endif
+#if defined(HAVE_LIBEWF_H) && defined(HAVE_LIBEWF)
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h> /* lseek, read, write, close */
+#endif
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h> /* open */
+#endif
+#include <stdio.h>
+#include <errno.h>
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h> /* free */
+#endif
+#ifdef HAVE_GLOB_H
+#include <glob.h>
+#endif
+#include "types.h"
+#include "common.h"
+#include "ewf.h"
+#include "fnctdsk.h"
+#ifndef O_BINARY
+#define O_BINARY 0
+#endif
+
+#include <libewf.h>
+#include "log.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);
+
+
+struct info_fewf_struct
+{
+ LIBEWF_HANDLE *handle;
+ uint64_t offset;
+ char file_name[DISKNAME_MAX];
+ int mode;
+ void *buffer;
+ unsigned int buffer_size;
+};
+
+disk_t *fewf_init(const char *device, const int verbose, const arch_fnct_t *arch, const int mode)
+{
+ unsigned int num_files=0;
+ char **filenames= NULL;
+ disk_t *disk_car=NULL;
+ struct info_fewf_struct *data;
+#ifdef HAVE_GLOB_H
+ glob_t globbuf;
+#endif
+ data=MALLOC(sizeof(*data));
+ data->offset=0;
+ strncpy(data->file_name,device,sizeof(data->file_name));
+ data->file_name[sizeof(data->file_name)-1]='\0';
+ data->buffer=NULL;
+ 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;
+ glob(data->file_name, GLOB_DOOFFS, NULL, &globbuf);
+ if(globbuf.gl_pathc>0)
+ {
+ filenames=MALLOC(globbuf.gl_pathc * sizeof(*filenames));
+ for (num_files=0; num_files<globbuf.gl_pathc; num_files++) {
+ filenames[num_files]=globbuf.gl_pathv[num_files];
+ }
+ }
+ }
+#else
+ filenames=MALLOC(1*sizeof(*filenames));
+ filenames[num_files] = data->file_name;
+ num_files++;
+#endif /*HAVE_GLOB_H*/
+ if(filenames!=NULL)
+ data->handle=libewf_open(filenames, num_files, LIBEWF_OPEN_READ);
+ if(data->handle==NULL)
+ {
+#ifdef HAVE_GLOB_H
+ globfree(&globbuf);
+#endif
+ free(filenames);
+ free(data);
+ return NULL;
+ }
+ if( libewf_parse_header_values( data->handle, LIBEWF_DATE_FORMAT_DAYMONTH) != 1 )
+ {
+ fprintf( stderr, "Unable to parse header values.\n" );
+ }
+ disk_car=(disk_t *)MALLOC(sizeof(*disk_car));
+ disk_car->arch=arch;
+ disk_car->sector_size=libewf_get_bytes_per_sector(data->handle);
+// 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;
+ disk_car->disk_size=libewf_get_media_size(data->handle);
+ disk_car->disk_real_size=disk_car->disk_size;
+// printf("libewf_get_media_size %llu\n",(long long unsigned) (disk_car->sector_size/disk_car->sector_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;
+#ifdef HAVE_GLOB_H
+ globfree(&globbuf);
+#endif
+ free(filenames);
+ return disk_car;
+}
+
+static const char *fewf_description(disk_t *disk_car)
+{
+ const struct info_fewf_struct *data=(const struct info_fewf_struct *)disk_car->data;
+ char buffer_disk_size[100];
+ snprintf(disk_car->description_txt, sizeof(disk_car->description_txt),"Image %s - %s - CHS %u %u %u%s",
+ data->file_name, size_to_unit(disk_car->disk_size,buffer_disk_size),
+ disk_car->CHS.cylinder+1, disk_car->CHS.head+1, disk_car->CHS.sector,((data->mode&O_RDWR)==O_RDWR?"":" (RO)"));
+ return disk_car->description_txt;
+}
+
+static const char *fewf_description_short(disk_t *disk_car)
+{
+ const struct info_fewf_struct *data=(const struct info_fewf_struct *)disk_car->data;
+ char buffer_disk_size[100];
+ snprintf(disk_car->description_short_txt, sizeof(disk_car->description_txt),"Image %s - %s%s",
+ data->file_name, size_to_unit(disk_car->disk_size,buffer_disk_size),
+ ((data->mode&O_RDWR)==O_RDWR?"":" (RO)"));
+ return disk_car->description_short_txt;
+}
+
+static int fewf_clean(disk_t *disk_car)
+{
+ if(disk_car->data!=NULL)
+ {
+ struct info_fewf_struct *data=(struct info_fewf_struct *)disk_car->data;
+ libewf_close(data->handle);
+ if(data->buffer!=NULL)
+ {
+ free(data->buffer);
+ data->buffer=NULL;
+ }
+ free(disk_car->data);
+ disk_car->data=NULL;
+ }
+ return 0;
+}
+
+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;
+ int64_t taille;
+ taille=libewf_read_random(data->handle, nom_buffer, count, offset);
+ if(taille!=count)
+ {
+ log_error("fewf_read(xxx,%u,buffer,%lu(%u/%u/%u)) read err: ",
+ (unsigned)(count/disk_car->sector_size), (long unsigned)(offset/disk_car->sector_size),
+ offset2cylinder(disk_car,offset), offset2head(disk_car,offset), offset2sector(disk_car,offset));
+ if(taille<0)
+ log_error("%s\n", strerror(errno));
+ else if(taille==0)
+ log_error("read after end of file\n");
+ else
+ log_error("Partial read\n");
+ if(taille<=0)
+ return -1;
+ }
+ 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;
+ log_error("fewf_nowrite(xx,%u,buffer,%lu(%u/%u/%u)) write refused\n",
+ (unsigned)(count/disk_car->sector_size), (long unsigned)(offset/disk_car->sector_size),
+ offset2cylinder(disk_car,offset), offset2head(disk_car,offset), offset2sector(disk_car,offset));
+ return -1;
+}
+
+const char*td_ewf_version(void)
+{
+#ifdef LIBEWF_VERSION
+ return LIBEWF_VERSION;
+#else
+ return "available";
+#endif
+}
+#else
+#include "ewf.h"
+const char*td_ewf_version(void)
+{
+ return "none";
+}
+#endif