Beispiel #1
0
/* Reads the page tags
 * Returns 1 if successful or -1 on error
 */
int libesedb_page_read_tags(
     libcdata_array_t *page_tags_array,
     libesedb_io_handle_t *io_handle,
     uint16_t number_of_page_tags,
     uint8_t *page_data,
     size_t page_data_size,
     libcerror_error_t **error )
{
	libesedb_page_tags_value_t *page_tags_value = NULL;
	uint8_t *page_tags_data                     = NULL;
	static char *function                       = "libesedb_page_read_tags";
	uint16_t page_tag_offset                    = 0;
	uint16_t page_tag_size                      = 0;
	uint16_t page_tags_index                    = 0;

#if defined( HAVE_DEBUG_OUTPUT )
	size_t page_tags_data_size                  = 0;
#endif

	if( page_tags_array == NULL )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
		 "%s: invalid page tags array.",
		 function );

		return( -1 );
	}
	if( io_handle == NULL )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
		 "%s: invalid IO handle.",
		 function );

		return( -1 );
	}
	if( page_data == NULL )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
		 "%s: invalid page data.",
		 function );

		return( -1 );
	}
	if( page_data_size > (size_t) SSIZE_MAX )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
		 LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
		 "%s: invalid page data size value exceeds maximum.",
		 function );

		return( -1 );
	}
	if( libcdata_array_resize(
	     page_tags_array,
	     number_of_page_tags,
	     (int (*)(intptr_t **, libcerror_error_t **)) &libesedb_page_tags_value_free,
	     error ) != 1 )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
		 LIBCERROR_RUNTIME_ERROR_RESIZE_FAILED,
		 "%s: unable to resize page tags array.",
		 function );

		goto on_error;
	}
#if defined( HAVE_DEBUG_OUTPUT )
	if( libcnotify_verbose != 0 )
	{
		page_tags_data_size = 4 * number_of_page_tags;

		libcnotify_printf(
		 "%s: page tags:\n",
		 function );
		libcnotify_print_data(
		 &( page_data[ page_data_size - page_tags_data_size ] ),
		 page_tags_data_size,
		 0 );
	}
#endif
	/* Read the page tags back to front
	 */
	page_tags_data = &( page_data[ page_data_size - 2 ] );

	for( page_tags_index = 0;
	     page_tags_index < number_of_page_tags;
	     page_tags_index++ )
	{
		if( libesedb_page_tags_value_initialize(
		     &page_tags_value,
		     error ) != 1 )
		{
			libcerror_error_set(
			 error,
			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
			 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
			 "%s: unable to create page tags value.",
			 function );

			goto on_error;
		}
		byte_stream_copy_to_uint16_little_endian(
		 page_tags_data,
		 page_tag_offset );

		page_tags_data -= 2;

		byte_stream_copy_to_uint16_little_endian(
		 page_tags_data,
		 page_tag_size );

		page_tags_data -= 2;

		if( ( io_handle->format_revision >= LIBESEDB_FORMAT_REVISION_EXTENDED_PAGE_HEADER )
		 && ( io_handle->page_size >= 16384 ) )
		{
			page_tags_value->flags  = 0;
			page_tags_value->offset = page_tag_offset & 0x7fff;
			page_tags_value->size   = page_tag_size & 0x7fff;;
		}
		else
		{
			page_tags_value->flags  = page_tag_offset >> 13;
			page_tags_value->offset = page_tag_offset & 0x1fff;
			page_tags_value->size   = page_tag_size & 0x1fff;
		}
#if defined( HAVE_DEBUG_OUTPUT )
		if( libcnotify_verbose != 0 )
		{
			libcnotify_printf(
			 "%s: page tag: %03" PRIu16 " offset\t\t\t\t: %" PRIu16 " (0x%04" PRIx16 ")\n",
			 function,
			 page_tags_index,
			 page_tags_value->offset,
			 page_tag_offset );

			libcnotify_printf(
			 "%s: page tag: %03" PRIu16 " size\t\t\t\t: %" PRIu16 " (0x%04" PRIx16 ")\n",
			 function,
			 page_tags_index,
			 page_tags_value->size,
			 page_tag_size );

			if( ( io_handle->format_revision < LIBESEDB_FORMAT_REVISION_EXTENDED_PAGE_HEADER )
			 && ( io_handle->page_size < 16384 ) )
			{
				libcnotify_printf(
				 "%s: page tag: %03" PRIu16 " flags\t\t\t\t: 0x%02" PRIx8 "",
				 function,
				 page_tags_index,
				 page_tags_value->flags );
				libesedb_debug_print_page_tag_flags(
				 page_tags_value->flags );
				libcnotify_printf(
				 "\n" );
			}
		}
#endif
		if( libcdata_array_set_entry_by_index(
		     page_tags_array,
		     (int) page_tags_index,
		     (intptr_t *) page_tags_value,
		     error ) != 1 )
		{
			libcerror_error_set(
			 error,
			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
			 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
			 "%s: unable to set page tag: %" PRIu16 ".",
			 function,
			 page_tags_index );

			goto on_error;
		}
		page_tags_value = NULL;
	}
#if defined( HAVE_DEBUG_OUTPUT )
	if( libcnotify_verbose != 0 )
	{
		libcnotify_printf(
		 "\n" );
	}
#endif
	return( 1 );

on_error:
	if( page_tags_value != NULL )
	{
		libesedb_page_tags_value_free(
		 &page_tags_value,
		 NULL );
	}
	return( -1 );
}
/* Appends a value entry
 * Returns if successful or -1 on error
 */
