Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F7712608
ewfacquire.c
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Size
102 KB
Referenced Files
None
Subscribers
None
ewfacquire.c
View Options
/*
* ewfacquire
* Reads data from a file or device and writes it in EWF format
*
* Copyright (c) 2006-2009, Joachim Metz <forensics@hoffmannbv.nl>,
* Hoffmann Investigations.
*
* Refer to AUTHORS for acknowledgements.
*
* This software is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This software 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 Lesser General Public License
* along with this software. If not, see <http://www.gnu.org/licenses/>.
*/
#include <common.h>
#include <memory.h>
#include <types.h>
#include <liberror.h>
#if defined( HAVE_STDLIB_H ) || defined( WINAPI )
#include <stdlib.h>
#endif
/* If libtool DLL support is enabled set LIBEWF_DLL_IMPORT
* before including libewf.h
*/
#if defined( _WIN32 ) && defined( DLL_EXPORT )
#define LIBEWF_DLL_IMPORT
#endif
#include <libewf.h>
#include <libsystem.h>
#include "byte_size_string.h"
#include "device_handle.h"
#include "ewfcommon.h"
#include "ewfinput.h"
#include "ewfoutput.h"
#include "imaging_handle.h"
#include "platform.h"
#include "process_status.h"
#include "storage_media_buffer.h"
#define EWFACQUIRE_2_TIB 0x20000000000ULL
#define EWFACQUIRE_INPUT_BUFFER_SIZE 64
imaging_handle_t *ewfacquire_imaging_handle = NULL;
int ewfacquire_abort = 0;
/* Prints the executable usage information to the stream
*/
void usage_fprint(
FILE *stream )
{
libsystem_character_t default_segment_file_size_string[ 16 ];
libsystem_character_t minimum_segment_file_size_string[ 16 ];
libsystem_character_t maximum_32bit_segment_file_size_string[ 16 ];
libsystem_character_t maximum_64bit_segment_file_size_string[ 16 ];
int result = 0;
if( stream == NULL )
{
return;
}
result = byte_size_string_create(
default_segment_file_size_string,
16,
EWFCOMMON_DEFAULT_SEGMENT_FILE_SIZE,
BYTE_SIZE_STRING_UNIT_MEBIBYTE,
NULL );
if( result == 1 )
{
result = byte_size_string_create(
minimum_segment_file_size_string,
16,
EWFCOMMON_MINIMUM_SEGMENT_FILE_SIZE,
BYTE_SIZE_STRING_UNIT_MEBIBYTE,
NULL );
}
if( result == 1 )
{
result = byte_size_string_create(
maximum_32bit_segment_file_size_string,
16,
EWFCOMMON_MAXIMUM_SEGMENT_FILE_SIZE_32BIT,
BYTE_SIZE_STRING_UNIT_MEBIBYTE,
NULL );
}
if( result == 1 )
{
result = byte_size_string_create(
maximum_64bit_segment_file_size_string,
16,
EWFCOMMON_MAXIMUM_SEGMENT_FILE_SIZE_64BIT,
BYTE_SIZE_STRING_UNIT_MEBIBYTE,
NULL );
}
fprintf( stream, "Use ewfacquire to acquire data from a file or device and store it in the EWF\n"
"format (Expert Witness Compression Format).\n\n" );
fprintf( stream, "Usage: ewfacquire [ -A codepage ] [ -b amount_of_sectors ] [ -B amount_of_bytes ]\n"
" [ -c compression_type ] [ -C case_number ] [ -d digest_type ]\n"
" [ -D description ] [ -e examiner_name ] [ -E evidence_number ]\n"
" [ -f format ] [ -g amount_of_sectors ] [ -l log_filename ]\n"
" [ -m media_type ] [ -M media_flags ] [ -N notes ] [ -o offset ]\n"
" [ -p process_buffer_size ] [ -P bytes_per_sector ]\n"
" [ -r read_error_retries ] [ -S segment_file_size ]\n"
" [ -t target ] [ -2 secondary_target ] [ -hqRsuvVw ] source\n\n" );
fprintf( stream, "\tsource: the source file or device\n\n" );
fprintf( stream, "\t-A: codepage of header section, options: ascii (default), windows-874,\n"
"\t windows-1250, windows-1251, windows-1252, windows-1253, windows-1254,\n"
"\t windows-1255, windows-1256, windows-1257, windows-1258\n" );
fprintf( stream, "\t-b: specify the amount of sectors to read at once (per chunk), options:\n"
"\t 64 (default), 128, 256, 512, 1024, 2048, 4096, 8192, 16384 or 32768\n" );
fprintf( stream, "\t-B: specify the amount of bytes to acquire (default is all bytes)\n" );
fprintf( stream, "\t-c: specify the compression type, options: none (default), empty-block, fast\n"
"\t or best\n" );
fprintf( stream, "\t-C: specify the case number (default is case_number).\n" );
fprintf( stream, "\t-d: calculate additional digest (hash) types besides md5, options: sha1\n" );
fprintf( stream, "\t-D: specify the description (default is description).\n" );
fprintf( stream, "\t-e: specify the examiner name (default is examiner_name).\n" );
fprintf( stream, "\t-E: specify the evidence number (default is evidence_number).\n" );
fprintf( stream, "\t-g specify the amount of sectors to be used as error granularity, options:\n"
"\t 64 (default), 128, 256, 512, 1024, 2048, 4096, 8192, 16384 or 32768\n" );
fprintf( stream, "\t-f: specify the EWF file format to write to, options: ewf, smart, ftk,\n"
"\t encase2, encase3, encase4, encase5, encase6 (default), linen5, linen6,\n"
"\t ewfx\n" );
fprintf( stream, "\t-h: shows this help\n" );
fprintf( stream, "\t-l: logs acquiry errors and the digest (hash) to the log_filename\n" );
fprintf( stream, "\t-m: specify the media type, options: fixed (default), removable, optical, memory\n" );
fprintf( stream, "\t-M: specify the media flags, options: logical, physical (default)\n" );
fprintf( stream, "\t-N: specify the notes (default is notes).\n" );
fprintf( stream, "\t-o: specify the offset to start to acquire (default is 0)\n" );
fprintf( stream, "\t-p: specify the process buffer size (default is the chunk size)\n" );
fprintf( stream, "\t-P: specify the amount of bytes per sector (default is 512)\n"
"\t (use this to override the automatic bytes per sector detection)\n" );
fprintf( stream, "\t-q: quiet shows no status information\n" );
fprintf( stream, "\t-r: specify the amount of retries when a read error occurs (default is 2)\n" );
fprintf( stream, "\t-R: resume acquiry at a safe point\n" );
fprintf( stream, "\t-s: swap byte pairs of the media data (from AB to BA)\n"
"\t (use this for big to little endian conversion and vice versa)\n" );
if( result == 1 )
{
fprintf( stream, "\t-S: specify the segment file size in bytes (default is %" PRIs_LIBSYSTEM ")\n"
"\t (minimum is %" PRIs_LIBSYSTEM ", maximum is %" PRIs_LIBSYSTEM " for encase6 format\n"
"\t and %" PRIs_LIBSYSTEM " for other formats)\n",
default_segment_file_size_string,
minimum_segment_file_size_string,
maximum_64bit_segment_file_size_string,
maximum_32bit_segment_file_size_string );
}
else
{
fprintf( stream, "\t-S: specify the segment file size in bytes (default is %" PRIu32 ")\n"
"\t (minimum is %" PRIu32 ", maximum is %" PRIu64 " for encase6 format\n"
"\t and %" PRIu32 " for other formats)\n",
(uint32_t) EWFCOMMON_DEFAULT_SEGMENT_FILE_SIZE,
(uint32_t) EWFCOMMON_MINIMUM_SEGMENT_FILE_SIZE,
(uint64_t) EWFCOMMON_MAXIMUM_SEGMENT_FILE_SIZE_64BIT,
(uint32_t) EWFCOMMON_MAXIMUM_SEGMENT_FILE_SIZE_32BIT );
}
fprintf( stream, "\t-t: specify the target file (without extension) to write to\n" );
fprintf( stream, "\t-u: unattended mode (disables user interaction)\n" );
fprintf( stream, "\t-v: verbose output to stderr\n" );
fprintf( stream, "\t-V: print version\n" );
fprintf( stream, "\t-w: wipe sectors on read error (mimic EnCase like behavior)\n" );
fprintf( stream, "\t-2: specify the secondary target file (without extension) to write to\n" );
}
/* Prints an overview of the acquiry parameters and asks the for confirmation
* Return 1 if confirmed by user, 0 otherwise or -1 on error
*/
int8_t ewfacquire_confirm_acquiry_parameters(
FILE *stream,
libsystem_character_t *input_buffer,
size_t input_buffer_size,
uint8_t resume_acquiry,
libsystem_character_t *filename,
libsystem_character_t *filename_secondary_copy,
libsystem_character_t *case_number,
libsystem_character_t *description,
libsystem_character_t *evidence_number,
libsystem_character_t *examiner_name,
libsystem_character_t *notes,
uint8_t media_type,
uint8_t media_flags,
int8_t compression_level,
uint8_t compression_flags,
uint8_t ewf_format,
off64_t acquiry_offset,
off64_t resume_acquiry_offset,
size64_t acquiry_size,
size64_t segment_file_size,
uint32_t bytes_per_sector,
uint32_t sectors_per_chunk,
uint32_t sector_error_granularity,
uint8_t read_error_retry,
uint8_t wipe_block_on_read_error,
liberror_error_t **error )
{
libsystem_character_t acquiry_size_string[ 16 ];
libsystem_character_t segment_file_size_string[ 16 ];
libsystem_character_t *fixed_string_variable = NULL;
static char *function = "ewfacquire_confirm_acquiry_parameters";
int8_t input_confirmed = -1;
int result = 0;
if( stream == NULL )
{
liberror_error_set(
error,
LIBERROR_ERROR_DOMAIN_ARGUMENTS,
LIBERROR_ARGUMENT_ERROR_INVALID_VALUE,
"%s: invalid stream.",
function );
return( -1 );
}
fprintf(
stream,
"The following acquiry parameters were provided:\n" );
fprintf(
stream,
"Image path and filename:\t%" PRIs_LIBSYSTEM "",
filename );
if( resume_acquiry == 0 )
{
if( ewf_format == LIBEWF_FORMAT_SMART )
{
fprintf(
stream,
".s01" );
}
else if( ( ewf_format == LIBEWF_FORMAT_EWF )
|| ( ewf_format == LIBEWF_FORMAT_EWFX ) )
{
fprintf(
stream,
".e01" );
}
else
{
fprintf(
stream,
".E01" );
}
}
fprintf(
stream,
"\n" );
if( filename_secondary_copy != NULL )
{
fprintf(
stream,
"Secondary copy:\t\t\t%" PRIs_LIBSYSTEM "",
filename_secondary_copy );
if( resume_acquiry == 0 )
{
if( ewf_format == LIBEWF_FORMAT_SMART )
{
fprintf(
stream,
".s01" );
}
else if( ( ewf_format == LIBEWF_FORMAT_EWF )
|| ( ewf_format == LIBEWF_FORMAT_EWFX ) )
{
fprintf(
stream,
".e01" );
}
else
{
fprintf(
stream,
".E01" );
}
}
fprintf(
stream,
"\n" );
}
fprintf(
stream,
"Case number:\t\t\t" );
if( case_number != NULL )
{
fprintf(
stream,
"%" PRIs_LIBSYSTEM "",
case_number );
}
fprintf(
stream,
"\n" );
fprintf(
stream,
"Description:\t\t\t" );
if( description != NULL )
{
fprintf(
stream,
"%" PRIs_LIBSYSTEM "",
description );
}
fprintf(
stream,
"\n" );
fprintf(
stream,
"Evidence number:\t\t" );
if( evidence_number != NULL )
{
fprintf(
stream,
"%" PRIs_LIBSYSTEM "",
evidence_number );
}
fprintf(
stream,
"\n" );
fprintf(
stream,
"Examiner name:\t\t\t" );
if( examiner_name != NULL )
{
fprintf(
stream,
"%" PRIs_LIBSYSTEM "",
examiner_name );
}
fprintf(
stream,
"\n" );
fprintf(
stream,
"Notes:\t\t\t\t" );
if( notes != NULL )
{
fprintf(
stream,
"%" PRIs_LIBSYSTEM "",
notes );
}
fprintf(
stream,
"\n" );
fprintf(
stream,
"Media type:\t\t\t" );
if( media_type == LIBEWF_MEDIA_TYPE_FIXED )
{
fprintf(
stream,
"fixed disk\n" );
}
else if( media_type == LIBEWF_MEDIA_TYPE_REMOVABLE )
{
fprintf(
stream,
"removable disk\n" );
}
else if( media_type == LIBEWF_MEDIA_TYPE_OPTICAL )
{
fprintf(
stream,
"optical disk (CD/DVD/BD)\n" );
}
else if( media_type == LIBEWF_MEDIA_TYPE_MEMORY )
{
fprintf(
stream,
"memory (RAM)\n" );
}
fprintf(
stream,
"Is physical:\t\t\t" );
if( ( media_flags & LIBEWF_MEDIA_FLAG_PHYSICAL ) == LIBEWF_MEDIA_FLAG_PHYSICAL )
{
fprintf(
stream,
"yes\n" );
}
else
{
fprintf(
stream,
"no\n" );
}
fprintf(
stream,
"Compression used:\t\t" );
if( compression_level == LIBEWF_COMPRESSION_FAST )
{
fprintf(
stream,
"fast\n" );
}
else if( compression_level == LIBEWF_COMPRESSION_BEST )
{
fprintf(
stream,
"best\n" );
}
else if( compression_level == LIBEWF_COMPRESSION_NONE )
{
if( ( compression_flags & LIBEWF_FLAG_COMPRESS_EMPTY_BLOCK ) == LIBEWF_FLAG_COMPRESS_EMPTY_BLOCK )
{
fprintf(
stream,
"empty block\n" );
}
else
{
fprintf(
stream,
"none\n" );
}
}
fprintf(
stream,
"EWF file format:\t\t" );
if( ewf_format == LIBEWF_FORMAT_EWF )
{
fprintf(
stream,
"original EWF\n" );
}
else if( ewf_format == LIBEWF_FORMAT_SMART )
{
fprintf(
stream,
"SMART\n" );
}
else if( ewf_format == LIBEWF_FORMAT_FTK )
{
fprintf(
stream,
"FTK Imager\n" );
}
else if( ewf_format == LIBEWF_FORMAT_ENCASE1 )
{
fprintf(
stream,
"EnCase 1\n" );
}
else if( ewf_format == LIBEWF_FORMAT_ENCASE2 )
{
fprintf(
stream,
"EnCase 2\n" );
}
else if( ewf_format == LIBEWF_FORMAT_ENCASE3 )
{
fprintf(
stream,
"EnCase 3\n" );
}
else if( ewf_format == LIBEWF_FORMAT_ENCASE4 )
{
fprintf(
stream,
"EnCase 4\n" );
}
else if( ewf_format == LIBEWF_FORMAT_ENCASE5 )
{
fprintf(
stream,
"EnCase 5\n" );
}
else if( ewf_format == LIBEWF_FORMAT_ENCASE6 )
{
fprintf(
stream,
"EnCase 6\n" );
}
else if( ewf_format == LIBEWF_FORMAT_LINEN5 )
{
fprintf(
stream,
"linen 5\n" );
}
else if( ewf_format == LIBEWF_FORMAT_LINEN6 )
{
fprintf(
stream,
"linen 6\n" );
}
else if( ewf_format == LIBEWF_FORMAT_EWFX )
{
fprintf(
stream,
"extended EWF (libewf)\n" );
}
else
{
fprintf(
stream,
"\n" );
}
fprintf(
stream, "Acquiry start offset:\t\t%" PRIi64 "\n",
acquiry_offset );
if( resume_acquiry != 0 )
{
fprintf(
stream, "Resuming acquiry at offset:\t%" PRIi64 "\n",
resume_acquiry_offset );
}
result = byte_size_string_create(
acquiry_size_string,
16,
acquiry_size,
BYTE_SIZE_STRING_UNIT_MEBIBYTE,
NULL );
fprintf(
stream,
"Amount of bytes to acquire:\t" );
if( acquiry_size == 0 )
{
fprintf(
stream,
"%" PRIu64 " (until end of input)",
acquiry_size );
}
else if( result == 1 )
{
fprintf(
stream,
"%" PRIs_LIBSYSTEM " (%" PRIu64 " bytes)",
acquiry_size_string, acquiry_size );
}
else
{
fprintf(
stream,
"%" PRIu64 " bytes",
acquiry_size );
}
fprintf(
stream,
"\n" );
result = byte_size_string_create(
segment_file_size_string,
16,
segment_file_size,
BYTE_SIZE_STRING_UNIT_MEBIBYTE,
NULL );
fprintf(
stream,
"Evidence segment file size:\t" );
if( result == 1 )
{
fprintf(
stream, "%" PRIs_LIBSYSTEM " (%" PRIu64 " bytes)",
segment_file_size_string,
segment_file_size );
}
else
{
fprintf(
stream,
"%" PRIu64 " bytes",
segment_file_size );
}
fprintf(
stream,
"\n" );
fprintf(
stream,
"Bytes per sector:\t\t%" PRIu32 "\n",
bytes_per_sector );
fprintf(
stream,
"Block size:\t\t\t%" PRIu32 " sectors\n",
sectors_per_chunk );
fprintf(
stream,
"Error granularity:\t\t%" PRIu32 " sectors\n",
sector_error_granularity );
fprintf(
stream,
"Retries on read error:\t\t%" PRIu8 "\n",
read_error_retry );
fprintf(
stream,
"Wipe sectors on read error:\t" );
if( wipe_block_on_read_error == 0 )
{
fprintf(
stream,
"no\n" );
}
else
{
fprintf(
stream,
"yes\n" );
}
fprintf(
stream,
"\n" );
/* Ask for confirmation
*/
while( input_confirmed == -1 )
{
if( ewfinput_get_fixed_string_variable(
stream,
input_buffer,
input_buffer_size,
_LIBSYSTEM_CHARACTER_T_STRING( "Continue acquiry with these values" ),
ewfinput_yes_no,
2,
0,
&fixed_string_variable,
error ) == -1 )
{
if( ( error != NULL )
&& ( *error != NULL ) )
{
libsystem_notify_print_error_backtrace(
*error );
}
liberror_error_free(
error );
fprintf(
stream,
"Unable to determine answer.\n" );
}
else if( ewfinput_determine_yes_no(
fixed_string_variable,
(uint8_t *) &input_confirmed,
error ) != 1 )
{
if( ( error != NULL )
&& ( *error != NULL ) )
{
libsystem_notify_print_error_backtrace(
*error );
}
liberror_error_free(
error );
fprintf(
stream,
"Selected option not supported, please try again or terminate using Ctrl^C.\n" );
input_confirmed = -1;
}
}
fprintf(
stream,
"\n" );
return( input_confirmed );
}
/* Reads a chunk of data from the file descriptor into the buffer
* Returns the amount of bytes read, 0 if at end of input or -1 on error
*/
ssize_t ewfacquire_read_buffer(
imaging_handle_t *imaging_handle,
device_handle_t *device_handle,
uint8_t *buffer,
size_t read_size,
off64_t current_offset,
size64_t total_input_size,
uint8_t read_error_retry,
uint32_t byte_error_granularity,
uint8_t wipe_block_on_read_error,
liberror_error_t **error )
{
libsystem_character_t error_string[ 128 ];
static char *function = "ewfacquire_read_buffer";
off64_t current_read_offset = 0;
off64_t current_calculated_offset = 0;
off64_t read_error_offset = 0;
ssize_t read_count = 0;
ssize_t read_error_buffer_offset = 0;
size_t remaining_read_size = 0;
size_t read_remaining_bytes = 0;
size_t error_remaining_bytes = 0;
size_t read_error_amount_of_bytes = 0;
uint32_t error_skip_bytes = 0;
uint32_t error_granularity_offset = 0;
int16_t read_amount_of_errors = 0;
if( imaging_handle == NULL )
{
liberror_error_set(
error,
LIBERROR_ERROR_DOMAIN_ARGUMENTS,
LIBERROR_ARGUMENT_ERROR_INVALID_VALUE,
"%s: invalid imaging handle.",
function );
return( -1 );
}
if( device_handle == NULL )
{
liberror_error_set(
error,
LIBERROR_ERROR_DOMAIN_ARGUMENTS,
LIBERROR_ARGUMENT_ERROR_INVALID_VALUE,
"%s: invalid device handle.",
function );
return( -1 );
}
if( buffer == NULL )
{
liberror_error_set(
error,
LIBERROR_ERROR_DOMAIN_ARGUMENTS,
LIBERROR_ARGUMENT_ERROR_INVALID_VALUE,
"%s: invalid buffer.",
function );
return( -1 );
}
if( read_size > (size_t) SSIZE_MAX )
{
liberror_error_set(
error,
LIBERROR_ERROR_DOMAIN_ARGUMENTS,
LIBERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
"%s: invalid read size value exceeds maximum.",
function );
return( -1 );
}
if( current_offset < 0 )
{
liberror_error_set(
error,
LIBERROR_ERROR_DOMAIN_ARGUMENTS,
LIBERROR_ARGUMENT_ERROR_VALUE_LESS_THAN_ZERO,
"%s: invalid current offset less than zero.",
function );
return( -1 );
}
if( byte_error_granularity == 0 )
{
liberror_error_set(
error,
LIBERROR_ERROR_DOMAIN_ARGUMENTS,
LIBERROR_ARGUMENT_ERROR_VALUE_ZERO_OR_LESS,
"%s: invalid byte error granularity zero or less.",
function );
return( -1 );
}
remaining_read_size = read_size;
while( read_amount_of_errors <= (int16_t) read_error_retry )
{
if( ewfacquire_abort != 0 )
{
break;
}
read_count = device_handle_read_buffer(
device_handle,
&( buffer[ read_error_buffer_offset ] ),
remaining_read_size,
error );
#if defined( HAVE_VERBOSE_OUTPUT )
libsystem_notify_verbose_printf(
"%s: read buffer at offset: %" PRIu64 " of size: %" PRIzd ".\n",
function,
current_offset + (off64_t) read_error_buffer_offset,
read_count );
#endif
if( read_count < 0 )
{
if( ( errno == ESPIPE )
|| ( errno == EPERM )
|| ( errno == ENXIO )
|| ( errno == ENODEV ) )
{
if( libsystem_error_copy_to_string(
errno,
error_string,
128,
error ) == 1 )
{
liberror_error_set(
error,
LIBERROR_ERROR_DOMAIN_IO,
LIBERROR_IO_ERROR_READ_FAILED,
"%s: error reading data: " PRIs_LIBSYSTEM ".",
function,
error_string );
}
else if( errno == ESPIPE )
{
liberror_error_set(
error,
LIBERROR_ERROR_DOMAIN_IO,
LIBERROR_IO_ERROR_READ_FAILED,
"%s: error reading data: invalid seek.",
function );
}
else if( errno == EPERM )
{
liberror_error_set(
error,
LIBERROR_ERROR_DOMAIN_IO,
LIBERROR_IO_ERROR_READ_FAILED,
"%s: error reading data: operation not permitted.",
function );
}
else if( errno == ENXIO )
{
liberror_error_set(
error,
LIBERROR_ERROR_DOMAIN_IO,
LIBERROR_IO_ERROR_READ_FAILED,
"%s: error reading data: no such device or address.",
function );
}
else if( errno == ENODEV )
{
liberror_error_set(
error,
LIBERROR_ERROR_DOMAIN_IO,
LIBERROR_IO_ERROR_READ_FAILED,
"%s: error reading data: no such device.",
function );
}
return( -1 );
}
#if defined( HAVE_VERBOSE_OUTPUT )
if( libsystem_error_copy_to_string(
errno,
error_string,
128,
error ) == 1 )
{
liberror_error_set(
error,
LIBERROR_ERROR_DOMAIN_IO,
LIBERROR_IO_ERROR_READ_FAILED,
"%s: error reading data: %" PRIs_LIBSYSTEM ".",
function,
error_string );
}
else
{
liberror_error_set(
error,
LIBERROR_ERROR_DOMAIN_IO,
LIBERROR_IO_ERROR_READ_FAILED,
"%s: error reading data.",
function );
}
#endif
if( ( error != NULL )
&& ( *error != NULL ) )
{
libsystem_notify_print_error_backtrace(
*error );
}
liberror_error_free(
error );
current_calculated_offset = current_offset + (off64_t) read_error_buffer_offset;
current_read_offset = device_handle_seek_offset(
device_handle,
0,
SEEK_CUR,
error );
if( current_read_offset != current_calculated_offset )
{
#if defined( HAVE_VERBOSE_OUTPUT )
libsystem_notify_verbose_printf(
"%s: correcting offset drift calculated: %" PRIjd ", current: %" PRIjd ".\n",
function,
current_calculated_offset,
current_read_offset );
#endif
if( current_read_offset < current_calculated_offset )
{
libsystem_notify_printf(
"%s: unable to correct offset drift.\n",
function );
return( -1 );
}
read_count = (ssize_t) ( current_read_offset - current_calculated_offset );
}
}
else
{
/* The last read is OK, correct read_count
*/
if( read_count == (ssize_t) remaining_read_size )
{
read_count = read_error_buffer_offset + remaining_read_size;
}
/* The entire read is OK
*/
if( read_count == (ssize_t) read_size )
{
break;
}
/* Check if the end of the input was reached
*/
if( ( current_offset + (off64_t) read_count ) >= (off64_t) total_input_size )
{
break;
}
/* No bytes were read
*/
if( read_count == 0 )
{
return( 0 );
}
}
/* Make sure read count is not negative
*/
if( read_count > 0 )
{
read_error_buffer_offset += read_count;
remaining_read_size -= (size_t) read_count;
}
/* There was a read error
*/
read_amount_of_errors++;
#if defined( HAVE_VERBOSE_OUTPUT )
libsystem_notify_verbose_printf(
"%s: read error: %" PRIi16 " at offset %" PRIjd ".\n",
function,
read_amount_of_errors,
current_offset + (off64_t) read_error_buffer_offset );
#endif
if( read_amount_of_errors > (int16_t) read_error_retry )
{
/* Check if last chunk is smaller than the chunk size and take corrective measures
*/
if( ( current_offset + (off64_t) read_size ) > (off64_t) total_input_size )
{
read_remaining_bytes = (size_t) ( total_input_size - current_offset );
}
else
{
read_remaining_bytes = read_size;
}
if( read_remaining_bytes > (size_t) SSIZE_MAX )
{
liberror_error_set(
error,
LIBERROR_ERROR_DOMAIN_ARGUMENTS,
LIBERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
"%s: invalid remaining bytes value exceeds maximum.",
function );
return( -1 );
}
error_remaining_bytes = read_remaining_bytes - read_error_buffer_offset;
read_error_offset = current_offset;
error_granularity_offset = ( read_error_buffer_offset / byte_error_granularity ) * byte_error_granularity;
error_skip_bytes = ( error_granularity_offset + byte_error_granularity ) - read_error_buffer_offset;
if( wipe_block_on_read_error == 1 )
{
#if defined( HAVE_VERBOSE_OUTPUT )
libsystem_notify_verbose_printf(
"%s: wiping block of %" PRIu32 " bytes at offset %" PRIu32 ".\n",
function,
byte_error_granularity,
error_granularity_offset );
#endif
if( memory_set(
&( buffer[ error_granularity_offset ] ),
0,
byte_error_granularity ) == NULL )
{
liberror_error_set(
error,
LIBERROR_ERROR_DOMAIN_MEMORY,
LIBERROR_MEMORY_ERROR_SET_FAILED,
"%s: unable to wipe data in chunk on error.",
function );
return( -1 );
}
read_error_offset += error_granularity_offset;
read_error_amount_of_bytes = byte_error_granularity;
}
else
{
#if defined( HAVE_VERBOSE_OUTPUT )
libsystem_notify_verbose_printf(
"%s: wiping remainder of block: %" PRIu32 " at offset %" PRIzd ".\n",
function,
error_skip_bytes,
read_error_buffer_offset );
#endif
if( memory_set(
&( buffer[ read_error_buffer_offset ] ),
0,
error_skip_bytes ) == NULL )
{
liberror_error_set(
error,
LIBERROR_ERROR_DOMAIN_MEMORY,
LIBERROR_MEMORY_ERROR_SET_FAILED,
"%s: unable to wipe data in chunk on error.",
function );
return( -1 );
}
read_error_offset += read_error_buffer_offset;
read_error_amount_of_bytes = error_skip_bytes;
}
#if defined( HAVE_VERBOSE_OUTPUT )
libsystem_notify_verbose_printf(
"%s: adding read error at offset: %" PRIu64 ", amount of bytes: %" PRIu32 ".\n",
function,
read_error_offset,
read_error_amount_of_bytes );
#endif
if( imaging_handle_add_read_error(
imaging_handle,
read_error_offset,
read_error_amount_of_bytes,
error ) != 1 )
{
liberror_error_set(
error,
LIBERROR_ERROR_DOMAIN_RUNTIME,
LIBERROR_RUNTIME_ERROR_APPEND_FAILED,
"%s: unable to add read errror.",
function );
return( -1 );
}
/* At the end of the input
*/
if( ( current_offset + (off64_t) read_remaining_bytes ) >= (off64_t) total_input_size )
{
#if defined( HAVE_VERBOSE_OUTPUT )
libsystem_notify_verbose_printf(
"%s: at end of input no remaining bytes to read from chunk.\n",
function );
#endif
read_count = (ssize_t) read_remaining_bytes;
break;
}
#if defined( HAVE_VERBOSE_OUTPUT )
libsystem_notify_verbose_printf(
"%s: skipping %" PRIu32 " bytes.\n",
function,
error_skip_bytes );
#endif
if( device_handle_seek_offset(
device_handle,
error_skip_bytes,
SEEK_CUR,
error ) == -1 )
{
if( libsystem_error_copy_to_string(
errno,
error_string,
128,
error ) == 1 )
{
libsystem_notify_printf(
"%s: unable skip %" PRIu32 " bytes after sector with error: %" PRIs_LIBSYSTEM ".",
function,
error_skip_bytes,
error_string );
}
else
{
libsystem_notify_printf(
"%s: unable to skip %" PRIu32 " bytes after sector.",
function,
error_skip_bytes );
}
return( -1 );
}
/* If error granularity skip is still within the chunk
*/
if( error_remaining_bytes > byte_error_granularity )
{
remaining_read_size = error_remaining_bytes - error_skip_bytes;
read_error_buffer_offset += error_skip_bytes;
read_amount_of_errors = 0;
#if defined( HAVE_VERBOSE_OUTPUT )
libsystem_notify_verbose_printf(
"%s: %" PRIzd " bytes remaining to read from chunk.\n",
function,
remaining_read_size );
#endif
}
else
{
read_count = (ssize_t) read_remaining_bytes;
#if defined( HAVE_VERBOSE_OUTPUT )
libsystem_notify_verbose_printf(
"%s: no bytes remaining to read from chunk.\n",
function );
#endif
break;
}
}
}
return( read_count );
}
/* Reads data from a file descriptor and writes it in EWF format
* Returns the amount of bytes written or -1 on error
*/
ssize64_t ewfacquire_read_input(
imaging_handle_t *imaging_handle,
device_handle_t *device_handle,
size64_t media_size,
size64_t acquiry_size,
off64_t acquiry_offset,
off64_t resume_acquiry_offset,
uint32_t bytes_per_sector,
uint8_t swap_byte_pairs,
uint32_t sector_error_granularity,
uint8_t read_error_retry,
uint8_t wipe_block_on_read_error,
size_t process_buffer_size,
libsystem_character_t *calculated_md5_hash_string,
size_t calculated_md5_hash_string_size,
libsystem_character_t *calculated_sha1_hash_string,
size_t calculated_sha1_hash_string_size,
process_status_t *process_status,
liberror_error_t **error )
{
storage_media_buffer_t *storage_media_buffer = NULL;
static char *function = "ewfacquire_read_input";
ssize64_t acquiry_count = 0;
size_t read_size = 0;
ssize_t read_count = 0;
ssize_t process_count = 0;
ssize_t write_count = 0;
uint32_t byte_error_granularity = 0;
uint32_t chunk_size = 0;
if( imaging_handle == NULL )
{
liberror_error_set(
error,
LIBERROR_ERROR_DOMAIN_ARGUMENTS,
LIBERROR_ARGUMENT_ERROR_INVALID_VALUE,
"%s: invalid imaging handle.",
function );
return( -1 );
}
if( device_handle == NULL )
{
liberror_error_set(
error,
LIBERROR_ERROR_DOMAIN_ARGUMENTS,
LIBERROR_ARGUMENT_ERROR_INVALID_VALUE,
"%s: invalid device handle.",
function );
return( -1 );
}
if( process_buffer_size > (size_t) SSIZE_MAX )
{
liberror_error_set(
error,
LIBERROR_ERROR_DOMAIN_ARGUMENTS,
LIBERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
"%s: invalid process buffer size value exceeds maximum.",
function );
return( -1 );
}
if( process_status == NULL )
{
liberror_error_set(
error,
LIBERROR_ERROR_DOMAIN_ARGUMENTS,
LIBERROR_ARGUMENT_ERROR_INVALID_VALUE,
"%s: invalid process status.",
function );
return( -1 );
}
if( ( acquiry_size == 0 )
|| ( acquiry_size > media_size )
|| ( acquiry_size > (ssize64_t) INT64_MAX ) )
{
liberror_error_set(
error,
LIBERROR_ERROR_DOMAIN_ARGUMENTS,
LIBERROR_ARGUMENT_ERROR_VALUE_OUT_OF_RANGE,
"%s: invalid write size value out of range.",
function );
return( -1 );
}
if( acquiry_offset > 0 )
{
if( ( acquiry_offset > (off64_t) media_size )
|| ( ( acquiry_size + acquiry_offset ) > media_size ) )
{
liberror_error_set(
error,
LIBERROR_ERROR_DOMAIN_RUNTIME,
LIBERROR_RUNTIME_ERROR_VALUE_OUT_OF_RANGE,
"%s: unable to acquire beyond media size.",
function );
return( -1 );
}
if( device_handle_seek_offset(
device_handle,
acquiry_offset,
SEEK_SET,
error ) == -1 )
{
liberror_error_set(
error,
LIBERROR_ERROR_DOMAIN_IO,
LIBERROR_IO_ERROR_SEEK_FAILED,
"%s: unable to find acquiry offset.",
function );
return( -1 );
}
}
if( resume_acquiry_offset > 0 )
{
if( ( acquiry_offset + resume_acquiry_offset ) > (off64_t) media_size )
{
liberror_error_set(
error,
LIBERROR_ERROR_DOMAIN_RUNTIME,
LIBERROR_RUNTIME_ERROR_VALUE_OUT_OF_RANGE,
"%s: unable to resume acquire beyond media size.",
function );
return( -1 );
}
if( device_handle_seek_offset(
device_handle,
resume_acquiry_offset,
SEEK_CUR,
error ) == -1 )
{
liberror_error_set(
error,
LIBERROR_ERROR_DOMAIN_IO,
LIBERROR_IO_ERROR_SEEK_FAILED,
"%s: unable to find acquiry offset.",
function );
return( -1 );
}
if( imaging_handle_seek_offset(
imaging_handle,
0,
error ) == -1 )
{
liberror_error_set(
error,
LIBERROR_ERROR_DOMAIN_IO,
LIBERROR_IO_ERROR_SEEK_FAILED,
"%s: unable to seek imaging offset.",
function );
return( -1 );
}
}
byte_error_granularity = sector_error_granularity * bytes_per_sector;
if( imaging_handle_get_chunk_size(
imaging_handle,
&chunk_size,
error ) != 1 )
{
liberror_error_set(
error,
LIBERROR_ERROR_DOMAIN_RUNTIME,
LIBERROR_RUNTIME_ERROR_GET_FAILED,
"%s: unable to retrieve chunk size.",
function );
return( -1 );
}
if( chunk_size == 0 )
{
liberror_error_set(
error,
LIBERROR_ERROR_DOMAIN_ARGUMENTS,
LIBERROR_ARGUMENT_ERROR_VALUE_OUT_OF_RANGE,
"%s: invalid chunk size.",
function );
return( -1 );
}
#if defined( HAVE_LOW_LEVEL_FUNCTIONS )
process_buffer_size = (size_t) chunk_size;
#else
if( process_buffer_size == 0 )
{
process_buffer_size = (size_t) chunk_size;
}
#endif
if( storage_media_buffer_initialize(
&storage_media_buffer,
process_buffer_size,
error ) != 1 )
{
liberror_error_set(
error,
LIBERROR_ERROR_DOMAIN_RUNTIME,
LIBERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
"%s: unable to create storage media buffer.",
function );
return( -1 );
}
while( acquiry_count < (ssize64_t) acquiry_size )
{
read_size = process_buffer_size;
if( ( (ssize64_t) acquiry_size - acquiry_count ) < (ssize64_t) read_size )
{
read_size = (size_t) ( (ssize64_t) acquiry_size - acquiry_count );
}
if( acquiry_count >= resume_acquiry_offset )
{
read_count = ewfacquire_read_buffer(
imaging_handle,
device_handle,
storage_media_buffer->raw_buffer,
storage_media_buffer->raw_buffer_size,
acquiry_offset + acquiry_count,
acquiry_size,
read_error_retry,
byte_error_granularity,
wipe_block_on_read_error,
error );
if( read_count < 0 )
{
liberror_error_set(
error,
LIBERROR_ERROR_DOMAIN_IO,
LIBERROR_IO_ERROR_READ_FAILED,
"%s: error reading data from input.",
function );
storage_media_buffer_free(
&storage_media_buffer,
NULL );
return( -1 );
}
if( read_count == 0 )
{
liberror_error_set(
error,
LIBERROR_ERROR_DOMAIN_IO,
LIBERROR_IO_ERROR_READ_FAILED,
"%s: unexpected end of input.",
function );
storage_media_buffer_free(
&storage_media_buffer,
NULL );
return( -1 );
}
#if defined( HAVE_LOW_LEVEL_FUNCTIONS )
storage_media_buffer->data_in_compression_buffer = 0;
#endif
storage_media_buffer->raw_buffer_amount = read_count;
/* Swap byte pairs
* The digest hashes are calcultated after swap
*/
if( ( swap_byte_pairs == 1 )
&& ( imaging_handle_swap_byte_pairs(
imaging_handle,
storage_media_buffer,
read_count,
error ) != 1 ) )
{
liberror_error_set(
error,
LIBERROR_ERROR_DOMAIN_CONVERSION,
LIBERROR_CONVERSION_ERROR_GENERIC,
"%s: unable to swap byte pairs.",
function );
storage_media_buffer_free(
&storage_media_buffer,
NULL );
return( -1 );
}
}
else
{
/* Align with resume acquiry offset if necessary
*/
if( ( resume_acquiry_offset - (off64_t) acquiry_count ) < (off64_t) read_size )
{
read_size = (size_t) ( resume_acquiry_offset - acquiry_count );
}
read_count = imaging_handle_read_buffer(
imaging_handle,
storage_media_buffer,
read_size,
error );
if( read_count < 0 )
{
liberror_error_set(
error,
LIBERROR_ERROR_DOMAIN_IO,
LIBERROR_IO_ERROR_READ_FAILED,
"%s: unable to read data.",
function );
storage_media_buffer_free(
&storage_media_buffer,
NULL );
return( -1 );
}
if( read_count == 0 )
{
liberror_error_set(
error,
LIBERROR_ERROR_DOMAIN_IO,
LIBERROR_IO_ERROR_READ_FAILED,
"%s: unexpected end of data.",
function );
storage_media_buffer_free(
&storage_media_buffer,
NULL );
return( -1 );
}
process_count = imaging_handle_prepare_read_buffer(
imaging_handle,
storage_media_buffer,
error );
if( process_count < 0 )
{
liberror_error_set(
error,
LIBERROR_ERROR_DOMAIN_IO,
LIBERROR_IO_ERROR_READ_FAILED,
"%s: unable to prepare buffer after read.",
function );
storage_media_buffer_free(
&storage_media_buffer,
NULL );
return( -1 );
}
if( process_count > (ssize_t) read_size )
{
liberror_error_set(
error,
LIBERROR_ERROR_DOMAIN_IO,
LIBERROR_IO_ERROR_READ_FAILED,
"%s: more bytes read than requested.",
function,
process_count, read_size );
storage_media_buffer_free(
&storage_media_buffer,
NULL );
return( -1 );
}
read_count = process_count;
#if defined( HAVE_LOW_LEVEL_FUNCTIONS )
/* Set the amount of chunk data in the buffer
*/
if( storage_media_buffer->data_in_compression_buffer == 1 )
{
storage_media_buffer->compression_buffer_amount = process_count;
}
#endif
}
if( imaging_handle_update_integrity_hash(
imaging_handle,
storage_media_buffer,
read_count,
error ) != 1 )
{
liberror_error_set(
error,
LIBERROR_ERROR_DOMAIN_RUNTIME,
LIBERROR_RUNTIME_ERROR_GENERIC,
"%s: unable to update integrity hash(es).",
function );
storage_media_buffer_free(
&storage_media_buffer,
NULL );
return( -1 );
}
if( acquiry_count >= resume_acquiry_offset )
{
process_count = imaging_handle_prepare_write_buffer(
imaging_handle,
storage_media_buffer,
error );
if( process_count < 0 )
{
liberror_error_set(
error,
LIBERROR_ERROR_DOMAIN_IO,
LIBERROR_IO_ERROR_READ_FAILED,
"%s: unable to prepare buffer before write.",
function );
storage_media_buffer_free(
&storage_media_buffer,
NULL );
return( -1 );
}
write_count = imaging_handle_write_buffer(
imaging_handle,
storage_media_buffer,
process_count,
error );
if( write_count < 0 )
{
liberror_error_set(
error,
LIBERROR_ERROR_DOMAIN_IO,
LIBERROR_IO_ERROR_WRITE_FAILED,
"%s: unable to write data to file.",
function );
storage_media_buffer_free(
&storage_media_buffer,
NULL );
return( -1 );
}
}
acquiry_count += read_count;
if( process_status_update(
process_status,
(size64_t) acquiry_count,
acquiry_size,
error ) != 1 )
{
liberror_error_set(
error,
LIBERROR_ERROR_DOMAIN_RUNTIME,
LIBERROR_RUNTIME_ERROR_SET_FAILED,
"%s: unable to update process status.",
function );
storage_media_buffer_free(
&storage_media_buffer,
NULL );
return( -1 );
}
if( ewfacquire_abort != 0 )
{
break;
}
}
if( storage_media_buffer_free(
&storage_media_buffer,
error ) != 1 )
{
liberror_error_set(
error,
LIBERROR_ERROR_DOMAIN_RUNTIME,
LIBERROR_RUNTIME_ERROR_FINALIZE_FAILED,
"%s: unable to free storage media buffer.",
function );
return( -1 );
}
if( acquiry_count >= resume_acquiry_offset )
{
write_count = imaging_handle_finalize(
imaging_handle,
calculated_md5_hash_string,
calculated_md5_hash_string_size,
calculated_sha1_hash_string,
calculated_sha1_hash_string_size,
error );
if( write_count == -1 )
{
liberror_error_set(
error,
LIBERROR_ERROR_DOMAIN_IO,
LIBERROR_IO_ERROR_WRITE_FAILED,
"%s: unable to finalize.",
function );
return( -1 );
}
acquiry_count += write_count;
}
return( acquiry_count );
}
/* Signal handler for ewfacquire
*/
void ewfacquire_signal_handler(
libsystem_signal_t signal )
{
liberror_error_t *error = NULL;
static char *function = "ewfacquire_signal_handler";
ewfacquire_abort = 1;
if( ( ewfacquire_imaging_handle != NULL )
&& ( imaging_handle_signal_abort(
ewfacquire_imaging_handle,
&error ) != 1 ) )
{
libsystem_notify_printf(
"%s: unable to signal imaging handle to abort.\n",
function );
libsystem_notify_print_error_backtrace(
error );
liberror_error_free(
&error );
return;
}
/* Force stdin to close otherwise any function reading it will remain blocked
*/
if( libsystem_file_io_close(
0 ) != 0 )
{
libsystem_notify_printf(
"%s: unable to close stdin.\n",
function );
}
}
/* The main program
*/
#if defined( LIBSYSTEM_HAVE_WIDE_CHARACTER )
int wmain( int argc, wchar_t * const argv[] )
#else
int main( int argc, char * const argv[] )
#endif
{
libsystem_character_t acquiry_operating_system[ 32 ];
libsystem_character_t input_buffer[ EWFACQUIRE_INPUT_BUFFER_SIZE ];
libsystem_character_t media_information_model[ 64 ];
libsystem_character_t media_information_serial_number[ 64 ];
device_handle_t *device_handle = NULL;
liberror_error_t *error = NULL;
process_status_t *process_status = NULL;
libsystem_character_t *acquiry_software_version = NULL;
libsystem_character_t *calculated_md5_hash_string = NULL;
libsystem_character_t *calculated_sha1_hash_string = NULL;
libsystem_character_t *case_number = NULL;
libsystem_character_t *description = NULL;
libsystem_character_t *evidence_number = NULL;
libsystem_character_t *examiner_name = NULL;
libsystem_character_t *fixed_string_variable = NULL;
libsystem_character_t *log_filename = NULL;
libsystem_character_t *notes = NULL;
libsystem_character_t *option_case_number = NULL;
libsystem_character_t *option_description = NULL;
libsystem_character_t *option_examiner_name = NULL;
libsystem_character_t *option_evidence_number = NULL;
libsystem_character_t *option_notes = NULL;
libsystem_character_t *option_secondary_target_filename = NULL;
libsystem_character_t *option_target_filename = NULL;
libsystem_character_t *program = _LIBSYSTEM_CHARACTER_T_STRING( "ewfacquire" );
libsystem_character_t *secondary_target_filename = NULL;
libsystem_character_t *target_filename = NULL;
FILE *log_file_stream = NULL;
libsystem_integer_t option = 0;
off64_t resume_acquiry_offset = 0;
ssize64_t read_count = 0;
size_t string_length = 0;
size_t secondary_target_filename_size = 0;
size_t target_filename_size = 0;
uint64_t acquiry_offset = 0;
uint64_t acquiry_size = 0;
uint64_t input_size_variable = 0;
uint64_t maximum_segment_file_size = 0;
uint64_t media_size = 0;
uint64_t process_buffer_size = EWFCOMMON_PROCESS_BUFFER_SIZE;
uint64_t segment_file_size = 0;
uint32_t bytes_per_sector = 512;
uint32_t sector_error_granularity = 0;
uint32_t sectors_per_chunk = 0;
uint8_t calculate_md5 = 1;
uint8_t calculate_sha1 = 0;
uint8_t compression_flags = 0;
uint8_t ewf_format = LIBEWF_FORMAT_ENCASE6;
uint8_t media_flags = LIBEWF_MEDIA_FLAG_PHYSICAL;
uint8_t media_type = LIBEWF_MEDIA_TYPE_FIXED;
uint8_t print_status_information = 1;
uint8_t read_error_retry = 2;
uint8_t resume_acquiry = 0;
uint8_t swap_byte_pairs = 0;
uint8_t verbose = 0;
uint8_t wipe_block_on_read_error = 0;
int8_t acquiry_parameters_confirmed = 0;
int8_t compression_level = LIBEWF_COMPRESSION_NONE;
int argument_set_compression = 0;
int argument_set_bytes_per_sector = 0;
int argument_set_format = 0;
int argument_set_media_type = 0;
int argument_set_offset = 0;
int argument_set_read_error_retry = 0;
int argument_set_sector_error_granularity = 0;
int argument_set_sectors_per_chunk = 0;
int argument_set_segment_file_size = 0;
int argument_set_size = 0;
int argument_set_media_flags = 0;
int argument_set_wipe_block_on_read_error = 0;
int default_media_flags = 0;
int default_media_type = 0;
int error_abort = 0;
int header_codepage = LIBEWF_CODEPAGE_ASCII;
int interactive_mode = 1;
int result = 0;
int status = 0;
libsystem_notify_set_stream(
stderr,
NULL );
libsystem_notify_set_verbose(
1 );
if( libsystem_initialize(
&error ) != 1 )
{
fprintf(
stderr,
"Unable to initialize system values.\n" );
libsystem_notify_print_error_backtrace(
error );
liberror_error_free(
&error );
return( EXIT_FAILURE );
}
ewfoutput_version_fprint(
stdout,
program );
while( ( option = libsystem_getopt(
argc,
argv,
_LIBSYSTEM_CHARACTER_T_STRING( "A:b:B:c:C:d:D:e:E:f:g:hl:m:M:N:o:p:P:qr:RsS:t:uvVw2:" ) ) ) != (libsystem_integer_t) -1 )
{
switch( option )
{
case (libsystem_integer_t) '?':
default:
fprintf(
stderr,
"Invalid argument: %" PRIs_LIBSYSTEM "\n",
argv[ optind ] );
usage_fprint(
stdout );
return( EXIT_FAILURE );
case (libsystem_integer_t) 'A':
if( ewfinput_determine_header_codepage(
optarg,
&header_codepage,
&error ) != 1 )
{
libsystem_notify_print_error_backtrace(
error );
liberror_error_free(
&error );
header_codepage = LIBEWF_CODEPAGE_ASCII;
fprintf(
stderr,
"Unsuported header codepage defaulting to: ascii.\n" );
}
break;
case (libsystem_integer_t) 'b':
if( ewfinput_determine_sectors_per_chunk(
optarg,
§ors_per_chunk,
&error ) != 1 )
{
libsystem_notify_print_error_backtrace(
error );
liberror_error_free(
&error );
sectors_per_chunk = 64;
fprintf(
stderr,
"Unsuported amount of sectors per chunk defaulting to: 64.\n" );
}
else
{
argument_set_sectors_per_chunk = 1;
}
break;
case (libsystem_integer_t) 'B':
string_length = libsystem_string_length(
optarg );
if( libsystem_string_to_uint64(
optarg,
string_length + 1,
&acquiry_size,
&error ) != 1 )
{
libsystem_notify_print_error_backtrace(
error );
liberror_error_free(
&error );
acquiry_size = 0;
fprintf(
stderr,
"Unsupported acquiry size defaulting to: all bytes.\n" );
}
argument_set_size = 1;
break;
case (libsystem_integer_t) 'c':
if( ewfinput_determine_compression_level(
optarg,
&compression_level,
&compression_flags,
&error ) != 1 )
{
libsystem_notify_print_error_backtrace(
error );
liberror_error_free(
&error );
compression_level = LIBEWF_COMPRESSION_NONE;
compression_flags = 0;
fprintf(
stderr,
"Unsupported compression type defaulting to: none.\n" );
}
else
{
argument_set_compression = 1;
}
break;
case (libsystem_integer_t) 'C':
option_case_number = optarg;
break;
case (libsystem_integer_t) 'd':
if( libsystem_string_compare(
optarg,
_LIBSYSTEM_CHARACTER_T_STRING( "sha1" ),
4 ) == 0 )
{
calculate_sha1 = 1;
}
else
{
fprintf(
stderr,
"Unsupported digest type.\n" );
}
break;
case (libsystem_integer_t) 'D':
option_description = optarg;
break;
case (libsystem_integer_t) 'e':
option_examiner_name = optarg;
break;
case (libsystem_integer_t) 'E':
option_evidence_number = optarg;
break;
case (libsystem_integer_t) 'f':
if( ewfinput_determine_ewf_format(
optarg,
&ewf_format,
&error ) != 1 )
{
libsystem_notify_print_error_backtrace(
error );
liberror_error_free(
&error );
ewf_format = LIBEWF_FORMAT_ENCASE6;
fprintf(
stderr,
"Unsupported EWF file format type defaulting to: encase6.\n" );
}
else
{
argument_set_format = 1;
}
break;
case (libsystem_integer_t) 'g':
if( ewfinput_determine_sectors_per_chunk(
optarg,
§or_error_granularity,
&error ) != 1 )
{
libsystem_notify_print_error_backtrace(
error );
liberror_error_free(
&error );
sector_error_granularity = 64;
fprintf(
stderr,
"Unsuported amount of sector error granularity defaulting to: 64.\n" );
}
else
{
argument_set_sector_error_granularity = 1;
}
break;
case (libsystem_integer_t) 'h':
usage_fprint(
stdout );
return( EXIT_SUCCESS );
case (libsystem_integer_t) 'l':
log_filename = optarg;
break;
case (libsystem_integer_t) 'm':
if( ewfinput_determine_media_type(
optarg,
&media_type,
&error ) != 1 )
{
libsystem_notify_print_error_backtrace(
error );
liberror_error_free(
&error );
media_type = LIBEWF_MEDIA_TYPE_FIXED;
fprintf(
stderr,
"Unsupported media type defaulting to: fixed.\n" );
}
else
{
argument_set_media_type = 1;
}
break;
case (libsystem_integer_t) 'M':
if( ewfinput_determine_media_flags(
optarg,
&media_flags,
&error ) != 1 )
{
libsystem_notify_print_error_backtrace(
error );
liberror_error_free(
&error );
media_flags = LIBEWF_MEDIA_FLAG_PHYSICAL;
fprintf(
stderr,
"Unsupported media flags defaulting to: physical.\n" );
}
else
{
argument_set_media_flags = 1;
}
break;
case (libsystem_integer_t) 'N':
option_notes = optarg;
break;
case (libsystem_integer_t) 'o':
string_length = libsystem_string_length(
optarg );
if( libsystem_string_to_uint64(
optarg,
string_length + 1,
&acquiry_offset,
&error ) != 1 )
{
libsystem_notify_print_error_backtrace(
error );
liberror_error_free(
&error );
acquiry_offset = 0;
fprintf(
stderr,
"Unsupported acquiry offset defaulting to: %" PRIu64 ".\n",
acquiry_offset );
}
argument_set_offset = 1;
break;
case (libsystem_integer_t) 'p':
string_length = libsystem_string_length(
optarg );
result = byte_size_string_convert(
optarg,
string_length,
&process_buffer_size,
&error );
if( result != 1 )
{
libsystem_notify_print_error_backtrace(
error );
liberror_error_free(
&error );
}
if( ( result != 1 )
|| ( process_buffer_size > (uint64_t) SSIZE_MAX ) )
{
process_buffer_size = 0;
fprintf(
stderr,
"Unsupported process buffer size defaulting to: chunk size.\n" );
}
break;
case (libsystem_integer_t) 'P':
string_length = libsystem_string_length(
optarg );
result = byte_size_string_convert(
optarg,
string_length,
&input_size_variable,
&error );
if( result != 1 )
{
libsystem_notify_print_error_backtrace(
error );
liberror_error_free(
&error );
}
if( ( result != 1 )
|| ( input_size_variable > (uint64_t) UINT32_MAX ) )
{
input_size_variable = 512;
fprintf(
stderr,
"Unsupported amount of bytes per sector defaulting to: %" PRIu64 ".\n",
input_size_variable );
}
else
{
argument_set_bytes_per_sector = 1;
}
bytes_per_sector = (uint32_t) input_size_variable;
break;
case (libsystem_integer_t) 'q':
print_status_information = 0;
break;
case (libsystem_integer_t) 'r':
string_length = libsystem_string_length(
optarg );
result = libsystem_string_to_uint64(
optarg,
string_length + 1,
&input_size_variable,
&error );
if( result != 1 )
{
libsystem_notify_print_error_backtrace(
error );
liberror_error_free(
&error );
}
if( ( result != 1 )
|| ( input_size_variable > 255 ) )
{
input_size_variable = 2;
fprintf(
stderr,
"Unsupported amount of read error retries defaulting to: %" PRIu64 ".\n",
input_size_variable );
}
read_error_retry = (uint8_t) input_size_variable;
argument_set_read_error_retry = 1;
break;
case (libsystem_integer_t) 'R':
resume_acquiry = 1;
break;
case (libsystem_integer_t) 's':
swap_byte_pairs = 1;
break;
case (libsystem_integer_t) 'S':
string_length = libsystem_string_length(
optarg );
result = byte_size_string_convert(
optarg,
string_length,
&segment_file_size,
NULL );
if( result != 1 )
{
libsystem_notify_print_error_backtrace(
error );
liberror_error_free(
&error );
}
argument_set_segment_file_size = 1;
if( ( result != 1 )
|| ( segment_file_size < EWFCOMMON_MINIMUM_SEGMENT_FILE_SIZE )
|| ( ( ewf_format == LIBEWF_FORMAT_ENCASE6 )
&& ( segment_file_size >= (uint64_t) EWFCOMMON_MAXIMUM_SEGMENT_FILE_SIZE_64BIT ) )
|| ( ( ewf_format != LIBEWF_FORMAT_ENCASE6 )
&& ( segment_file_size >= (uint64_t) EWFCOMMON_MAXIMUM_SEGMENT_FILE_SIZE_32BIT ) ) )
{
segment_file_size = EWFCOMMON_DEFAULT_SEGMENT_FILE_SIZE;
fprintf(
stderr,
"Unsupported segment file size defaulting to: %" PRIu64 ".\n",
segment_file_size );
}
break;
case (libsystem_integer_t) 't':
option_target_filename = optarg;
break;
case (libsystem_integer_t) 'u':
interactive_mode = 0;
break;
case (libsystem_integer_t) 'v':
verbose = 1;
break;
case (libsystem_integer_t) 'V':
ewfoutput_copyright_fprint(
stdout );
return( EXIT_SUCCESS );
case (libsystem_integer_t) 'w':
wipe_block_on_read_error = 1;
argument_set_wipe_block_on_read_error = 1;
break;
case (libsystem_integer_t) '2':
option_secondary_target_filename = optarg;
break;
}
}
if( optind == argc )
{
fprintf(
stderr,
"Missing source file or device.\n" );
usage_fprint(
stdout );
return( EXIT_FAILURE );
}
libsystem_notify_set_verbose(
verbose );
#if defined( HAVE_V2_API )
libewf_notify_set_verbose(
verbose );
libewf_notify_set_stream(
stderr,
NULL );
#else
libewf_set_notify_values(
stderr,
verbose );
#endif
/* Check if to read from stdin
*/
if( libsystem_string_compare(
argv[ optind ],
_LIBSYSTEM_CHARACTER_T_STRING( "-" ),
1 ) == 0 )
{
fprintf(
stderr,
"Reading from stdin not supported.\n" );
return( EXIT_FAILURE );
}
if( device_handle_initialize(
&device_handle,
&error ) != 1 )
{
fprintf(
stderr,
"Unable to create device handle.\n" );
libsystem_notify_print_error_backtrace(
error );
liberror_error_free(
&error );
return( EXIT_FAILURE );
}
/* Open the input file or device size
*/
if( device_handle_open_input(
device_handle,
argv[ optind ],
&error ) != 1 )
{
fprintf(
stderr,
"Unable to open file or device: %" PRIs_LIBSYSTEM ".\n",
argv[ optind ] );
libsystem_notify_print_error_backtrace(
error );
liberror_error_free(
&error );
device_handle_free(
&device_handle,
NULL );
return( EXIT_FAILURE );
}
if( device_handle_get_media_size(
device_handle,
&media_size,
&error ) != 1 )
{
fprintf(
stderr,
"Unable to retrieve media size.\n" );
libsystem_notify_print_error_backtrace(
error );
liberror_error_free(
&error );
device_handle_close(
device_handle,
NULL );
device_handle_free(
&device_handle,
NULL );
return( EXIT_FAILURE );
}
if( ( argument_set_bytes_per_sector == 0 )
&& ( device_handle_get_bytes_per_sector(
device_handle,
&bytes_per_sector,
&error ) != 1 ) )
{
fprintf(
stderr,
"Unable to retrieve bytes per sector.\n" );
libsystem_notify_print_error_backtrace(
error );
liberror_error_free(
&error );
device_handle_close(
device_handle,
NULL );
device_handle_free(
&device_handle,
NULL );
return( EXIT_FAILURE );
}
if( ( argument_set_media_type == 0 )
&& ( device_handle_get_media_type(
device_handle,
&media_type,
&error ) != 1 ) )
{
media_type = LIBEWF_MEDIA_TYPE_FIXED;
fprintf(
stderr,
"Unable to retrieve media type defaulting to: fixed.\n" );
libsystem_notify_print_error_backtrace(
error );
liberror_error_free(
&error );
}
if( device_handle_media_information_fprint(
device_handle,
stdout,
&error ) != 1 )
{
fprintf(
stderr,
"Unable to print media information.\n" );
libsystem_notify_print_error_backtrace(
error );
liberror_error_free(
&error );
}
if( ( acquiry_size == 0 )
|| ( acquiry_size > ( media_size - acquiry_offset ) ) )
{
acquiry_size = media_size - acquiry_offset;
}
/* Create the output targets
*/
if( option_target_filename != NULL )
{
string_length = libsystem_string_length(
option_target_filename );
if( string_length > 0 )
{
target_filename_size = string_length + 1;
target_filename = (libsystem_character_t *) memory_allocate(
sizeof( libsystem_character_t ) * target_filename_size );
if( target_filename == NULL )
{
fprintf(
stderr,
"Unable to create target filename string.\n" );
error_abort = 1;
}
else if( libsystem_string_copy(
target_filename,
option_target_filename,
target_filename_size ) == NULL )
{
fprintf(
stderr,
"Unable to set target filename string.\n" );
error_abort = 1;
}
}
}
else
{
target_filename_size = 1024;
target_filename = (libsystem_character_t *) memory_allocate(
sizeof( libsystem_character_t ) * target_filename_size );
if( target_filename == NULL )
{
fprintf(
stderr,
"Unable to create target filename string.\n" );
error_abort = 1;
}
/* Make sure to set the target filename if in unattended mode
*/
else if( interactive_mode == 0 )
{
if( libsystem_string_copy(
target_filename,
_LIBSYSTEM_CHARACTER_T_STRING( "image" ),
7 ) == NULL )
{
fprintf(
stderr,
"Unable to set target filename string.\n" );
error_abort = 1;
}
target_filename[ 7 ] = 0;
}
}
if( option_secondary_target_filename != NULL )
{
string_length = libsystem_string_length(
option_secondary_target_filename );
if( string_length > 0 )
{
secondary_target_filename_size = string_length + 1;
secondary_target_filename = (libsystem_character_t *) memory_allocate(
sizeof( libsystem_character_t ) * secondary_target_filename_size );
if( secondary_target_filename == NULL )
{
fprintf(
stderr,
"Unable to create secondary target filename string.\n" );
error_abort = 1;
}
else if( libsystem_string_copy(
secondary_target_filename,
option_secondary_target_filename,
secondary_target_filename_size ) == NULL )
{
fprintf(
stderr,
"Unable to set secondary target filename string.\n" );
error_abort = 1;
}
}
if( ( target_filename_size == secondary_target_filename_size )
&& ( libsystem_string_compare(
target_filename,
secondary_target_filename,
target_filename_size ) == 0 ) )
{
fprintf(
stderr,
"Primary and secondary target cannot be the same.\n" );
error_abort = 1;
}
}
/* Create the input buffers
*/
if( error_abort == 0 )
{
if( option_case_number != NULL )
{
string_length = libsystem_string_length(
option_case_number );
if( string_length > 0 )
{
case_number = (libsystem_character_t *) memory_allocate(
sizeof( libsystem_character_t ) * ( string_length + 1 ) );
if( case_number == NULL )
{
fprintf(
stderr,
"Unable to create case number string.\n" );
error_abort = 1;
}
else if( libsystem_string_copy(
case_number,
option_case_number,
string_length + 1 ) == NULL )
{
fprintf(
stderr,
"Unable to set case number string.\n" );
error_abort = 1;
}
}
}
else
{
case_number = (libsystem_character_t *) memory_allocate(
sizeof( libsystem_character_t ) * 256 );
if( case_number == NULL )
{
fprintf(
stderr,
"Unable to create case number string.\n" );
error_abort = 1;
}
}
}
if( error_abort == 0 )
{
if( option_description != NULL )
{
string_length = libsystem_string_length(
option_description );
if( string_length > 0 )
{
description = (libsystem_character_t *) memory_allocate(
sizeof( libsystem_character_t ) * ( string_length + 1 ) );
if( description == NULL )
{
fprintf(
stderr,
"Unable to create description string.\n" );
error_abort = 1;
}
else if( libsystem_string_copy(
description,
option_description,
string_length + 1 ) == NULL )
{
fprintf(
stderr,
"Unable to set description string.\n" );
error_abort = 1;
}
}
}
else
{
description = (libsystem_character_t *) memory_allocate(
sizeof( libsystem_character_t ) * 256 );
if( description == NULL )
{
fprintf(
stderr,
"Unable to create description string.\n" );
error_abort = 1;
}
}
}
if( error_abort == 0 )
{
if( option_examiner_name != NULL )
{
string_length = libsystem_string_length(
option_examiner_name );
if( string_length > 0 )
{
examiner_name = (libsystem_character_t *) memory_allocate(
sizeof( libsystem_character_t ) * ( string_length + 1 ) );
if( examiner_name == NULL )
{
fprintf(
stderr,
"Unable to create examiner name string.\n" );
error_abort = 1;
}
else if( libsystem_string_copy(
examiner_name,
option_examiner_name,
string_length + 1 ) == NULL )
{
fprintf(
stderr,
"Unable to set examiner name string.\n" );
error_abort = 1;
}
}
}
else
{
evidence_number = (libsystem_character_t *) memory_allocate(
sizeof( libsystem_character_t ) * 256 );
if( evidence_number == NULL )
{
fprintf(
stderr,
"Unable to create evidence number string.\n" );
error_abort = 1;
}
}
}
if( error_abort == 0 )
{
if( option_evidence_number != NULL )
{
string_length = libsystem_string_length(
option_evidence_number );
if( string_length > 0 )
{
evidence_number = (libsystem_character_t *) memory_allocate(
sizeof( libsystem_character_t ) * ( string_length + 1 ) );
if( evidence_number == NULL )
{
fprintf(
stderr,
"Unable to create evidence number string.\n" );
error_abort = 1;
}
else if( libsystem_string_copy(
evidence_number,
option_evidence_number,
string_length + 1 ) == NULL )
{
fprintf(
stderr,
"Unable to set evidence number string.\n" );
error_abort = 1;
}
}
}
else
{
examiner_name = (libsystem_character_t *) memory_allocate(
sizeof( libsystem_character_t ) * 256 );
if( examiner_name == NULL )
{
fprintf(
stderr,
"Unable to create examiner name string.\n" );
error_abort = 1;
}
}
}
if( error_abort == 0 )
{
if( option_notes != NULL )
{
string_length = libsystem_string_length(
option_notes );
if( string_length > 0 )
{
notes = (libsystem_character_t *) memory_allocate(
sizeof( libsystem_character_t ) * ( string_length + 1 ) );
if( notes == NULL )
{
fprintf(
stderr,
"Unable to create notes string.\n" );
error_abort = 1;
}
else if( libsystem_string_copy(
notes,
option_notes,
string_length + 1 ) == NULL )
{
fprintf(
stderr,
"Unable to set notes string.\n" );
error_abort = 1;
}
}
}
else
{
notes = (libsystem_character_t *) memory_allocate(
sizeof( libsystem_character_t ) * 256 );
if( notes == NULL )
{
fprintf(
stderr,
"Unable to create notes string.\n" );
error_abort = 1;
}
}
}
/* Set up the imaging handle
*/
if( imaging_handle_initialize(
&ewfacquire_imaging_handle,
calculate_md5,
calculate_sha1,
&error ) != 1 )
{
fprintf(
stderr,
"Unable to create imaging handle.\n" );
libsystem_notify_print_error_backtrace(
error );
liberror_error_free(
&error );
error_abort = 1;
}
if( error_abort != 0 )
{
if( case_number != NULL )
{
memory_free(
case_number );
}
if( description != NULL )
{
memory_free(
description );
}
if( examiner_name != NULL )
{
memory_free(
examiner_name );
}
if( evidence_number != NULL )
{
memory_free(
evidence_number );
}
if( notes != NULL )
{
memory_free(
notes );
}
if( secondary_target_filename != NULL )
{
memory_free(
secondary_target_filename );
}
if( target_filename != NULL )
{
memory_free(
target_filename );
}
device_handle_close(
device_handle,
NULL );
device_handle_free(
&device_handle,
NULL );
return( EXIT_FAILURE );
}
/* Request the necessary case data
*/
while( ( interactive_mode == 1 )
&& ( acquiry_parameters_confirmed == 0 ) )
{
fprintf(
stdout,
"Acquiry parameters required, please provide the necessary input\n" );
/* Target filename
*/
if( resume_acquiry != 0 )
{
while( ewfinput_get_string_variable(
stdout,
_LIBSYSTEM_CHARACTER_T_STRING( "Image path and filename with extension" ),
target_filename,
1024,
&error ) != 1 )
{
libsystem_notify_print_error_backtrace(
error );
liberror_error_free(
&error );
fprintf(
stdout,
"Filename is required, please try again or terminate using Ctrl^C.\n" );
}
}
else if( option_target_filename == NULL )
{
while( ewfinput_get_string_variable(
stdout,
_LIBSYSTEM_CHARACTER_T_STRING( "Image path and filename without extension" ),
target_filename,
1024,
&error ) != 1 )
{
libsystem_notify_print_error_backtrace(
error );
liberror_error_free(
&error );
fprintf(
stdout,
"Filename is required, please try again or terminate using Ctrl^C.\n" );
}
}
if( resume_acquiry != 0 )
{
if( libsystem_signal_attach(
ewfacquire_signal_handler,
&error ) != 1 )
{
fprintf(
stderr,
"Unable to attach signal handler.\n" );
libsystem_notify_print_error_backtrace(
error );
liberror_error_free(
&error );
}
if( imaging_handle_open_output(
ewfacquire_imaging_handle,
target_filename,
resume_acquiry,
&error ) != 1 )
{
fprintf(
stdout,
"Unable to resume acquire.\n" );
libsystem_notify_print_error_backtrace(
error );
liberror_error_free(
&error );
resume_acquiry = 0;
}
if( libsystem_signal_detach(
&error ) != 1 )
{
fprintf(
stderr,
"Unable to detach signal handler.\n" );
libsystem_notify_print_error_backtrace(
error );
liberror_error_free(
&error );
}
}
if( resume_acquiry != 0 )
{
if( imaging_handle_get_output_values(
ewfacquire_imaging_handle,
case_number,
256,
description,
256,
evidence_number,
256,
examiner_name,
256,
notes,
256,
&bytes_per_sector,
&acquiry_size,
&media_type,
&media_flags,
&compression_level,
&compression_flags,
&ewf_format,
&segment_file_size,
§ors_per_chunk,
§or_error_granularity,
&error ) != 1 )
{
fprintf(
stdout,
"Unable to determine previous acquiry parameters.\n" );
libsystem_notify_print_error_backtrace(
error );
liberror_error_free(
&error );
imaging_handle_close(
ewfacquire_imaging_handle,
NULL );
resume_acquiry = 0;
}
}
if( resume_acquiry != 0 )
{
if( imaging_handle_get_offset(
ewfacquire_imaging_handle,
(off64_t *) &resume_acquiry_offset,
&error ) != 1 )
{
fprintf(
stdout,
"Unable to determine resume acquiry offset.\n" );
libsystem_notify_print_error_backtrace(
error );
liberror_error_free(
&error );
imaging_handle_close(
ewfacquire_imaging_handle,
NULL );
resume_acquiry = 0;
}
}
if( resume_acquiry != 0 )
{
fprintf(
stdout,
"Resuming acquire at offset: %" PRIu64 ".\n",
resume_acquiry_offset );
}
if( resume_acquiry == 0 )
{
/* Case number
*/
if( ( option_case_number == NULL )
&& ( ewfinput_get_string_variable(
stdout,
_LIBSYSTEM_CHARACTER_T_STRING( "Case number" ),
case_number,
256,
&error ) == -1 ) )
{
libsystem_notify_print_error_backtrace(
error );
liberror_error_free(
&error );
fprintf(
stdout,
"Unable to set case number string.\n" );
case_number[ 0 ] = 0;
}
/* Description
*/
if( ( option_description == NULL )
&& ( ewfinput_get_string_variable(
stdout,
_LIBSYSTEM_CHARACTER_T_STRING( "Description" ),
description,
256,
&error ) == -1 ) )
{
libsystem_notify_print_error_backtrace(
error );
liberror_error_free(
&error );
fprintf(
stdout,
"Unable to set description string.\n" );
description[ 0 ] = 0;
}
/* Evidence number
*/
if( ( option_evidence_number == NULL )
&& ( ewfinput_get_string_variable(
stdout,
_LIBSYSTEM_CHARACTER_T_STRING( "Evidence number" ),
evidence_number,
256,
&error ) == -1 ) )
{
libsystem_notify_print_error_backtrace(
error );
liberror_error_free(
&error );
fprintf(
stdout,
"Unable to set evidence number string.\n" );
evidence_number[ 0 ] = 0;
}
/* Examiner name
*/
if( ( option_examiner_name == NULL )
&& ( ewfinput_get_string_variable(
stdout,
_LIBSYSTEM_CHARACTER_T_STRING( "Examiner name" ),
examiner_name,
256,
&error ) == -1 ) )
{
libsystem_notify_print_error_backtrace(
error );
liberror_error_free(
&error );
fprintf(
stdout,
"Unable to set examiner name string.\n" );
examiner_name[ 0 ] = 0;
}
/* Notes
*/
if( ( option_notes == NULL )
&& ( ewfinput_get_string_variable(
stdout,
_LIBSYSTEM_CHARACTER_T_STRING( "Notes" ),
notes,
256,
&error ) == -1 ) )
{
libsystem_notify_print_error_backtrace(
error );
liberror_error_free(
&error );
fprintf(
stdout,
"Unable to set notes string.\n" );
notes[ 0 ] = 0;
}
/* Media type
*/
if( argument_set_media_type == 0 )
{
if( media_type == LIBEWF_MEDIA_TYPE_REMOVABLE )
{
default_media_type = 1;
}
else if( media_type == LIBEWF_MEDIA_TYPE_OPTICAL )
{
default_media_type = 2;
}
else if( media_type == LIBEWF_MEDIA_TYPE_MEMORY )
{
default_media_type = 3;
}
else
{
default_media_type = EWFINPUT_MEDIA_TYPES_DEFAULT;
}
if( ewfinput_get_fixed_string_variable(
stdout,
input_buffer,
EWFACQUIRE_INPUT_BUFFER_SIZE,
_LIBSYSTEM_CHARACTER_T_STRING( "Media type" ),
ewfinput_media_types,
EWFINPUT_MEDIA_TYPES_AMOUNT,
(uint8_t) default_media_type,
&fixed_string_variable,
&error ) == -1 )
{
libsystem_notify_print_error_backtrace(
error );
liberror_error_free(
&error );
fprintf(
stdout,
"Unable to determine media type defaulting to: fixed.\n" );
media_type = LIBEWF_MEDIA_TYPE_FIXED;
}
else if( ewfinput_determine_media_type(
fixed_string_variable,
&media_type,
&error ) != 1 )
{
libsystem_notify_print_error_backtrace(
error );
liberror_error_free(
&error );
fprintf(
stdout,
"Unsupported media type defaulting to: fixed.\n" );
media_type = LIBEWF_MEDIA_TYPE_FIXED;
}
}
/* Media flags
*/
if( argument_set_media_flags == 0 )
{
default_media_flags = EWFINPUT_MEDIA_FLAGS_DEFAULT;
if( ( media_type == LIBEWF_MEDIA_TYPE_REMOVABLE )
|| ( media_type == LIBEWF_MEDIA_TYPE_OPTICAL ) )
{
default_media_flags = 0;
}
if( ewfinput_get_fixed_string_variable(
stdout,
input_buffer,
EWFACQUIRE_INPUT_BUFFER_SIZE,
_LIBSYSTEM_CHARACTER_T_STRING( "Media characteristics" ),
ewfinput_media_flags,
EWFINPUT_MEDIA_FLAGS_AMOUNT,
(uint8_t) default_media_flags,
&fixed_string_variable,
&error ) == -1 )
{
libsystem_notify_print_error_backtrace(
error );
liberror_error_free(
&error );
fprintf(
stdout,
"Unable to determine media flags defaulting to: physical.\n" );
media_flags = LIBEWF_MEDIA_FLAG_PHYSICAL;
}
else if( ewfinput_determine_media_flags(
fixed_string_variable,
&media_flags,
&error ) != 1 )
{
libsystem_notify_print_error_backtrace(
error );
liberror_error_free(
&error );
fprintf(
stdout,
"Unsupported media flags defaulting to: physical.\n" );
media_flags = LIBEWF_MEDIA_FLAG_PHYSICAL;
}
}
/* Compression
*/
if( argument_set_compression == 0 )
{
if( ewfinput_get_fixed_string_variable(
stdout,
input_buffer,
EWFACQUIRE_INPUT_BUFFER_SIZE,
_LIBSYSTEM_CHARACTER_T_STRING( "Use compression" ),
ewfinput_compression_levels,
EWFINPUT_COMPRESSION_LEVELS_AMOUNT,
EWFINPUT_COMPRESSION_LEVELS_DEFAULT,
&fixed_string_variable,
&error ) == -1 )
{
libsystem_notify_print_error_backtrace(
error );
liberror_error_free(
&error );
fprintf(
stdout,
"Unable to determine compression type defaulting to: none.\n" );
compression_level = LIBEWF_COMPRESSION_NONE;
compression_flags = 0;
}
else if( ewfinput_determine_compression_level(
fixed_string_variable,
&compression_level,
&compression_flags,
&error ) != 1 )
{
libsystem_notify_print_error_backtrace(
error );
liberror_error_free(
&error );
fprintf(
stdout,
"Unsupported compression type defaulting to: none.\n" );
compression_level = LIBEWF_COMPRESSION_NONE;
compression_flags = 0;
}
}
/* File format
*/
if( argument_set_format == 0 )
{
if( ewfinput_get_fixed_string_variable(
stdout,
input_buffer,
EWFACQUIRE_INPUT_BUFFER_SIZE,
_LIBSYSTEM_CHARACTER_T_STRING( "Use EWF file format" ),
ewfinput_format_types,
EWFINPUT_FORMAT_TYPES_AMOUNT,
EWFINPUT_FORMAT_TYPES_DEFAULT,
&fixed_string_variable,
&error ) == -1 )
{
libsystem_notify_print_error_backtrace(
error );
liberror_error_free(
&error );
fprintf(
stdout,
"Unable to determine EWF file format type defaulting to: encase6.\n" );
ewf_format = LIBEWF_FORMAT_ENCASE6;
}
else if( ewfinput_determine_ewf_format(
fixed_string_variable,
&ewf_format,
&error ) != 1 )
{
libsystem_notify_print_error_backtrace(
error );
liberror_error_free(
&error );
fprintf(
stdout,
"Unsupported EWF file format type defaulting to: encase6.\n" );
ewf_format = LIBEWF_FORMAT_ENCASE6;
}
}
}
if( ( resume_acquiry == 0 )
|| ( acquiry_size != media_size ) )
{
/* Offset of data to acquire
*/
if( ( argument_set_offset == 0 )
&& ( ewfinput_get_size_variable(
stdout,
input_buffer,
EWFACQUIRE_INPUT_BUFFER_SIZE,
_LIBSYSTEM_CHARACTER_T_STRING( "Start to acquire at offset" ),
0,
media_size,
0,
&acquiry_offset,
&error ) == -1 ) )
{
libsystem_notify_print_error_backtrace(
error );
liberror_error_free(
&error );
acquiry_offset = 0;
fprintf(
stdout,
"Unable to determine acquiry offset defaulting to: %" PRIu64 ".\n",
acquiry_offset );
}
}
if( resume_acquiry == 0 )
{
/* Size of data to acquire
*/
if( ( argument_set_size == 0 )
&& ( ewfinput_get_size_variable(
stdout,
input_buffer,
EWFACQUIRE_INPUT_BUFFER_SIZE,
_LIBSYSTEM_CHARACTER_T_STRING( "The amount of bytes to acquire" ),
0,
( media_size - acquiry_offset ),
( media_size - acquiry_offset ),
&acquiry_size,
&error ) == -1 ) )
{
libsystem_notify_print_error_backtrace(
error );
liberror_error_free(
&error );
acquiry_size = media_size - acquiry_offset;
fprintf(
stdout,
"Unable to determine input size defaulting to: %" PRIu64 ".\n",
acquiry_size );
}
/* Segment file size
*/
if( argument_set_segment_file_size == 0 )
{
if( ewf_format == LIBEWF_FORMAT_ENCASE6 )
{
maximum_segment_file_size = EWFCOMMON_MAXIMUM_SEGMENT_FILE_SIZE_64BIT;
}
else
{
maximum_segment_file_size = EWFCOMMON_MAXIMUM_SEGMENT_FILE_SIZE_32BIT;
}
if( segment_file_size == 0 )
{
segment_file_size = EWFCOMMON_DEFAULT_SEGMENT_FILE_SIZE;
}
if( ewfinput_get_byte_size_variable(
stdout,
input_buffer,
EWFACQUIRE_INPUT_BUFFER_SIZE,
_LIBSYSTEM_CHARACTER_T_STRING( "Evidence segment file size in bytes" ),
EWFCOMMON_MINIMUM_SEGMENT_FILE_SIZE,
maximum_segment_file_size,
segment_file_size,
&segment_file_size,
&error ) == -1 )
{
libsystem_notify_print_error_backtrace(
error );
liberror_error_free(
&error );
segment_file_size = EWFCOMMON_DEFAULT_SEGMENT_FILE_SIZE;
fprintf(
stdout,
"Unable to determine segment file size defaulting to: %" PRIu64 ".\n",
segment_file_size );
}
/* Make sure the segment file size is smaller than or equal to the maximum
*/
if( segment_file_size > maximum_segment_file_size )
{
segment_file_size = maximum_segment_file_size;
}
}
/* Bytes per sector
*/
if( argument_set_bytes_per_sector == 0 )
{
if( ewfinput_get_size_variable(
stdout,
input_buffer,
EWFACQUIRE_INPUT_BUFFER_SIZE,
_LIBSYSTEM_CHARACTER_T_STRING( "The amount of bytes per sector" ),
0,
UINT32_MAX,
bytes_per_sector,
&input_size_variable,
&error ) == -1 )
{
libsystem_notify_print_error_backtrace(
error );
liberror_error_free(
&error );
input_size_variable = 512;
fprintf(
stdout,
"Unable to determine bytes per sector defaulting to: %" PRIu64 ".\n",
input_size_variable );
}
bytes_per_sector = (uint32_t) input_size_variable;
}
/* Chunk size (sectors per block)
*/
if( argument_set_sectors_per_chunk == 0 )
{
if( ewfinput_get_fixed_string_variable(
stdout,
input_buffer,
EWFACQUIRE_INPUT_BUFFER_SIZE,
_LIBSYSTEM_CHARACTER_T_STRING( "The amount of sectors to read at once" ),
ewfinput_sector_per_block_sizes,
EWFINPUT_SECTOR_PER_BLOCK_SIZES_AMOUNT,
EWFINPUT_SECTOR_PER_BLOCK_SIZES_DEFAULT,
&fixed_string_variable,
&error ) == -1 )
{
libsystem_notify_print_error_backtrace(
error );
liberror_error_free(
&error );
fprintf(
stdout,
"Unable to determine sectors per chunk defaulting to: 64.\n" );
sectors_per_chunk = 64;
}
else if( ewfinput_determine_sectors_per_chunk(
fixed_string_variable,
§ors_per_chunk,
&error ) != 1 )
{
libsystem_notify_print_error_backtrace(
error );
liberror_error_free(
&error );
fprintf(
stdout,
"Unsupported sectors per chunk defaulting to: 64.\n" );
sectors_per_chunk = 64;
}
}
/* Error granularity
*/
if( argument_set_sector_error_granularity == 0 )
{
if( ewfinput_get_size_variable(
stdout,
input_buffer,
EWFACQUIRE_INPUT_BUFFER_SIZE,
_LIBSYSTEM_CHARACTER_T_STRING( "The amount of sectors to be used as error granularity" ),
1,
(uint64_t) sectors_per_chunk,
64,
&input_size_variable,
&error ) == -1 )
{
libsystem_notify_print_error_backtrace(
error );
liberror_error_free(
&error );
input_size_variable = 64;
fprintf(
stdout,
"Unable to determine sector error granularity defaulting to: %" PRIu64 ".\n",
input_size_variable );
}
sector_error_granularity = (uint32_t) input_size_variable;
}
}
/* The amount of read error retry
*/
if( argument_set_read_error_retry == 0 )
{
if( ewfinput_get_size_variable(
stdout,
input_buffer,
EWFACQUIRE_INPUT_BUFFER_SIZE,
_LIBSYSTEM_CHARACTER_T_STRING( "The amount of retries when a read error occurs" ),
0,
255,
2,
&input_size_variable,
&error ) == -1 )
{
libsystem_notify_print_error_backtrace(
error );
liberror_error_free(
&error );
input_size_variable = 2;
fprintf(
stdout,
"Unable to determine read error retry defaulting to: %" PRIu64 ".\n",
input_size_variable );
}
read_error_retry = (uint8_t) input_size_variable;
}
/* Wipe the sector on error
*/
if( argument_set_wipe_block_on_read_error == 0 )
{
if( ewfinput_get_fixed_string_variable(
stdout,
input_buffer,
EWFACQUIRE_INPUT_BUFFER_SIZE,
_LIBSYSTEM_CHARACTER_T_STRING( "Wipe sectors on read error (mimic EnCase like behavior)" ),
ewfinput_yes_no,
2,
1,
&fixed_string_variable,
&error ) == -1 )
{
libsystem_notify_print_error_backtrace(
error );
liberror_error_free(
&error );
fprintf(
stdout,
"Unable to determine wipe chunk on error defaulting to: no.\n" );
wipe_block_on_read_error = 0;
}
else if( ewfinput_determine_yes_no(
fixed_string_variable,
&wipe_block_on_read_error,
&error ) != 1 )
{
libsystem_notify_print_error_backtrace(
error );
liberror_error_free(
&error );
fprintf(
stdout,
"Unsupported wipe chunk on error defaulting to: no.\n" );
wipe_block_on_read_error = 0;
}
}
fprintf(
stdout,
"\n" );
/* Check if user is content with the acquiry parameters
*/
acquiry_parameters_confirmed = ewfacquire_confirm_acquiry_parameters(
stdout,
input_buffer,
EWFACQUIRE_INPUT_BUFFER_SIZE,
resume_acquiry,
target_filename,
secondary_target_filename,
case_number,
description,
evidence_number,
examiner_name,
notes,
media_type,
media_flags,
compression_level,
compression_flags,
ewf_format,
(off64_t) acquiry_offset,
resume_acquiry_offset,
(size64_t) acquiry_size,
(size64_t) segment_file_size,
bytes_per_sector,
sectors_per_chunk,
sector_error_granularity,
read_error_retry,
wipe_block_on_read_error,
&error );
if( acquiry_parameters_confirmed == -1 )
{
fprintf(
stdout,
"Unable to determine if acquiry parameters are correct aborting.\n" );
ewfacquire_abort = 1;
break;
}
/* Reset all parameters provided as command line arguments
*/
else if( acquiry_parameters_confirmed == 0 )
{
argument_set_compression = 0;
argument_set_format = 0;
argument_set_media_type = 0;
argument_set_offset = 0;
argument_set_read_error_retry = 0;
argument_set_sector_error_granularity = 0;
argument_set_sectors_per_chunk = 0;
argument_set_segment_file_size = 0;
argument_set_size = 0;
argument_set_media_flags = 0;
argument_set_wipe_block_on_read_error = 0;
if( resume_acquiry != 0 )
{
if( imaging_handle_close(
ewfacquire_imaging_handle,
&error ) != 0 )
{
fprintf(
stdout,
"Unable to close output file(s).\n" );
ewfacquire_abort = 1;
break;
}
}
}
else if( acquiry_size > EWFACQUIRE_2_TIB )
{
if( ( ewf_format != LIBEWF_FORMAT_ENCASE6 )
&& ( ewf_format != LIBEWF_FORMAT_EWFX ) )
{
fprintf(
stdout,
"Cannot acquire more than 2 TiB in selected ewf format.\n" );
acquiry_parameters_confirmed = 0;
}
}
}
if( libsystem_signal_attach(
ewfacquire_signal_handler,
&error ) != 1 )
{
fprintf(
stderr,
"Unable to attach signal handler.\n" );
libsystem_notify_print_error_backtrace(
error );
liberror_error_free(
&error );
}
if( resume_acquiry == 0 )
{
if( ewfacquire_abort == 0 )
{
if( platform_get_operating_system(
acquiry_operating_system,
32,
&error ) != 1 )
{
fprintf(
stdout,
"Unable to determine operating system.\n" );
libsystem_notify_print_error_backtrace(
error );
liberror_error_free(
&error );
acquiry_operating_system[ 0 ] = 0;
}
acquiry_software_version = _LIBSYSTEM_CHARACTER_T_STRING( LIBEWF_VERSION_STRING );
if( device_handle_get_media_information_value(
device_handle,
"model",
5,
media_information_model,
64,
&error ) != 1 )
{
fprintf(
stdout,
"Unable to retrieve model.\n" );
libsystem_notify_print_error_backtrace(
error );
liberror_error_free(
&error );
media_information_model[ 0 ] = 0;
}
if( device_handle_get_media_information_value(
device_handle,
"serial_number",
13,
media_information_serial_number,
64,
&error ) != 1 )
{
fprintf(
stdout,
"Unable to retrieve serial number.\n" );
libsystem_notify_print_error_backtrace(
error );
liberror_error_free(
&error );
media_information_serial_number[ 0 ] = 0;
}
if( imaging_handle_open_output(
ewfacquire_imaging_handle,
target_filename,
resume_acquiry,
&error ) != 1 )
{
fprintf(
stderr,
"Unable to open output file(s).\n" );
imaging_handle_free(
&ewfacquire_imaging_handle,
NULL );
error_abort = 1;
}
}
if( ( ewfacquire_abort == 0 )
&& ( error_abort == 0 ) )
{
if( secondary_target_filename != NULL )
{
if( imaging_handle_open_secondary_output(
ewfacquire_imaging_handle,
secondary_target_filename,
resume_acquiry,
&error ) != 1 )
{
fprintf(
stderr,
"Unable to open secondary output file(s).\n" );
imaging_handle_free(
&ewfacquire_imaging_handle,
NULL );
error_abort = 1;
}
}
}
if( ( ewfacquire_abort == 0 )
&& ( error_abort == 0 ) )
{
if( imaging_handle_set_output_values(
ewfacquire_imaging_handle,
case_number,
libsystem_string_length(
case_number ),
description,
libsystem_string_length(
description ),
evidence_number,
libsystem_string_length(
evidence_number ),
examiner_name,
libsystem_string_length(
examiner_name ),
notes,
libsystem_string_length(
notes ),
acquiry_operating_system,
libsystem_string_length(
acquiry_operating_system ),
program,
libsystem_string_length(
program ),
acquiry_software_version,
libsystem_string_length(
acquiry_software_version ),
media_information_model,
libsystem_string_length(
media_information_model ),
media_information_serial_number,
libsystem_string_length(
media_information_serial_number ),
header_codepage,
bytes_per_sector,
acquiry_size,
media_type,
media_flags,
compression_level,
compression_flags,
ewf_format,
segment_file_size,
sectors_per_chunk,
sector_error_granularity,
&error ) != 1 )
{
fprintf(
stderr,
"Unable to initialize output settings.\n" );
imaging_handle_close(
ewfacquire_imaging_handle,
NULL );
error_abort = 1;
}
}
if( ( ewfacquire_abort == 0 )
&& ( error_abort == 0 ) )
{
/* TODO for now just fake one session
*/
if( media_type == LIBEWF_MEDIA_TYPE_OPTICAL )
{
if( media_size > (size_t) UINT32_MAX )
{
fprintf(
stderr,
"Invalid media size value out of range to add session.\n" );
imaging_handle_close(
ewfacquire_imaging_handle,
NULL );
error_abort = 1;
}
if( imaging_handle_add_session(
ewfacquire_imaging_handle,
bytes_per_sector,
media_size,
&error ) != 1 )
{
fprintf(
stderr,
"Unable to add session.\n" );
imaging_handle_close(
ewfacquire_imaging_handle,
NULL );
error_abort = 1;
}
}
}
}
memory_free(
notes );
memory_free(
examiner_name );
memory_free(
evidence_number );
memory_free(
description );
memory_free(
case_number );
if( secondary_target_filename != NULL )
{
memory_free(
secondary_target_filename );
}
memory_free(
target_filename );
if( error_abort != 0 )
{
libsystem_notify_print_error_backtrace(
error );
liberror_error_free(
&error );
imaging_handle_free(
&ewfacquire_imaging_handle,
NULL );
device_handle_close(
device_handle,
NULL );
device_handle_free(
&device_handle,
NULL );
return( EXIT_FAILURE );
}
if( calculate_md5 == 1 )
{
calculated_md5_hash_string = (libsystem_character_t *) memory_allocate(
sizeof( libsystem_character_t ) * DIGEST_HASH_STRING_SIZE_MD5 );
if( calculated_md5_hash_string == NULL )
{
fprintf(
stderr,
"Unable to create calculated MD5 hash string.\n" );
imaging_handle_close(
ewfacquire_imaging_handle,
NULL );
imaging_handle_free(
&ewfacquire_imaging_handle,
NULL );
device_handle_close(
device_handle,
NULL );
device_handle_free(
&device_handle,
NULL );
return( EXIT_FAILURE );
}
}
if( calculate_sha1 == 1 )
{
calculated_sha1_hash_string = (libsystem_character_t *) memory_allocate(
sizeof( libsystem_character_t ) * DIGEST_HASH_STRING_SIZE_SHA1 );
if( calculated_sha1_hash_string == NULL )
{
fprintf(
stderr,
"Unable to create calculated SHA1 hash string.\n" );
memory_free(
calculated_md5_hash_string );
imaging_handle_close(
ewfacquire_imaging_handle,
NULL );
imaging_handle_free(
&ewfacquire_imaging_handle,
NULL );
device_handle_close(
device_handle,
NULL );
device_handle_free(
&device_handle,
NULL );
return( EXIT_FAILURE );
}
}
if( ewfacquire_abort == 0 )
{
if( process_status_initialize(
&process_status,
_LIBSYSTEM_CHARACTER_T_STRING( "Acquiry" ),
_LIBSYSTEM_CHARACTER_T_STRING( "acquired" ),
_LIBSYSTEM_CHARACTER_T_STRING( "Written" ),
stdout,
print_status_information,
&error ) != 1 )
{
fprintf(
stderr,
"Unable to initialize process status.\n" );
libsystem_notify_print_error_backtrace(
error );
liberror_error_free(
&error );
if( calculate_sha1 == 1 )
{
memory_free(
calculated_sha1_hash_string );
}
if( calculate_md5 == 1 )
{
memory_free(
calculated_md5_hash_string );
}
imaging_handle_close(
ewfacquire_imaging_handle,
NULL );
imaging_handle_free(
&ewfacquire_imaging_handle,
NULL );
device_handle_close(
device_handle,
NULL );
device_handle_free(
&device_handle,
NULL );
return( EXIT_FAILURE );
}
if( process_status_start(
process_status,
&error ) != 1 )
{
fprintf(
stderr,
"Unable to start process status.\n" );
libsystem_notify_print_error_backtrace(
error );
liberror_error_free(
&error );
process_status_free(
&process_status,
NULL );
if( calculate_sha1 == 1 )
{
memory_free(
calculated_sha1_hash_string );
}
if( calculate_md5 == 1 )
{
memory_free(
calculated_md5_hash_string );
}
imaging_handle_close(
ewfacquire_imaging_handle,
NULL );
imaging_handle_free(
&ewfacquire_imaging_handle,
NULL );
device_handle_close(
device_handle,
NULL );
device_handle_free(
&device_handle,
NULL );
return( EXIT_FAILURE );
}
/* Start acquiring data
*/
read_count = ewfacquire_read_input(
ewfacquire_imaging_handle,
device_handle,
media_size,
(size64_t) acquiry_size,
(off64_t) acquiry_offset,
resume_acquiry_offset,
bytes_per_sector,
swap_byte_pairs,
sector_error_granularity,
read_error_retry,
wipe_block_on_read_error,
(size_t) process_buffer_size,
calculated_md5_hash_string,
DIGEST_HASH_STRING_SIZE_MD5,
calculated_sha1_hash_string,
DIGEST_HASH_STRING_SIZE_SHA1,
process_status,
&error );
if( read_count <= -1 )
{
libsystem_notify_print_error_backtrace(
error );
liberror_error_free(
&error );
status = PROCESS_STATUS_FAILED;
}
else
{
status = PROCESS_STATUS_COMPLETED;
}
}
/* Done acquiring data
*/
if( device_handle_close(
device_handle,
&error ) != 0 )
{
fprintf(
stderr,
"Unable to close input file or device.\n" );
libsystem_notify_print_error_backtrace(
error );
liberror_error_free(
&error );
process_status_free(
&process_status,
NULL );
if( calculate_sha1 == 1 )
{
memory_free(
calculated_sha1_hash_string );
}
if( calculate_md5 == 1 )
{
memory_free(
calculated_md5_hash_string );
}
imaging_handle_close(
ewfacquire_imaging_handle,
NULL );
imaging_handle_free(
&ewfacquire_imaging_handle,
NULL );
device_handle_free(
&device_handle,
NULL );
return( EXIT_FAILURE );
}
if( device_handle_free(
&device_handle,
&error ) != 1 )
{
fprintf(
stderr,
"Unable to free device handle.\n" );
libsystem_notify_print_error_backtrace(
error );
liberror_error_free(
&error );
process_status_free(
&process_status,
NULL );
if( calculate_sha1 == 1 )
{
memory_free(
calculated_sha1_hash_string );
}
if( calculate_md5 == 1 )
{
memory_free(
calculated_md5_hash_string );
}
imaging_handle_close(
ewfacquire_imaging_handle,
NULL );
imaging_handle_free(
&ewfacquire_imaging_handle,
NULL );
return( EXIT_FAILURE );
}
if( ewfacquire_abort != 0 )
{
status = PROCESS_STATUS_ABORTED;
}
if( process_status_stop(
process_status,
(size64_t) read_count,
status,
&error ) != 1 )
{
fprintf(
stderr,
"Unable to stop process status.\n" );
libsystem_notify_print_error_backtrace(
error );
liberror_error_free(
&error );
process_status_free(
&process_status,
NULL );
if( calculate_sha1 == 1 )
{
memory_free(
calculated_sha1_hash_string );
}
if( calculate_md5 == 1 )
{
memory_free(
calculated_md5_hash_string );
}
imaging_handle_close(
ewfacquire_imaging_handle,
NULL );
imaging_handle_free(
&ewfacquire_imaging_handle,
NULL );
return( EXIT_FAILURE );
}
if( process_status_free(
&process_status,
&error ) != 1 )
{
fprintf(
stderr,
"Unable to free process status.\n" );
libsystem_notify_print_error_backtrace(
error );
liberror_error_free(
&error );
if( calculate_sha1 == 1 )
{
memory_free(
calculated_sha1_hash_string );
}
if( calculate_md5 == 1 )
{
memory_free(
calculated_md5_hash_string );
}
imaging_handle_close(
ewfacquire_imaging_handle,
NULL );
imaging_handle_free(
&ewfacquire_imaging_handle,
NULL );
return( EXIT_FAILURE );
}
if( status == PROCESS_STATUS_COMPLETED )
{
if( log_filename != NULL )
{
log_file_stream = libsystem_file_stream_open(
log_filename,
_LIBSYSTEM_CHARACTER_T_STRING( "a" ) );
if( log_file_stream == NULL )
{
fprintf(
stderr,
"Unable to open log file: %s.\n",
log_filename );
}
}
if( imaging_handle_acquiry_errors_fprint(
ewfacquire_imaging_handle,
stdout,
&error ) != 1 )
{
fprintf(
stderr,
"Unable to print acquiry errors.\n" );
libsystem_notify_print_error_backtrace(
error );
liberror_error_free(
&error );
}
if( ( log_file_stream != NULL )
&& ( imaging_handle_acquiry_errors_fprint(
ewfacquire_imaging_handle,
log_file_stream,
&error ) != 1 ) )
{
fprintf(
stderr,
"Unable to write acquiry errors in log file.\n" );
libsystem_notify_print_error_backtrace(
error );
liberror_error_free(
&error );
}
}
if( imaging_handle_close(
ewfacquire_imaging_handle,
&error ) != 0 )
{
fprintf(
stderr,
"Unable to close output file(s).\n" );
libsystem_notify_print_error_backtrace(
error );
liberror_error_free(
&error );
if( log_file_stream != NULL )
{
libsystem_file_stream_close(
log_file_stream );
}
if( calculate_sha1 == 1 )
{
memory_free(
calculated_sha1_hash_string );
}
if( calculate_md5 == 1 )
{
memory_free(
calculated_md5_hash_string );
}
imaging_handle_free(
&ewfacquire_imaging_handle,
NULL );
return( EXIT_FAILURE );
}
if( imaging_handle_free(
&ewfacquire_imaging_handle,
&error ) != 1 )
{
fprintf(
stderr,
"Unable to free imaging handle.\n" );
libsystem_notify_print_error_backtrace(
error );
liberror_error_free(
&error );
if( log_file_stream != NULL )
{
libsystem_file_stream_close(
log_file_stream );
}
if( calculate_sha1 == 1 )
{
memory_free(
calculated_sha1_hash_string );
}
if( calculate_md5 == 1 )
{
memory_free(
calculated_md5_hash_string );
}
return( EXIT_FAILURE );
}
if( libsystem_signal_detach(
&error ) != 1 )
{
fprintf(
stderr,
"Unable to detach signal handler.\n" );
libsystem_notify_print_error_backtrace(
error );
liberror_error_free(
&error );
}
if( status != PROCESS_STATUS_COMPLETED )
{
if( log_file_stream != NULL )
{
libsystem_file_stream_close(
log_file_stream );
}
if( calculate_sha1 == 1 )
{
memory_free(
calculated_sha1_hash_string );
}
if( calculate_md5 == 1 )
{
memory_free(
calculated_md5_hash_string );
}
return( EXIT_FAILURE );
}
if( calculate_md5 == 1 )
{
fprintf(
stdout,
"MD5 hash calculated over data:\t%" PRIs_LIBSYSTEM "\n",
calculated_md5_hash_string );
if( log_file_stream != NULL )
{
fprintf(
log_file_stream,
"MD5 hash calculated over data:\t%" PRIs_LIBSYSTEM "\n",
calculated_md5_hash_string );
}
memory_free(
calculated_md5_hash_string );
}
if( calculate_sha1 == 1 )
{
fprintf(
stdout,
"SHA1 hash calculated over data:\t%" PRIs_LIBSYSTEM "\n",
calculated_sha1_hash_string );
if( log_file_stream != NULL )
{
fprintf(
log_file_stream,
"SHA1 hash calculated over data:\t%" PRIs_LIBSYSTEM "\n",
calculated_sha1_hash_string );
}
memory_free(
calculated_sha1_hash_string );
}
if( log_file_stream != NULL )
{
if( libsystem_file_stream_close(
log_file_stream ) != 0 )
{
fprintf(
stderr,
"Unable to close log file: %s.\n",
log_filename );
}
}
return( EXIT_SUCCESS );
}
File Metadata
Details
Attached
Mime Type
text/x-c
Expires
Fri, Nov 21, 5:27 AM (1 d, 19 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1361001
Default Alt Text
ewfacquire.c (102 KB)
Attached To
Mode
rXMOUNT xmount
Attached
Detach File
Event Timeline
Log In to Comment