Example #1
0
/* 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 );
}