int libfvalue_data_handle_append_value_entry(
     libfvalue_data_handle_t *data_handle,
     int *value_entry_index,
     const uint8_t *value_entry_data,
     size_t value_entry_data_size,
     int encoding,
     libcerror_error_t **error )
{
	libfvalue_internal_data_handle_t *internal_data_handle = NULL;
	libfvalue_value_entry_t *value_entry                   = NULL;
	void *reallocation                                     = NULL;
	static char *function                                  = "libfvalue_data_handle_append_value_entry";

	if( data_handle == NULL )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
		 "%s: invalid data handle.",
		 function );

		return( -1 );
	}
	internal_data_handle = (libfvalue_internal_data_handle_t *) data_handle;

	if( value_entry_index == NULL )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
		 "%s: invalid value entry index.",
		 function );

		return( -1 );
	}
	if( value_entry_data == NULL )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
		 "%s: invalid value entry data.",
		 function );

		return( -1 );
	}
	if( value_entry_data_size > (size_t) SSIZE_MAX )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
		 LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
		 "%s: invalid value entry data size value exceeds maximum.",
		 function );

		return( -1 );
	}
	if( internal_data_handle->data == NULL )
	{
		if( libfvalue_data_handle_set_data(
		     data_handle,
		     value_entry_data,
		     value_entry_data_size,
		     encoding,
		     LIBFVALUE_VALUE_DATA_FLAG_MANAGED,
		     error ) != 1 )
		{
			libcerror_error_set(
			 error,
			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
			 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
			 "%s: unable to set data in data handle.",
			 function );

			goto on_error;
		}
		internal_data_handle->encoding = encoding;
	}
	else
	{
		if( encoding != internal_data_handle->encoding )
		{
			libcerror_error_set(
			 error,
			 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
			 LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
			 "%s: invalid encoding value out of bounds.",
			 function );

			return( -1 );
		}
		if( ( internal_data_handle->data_size + value_entry_data_size ) > (size_t) SSIZE_MAX )
		{
			libcerror_error_set(
			 error,
			 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
			 LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
			 "%s: invalid value entry data size value exceeds maximum.",
			 function );

			return( -1 );
		}
		if( internal_data_handle->value_entries == NULL )
		{
			if( libcdata_array_initialize(
			     &( internal_data_handle->value_entries ),
			     1,
			     error ) != 1 )
			{
				libcerror_error_set(
				 error,
				 LIBCERROR_ERROR_DOMAIN_RUNTIME,
				 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
				 "%s: unable to create value entries array.",
				 function );

				goto on_error;
			}
			if( libfvalue_value_entry_initialize(
			     &value_entry,
			     error ) != 1 )
			{
				libcerror_error_set(
				 error,
				 LIBCERROR_ERROR_DOMAIN_RUNTIME,
				 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
				 "%s: unable to create value entry.",
				 function );

				goto on_error;
			}
			value_entry->offset = 0;
			value_entry->size   = internal_data_handle->data_size;

			if( libcdata_array_set_entry_by_index(
			     internal_data_handle->value_entries,
			     0,
			     (intptr_t *) value_entry,
			     error ) != 1 )
			{
				libcerror_error_set(
				 error,
				 LIBCERROR_ERROR_DOMAIN_RUNTIME,
				 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
				 "%s: unable to set entry: 0 in values entries array.",
				 function );

				goto on_error;
			}
			value_entry = NULL;
		}
		if( libfvalue_value_entry_initialize(
		     &value_entry,
		     error ) != 1 )
		{
			libcerror_error_set(
			 error,
			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
			 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
			 "%s: unable to create value entry.",
			 function );

			goto on_error;
		}
		value_entry->offset = internal_data_handle->data_size;
		value_entry->size   = value_entry_data_size;

		reallocation = memory_reallocate(
		                internal_data_handle->data,
		                internal_data_handle->data_size + value_entry_data_size );

		if( reallocation == NULL )
		{
			libcerror_error_set(
			 error,
			 LIBCERROR_ERROR_DOMAIN_MEMORY,
			 LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
			 "%s: unable to resize array entries.",
			 function );

			goto on_error;
		}
		internal_data_handle->data       = (uint8_t *) reallocation;
		internal_data_handle->data_size += value_entry_data_size;

		if( memory_copy(
		     &( ( internal_data_handle->data )[ value_entry->offset ] ),
		     value_entry_data,
		     value_entry->size ) == NULL )
		{
			libcerror_error_set(
			 error,
			 LIBCERROR_ERROR_DOMAIN_MEMORY,
			 LIBCERROR_MEMORY_ERROR_COPY_FAILED,
			 "%s: unable to copy value entry data.",
			 function );

			goto on_error;
		}
		if( libcdata_array_append_entry(
		     internal_data_handle->value_entries,
		     value_entry_index,
		     (intptr_t *) value_entry,
		     error ) != 1 )
		{
			libcerror_error_set(
			 error,
			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
			 LIBCERROR_RUNTIME_ERROR_APPEND_FAILED,
			 "%s: unable to append entry to values entries array.",
			 function );

			goto on_error;
		}
		value_entry = NULL;
	}
	return( 1 );

on_error:
	if( value_entry != NULL )
	{
		libfvalue_value_entry_free(
		 &value_entry,
		 NULL );
	}
	return( -1 );
}
Beispiel #3
0
/* Reads the page values
 * Returns 1 if successful or -1 on error
 */
