/* Tests writing data of media size to EWF file(s) with a maximum segment size * Return 1 if successful, 0 if not or -1 on error */ int ewf_test_write_chunk( const libcstring_system_character_t *filename, size64_t media_size, size64_t maximum_segment_size, int8_t compression_level, uint8_t compression_flags, libcerror_error_t **error ) { libewf_handle_t *handle = NULL; uint8_t *checksum_buffer = NULL; uint8_t *chunk_buffer = NULL; uint8_t *compressed_chunk_buffer = NULL; static char *function = "ewf_test_write_chunk"; size_t chunk_buffer_size = 0; size_t compressed_chunk_buffer_size = 0; ssize_t process_count = 0; ssize_t write_count = 0; uint32_t chunk_checksum = 0; uint32_t sectors_per_chunk = 0; int8_t is_compressed = 0; int8_t process_checksum = 0; int sector_iterator = 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( LIBCSTRING_HAVE_WIDE_SYSTEM_CHARACTER ) if( libewf_handle_open_wide( handle, (wchar_t * const *) &filename, 1, LIBEWF_OPEN_WRITE, error ) != 1 ) #else if( libewf_handle_open( handle, (char * const *) &filename, 1, LIBEWF_OPEN_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( media_size > 0 ) { if( libewf_handle_set_media_size( handle, media_size, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_SET_FAILED, "%s: unable set media size.", function ); goto on_error; } } if( maximum_segment_size > 0 ) { if( libewf_handle_set_maximum_segment_size( handle, maximum_segment_size, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_SET_FAILED, "%s: unable set maximum segment size.", function ); goto on_error; } } if( libewf_handle_set_compression_values( handle, compression_level, compression_flags, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_SET_FAILED, "%s: unable set compression values.", function ); goto on_error; } sectors_per_chunk = 64; if( libewf_handle_set_sectors_per_chunk( handle, sectors_per_chunk, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_SET_FAILED, "%s: unable set sectors per chunk.", function ); goto on_error; } chunk_buffer_size = sectors_per_chunk * 512; /* Use the chunck buffer also as checksum buffer */ chunk_buffer = (uint8_t *) memory_allocate( sizeof( uint8_t ) * ( chunk_buffer_size + 4 ) ); /* The compressed data can become larger than the uncompressed data */ compressed_chunk_buffer_size = chunk_buffer_size * 2; compressed_chunk_buffer = (uint8_t *) memory_allocate( sizeof( uint8_t ) * compressed_chunk_buffer_size ); if( chunk_buffer != NULL ) { checksum_buffer = &( chunk_buffer[ chunk_buffer_size - 1 ] ); } for( sector_iterator = 0; sector_iterator < 26; sector_iterator++ ) { if( memory_set( chunk_buffer, (int) 'A' + sector_iterator, chunk_buffer_size ) == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_MEMORY, LIBCERROR_MEMORY_ERROR_SET_FAILED, "%s: unable set value in chunk buffer.", function ); goto on_error; } process_count = libewf_handle_prepare_write_chunk( handle, chunk_buffer, chunk_buffer_size, compressed_chunk_buffer, &compressed_chunk_buffer_size, &is_compressed, &chunk_checksum, &process_checksum, error ); if( process_count == -1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_SET_FAILED, "%s: unable to prepare chunk buffer before writing.", function ); goto on_error; } if( is_compressed == 0 ) { write_count = libewf_handle_write_chunk( handle, chunk_buffer, chunk_buffer_size, chunk_buffer_size, is_compressed, checksum_buffer, chunk_checksum, process_checksum, error ); } else { write_count = libewf_handle_write_chunk( handle, compressed_chunk_buffer, compressed_chunk_buffer_size, chunk_buffer_size, is_compressed, checksum_buffer, chunk_checksum, process_checksum, error ); } if( write_count < 0 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_IO, LIBCERROR_IO_ERROR_WRITE_FAILED, "%s: unable write chunk of size: %" PRIzd ".", function, chunk_buffer_size ); goto on_error; } if( media_size > (size64_t) chunk_buffer_size ) { media_size -= chunk_buffer_size; } else if( media_size > 0 ) { media_size = 0; } if( media_size == 0 ) { break; } } memory_free( compressed_chunk_buffer ); compressed_chunk_buffer = NULL; memory_free( chunk_buffer ); chunk_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( compressed_chunk_buffer != NULL ) { memory_free( compressed_chunk_buffer ); } if( chunk_buffer != NULL ) { memory_free( chunk_buffer ); } if( handle != NULL ) { libewf_handle_close( handle, NULL ); libewf_handle_free( &handle, NULL ); } 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 ); }