/* * EwfSize */ static int EwfSize(void *p_handle, uint64_t *p_size) { pts_EwfHandle p_ewf_handle=(pts_EwfHandle)p_handle; #ifdef HAVE_LIBEWF_V2_API if(libewf_handle_get_media_size(p_ewf_handle->h_ewf,p_size,NULL)!=1) { #else if(libewf_get_media_size(p_ewf_handle->h_ewf,p_size)!=1) { #endif return EWF_GET_SIZE_FAILED; } return EWF_OK; } /* * EwfRead */ static int EwfRead(void *p_handle, char *p_buf, off_t offset, size_t count, size_t *p_read, int *p_errno) { pts_EwfHandle p_ewf_handle=(pts_EwfHandle)p_handle; // TODO: Return value of libewf_handle_read_buffer is ssize_t with -1 on error size_t bytes_read; #ifdef HAVE_LIBEWF_V2_API if(libewf_handle_seek_offset(p_ewf_handle->h_ewf, offset, SEEK_SET, NULL)!=-1) #else if(libewf_seek_offset(p_ewf_handle->h_ewf,offset)!=-1) #endif { #ifdef HAVE_LIBEWF_V2_API bytes_read=libewf_handle_read_buffer(p_ewf_handle->h_ewf, p_buf, count, NULL); #else bytes_read=libewf_read_buffer(p_ewf_handle->h_ewf,p_buf,count); #endif if(bytes_read!=count) return EWF_READ_FAILED; } else { return EWF_SEEK_FAILED; } *p_read=bytes_read; return EWF_OK; }
/* Tests libewf_handle_seek_offset * Returns 1 if successful, 0 if not or -1 on error */ int ewf_test_seek_offset( libewf_handle_t *handle, off64_t input_offset, int input_whence, off64_t expected_offset, libcerror_error_t **error ) { static char *function = "ewf_test_seek_offset"; off64_t result_offset = 0; result_offset = libewf_handle_seek_offset( handle, input_offset, input_whence, error ); if( result_offset != expected_offset ) { if( result_offset == -1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_IO, LIBCERROR_IO_ERROR_SEEK_FAILED, "%s: unable to seek offset: %" PRIi64 ".", function, input_offset ); return( -1 ); } fprintf( stderr, "%s: unexpected result offset: %" PRIi64 "\n", function, result_offset ); return( 0 ); } if( result_offset == -1 ) { libcerror_error_free( error ); } return( 1 ); }
static ut64 ewf__lseek(RIO *io, RIODesc *fd, ut64 offset, int whence) { if (RIOEWF_IS_VALID (fd)) { size64_t media_size; switch (whence) { case SEEK_SET: /* ignore */ break; case SEEK_CUR: offset += io->off; break; case SEEK_END: if (libewf_handle_get_media_size ( RIOEWF_HANDLE (fd), &media_size, NULL)) offset = media_size - offset; break; } libewf_handle_seek_offset (RIOEWF_HANDLE (fd), offset, whence, NULL); return offset; } return (ut64)-1; }
/* Seeks a specific offset from the input handle * Return the offset if successful or -1 on error */ off64_t mount_handle_seek_offset( mount_handle_t *mount_handle, off64_t offset, int whence, libcerror_error_t **error ) { static char *function = "mount_handle_seek_offset"; if( mount_handle == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid mount handle.", function ); return( -1 ); } offset = libewf_handle_seek_offset( mount_handle->input_handle, offset, whence, error ); if( offset == -1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_IO, LIBCERROR_IO_ERROR_SEEK_FAILED, "%s: unable to seek offset in input handle.", function ); return( -1 ); } return( offset ); }
/* Tests libewf_handle_seek_offset * Returns 1 if successful, 0 if not or -1 on error */ int ewf_test_seek_offset( libewf_handle_t *handle, off64_t input_offset, int input_whence, off64_t output_offset ) { libcerror_error_t *error = NULL; const char *whence_string = NULL; off64_t result_offset = 0; int result = 0; if( handle == NULL ) { return( -1 ); } if( input_whence == SEEK_CUR ) { whence_string = "SEEK_CUR"; } else if( input_whence == SEEK_END ) { whence_string = "SEEK_END"; } else if( input_whence == SEEK_SET ) { whence_string = "SEEK_SET"; } else { whence_string = "UNKNOWN"; } fprintf( stdout, "Testing seek of offset: %" PRIi64 " and whence: %s\t", input_offset, whence_string ); result_offset = libewf_handle_seek_offset( handle, input_offset, input_whence, &error ); if( result_offset == output_offset ) { result = 1; } if( result != 0 ) { fprintf( stdout, "(PASS)" ); } else { fprintf( stdout, "(FAIL)" ); } fprintf( stdout, "\n" ); if( error != NULL ) { if( result != 1 ) { libcerror_error_backtrace_fprint( error, stderr ); } libcerror_error_free( &error ); } return( result ); }
/* Seeks a certain offset in the media data * Returns a Python object holding the offset if successful or NULL on error */ PyObject *pyewf_handle_seek_offset( pyewf_handle_t *pyewf_handle, PyObject *arguments, PyObject *keywords ) { char error_string[ PYEWF_ERROR_STRING_SIZE ]; liberror_error_t *error = NULL; static char *function = "pyewf_handle_seek_offset"; static char *keyword_list[] = { "offset", "whence", NULL }; off64_t offset = 0; int whence = 0; if( pyewf_handle == NULL ) { PyErr_Format( PyExc_TypeError, "%s: invalid pyewf handle.", function ); return( NULL ); } if( pyewf_handle->handle == NULL ) { PyErr_Format( PyExc_TypeError, "%s: invalid pyewf handle - missing libewf handle.", function ); return( NULL ); } if( PyArg_ParseTupleAndKeywords( arguments, keywords, "L|i", keyword_list, &offset, &whence ) == 0 ) { return( NULL ); } if( libewf_handle_seek_offset( pyewf_handle->handle, offset, whence, &error ) < 0 ) { if( liberror_error_backtrace_sprint( error, error_string, PYEWF_ERROR_STRING_SIZE ) == -1 ) { PyErr_Format( PyExc_IOError, "%s: unable to seek offset.", function ); } else { PyErr_Format( PyExc_IOError, "%s: unable to seek offset.\n%s", function, error_string ); } liberror_error_free( &error ); return( NULL ); } return( Py_None ); }
/* Tests libewf_handle_read_buffer and libewf_handle_write_buffer * Returns 1 if successful, 0 if not or -1 on error */ int ewf_test_read_write_buffer( libewf_handle_t *handle, uint8_t *buffer, size_t buffer_size, size64_t input_size, size64_t expected_size, liberror_error_t **error ) { static char *function = "ewf_test_read_write_buffer"; size64_t remaining_size = 0; size64_t result_size = 0; size_t read_size = 0; ssize_t read_count = 0; ssize_t write_count = 0; remaining_size = input_size; while( remaining_size > 0 ) { read_size = buffer_size; if( remaining_size < (size64_t) read_size ) { read_size = (size_t) remaining_size; } read_count = libewf_handle_read_buffer( handle, 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 buffer of size: %" PRIzd ".", function, read_size ); return( -1 ); } else if( read_count == 0 ) { break; } if( libewf_handle_seek_offset( handle, -1 * (off64_t) read_count, SEEK_CUR, error ) == -1 ) { liberror_error_set( error, LIBERROR_ERROR_DOMAIN_IO, LIBERROR_IO_ERROR_READ_FAILED, "%s: unable to seek previous offset.", function ); return( -1 ); } if( memory_set( buffer, (int) 'B', (size_t) read_count ) == NULL ) { liberror_error_set( error, LIBERROR_ERROR_DOMAIN_MEMORY, LIBERROR_MEMORY_ERROR_SET_FAILED, "%s: unable set value in buffer.", function ); return( -1 ); } write_count = libewf_handle_write_buffer( handle, buffer, (size_t) read_count, error ); if( write_count < 0 ) { liberror_error_set( error, LIBERROR_ERROR_DOMAIN_IO, LIBERROR_IO_ERROR_WRITE_FAILED, "%s: unable write buffer of size: %" PRIzd ".", function, read_count ); return( -1 ); } if( write_count != read_count ) { break; } remaining_size -= (size64_t) write_count; result_size += (size64_t) write_count; } if( expected_size != result_size ) { fprintf( stderr, "%s: unexpected read/write count: %" PRIu64 "\n", function, result_size ); return( 0 ); } return( 1 ); }
/* Tests libewf_handle_read_chunk, libewf_handle_write_chunk, libewf_handle_prepare_read_chunk and libewf_handle_prepare_write_chunk * Returns 1 if successful, 0 if not or -1 on error */ int ewf_test_read_write_chunk( libewf_handle_t *handle, uint8_t *data_buffer, size_t data_buffer_size, uint8_t *chunk_buffer, size_t chunk_buffer_size, size64_t input_size, size64_t expected_size, liberror_error_t **error ) { uint8_t checksum_buffer[ 4 ]; static char *function = "ewf_test_read_write_chunk"; size64_t remaining_size = 0; size64_t result_size = 0; size_t chunk_data_size = 0; size_t data_size = 0; size_t write_size = 0; ssize_t process_count = 0; ssize_t read_count = 0; ssize_t write_count = 0; uint32_t chunk_checksum = 0; int8_t is_compressed = 0; int8_t process_checksum = 0; remaining_size = input_size; while( remaining_size > 0 ) { read_count = libewf_handle_read_chunk( handle, chunk_buffer, chunk_buffer_size, &is_compressed, (void *) checksum_buffer, &chunk_checksum, &process_checksum, error ); if( read_count < 0 ) { liberror_error_set( error, LIBERROR_ERROR_DOMAIN_IO, LIBERROR_IO_ERROR_READ_FAILED, "%s: unable to read chunk of size: %" PRIzd ".", function, chunk_buffer_size ); return( -1 ); } else if( read_count == 0 ) { break; } data_size = data_buffer_size; process_count = libewf_handle_prepare_read_chunk( handle, chunk_buffer, (size_t) read_count, data_buffer, &data_size, is_compressed, chunk_checksum, process_checksum, error ); if( process_count < 0 ) { liberror_error_set( error, LIBERROR_ERROR_DOMAIN_IO, LIBERROR_IO_ERROR_READ_FAILED, "%s: unable to prepare chunk of size: %" PRIzd " after read.", function, read_count ); return( -1 ); } if( libewf_handle_seek_offset( handle, -1 * (off64_t) process_count, SEEK_CUR, error ) == -1 ) { liberror_error_set( error, LIBERROR_ERROR_DOMAIN_IO, LIBERROR_IO_ERROR_READ_FAILED, "%s: unable to seek previous offset.", function ); return( -1 ); } if( memory_set( data_buffer, (int) 'C', data_buffer_size ) == NULL ) { liberror_error_set( error, LIBERROR_ERROR_DOMAIN_MEMORY, LIBERROR_MEMORY_ERROR_SET_FAILED, "%s: unable set value in buffer.", function ); return( -1 ); } write_size = process_count; chunk_data_size = chunk_buffer_size; process_count = libewf_handle_prepare_write_chunk( handle, data_buffer, write_size, chunk_buffer, &chunk_data_size, &is_compressed, &chunk_checksum, &process_checksum, error ); if( process_count < 0 ) { liberror_error_set( error, LIBERROR_ERROR_DOMAIN_RUNTIME, LIBERROR_RUNTIME_ERROR_SET_FAILED, "%s: unable to prepare chunk buffer before writing.", function ); return( -1 ); } if( is_compressed == 0 ) { write_count = libewf_handle_write_chunk( handle, data_buffer, process_count, write_size, is_compressed, checksum_buffer, chunk_checksum, process_checksum, error ); } else { write_count = libewf_handle_write_chunk( handle, chunk_buffer, chunk_data_size, write_size, is_compressed, checksum_buffer, chunk_checksum, process_checksum, error ); } if( write_count < 0 ) { liberror_error_set( error, LIBERROR_ERROR_DOMAIN_IO, LIBERROR_IO_ERROR_WRITE_FAILED, "%s: unable write chunk of size: %" PRIzd ".", function, chunk_data_size ); return( -1 ); } remaining_size -= (size64_t) write_size; result_size += (size64_t) write_size; } if( expected_size != result_size ) { fprintf( stderr, "%s: unexpected read/write count: %" PRIu64 "\n", function, result_size ); return( 0 ); } return( 1 ); }
/* Tests reading/writing data of a specific size at a specific offset * Return 1 if successful, 0 if not or -1 on error */ int ewf_test_read_write_delta( libcstring_system_character_t * const filenames[], int number_of_filenames, const libcstring_system_character_t *delta_segment_filename, off64_t write_offset, size64_t write_size, libcerror_error_t **error ) { libewf_handle_t *handle = NULL; uint8_t *buffer = NULL; static char *function = "ewf_test_read_write_delta"; size_t delta_segment_filename_length = 0; size_t read_size = 0; ssize_t read_count = 0; ssize_t write_count = 0; if( libewf_handle_initialize( &handle, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, "%s: unable to create handle.", function ); goto on_error; } #if defined( HAVE_DEBUG_OUTPUT ) && defined( EWF_TEST_READ_WRITE_DELTA_VERBOSE ) libewf_notify_set_verbose( 1 ); libewf_notify_set_stream( stderr, NULL ); #endif #if defined( LIBCSTRING_HAVE_WIDE_SYSTEM_CHARACTER ) if( libewf_handle_open_wide( handle, filenames, number_of_filenames, LIBEWF_OPEN_READ_WRITE, error ) != 1 ) #else if( libewf_handle_open( handle, filenames, number_of_filenames, LIBEWF_OPEN_READ_WRITE, error ) != 1 ) #endif { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_IO, LIBCERROR_IO_ERROR_OPEN_FAILED, "%s: unable to open handle.", function ); goto on_error; } if( delta_segment_filename != NULL ) { delta_segment_filename_length = libcstring_system_string_length( delta_segment_filename ); #if defined( LIBCSTRING_HAVE_WIDE_SYSTEM_CHARACTER ) if( libewf_handle_set_delta_segment_filename_wide( handle, delta_segment_filename, delta_segment_filename_length, error ) != 1 ) #else if( libewf_handle_set_delta_segment_filename( handle, delta_segment_filename, delta_segment_filename_length, error ) != 1 ) #endif { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_SET_FAILED, "%s: unable to set delta segment filename.", function ); goto on_error; } } if( libewf_handle_seek_offset( handle, write_offset, SEEK_SET, error ) == -1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_IO, LIBCERROR_IO_ERROR_OPEN_FAILED, "%s: unable to seek offset: %" PRIi64 ".", function, write_offset ); goto on_error; } buffer = (uint8_t *) memory_allocate( EWF_TEST_BUFFER_SIZE ); while( write_size > 0 ) { if( write_size > (size64_t) EWF_TEST_BUFFER_SIZE ) { read_size = EWF_TEST_BUFFER_SIZE; } else { read_size = (size_t) write_size; } read_count = libewf_handle_read_buffer( handle, buffer, read_size, error ); if( read_count < 0 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_IO, LIBCERROR_IO_ERROR_WRITE_FAILED, "%s: unable read buffer of size: %" PRIzd ".", function, read_size ); goto on_error; } if( memory_set( buffer, (int) 'X', (size_t) read_count ) == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_MEMORY, LIBCERROR_MEMORY_ERROR_SET_FAILED, "%s: unable set value in buffer.", function ); goto on_error; } if( libewf_handle_seek_offset( handle, -1 * (off64_t) read_size, SEEK_CUR, error ) == -1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_IO, LIBCERROR_IO_ERROR_OPEN_FAILED, "%s: unable to seek previous offset.", function ); goto on_error; } write_count = libewf_handle_write_buffer( handle, buffer, (size_t) read_count, error ); if( write_count < 0 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_IO, LIBCERROR_IO_ERROR_WRITE_FAILED, "%s: unable write buffer of size: %" PRIzd ".", function, read_count ); goto on_error; } if( write_count != read_count ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_IO, LIBCERROR_IO_ERROR_WRITE_FAILED, "%s: unable write buffer of size: %" PRIzd ".", function, read_count ); goto on_error; } write_offset += write_count; write_size -= write_count; } memory_free( buffer ); buffer = NULL; if( libewf_handle_close( handle, error ) != 0 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_IO, LIBCERROR_IO_ERROR_CLOSE_FAILED, "%s: unable to close handle.", function ); goto on_error; } if( libewf_handle_free( &handle, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED, "%s: unable to free handle.", function ); goto on_error; } return( 1 ); on_error: if( buffer != NULL ) { memory_free( buffer ); } if( handle != NULL ) { libewf_handle_close( handle, NULL ); libewf_handle_free( &handle, NULL ); } return( -1 ); }
/* * EwfOpen */ static int EwfOpen(void *p_handle, const char **pp_filename_arr, uint64_t filename_arr_len) { pts_EwfHandle p_ewf_handle=(pts_EwfHandle)p_handle; // We need at least one file if(filename_arr_len==0) return EWF_NO_INPUT_FILES; // Make sure all files are EWF files for(uint64_t i=0;i<filename_arr_len;i++) { #ifdef HAVE_LIBEWF_V2_API if(libewf_check_file_signature(pp_filename_arr[i],NULL)!=1) #else if(libewf_check_file_signature(pp_filename_arr[i])!=1) #endif { return EWF_INVALID_INPUT_FILES; } } // Open EWF file #ifdef HAVE_LIBEWF_V2_API if(libewf_handle_open(p_ewf_handle->h_ewf, (char* const*)pp_filename_arr, filename_arr_len, libewf_get_access_flags_read(), NULL)!=1) #else p_ewf_handle->h_ewf=libewf_open((char* const*)pp_filename_arr, filename_arr_len, libewf_get_flags_read()); if(p_ewf_handle->h_ewf==NULL) #endif { return EWF_OPEN_FAILED; } #ifdef HAVE_LIBEWF_V2_API // Try to read 1 byte from the image end to verify that all segments were // specified (Only needed because libewf_handle_open() won't fail even if not // all segments were specified!) uint64_t image_size=0; char buf; if(libewf_handle_get_media_size(p_ewf_handle->h_ewf,&image_size,NULL)!=1) { return EWF_GET_SIZE_FAILED; } if(image_size==0) return EWF_OK; LIBXMOUNT_LOG_DEBUG(p_ewf_handle->debug, "Trying to read last byte of image at offset %" PRIu64 " (image size = %" PRIu64 " bytes)\n", image_size-1, image_size); if(libewf_handle_seek_offset(p_ewf_handle->h_ewf, image_size-1, SEEK_SET, NULL)==-1) { return EWF_OPEN_FAILED_SEEK; } if(libewf_handle_read_buffer(p_ewf_handle->h_ewf,&buf,1,NULL)!=1) { return EWF_OPEN_FAILED_READ; } #endif #ifndef HAVE_LIBEWF_V2_API // Parse EWF header if(libewf_parse_header_values(p_ewf_handle->h_ewf, LIBEWF_DATE_FORMAT_ISO8601)!=1) { return EWF_HEADER_PARSING_FAILED; } #endif return EWF_OK; }