int libesedb_page_read_values(
     libesedb_page_t *page,
     libesedb_io_handle_t *io_handle,
     libcdata_array_t *page_tags_array,
     uint8_t *page_values_data,
     size_t page_values_data_size,
     size_t page_values_data_offset,
     libcerror_error_t **error )
{
	libesedb_page_tags_value_t *page_tags_value = NULL;
	libesedb_page_value_t *page_value           = NULL;
	static char *function                       = "libesedb_page_read_values";
	uint16_t page_tags_index                    = 0;
	int number_of_page_tags                     = 0;

	if( page == NULL )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
		 "%s: invalid page.",
		 function );

		return( -1 );
	}
	if( page->values_array == NULL )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
		 LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
		 "%s: invalid page  - missing values array.",
		 function );

		return( -1 );
	}
	if( io_handle == NULL )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
		 "%s: invalid IO handle.",
		 function );

		return( -1 );
	}
	if( page_tags_array == NULL )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
		 "%s: invalid page tags array.",
		 function );

		return( -1 );
	}
	if( page_values_data == NULL )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
		 "%s: invalid page values data.",
		 function );

		return( -1 );
	}
	if( page_values_data_size > (size_t) SSIZE_MAX )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
		 LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
		 "%s: invalid page values data size value exceeds maximum.",
		 function );

		return( -1 );
	}
	if( libcdata_array_get_number_of_entries(
	     page_tags_array,
	     &number_of_page_tags,
	     error ) != 1 )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
		 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
		 "%s: unable to retrieve number of page tags.",
		 function );

		return( -1 );
	}
	if( libcdata_array_resize(
	     page->values_array,
	     number_of_page_tags,
	     (int (*)(intptr_t **, libcerror_error_t **)) &libesedb_page_value_free,
	     error ) != 1 )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
		 LIBCERROR_RUNTIME_ERROR_RESIZE_FAILED,
		 "%s: unable to resize page values array.",
		 function );

		goto on_error;
	}
	for( page_tags_index = 0;
	     page_tags_index < number_of_page_tags;
	     page_tags_index++ )
	{
		if( libcdata_array_get_entry_by_index(
		     page_tags_array,
		     page_tags_index,
		     (intptr_t **) &page_tags_value,
		     error ) != 1 )
		{
			libcerror_error_set(
			 error,
			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
			 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
			 "%s: unable to retrieve page tag: %" PRIu16 ".",
			 function,
			 page_tags_index );

			goto on_error;
		}
		if( page_tags_value == NULL )
		{
			libcerror_error_set(
			 error,
			 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
			 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
			 "%s: invalid page tags value.",
			 function );

			goto on_error;
		}
		if( libesedb_page_value_initialize(
		     &page_value,
		     error ) != 1 )
		{
			libcerror_error_set(
			 error,
			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
			 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
			 "%s: unable to create tags value.",
			 function );

			goto on_error;
		}
		if( page_tags_value->offset > page->data_size )
		{
			libcerror_error_set(
			 error,
			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
			 LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
			 "%s: unsupported page tags value offset value out of bounds.",
			 function );

#if defined( HAVE_DEBUG_OUTPUT )
			if( libcnotify_verbose != 0 )
			{
				libcnotify_printf(
				 "%s: page value: %03" PRIu16 " offset: % 5" PRIu16 ", size: % 5" PRIu16 "\n",
				 function,
				 page_tags_index,
				 page_tags_value->offset,
				 page_tags_value->size );
			}
#endif
			goto on_error;
		}
		if( page_tags_value->size > ( page->data_size - page_tags_value->offset ) )
		{
			libcerror_error_set(
			 error,
			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
			 LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
			 "%s: unsupported page tags value size value out of bounds.",
			 function );

#if defined( HAVE_DEBUG_OUTPUT )
			if( libcnotify_verbose != 0 )
			{
				libcnotify_printf(
				 "%s: page value: %03" PRIu16 " offset: % 5" PRIu16 ", size: % 5" PRIu16 "\n",
				 function,
				 page_tags_index,
				 page_tags_value->offset,
				 page_tags_value->size );
			}
#endif
			goto on_error;
		}
		if( ( io_handle->format_revision >= LIBESEDB_FORMAT_REVISION_EXTENDED_PAGE_HEADER )
		 && ( io_handle->page_size >= 16384 ) )
		{
			/* The page tags flags are stored in the upper byte of the first 16-bit value
			 */
			page_tags_value->flags = page_values_data[ page_tags_value->offset + 1 ] >> 5;

			page_values_data[ page_tags_value->offset + 1 ] &= 0x1f;
		}
#if defined( HAVE_DEBUG_OUTPUT )
		if( libcnotify_verbose != 0 )
		{
			libcnotify_printf(
			 "%s: page value: %03" PRIu16 " offset: % 5" PRIu16 ", size: % 5" PRIu16 ", flags: 0x%02" PRIx8 "",
			 function,
			 page_tags_index,
			 page_tags_value->offset,
			 page_tags_value->size,
			 page_tags_value->flags );
			libesedb_debug_print_page_tag_flags(
			 page_tags_value->flags );
			libcnotify_printf(
			 "\n" );
		}
#endif
		page_value->data   = &( page_values_data[ page_tags_value->offset ] );
		page_value->offset = (uint16_t) ( page_values_data_offset + page_tags_value->offset );
		page_value->size   = page_tags_value->size;
		page_value->flags  = page_tags_value->flags;

		if( libcdata_array_set_entry_by_index(
		     page->values_array,
		     (int) page_tags_index,
		     (intptr_t *) page_value,
		     error ) != 1 )
		{
			libcerror_error_set(
			 error,
			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
			 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
			 "%s: unable to set page value: %" PRIu16 ".",
			 function,
			 page_tags_index );

			goto on_error;
		}
		page_value = NULL;
	}
Beispiel #4
0
/* Reads the manifest
 * Returns 1 if successful or -1 on error
 */
int libfwevt_manifest_read(
     libfwevt_manifest_t *manifest,
     const uint8_t *data,
     size_t data_size,
     libcerror_error_t **error )
{
	libfwevt_internal_manifest_t *internal_manifest = NULL;
	libfwevt_provider_t *provider                   = NULL;
	fwevt_template_manifest_t *wevt_manifest        = NULL;
	fwevt_template_provider_entry_t *provider_entry = NULL;
	static char *function                           = "libfwevt_manifest_read";
	size_t data_offset                              = 0;
	uint32_t number_of_providers                    = 0;
	uint32_t provider_data_offset                   = 0;
	uint32_t provider_index                         = 0;

#if defined( HAVE_DEBUG_OUTPUT )
	system_character_t guid_string[ 48 ];

	libfguid_identifier_t *guid                     = NULL;
	uint32_t value_32bit                            = 0;
	int result                                      = 0;
#endif

	if( manifest == NULL )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
		 "%s: invalid manifest.",
		 function );

		return( -1 );
	}
	internal_manifest = (libfwevt_internal_manifest_t *) manifest;

	if( data == NULL )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
		 "%s: invalid data.",
		 function );

		return( -1 );
	}
	if( data_size > (size_t) SSIZE_MAX )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
		 LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
		 "%s: invalid data size value exceeds maximum.",
		 function );

		return( -1 );
	}
	if( data_size < sizeof( fwevt_template_manifest_t ) )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
		 LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
		 "%s: invalid data value too small.",
		 function );

		return( -1 );
	}
	wevt_manifest = (fwevt_template_manifest_t *) data;

#if defined( HAVE_DEBUG_OUTPUT )
	if( libcnotify_verbose != 0 )
	{
		libcnotify_printf(
		 "%s: manifest data:\n",
		 function );
		libcnotify_print_data(
		 (uint8_t *) wevt_manifest,
		 sizeof( fwevt_template_manifest_t ),
		 0 );
	}
#endif
	byte_stream_copy_to_uint16_little_endian(
	 wevt_manifest->major_version,
	 internal_manifest->major_version );

	byte_stream_copy_to_uint16_little_endian(
	 wevt_manifest->minor_version,
	 internal_manifest->minor_version );

	byte_stream_copy_to_uint32_little_endian(
	 wevt_manifest->number_of_providers,
	 number_of_providers );

#if defined( HAVE_DEBUG_OUTPUT )
	if( libcnotify_verbose != 0 )
	{
		libcnotify_printf(
		 "%s: signature\t\t\t\t\t: %c%c%c%c\n",
		 function,
		 wevt_manifest->signature[ 0 ],
		 wevt_manifest->signature[ 1 ],
		 wevt_manifest->signature[ 2 ],
		 wevt_manifest->signature[ 3 ] );

		byte_stream_copy_to_uint32_little_endian(
		 wevt_manifest->size,
		 value_32bit );
		libcnotify_printf(
		 "%s: size\t\t\t\t\t\t: %" PRIu32 "\n",
		 function,
		 value_32bit );

		libcnotify_printf(
		 "%s: major version\t\t\t\t\t: %" PRIu16 "\n",
		 function,
		 internal_manifest->major_version );

		libcnotify_printf(
		 "%s: minor version\t\t\t\t\t: %" PRIu16 "\n",
		 function,
		 internal_manifest->minor_version );

		libcnotify_printf(
		 "%s: number of providers\t\t\t\t: %" PRIu32 "\n",
		 function,
		 number_of_providers );

		libcnotify_printf(
		 "\n" );
	}
#endif
	if( memory_compare(
	     wevt_manifest->signature,
	     "CRIM",
	     4 ) != 0 )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
		 LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
		 "%s: unsupported manifest signature.",
		 function );

		goto on_error;
	}
	data_offset = sizeof( fwevt_template_manifest_t );

	if( libcdata_array_initialize(
	     &( internal_manifest->providers_array ),
	     number_of_providers,
	     error ) != 1 )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
		 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
		 "%s: unable to create providers array.",
		 function );

		goto on_error;
	}
	for( provider_index = 0;
	     provider_index < number_of_providers;
	     provider_index++ )
	{
		if( data_offset >= data_size )
		{
			libcerror_error_set(
			 error,
			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
			 LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
			 "%s: invalid data offset value out of bounds.",
			 function );

			goto on_error;
		}
		provider_entry = (fwevt_template_provider_entry_t *) &( data[ data_offset ] );

		if( ( data_offset + sizeof( fwevt_template_provider_entry_t ) ) >= data_size )
		{
			libcerror_error_set(
			 error,
			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
			 LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
			 "%s: invalid data value too small.",
			 function );

			goto on_error;
		}
		byte_stream_copy_to_uint32_little_endian(
		 provider_entry->data_offset,
		 provider_data_offset );

#if defined( HAVE_DEBUG_OUTPUT )
		if( libcnotify_verbose != 0 )
		{
			if( libfguid_identifier_initialize(
			     &guid,
			     error ) != 1 )
			{
				libcerror_error_set(
				 error,
				 LIBCERROR_ERROR_DOMAIN_RUNTIME,
				 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
				 "%s: unable to create GUID.",
				 function );

				goto on_error;
			}
			if( libfguid_identifier_copy_from_byte_stream(
			     guid,
			     provider_entry->identifier,
			     16,
			     LIBFGUID_ENDIAN_LITTLE,
			     error ) != 1 )
			{
				libcerror_error_set(
				 error,
				 LIBCERROR_ERROR_DOMAIN_RUNTIME,
				 LIBCERROR_RUNTIME_ERROR_COPY_FAILED,
				 "%s: unable to copy byte stream to GUID.",
				 function );

				goto on_error;
			}
#if defined( HAVE_WIDE_SYSTEM_CHARACTER )
			result = libfguid_identifier_copy_to_utf16_string(
				  guid,
				  (uint16_t *) guid_string,
				  48,
				  LIBFGUID_STRING_FORMAT_FLAG_USE_LOWER_CASE,
				  error );
#else
			result = libfguid_identifier_copy_to_utf8_string(
				  guid,
				  (uint8_t *) guid_string,
				  48,
				  LIBFGUID_STRING_FORMAT_FLAG_USE_LOWER_CASE,
				  error );
#endif
			if( result != 1 )
			{
				libcerror_error_set(
				 error,
				 LIBCERROR_ERROR_DOMAIN_RUNTIME,
				 LIBCERROR_RUNTIME_ERROR_COPY_FAILED,
				 "%s: unable to copy GUID to string.",
				 function );

				goto on_error;
			}
			libcnotify_printf(
			 "%s: provider entry: %02" PRIu32 " identifier\t\t\t: %" PRIs_SYSTEM "\n",
			 function,
			 provider_index,
			 guid_string );

			if( libfguid_identifier_free(
			     &guid,
			     error ) != 1 )
			{
				libcerror_error_set(
				 error,
				 LIBCERROR_ERROR_DOMAIN_RUNTIME,
				 LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
				 "%s: unable to free GUID.",
				 function );

				goto on_error;
			}
			libcnotify_printf(
			 "%s: provider entry: %02" PRIu32 " data offset\t\t\t: 0x%08" PRIx32 "\n",
			 function,
			 provider_index,
			 provider_data_offset );
		}
#endif
		data_offset += sizeof( fwevt_template_provider_entry_t );

		if( libfwevt_provider_initialize(
		     &provider,
		     provider_entry->identifier,
		     16,
		     error ) != 1 )
		{
			libcerror_error_set(
			 error,
			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
			 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
			 "%s: unable to create provider: %" PRIu32 ".",
			 function,
			 provider_index );

			goto on_error;
		}
		if( libfwevt_provider_read(
		     provider,
		     data,
		     data_size,
		     (size_t) provider_data_offset,
		     error ) != 1 )
		{
			libcerror_error_set(
			 error,
			 LIBCERROR_ERROR_DOMAIN_IO,
			 LIBCERROR_IO_ERROR_READ_FAILED,
			 "%s: unable to read provider: %d.",
			 function,
			 provider_index );

			goto on_error;
		}
		if( libcdata_array_set_entry_by_index(
		     internal_manifest->providers_array,
		     (int) provider_index,
		     (intptr_t *) provider,
		     error ) != 1 )
		{
			libcerror_error_set(
			 error,
			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
			 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
			 "%s: unable to set provider: %" PRIu32 ".",
			 function,
			 provider_index );

			goto on_error;
		}
		provider = NULL;
	}
/* TODO refactor to read on demand ? */
	for( provider_index = 0;
	     provider_index < number_of_providers;
	     provider_index++ )
	{
		if( libcdata_array_get_entry_by_index(
		     internal_manifest->providers_array,
		     provider_index,
		     (intptr_t **) &provider,
		     error ) != 1 )
		{
			libcerror_error_set(
			 error,
			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
			 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
			 "%s: unable to retrieve provider: %d.",
			 function,
			 provider_index );

			provider = NULL;

			goto on_error;
		}
		if( libfwevt_provider_read_channels(
		     provider,
		     data,
		     data_size,
		     error ) != 1 )
		{
			libcerror_error_set(
			 error,
			 LIBCERROR_ERROR_DOMAIN_IO,
			 LIBCERROR_IO_ERROR_READ_FAILED,
			 "%s: unable to read channels.",
			 function );

			provider = NULL;

			goto on_error;
		}
		if( libfwevt_provider_read_events(
		     provider,
		     data,
		     data_size,
		     error ) != 1 )
		{
			libcerror_error_set(
			 error,
			 LIBCERROR_ERROR_DOMAIN_IO,
			 LIBCERROR_IO_ERROR_READ_FAILED,
			 "%s: unable to read events.",
			 function );

			provider = NULL;

			goto on_error;
		}
		if( libfwevt_provider_read_keywords(
		     provider,
		     data,
		     data_size,
		     error ) != 1 )
		{
			libcerror_error_set(
			 error,
			 LIBCERROR_ERROR_DOMAIN_IO,
			 LIBCERROR_IO_ERROR_READ_FAILED,
			 "%s: unable to read keywords.",
			 function );

			provider = NULL;

			goto on_error;
		}
		if( libfwevt_provider_read_levels(
		     provider,
		     data,
		     data_size,
		     error ) != 1 )
		{
			libcerror_error_set(
			 error,
			 LIBCERROR_ERROR_DOMAIN_IO,
			 LIBCERROR_IO_ERROR_READ_FAILED,
			 "%s: unable to read levels.",
			 function );

			provider = NULL;

			goto on_error;
		}
		if( libfwevt_provider_read_maps(
		     provider,
		     data,
		     data_size,
		     error ) != 1 )
		{
			libcerror_error_set(
			 error,
			 LIBCERROR_ERROR_DOMAIN_IO,
			 LIBCERROR_IO_ERROR_READ_FAILED,
			 "%s: unable to read maps.",
			 function );

			provider = NULL;

			goto on_error;
		}
		if( libfwevt_provider_read_opcodes(
		     provider,
		     data,
		     data_size,
		     error ) != 1 )
		{
			libcerror_error_set(
			 error,
			 LIBCERROR_ERROR_DOMAIN_IO,
			 LIBCERROR_IO_ERROR_READ_FAILED,
			 "%s: unable to read opcodes.",
			 function );

			provider = NULL;

			goto on_error;
		}
		if( libfwevt_provider_read_tasks(
		     provider,
		     data,
		     data_size,
		     error ) != 1 )
		{
			libcerror_error_set(
			 error,
			 LIBCERROR_ERROR_DOMAIN_IO,
			 LIBCERROR_IO_ERROR_READ_FAILED,
			 "%s: unable to read tasks.",
			 function );

			provider = NULL;

			goto on_error;
		}
		if( libfwevt_provider_read_templates(
		     provider,
		     data,
		     data_size,
		     error ) != 1 )
		{
			libcerror_error_set(
			 error,
			 LIBCERROR_ERROR_DOMAIN_IO,
			 LIBCERROR_IO_ERROR_READ_FAILED,
			 "%s: unable to read templates.",
			 function );

			provider = NULL;

			goto on_error;
		}
	}
/* TODO end refactor */
#if defined( HAVE_DEBUG_OUTPUT )
	if( libcnotify_verbose != 0 )
	{
		if( number_of_providers > 0 )
		{
			libcnotify_printf(
			 "\n" );
		}
	}
#endif
	return( 1 );

on_error:
#if defined( HAVE_DEBUG_OUTPUT )
	if( guid != NULL )
	{
		libfguid_identifier_free(
		 &guid,
		 NULL );
	}
#endif
	if( provider != NULL )
	{
		libfwevt_provider_free(
		 &provider,
		 NULL );
	}
	if( internal_manifest->providers_array != NULL )
	{
		libcdata_array_free(
		 &( internal_manifest->providers_array ),
		 (int (*)(intptr_t **, libcerror_error_t **)) &libfwevt_provider_free,
		 NULL );
	}
	return( -1 );
}
Beispiel #5
0
/* Sets the cache value for the specific index
 * Returns 1 if successful or -1 on error
 */
int libfcache_cache_set_value_by_index(
     libfcache_cache_t *cache,
     int cache_entry_index,
     int file_index,
     off64_t offset,
     time_t timestamp,
     intptr_t *value,
     int (*free_value)(
            intptr_t **value,
            libcerror_error_t **error ),
     uint8_t flags,
     libcerror_error_t **error )
{
	libfcache_cache_value_t *cache_value       = NULL;
	libfcache_internal_cache_t *internal_cache = NULL;
	static char *function                     = "libfcache_cache_set_value_by_index";

	if( cache == NULL )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
		 "%s: invalid cache.",
		 function );

		return( -1 );
	}
	internal_cache = (libfcache_internal_cache_t *) cache;

	if( libcdata_array_get_entry_by_index(
	     internal_cache->entries,
	     cache_entry_index,
	     (intptr_t **) &cache_value,
	     error ) != 1 )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
		 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
		 "%s: unable to retrieve cache value: %d from entries array.",
		 function,
		 cache_entry_index );

		return( -1 );
	}
	if( cache_value == NULL )
	{
		if( libfcache_cache_value_initialize(
		     &cache_value,
		     error ) != 1 )
		{
			libcerror_error_set(
			 error,
			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
			 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
			 "%s: unable to create cache value.",
			 function );

			return( -1 );
		}
		if( libcdata_array_set_entry_by_index(
		     internal_cache->entries,
		     cache_entry_index,
		     (intptr_t *) cache_value,
		     error ) != 1 )
		{
			libcerror_error_set(
			 error,
			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
			 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
			 "%s: unable to set cache value: %d in entries array.",
			 function,
			 cache_entry_index );

			libfcache_cache_value_free(
			 &cache_value,
			 NULL );

			return( -1 );
		}
		internal_cache->number_of_cache_values++;
	}
	if( libfcache_cache_value_set_value(
	     cache_value,
	     value,
	     free_value,
	     flags,
	     error ) != 1 )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
		 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
		 "%s: unable to set value in cache value.",
		 function );

		return( -1 );
	}
	if( libfcache_cache_value_set_identifier(
	     cache_value,
	     file_index,
	     offset,
	     timestamp,
	     error ) != 1 )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
		 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
		 "%s: unable to set identifier in cache value.",
		 function );

		return( -1 );
	}
	return( 1 );
}
/* Sets the offset and size of a specific segment
 * Returns 1 if successful or -1 on error
 */
int libfdata_segments_array_set_segment_by_index(
     libcdata_array_t *segments_array,
     libcdata_array_t *mapped_ranges_array,
     size64_t *data_size,
     int segment_index,
     int segment_file_index,
     off64_t segment_offset,
     size64_t segment_size,
     uint32_t segment_flags,
     libcerror_error_t **error )
{
	libfdata_mapped_range_t *mapped_range = NULL;
	libfdata_range_t *segment_data_range  = NULL;
	static char *function                 = "libfdata_segments_array_set_segment_by_index";
	off64_t previous_segment_offset       = 0;
	size64_t previous_segment_size        = 0;
	uint32_t previous_segment_flags       = 0;
	int previous_segment_file_index       = 0;

	if( data_size == NULL )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
		 "%s: invalid data size.",
		 function );

		return( -1 );
	}
	if( segment_file_index < 0 )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
		 LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
		 "%s: invalid segment file index value out of bounds.",
		 function );

		return( -1 );
	}
	if( segment_offset < 0 )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
		 LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
		 "%s: invalid segment offset value out of bounds.",
		 function );

		return( -1 );
	}
	if( libcdata_array_get_entry_by_index(
	     segments_array,
	     segment_index,
	     (intptr_t **) &segment_data_range,
	     error ) != 1 )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
		 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
		 "%s: unable to retrieve entry: %d from segments array.",
		 function,
		 segment_index );

		return( -1 );
	}
	if( segment_data_range == NULL )
	{
		if( libfdata_range_initialize(
		     &segment_data_range,
		     error ) != 1 )
		{
			libcerror_error_set(
			 error,
			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
			 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
			 "%s: unable to create segment data range.",
			 function );

			return( -1 );
		}
		if( libcdata_array_set_entry_by_index(
		     segments_array,
		     segment_index,
		     (intptr_t *) segment_data_range,
		     error ) != 1 )
		{
			libcerror_error_set(
			 error,
			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
			 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
			 "%s: unable to set entry: %d to segments array.",
			 function,
			 segment_index );

			libfdata_range_free(
			 &segment_data_range,
			 NULL );

			return( -1 );
		}
	}
	else
	{
		if( libfdata_range_get(
		     segment_data_range,
		     &previous_segment_file_index,
		     &previous_segment_offset,
		     &previous_segment_size,
		     &previous_segment_flags,
		     error ) != 1 )
		{
			libcerror_error_set(
			 error,
			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
			 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
			 "%s: unable to retrieve segment: %d data range values.",
			 function,
			 segment_index );

			return( -1 );
		}
		*data_size -= previous_segment_size;
	}
	if( libfdata_range_set(
	     segment_data_range,
	     segment_file_index,
	     segment_offset,
	     segment_size,
	     segment_flags,
	     error ) != 1 )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
		 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
		 "%s: unable to set segment data range values.",
		 function );

		return( -1 );
	}
	/* Make sure there is a mapped range entry for every segment
	 */
	if( libcdata_array_get_entry_by_index(
	     mapped_ranges_array,
	     segment_index,
	     (intptr_t **) &mapped_range,
	     error ) != 1 )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
		 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
		 "%s: unable to retrieve entry: %d from mapped ranges array.",
		 function,
		 segment_index );

		return( -1 );
	}
	if( mapped_range == NULL )
	{
		if( libfdata_mapped_range_initialize(
		     &mapped_range,
		     error ) != 1 )
		{
			libcerror_error_set(
			 error,
			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
			 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
			 "%s: unable to create mapped range.",
			 function );

			return( -1 );
		}
		if( libcdata_array_set_entry_by_index(
		     mapped_ranges_array,
		     segment_index,
		     (intptr_t *) mapped_range,
		     error ) != 1 )
		{
			libcerror_error_set(
			 error,
			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
			 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
			 "%s: unable to set entry: %d in mapped ranges array.",
			 function,
			 segment_index );

			libfdata_mapped_range_free(
			 &mapped_range,
			 NULL );

			return( -1 );
		}
	}
	*data_size += segment_size;

	return( 1 );
}
/* Appends a segment
 * Returns 1 if successful or -1 on error
 */
int libfdata_segments_array_append_segment(
     libcdata_array_t *segments_array,
     libcdata_array_t *mapped_ranges_array,
     size64_t *data_size,
     int *segment_index,
     int segment_file_index,
     off64_t segment_offset,
     size64_t segment_size,
     uint32_t segment_flags,
     libcerror_error_t **error )
{
	libfdata_mapped_range_t *mapped_range = NULL;
	libfdata_range_t *segment_data_range  = NULL;
	static char *function                 = "libfdata_segments_array_append_segment";
	int mapped_range_index                = -1;

	if( data_size == NULL )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
		 "%s: invalid data size.",
		 function );

		return( -1 );
	}
	if( segment_file_index < 0 )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
		 LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
		 "%s: invalid segment file index value out of bounds.",
		 function );

		return( -1 );
	}
	if( segment_offset < 0 )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
		 LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
		 "%s: invalid segment offset value out of bounds.",
		 function );

		return( -1 );
	}
	if( libfdata_mapped_range_initialize(
	     &mapped_range,
	     error ) != 1 )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
		 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
		 "%s: unable to create mapped range.",
		 function );

		goto on_error;
	}
	if( libfdata_mapped_range_set(
	     mapped_range,
	     (off64_t) *data_size,
	     segment_size,
	     error ) != 1 )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
		 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
		 "%s: unable to set mapped range values.",
		 function );

		goto on_error;
	}
	if( libcdata_array_append_entry(
	     mapped_ranges_array,
	     &mapped_range_index,
	     (intptr_t *) mapped_range,
	     error ) != 1 )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
		 LIBCERROR_RUNTIME_ERROR_APPEND_FAILED,
		 "%s: unable to append mapped range to array.",
		 function );

		goto on_error;
	}
	if( libfdata_range_initialize(
	     &segment_data_range,
	     error ) != 1 )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
		 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
		 "%s: unable to create segment data range.",
		 function );

		goto on_error;
	}
	if( libfdata_range_set(
	     segment_data_range,
	     segment_file_index,
	     segment_offset,
	     segment_size,
	     segment_flags,
	     error ) != 1 )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
		 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
		 "%s: unable to set segment data range values.",
		 function );

		goto on_error;
	}
	if( libcdata_array_append_entry(
	     segments_array,
	     segment_index,
	     (intptr_t *) segment_data_range,
	     error ) != 1 )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
		 LIBCERROR_RUNTIME_ERROR_APPEND_FAILED,
		 "%s: unable to append data range to segments array.",
		 function );

		goto on_error;
	}
#if defined( HAVE_DEBUG_OUTPUT )
	if( libcnotify_verbose != 0 )
	{
		libcnotify_printf(
		 "%s: segment: %03d\tfile index: %03d offset: 0x%08" PRIx64 " - 0x%08" PRIx64 " (size: %" PRIu64 ")\n",
		 function,
		 *segment_index,
		 segment_file_index,
		 segment_offset,
		 segment_offset + segment_size,
		 segment_size );

		libcnotify_printf(
		 "%s: segment: %03d\tmapped range: 0x%08" PRIx64 " - 0x%08" PRIx64 " (size: %" PRIu64 ")\n",
		 function,
		 *segment_index,
		 *data_size,
		 *data_size + segment_size,
		 segment_size );

		libcnotify_printf(
		 "\n" );
	}
#endif
	*data_size += segment_size;

	return( 1 );

on_error:
	if( segment_data_range != NULL )
	{
		libfdata_range_free(
		 &segment_data_range,
		 NULL );
	}
	if( mapped_range_index != -1 )
	{
		libcdata_array_set_entry_by_index(
		 mapped_ranges_array,
		 mapped_range_index,
		 NULL,
		 NULL );
	}
	if( mapped_range != NULL )
	{
		libfdata_mapped_range_free(
		 &mapped_range,
		 NULL );
	}
	return( -1 );
}
/* Prepends a segment
 * Returns 1 if successful or -1 on error
 */
int libfdata_segments_array_prepend_segment(
     libcdata_array_t *segments_array,
     libcdata_array_t *mapped_ranges_array,
     size64_t *data_size,
     int segment_file_index,
     off64_t segment_offset,
     size64_t segment_size,
     uint32_t segment_flags,
     libcerror_error_t **error )
{
	libfdata_mapped_range_t *mapped_range = NULL;
	libfdata_range_t *segment_data_range  = NULL;
	static char *function                 = "libfdata_segments_array_prepend_segment";
	int mapped_range_index                = -1;

	if( data_size == NULL )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
		 "%s: invalid data size.",
		 function );

		return( -1 );
	}
	if( segment_file_index < 0 )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
		 LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
		 "%s: invalid segment file index value out of bounds.",
		 function );

		return( -1 );
	}
	if( segment_offset < 0 )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
		 LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
		 "%s: invalid segment offset value out of bounds.",
		 function );

		return( -1 );
	}
	if( segment_size > (size64_t) INT64_MAX )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
		 LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
		 "%s: invalid segment size value out of bounds.",
		 function );

		return( -1 );
	}
	if( libfdata_mapped_range_initialize(
	     &mapped_range,
	     error ) != 1 )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
		 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
		 "%s: unable to create mapped range.",
		 function );

		goto on_error;
	}
	if( libfdata_mapped_range_set(
	     mapped_range,
	     (off64_t) *data_size,
	     segment_size,
	     error ) != 1 )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
		 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
		 "%s: unable to set mapped range values.",
		 function );

		goto on_error;
	}
	if( libcdata_array_append_entry(
	     mapped_ranges_array,
	     &mapped_range_index,
	     (intptr_t *) mapped_range,
	     error ) != 1 )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
		 LIBCERROR_RUNTIME_ERROR_APPEND_FAILED,
		 "%s: unable to append mapped range to array.",
		 function );

		goto on_error;
	}
	if( libfdata_range_initialize(
	     &segment_data_range,
	     error ) != 1 )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
		 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
		 "%s: unable to create segment data range.",
		 function );

		goto on_error;
	}
	if( libfdata_range_set(
	     segment_data_range,
	     segment_file_index,
	     segment_offset,
	     segment_size,
	     segment_flags,
	     error ) != 1 )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
		 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
		 "%s: unable to set segment data range values.",
		 function );

		goto on_error;
	}
	if( libcdata_array_prepend_entry(
	     segments_array,
	     (intptr_t *) segment_data_range,
	     error ) != 1 )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
		 LIBCERROR_RUNTIME_ERROR_APPEND_FAILED,
		 "%s: unable to prepend data range to segments array.",
		 function );

		goto on_error;
	}
	*data_size += segment_size;

	return( 1 );

on_error:
	if( segment_data_range != NULL )
	{
		libfdata_range_free(
		 &segment_data_range,
		 NULL );
	}
	if( mapped_range_index != -1 )
	{
		libcdata_array_set_entry_by_index(
		 mapped_ranges_array,
		 mapped_range_index,
		 NULL,
		 NULL );
	}
	if( mapped_range != NULL )
	{
		libfdata_mapped_range_free(
		 &mapped_range,
		 NULL );
	}
	return( -1 );
}