Пример #1
0
/* Reads an free map
 * Returns 1 if successful or -1 on error
 */
int libpff_free_map_read(
     libcdata_range_list_t *unallocated_block_list,
     libbfio_handle_t *file_io_handle,
     off64_t free_map_offset,
     uint8_t file_type,
     libcerror_error_t **error )
{
	uint8_t *free_map_data       = NULL;
	uint8_t *table_data          = NULL;
	static char *function        = "libpff_free_map_read";
	off64_t back_pointer_offset  = 0;
	off64_t unallocated_offset   = 0;
	size_t read_size             = 0;
	size_t unallocated_size      = 0;
	size_t allocation_block_size = 0;
	ssize_t read_count           = 0;
	uint32_t stored_checksum     = 0;
	uint32_t calculated_checksum = 0;
	uint16_t table_iterator      = 0;
	uint8_t bit_iterator         = 0;
	uint8_t free_map_entry       = 0;
	uint8_t free_map_type        = 0;
	uint8_t free_map_type_copy   = 0;
	int result                   = 0;

#if defined( HAVE_DEBUG_OUTPUT )
	uint16_t value_16bit         = 0;
#endif

	if( unallocated_block_list == NULL )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
		 "%s: invalid unallocated block list.",
		 function );

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

		return( -1 );
	}
	if( ( file_type != LIBPFF_FILE_TYPE_32BIT )
	 && ( file_type != LIBPFF_FILE_TYPE_64BIT ) )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
		 LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
		 "%s: unsupported file type.",
		 function );

		return( -1 );
	}
	if( libbfio_handle_seek_offset(
	     file_io_handle,
	     free_map_offset,
	     SEEK_SET,
	     error ) == -1 )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_IO,
		 LIBCERROR_IO_ERROR_SEEK_FAILED,
		 "%s: unable to seek free map offset: %" PRIi64 ".",
		 function,
		 free_map_offset );

		goto on_error;
	}
	if( file_type == LIBPFF_FILE_TYPE_32BIT )
	{
		read_size = sizeof( pff_free_map_32bit_t );
	}
	else if( file_type == LIBPFF_FILE_TYPE_64BIT )
	{
		read_size = sizeof( pff_free_map_64bit_t );
	}
	free_map_data = (uint8_t *) memory_allocate(
	                             sizeof( uint8_t ) * read_size );

	if( free_map_data == NULL )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_MEMORY,
		 LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
		 "%s: unable to create alloction table data.",
		 function );

		goto on_error;
	}
	read_count = libbfio_handle_read_buffer(
	              file_io_handle,
	              free_map_data,
	              read_size,
	              error );

	if( read_count != (ssize_t) read_size )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_IO,
		 LIBCERROR_IO_ERROR_READ_FAILED,
		 "%s: unable to read free map.",
		 function );

		goto on_error;
	}
#if defined( HAVE_DEBUG_OUTPUT )
	if( libcnotify_verbose != 0 )
	{
		libcnotify_printf(
		 "%s: free map:\n",
		 function );
		libcnotify_print_data(
		 free_map_data,
		 read_size,
		 0 );
	}
#endif
	if( file_type == LIBPFF_FILE_TYPE_32BIT )
	{
		table_data         = ( (pff_free_map_32bit_t *) free_map_data )->data;
		free_map_type      = ( (pff_free_map_32bit_t *) free_map_data )->type;
		free_map_type_copy = ( (pff_free_map_32bit_t *) free_map_data )->type_copy;

		byte_stream_copy_to_uint32_little_endian(
		 ( (pff_free_map_32bit_t *) free_map_data )->back_pointer,
		 back_pointer_offset );
		byte_stream_copy_to_uint32_little_endian(
		 ( (pff_free_map_32bit_t *) free_map_data )->checksum,
		 stored_checksum );
	}
	else if( file_type == LIBPFF_FILE_TYPE_64BIT )
	{
		table_data         = ( (pff_free_map_64bit_t *) free_map_data )->data;
		free_map_type      = ( (pff_free_map_64bit_t *) free_map_data )->type;
		free_map_type_copy = ( (pff_free_map_64bit_t *) free_map_data )->type_copy;

		byte_stream_copy_to_uint32_little_endian(
		 ( (pff_free_map_64bit_t *) free_map_data )->checksum,
		 stored_checksum );
		byte_stream_copy_to_uint64_little_endian(
		 ( (pff_free_map_64bit_t *) free_map_data )->back_pointer,
		 back_pointer_offset );
	}
#if defined( HAVE_DEBUG_OUTPUT )
	if( libcnotify_verbose != 0 )
	{
		libcnotify_printf(
		 "%s: type\t\t: 0x%02" PRIx8 "\n",
		 function,
		 free_map_type );
		libcnotify_printf(
		 "%s: type copy\t: 0x%02" PRIx8 "\n",
		 function,
		 free_map_type_copy );

		if( file_type == LIBPFF_FILE_TYPE_32BIT )
		{
			byte_stream_copy_to_uint16_little_endian(
			 ( (pff_free_map_32bit_t *) free_map_data )->signature,
			 value_16bit );
			libcnotify_printf(
			 "%s: signature\t: 0x%04" PRIx16 "\n",
			 function,
			 value_16bit );

			libcnotify_printf(
			 "%s: back pointer\t: %" PRIu64 "\n",
			 function,
			 back_pointer_offset );

			libcnotify_printf(
			 "%s: checksum\t: 0x%" PRIx32 "\n",
			 function,
			 stored_checksum );
		}
		else if( file_type == LIBPFF_FILE_TYPE_64BIT )
		{
			byte_stream_copy_to_uint16_little_endian(
			 ( (pff_free_map_64bit_t *) free_map_data )->signature,
			 value_16bit );
			libcnotify_printf(
			 "%s: signature\t: 0x%04" PRIx16 "\n",
			 function,
			 value_16bit );

			libcnotify_printf(
			 "%s: checksum\t\t: 0x%" PRIx32 "\n",
			 function,
			 stored_checksum );

			libcnotify_printf(
			 "%s: back pointer\t: %" PRIu64 "\n",
			 function,
			 back_pointer_offset );
		}
		libcnotify_printf(
		 "\n" );
	}
#endif

	if( libfmapi_checksum_calculate_weak_crc32(
	     &calculated_checksum,
	     table_data,
	     496,
	     0,
	     error ) != 1 )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
		 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
		 "%s: unable to calculate weak CRC-32.",
		 function );

		goto on_error;
	}
	if( stored_checksum != calculated_checksum )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_INPUT,
		 LIBCERROR_INPUT_ERROR_CHECKSUM_MISMATCH,
		 "%s: mismatch in checksum ( %" PRIu32 " != %" PRIu32 " ).",
		 function,
		 stored_checksum,
		 calculated_checksum );

		/* TODO implement error tollerance
		 */
		goto on_error;
	}
	if( free_map_type != free_map_type_copy )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_INPUT,
		 LIBCERROR_INPUT_ERROR_CHECKSUM_MISMATCH,
		 "%s: mismatch in allocation table type ( 0x%02" PRIx8 " != 0x%02" PRIx8 " ).",
		 function,
		 free_map_type,
		 free_map_type_copy );

		/* TODO implement error tollerance
		 */
		goto on_error;
	}
	if( ( free_map_type != LIBPFF_FREE_MAP_TYPE_DATA )
	 && ( free_map_type != LIBPFF_FREE_MAP_TYPE_PAGE ) )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
		 LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
		 "%s: unsupported allocation table type: 0x%08" PRIx32 "",
		 function,
		 free_map_type );

		/* TODO implement error tollerance
		 */
		goto on_error;
	}
	/* TODO */
	if( free_map_type == LIBPFF_FREE_MAP_TYPE_PAGE )
	{
		allocation_block_size = 512;
		back_pointer_offset  -= 0x200;
	}
	else if( free_map_type == LIBPFF_FREE_MAP_TYPE_DATA )
	{
		allocation_block_size = 64;
	}
	for( table_iterator = 0;
	     table_iterator < 496;
	     table_iterator++ )
	{
		free_map_entry = table_data[ table_iterator ];

		for( bit_iterator = 0;
		     bit_iterator < 8;
		     bit_iterator++ )
		{
			if( ( free_map_entry & 0x80 ) == 0 )
			{
				if( unallocated_size == 0 )
				{
					unallocated_offset = back_pointer_offset;
				}
				unallocated_size += allocation_block_size;
			}
			else if( unallocated_size > 0 )
			{
				result = libcdata_range_list_insert_range(
				          unallocated_block_list,
				          unallocated_offset,
				          unallocated_size,
				          NULL,
				          NULL,
				          NULL,
				          error );

				if( result == -1 )
				{
					libcerror_error_set(
					 error,
					 LIBCERROR_ERROR_DOMAIN_RUNTIME,
					 LIBCERROR_RUNTIME_ERROR_APPEND_FAILED,
					 "%s: unable to append unallocated block to list.",
					 function );

					goto on_error;
				}
				unallocated_size = 0;
			}
			free_map_entry <<= 1;

			back_pointer_offset += allocation_block_size;
		}
	}
	if( unallocated_size > 0 )
	{
		result = libcdata_range_list_insert_range(
		          unallocated_block_list,
		          unallocated_offset,
		          unallocated_size,
		          NULL,
		          NULL,
		          NULL,
		          error );

		if( result == -1 )
		{
			libcerror_error_set(
			 error,
			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
			 LIBCERROR_RUNTIME_ERROR_APPEND_FAILED,
			 "%s: unable to append unallocated block to list.",
			 function );

			goto on_error;
		}
		unallocated_size = 0;
	}
	memory_free(
	 free_map_data );

	return( 1 );

on_error:
	if( free_map_data != NULL )
	{
		memory_free(
		 free_map_data );
	}
	return( -1 );
}
Пример #2
0
/* Reads a page and its values
 * Returns 1 if successful or -1 on error
 */
int libesedb_page_read(
     libesedb_page_t *page,
     libesedb_io_handle_t *io_handle,
     libbfio_handle_t *file_io_handle,
     off64_t file_offset,
     libcerror_error_t **error )
{
	libcdata_array_t *page_tags_array  = NULL;
	uint8_t *page_values_data          = NULL;
	static char *function              = "libesedb_page_read";
	size_t page_values_data_offset     = 0;
	size_t page_values_data_size       = 0;
	ssize_t read_count                 = 0;
	uint32_t calculated_ecc32_checksum = 0;
	uint32_t calculated_page_number    = 0;
	uint32_t calculated_xor32_checksum = 0;
	uint32_t stored_ecc32_checksum     = 0;
	uint32_t stored_page_number        = 0;
	uint32_t stored_xor32_checksum     = 0;
	uint16_t available_data_size       = 0;
	uint16_t available_page_tag        = 0;

#if defined( HAVE_DEBUG_OUTPUT )
	uint64_t value_64bit               = 0;
	uint16_t value_16bit               = 0;
#endif

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

		return( -1 );
	}
	if( page->data != NULL )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
		 LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
		 "%s: invalid page data already set.",
		 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 );
	}
	calculated_page_number = (uint32_t) ( ( file_offset - io_handle->page_size ) / io_handle->page_size );

	page->offset = file_offset;

#if defined( HAVE_DEBUG_OUTPUT )
	if( libcnotify_verbose != 0 )
	{
		libcnotify_printf(
		 "%s: reading page: %" PRIu32 " at offset: %" PRIi64 " (0x%08" PRIx64 ")\n",
		 function,
		 calculated_page_number,
		 page->offset,
		 page->offset );
	}
#endif
	if( libbfio_handle_seek_offset(
	     file_io_handle,
	     page->offset,
	     SEEK_SET,
	     error ) == -1 )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_IO,
		 LIBCERROR_IO_ERROR_SEEK_FAILED,
		 "%s: unable to seek page offset: %" PRIi64 ".",
		 function,
		 page->offset );

		goto on_error;
	}
	page->data = (uint8_t *) memory_allocate(
	                          (size_t) io_handle->page_size );

	if( page->data == NULL )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_MEMORY,
		 LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
		 "%s: unable to create page data.",
		 function );

		goto on_error;
	}
	page->data_size = (size_t) io_handle->page_size;

	read_count = libbfio_handle_read_buffer(
	              file_io_handle,
	              page->data,
	              page->data_size,
	              error );

	if( read_count != (ssize_t) page->data_size )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_IO,
		 LIBCERROR_IO_ERROR_READ_FAILED,
		 "%s: unable to read page data.",
		 function );

		goto on_error;
	}
	page_values_data      = page->data;
	page_values_data_size = page->data_size;

#if defined( HAVE_DEBUG_OUTPUT )
	if( libcnotify_verbose != 0 )
	{
		libcnotify_printf(
		 "%s: page header:\n",
		 function );
		libcnotify_print_data(
		 page_values_data,
		 sizeof( esedb_page_header_t ),
		 0 );
	}
#endif
	page->page_number = calculated_page_number;

	byte_stream_copy_to_uint16_little_endian(
	 ( (esedb_page_header_t *) page_values_data )->available_data_size,
	 available_data_size );

	byte_stream_copy_to_uint32_little_endian(
	 ( (esedb_page_header_t *) page_values_data )->previous_page,
	 page->previous_page_number );
	byte_stream_copy_to_uint32_little_endian(
	 ( (esedb_page_header_t *) page_values_data )->next_page,
	 page->next_page_number );
	byte_stream_copy_to_uint32_little_endian(
	 ( (esedb_page_header_t *) page_values_data )->father_data_page_object_identifier,
	 page->father_data_page_object_identifier );

	byte_stream_copy_to_uint16_little_endian(
	 ( (esedb_page_header_t *) page_values_data )->available_page_tag,
	 available_page_tag );

	byte_stream_copy_to_uint32_little_endian(
	 ( (esedb_page_header_t *) page_values_data )->page_flags,
	 page->flags );

	/* Make sure to read after the page flags
	 */
	if( ( io_handle->format_revision >= LIBESEDB_FORMAT_REVISION_EXTENDED_PAGE_HEADER )
	 && ( io_handle->page_size >= 16384 ) )
	{
		/* TODO handle checksum */
	}
	else
	{
		byte_stream_copy_to_uint32_little_endian(
		 ( (esedb_page_header_t *) page_values_data )->xor_checksum,
		 stored_xor32_checksum );

		if( ( io_handle->format_revision >= LIBESEDB_FORMAT_REVISION_NEW_RECORD_FORMAT )
		 && ( ( page->flags & LIBESEDB_PAGE_FLAG_IS_NEW_RECORD_FORMAT ) != 0 ) )
		{
			byte_stream_copy_to_uint32_little_endian(
			 ( (esedb_page_header_t *) page_values_data )->ecc_checksum,
			 stored_ecc32_checksum );
		}
		else
		{
			byte_stream_copy_to_uint32_little_endian(
			 ( (esedb_page_header_t *) page_values_data )->page_number,
			 stored_page_number );
		}
	}
#if defined( HAVE_DEBUG_OUTPUT )
	if( libcnotify_verbose != 0 )
	{
		libcnotify_printf(
		 "%s: current page number\t\t\t\t\t: %" PRIu32 "\n",
		 function,
		 calculated_page_number );

		if( ( io_handle->format_revision >= LIBESEDB_FORMAT_REVISION_EXTENDED_PAGE_HEADER )
		 && ( io_handle->page_size >= 16384 ) )
		{
			/* TODO handle checksum */

			byte_stream_copy_to_uint64_little_endian(
			 page_values_data,
			 value_64bit );
			libcnotify_printf(
			 "%s: checksum\t\t\t\t\t\t: 0x%08" PRIx64 "\n",
			 function,
			 value_64bit );
		}
		else
		{
			libcnotify_printf(
			 "%s: XOR checksum\t\t\t\t\t: 0x%08" PRIx32 "\n",
			 function,
			 stored_xor32_checksum );

			if( ( io_handle->format_revision >= LIBESEDB_FORMAT_REVISION_NEW_RECORD_FORMAT )
			 && ( ( page->flags & LIBESEDB_PAGE_FLAG_IS_NEW_RECORD_FORMAT ) != 0 ) )
			{
				libcnotify_printf(
				 "%s: ECC checksum\t\t\t\t\t: 0x%08" PRIx32 "\n",
				 function,
				 stored_ecc32_checksum );
			}
			else
			{
				libcnotify_printf(
				 "%s: page number\t\t\t\t\t\t: %" PRIu32 "\n",
				 function,
				 stored_page_number );
			}
		}
		libcnotify_printf(
		 "%s: database modification time:\n",
		 function );
		libcnotify_print_data(
		 ( (esedb_page_header_t *) page_values_data )->database_modification_time,
		 8,
		 0 );

		libcnotify_printf(
		 "%s: previous page number\t\t\t\t: %" PRIu32 "\n",
		 function,
		 page->previous_page_number );
		libcnotify_printf(
		 "%s: next page number\t\t\t\t\t: %" PRIu32 "\n",
		 function,
		 page->next_page_number );
		libcnotify_printf(
		 "%s: father data page (FDP) object identifier\t\t: %" PRIu32 "\n",
		 function,
		 page->father_data_page_object_identifier );

		libcnotify_printf(
		 "%s: available data size\t\t\t\t\t: %" PRIu32 "\n",
		 function,
		 available_data_size );

		byte_stream_copy_to_uint16_little_endian(
		 ( (esedb_page_header_t *) page_values_data )->available_uncommitted_data_size,
		 value_16bit );
		libcnotify_printf(
		 "%s: available uncommitted data size\t\t\t: %" PRIu16 "\n",
		 function,
		 value_16bit );

		byte_stream_copy_to_uint16_little_endian(
		 ( (esedb_page_header_t *) page_values_data )->available_data_offset,
		 value_16bit );
		libcnotify_printf(
		 "%s: available data offset\t\t\t\t: %" PRIu16 "\n",
		 function,
		 value_16bit );

		libcnotify_printf(
		 "%s: available page tag\t\t\t\t\t: %" PRIu32 "\n",
		 function,
		 available_page_tag );

		libcnotify_printf(
		 "%s: page flags\t\t\t\t\t\t: 0x%08" PRIx32 "\n",
		 function,
		 page->flags );
		libesedb_debug_print_page_flags(
		 page->flags );
		libcnotify_printf(
		 "\n" );
	}
#endif
	/* TODO for now don't bother calculating a checksum for uninitialized pages */

	if( ( page_values_data[ 0 ] != 0 )
	 || ( page_values_data[ 1 ] != 0 )
	 || ( page_values_data[ 2 ] != 0 )
	 || ( page_values_data[ 3 ] != 0 ) )
	{
		if( ( io_handle->format_revision >= LIBESEDB_FORMAT_REVISION_EXTENDED_PAGE_HEADER )
		 && ( io_handle->page_size >= 16384 ) )
		{
			/* TODO handle checksum */
		}
		else if( ( io_handle->format_revision >= LIBESEDB_FORMAT_REVISION_NEW_RECORD_FORMAT )
		      && ( ( page->flags & LIBESEDB_PAGE_FLAG_IS_NEW_RECORD_FORMAT ) != 0 ) )
		{
			if( libesedb_checksum_calculate_little_endian_ecc32(
			     &calculated_ecc32_checksum,
			     &calculated_xor32_checksum,
			     page_values_data,
			     page_values_data_size,
			     8,
			     calculated_page_number,
			     error ) != 1 )
			{
				libcerror_error_set(
				 error,
				 LIBCERROR_ERROR_DOMAIN_RUNTIME,
				 LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
				 "%s: unable to calculate ECC-32 and XOR-32 checksum.",
				 function );

				goto on_error;
			}
		}
		else
		{
			if( libesedb_checksum_calculate_little_endian_xor32(
			     &calculated_xor32_checksum,
			     &( page_values_data[ 4 ] ),
			     page_values_data_size - 4,
			     0x89abcdef,
			     error ) != 1 )
			{
				libcerror_error_set(
				 error,
				 LIBCERROR_ERROR_DOMAIN_RUNTIME,
				 LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
				 "%s: unable to calculate XOR-32 checksum.",
				 function );

				goto on_error;
			}
		}
		if( stored_xor32_checksum != calculated_xor32_checksum )
		{
#ifdef TODO
			libcerror_error_set(
			 error,
			 LIBCERROR_ERROR_DOMAIN_INPUT,
			 LIBCERROR_INPUT_ERROR_CRC_MISMATCH,
			 "%s: mismatch in page XOR-32 checksum ( 0x%08" PRIx32 " != 0x%08" PRIx32 " ).",
			 function,
			 stored_xor32_checksum,
			 calculated_xor32_checksum );

			goto on_error;
#else
			if( libcnotify_verbose != 0 )
			{
				libcnotify_printf(
				 "%s: mismatch in page XOR-32 checksum ( 0x%08" PRIx32 " != 0x%08" PRIx32 " ).\n",
				 function,
				 stored_xor32_checksum,
				 calculated_xor32_checksum );
			}
#endif
		}
		if( stored_ecc32_checksum != calculated_ecc32_checksum )
		{
#ifdef TODO
			libcerror_error_set(
			 error,
			 LIBCERROR_ERROR_DOMAIN_INPUT,
			 LIBCERROR_INPUT_ERROR_CRC_MISMATCH,
			 "%s: mismatch in page ECC-32 checksum ( 0x%08" PRIx32 " != 0x%08" PRIx32 " ).",
			 function,
			 stored_ecc32_checksum,
			 calculated_ecc32_checksum );

			goto on_error;
#else
			if( libcnotify_verbose != 0 )
			{
				libcnotify_printf(
				 "%s: mismatch in page ECC-32 checksum ( 0x%08" PRIx32 " != 0x%08" PRIx32 " ).\n",
				 function,
				 stored_ecc32_checksum,
				 calculated_ecc32_checksum );
			}
#endif
		}
	}
	page_values_data        += sizeof( esedb_page_header_t );
	page_values_data_size   -= sizeof( esedb_page_header_t );
	page_values_data_offset += sizeof( esedb_page_header_t );

	if( ( io_handle->format_revision >= LIBESEDB_FORMAT_REVISION_EXTENDED_PAGE_HEADER )
	 && ( io_handle->page_size >= 16384 ) )
	{
#if defined( HAVE_DEBUG_OUTPUT )
		if( libcnotify_verbose != 0 )
		{
			libcnotify_printf(
			 "%s: extended page header:\n",
			 function );
			libcnotify_print_data(
			 page_values_data,
			 40,
			 0 );
		}
#endif
#if defined( HAVE_DEBUG_OUTPUT )
		if( libcnotify_verbose != 0 )
		{
			byte_stream_copy_to_uint64_little_endian(
			 ( (esedb_extended_page_header_t *) page_values_data )->checksum1,
			 value_64bit );
			libcnotify_printf(
			 "%s: checksum1\t\t\t\t\t\t: 0x%08" PRIx64 "\n",
			 function,
			 value_64bit );

			byte_stream_copy_to_uint64_little_endian(
			 ( (esedb_extended_page_header_t *) page_values_data )->checksum2,
			 value_64bit );
			libcnotify_printf(
			 "%s: checksum2\t\t\t\t\t\t: 0x%08" PRIx64 "\n",
			 function,
			 value_64bit );

			byte_stream_copy_to_uint64_little_endian(
			 ( (esedb_extended_page_header_t *) page_values_data )->checksum3,
			 value_64bit );
			libcnotify_printf(
			 "%s: checksum3\t\t\t\t\t\t: 0x%08" PRIx64 "\n",
			 function,
			 value_64bit );

			byte_stream_copy_to_uint64_little_endian(
			 ( (esedb_extended_page_header_t *) page_values_data )->page_number,
			 value_64bit );
			libcnotify_printf(
			 "%s: page number\t\t\t\t\t\t: %" PRIu64 "\n",
			 function,
			 value_64bit );

			libcnotify_printf(
			 "%s: unknown1:\n",
			 function );
			libcnotify_print_data(
			 ( (esedb_extended_page_header_t *) page_values_data )->unknown1,
			 8,
			 0 );
		}
#endif
		page_values_data        += sizeof( esedb_extended_page_header_t );
		page_values_data_size   -= sizeof( esedb_extended_page_header_t );
		page_values_data_offset += sizeof( esedb_extended_page_header_t );
	}
	if( available_page_tag > 0 )
	{
		/* Create the page tags array
		 */
		if( libcdata_array_initialize(
		     &page_tags_array,
		     0,
		     error ) != 1 )
		{
			libcerror_error_set(
			 error,
			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
			 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
			 "%s: unable to create page tags array.",
			 function );

			goto on_error;
		}
		if( libesedb_page_read_tags(
		     page_tags_array,
		     io_handle,
		     available_page_tag,
		     page->data,
		     page->data_size,
		     error ) != 1 )
		{
			libcerror_error_set(
			 error,
			 LIBCERROR_ERROR_DOMAIN_IO,
			 LIBCERROR_IO_ERROR_READ_FAILED,
			 "%s: unable to read page tags.",
			 function );

			goto on_error;
		}
		/* The offsets in the page tags are relative after the page header
		 */
		if( libesedb_page_read_values(
		     page,
		     io_handle,
		     page_tags_array,
		     page_values_data,
		     page_values_data_size,
		     page_values_data_offset,
		     error ) != 1 )
		{
			libcerror_error_set(
			 error,
			 LIBCERROR_ERROR_DOMAIN_IO,
			 LIBCERROR_IO_ERROR_READ_FAILED,
			 "%s: unable to read page values.",
			 function );

			goto on_error;
		}
		if( libcdata_array_free(
		     &page_tags_array,
		     (int (*)(intptr_t **, libcerror_error_t **)) &libesedb_page_tags_value_free,
		     error ) != 1 )
		{
			libcerror_error_set(
			 error,
			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
			 LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
			 "%s: unable to free the page tags array.",
			 function );

			goto on_error;
		}
	}
	return( 1 );

on_error:
	if( page_tags_array != NULL )
	{
		libcdata_array_free(
		 &page_tags_array,
		 (int (*)(intptr_t **, libcerror_error_t **)) &libesedb_page_tags_value_free,
		 NULL );
	}
	if( page->data != NULL )
	{
		memory_free(
		 page->data );

		page->data = NULL;
	}
	return( -1 );
}
Пример #3
0
/* Determines if a file contains a BDE volume signature using a Basic File IO (bfio) handle
 * Returns 1 if true, 0 if not or -1 on error
 */
int libbde_check_volume_signature_file_io_handle(
     libbfio_handle_t *file_io_handle,
     libcerror_error_t **error )
{
	uint8_t signature[ 12 ];

	static char *function      = "libbde_check_volume_signature_file_io_handle";
	ssize_t read_count         = 0;
	int file_io_handle_is_open = 0;

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

		return( -1 );
	}
	file_io_handle_is_open = libbfio_handle_is_open(
	                          file_io_handle,
	                          error );

	if( file_io_handle_is_open == -1 )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_IO,
		 LIBCERROR_IO_ERROR_OPEN_FAILED,
		 "%s: unable to open file.",
		 function );

		return( -1 );
	}
	else if( file_io_handle_is_open == 0 )
	{
		if( libbfio_handle_open(
		     file_io_handle,
		     LIBBFIO_OPEN_READ,
		     error ) != 1 )
		{
			libcerror_error_set(
			 error,
			 LIBCERROR_ERROR_DOMAIN_IO,
			 LIBCERROR_IO_ERROR_OPEN_FAILED,
			 "%s: unable to open file.",
			 function );

			return( -1 );
		}
	}
	if( libbfio_handle_seek_offset(
	     file_io_handle,
	     0,
	     SEEK_SET,
	     error ) == -1 )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_IO,
		 LIBCERROR_IO_ERROR_SEEK_FAILED,
		 "%s: unable to seek file header offset: 0.",
		 function );

		if( file_io_handle_is_open == 0 )
		{
			libbfio_handle_close(
			 file_io_handle,
			 error );
		}
		return( -1 );
	}
	read_count = libbfio_handle_read_buffer(
	              file_io_handle,
	              signature,
	              12,
	              error );

	if( read_count != 12 )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_IO,
		 LIBCERROR_IO_ERROR_READ_FAILED,
		 "%s: unable to read signature.",
		 function );

		if( file_io_handle_is_open == 0 )
		{
			libbfio_handle_close(
			 file_io_handle,
			 error );
		}
		return( -1 );
	}
	if( file_io_handle_is_open == 0 )
	{
		if( libbfio_handle_close(
		     file_io_handle,
		     error ) != 0 )
		{
			libcerror_error_set(
			 error,
			 LIBCERROR_ERROR_DOMAIN_IO,
			 LIBCERROR_IO_ERROR_CLOSE_FAILED,
			 "%s: unable to close file.",
			 function );

			return( -1 );
		}
	}
	if( memory_compare(
	     bde_signature,
	     &( signature[ 3 ] ),
	     8 ) == 0 )
	{
		return( 1 );
	}
	return( 0 );
}
Пример #4
0
/* Reads the metadata area
 * Returns 1 if successful or -1 on error
 */
int libvslvm_metadata_area_read(
     libvslvm_metadata_area_t *metadata_area,
     libbfio_handle_t *file_io_handle,
     off64_t file_offset,
     libcerror_error_t **error )
{
	vslvm_raw_location_descriptor_t raw_location_descriptor_data;
	vslvm_metadata_area_header_t metadata_area_header;

	libvslvm_raw_location_descriptor_t *raw_location_descriptor = NULL;
	static char *function                                       = "libvslvm_metadata_area_read";
	ssize_t read_count                                          = 0;
	uint64_t offset                                             = 0;
	uint64_t size                                               = 0;
	uint32_t checksum                                           = 0;
	uint32_t flags                                              = 0;
	int entry_index                                             = 0;
	int result                                                  = 0;

#if defined( HAVE_DEBUG_OUTPUT )
	uint64_t value_64bit                                        = 0;
	uint32_t value_32bit                                        = 0;
#endif

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

		return( -1 );
	}
#if defined( HAVE_DEBUG_OUTPUT )
	if( libcnotify_verbose != 0 )
	{
		libcnotify_printf(
		 "%s: reading metadata area at offset: %" PRIi64 "\n",
		 function,
		 file_offset );
	}
#endif
	if( libbfio_handle_seek_offset(
	     file_io_handle,
	     file_offset,
	     SEEK_SET,
	     error ) == -1 )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_IO,
		 LIBCERROR_IO_ERROR_SEEK_FAILED,
		 "%s: unable to seek offset: %" PRIi64 " (0x%08" PRIx64 ").",
		 function,
		 file_offset,
		 file_offset );

		goto on_error;
	}
	read_count = libbfio_handle_read_buffer(
	              file_io_handle,
	              (uint8_t *) &metadata_area_header,
	              sizeof( vslvm_metadata_area_header_t ),
	              error );

	if( read_count != (ssize_t) sizeof( vslvm_metadata_area_header_t ) )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_IO,
		 LIBCERROR_IO_ERROR_READ_FAILED,
		 "%s: unable to read metadata area header.",
		 function );

		goto on_error;
	}
#if defined( HAVE_DEBUG_OUTPUT )
	if( libcnotify_verbose != 0 )
	{
		libcnotify_printf(
		 "%s: metadata area header data:\n",
		 function );
		libcnotify_print_data(
		 (uint8_t *) &metadata_area_header,
		 sizeof( vslvm_metadata_area_header_t ),
		 0 );
	}
#endif
	if( memory_compare(
	     metadata_area_header.signature,
	     vslvm_metadata_area_signature,
	     8 ) != 0 )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
		 LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
		 "%s: unsupported metadata area signature.",
		 function );

		goto on_error;
	}
#if defined( HAVE_DEBUG_OUTPUT )
	if( libcnotify_verbose != 0 )
	{
		byte_stream_copy_to_uint32_little_endian(
		 metadata_area_header.checksum,
		 value_32bit );
		libcnotify_printf(
		 "%s: checksum\t\t\t\t\t: 0x%08" PRIx32 "\n",
		 function,
		 value_32bit );

		libcnotify_printf(
		 "%s: signature\t\t\t\t\t: %c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c\n",
		 function,
		 metadata_area_header.signature[ 0 ],
		 metadata_area_header.signature[ 1 ],
		 metadata_area_header.signature[ 2 ],
		 metadata_area_header.signature[ 3 ],
		 metadata_area_header.signature[ 4 ],
		 metadata_area_header.signature[ 5 ],
		 metadata_area_header.signature[ 6 ],
		 metadata_area_header.signature[ 7 ],
		 metadata_area_header.signature[ 8 ],
		 metadata_area_header.signature[ 9 ],
		 metadata_area_header.signature[ 10 ],
		 metadata_area_header.signature[ 11 ],
		 metadata_area_header.signature[ 12 ],
		 metadata_area_header.signature[ 13 ],
		 metadata_area_header.signature[ 14 ],
		 metadata_area_header.signature[ 15 ] );

		byte_stream_copy_to_uint32_little_endian(
		 metadata_area_header.version,
		 value_32bit );
		libcnotify_printf(
		 "%s: version\t\t\t\t\t: %" PRIu32 "\n",
		 function,
		 value_32bit );

		byte_stream_copy_to_uint64_little_endian(
		 metadata_area_header.data_offset,
		 value_64bit );
		libcnotify_printf(
		 "%s: data offset\t\t\t\t: 0x%08" PRIx64 "\n",
		 function,
		 value_64bit );

		byte_stream_copy_to_uint64_little_endian(
		 metadata_area_header.data_size,
		 value_64bit );
		libcnotify_printf(
		 "%s: data size\t\t\t\t\t: %" PRIu64 "\n",
		 function,
		 value_64bit );

		libcnotify_printf(
		 "\n" );
	}
#endif
/* TODO calculate checksum */

	do
	{
		read_count = libbfio_handle_read_buffer(
		              file_io_handle,
		              (uint8_t *) &raw_location_descriptor_data,
		              sizeof( vslvm_raw_location_descriptor_t ),
		              error );

		if( read_count != (ssize_t) sizeof( vslvm_raw_location_descriptor_t ) )
		{
			libcerror_error_set(
			 error,
			 LIBCERROR_ERROR_DOMAIN_IO,
			 LIBCERROR_IO_ERROR_READ_FAILED,
			 "%s: unable to read raw location descriptor.",
			 function );

			goto on_error;
		}
#if defined( HAVE_DEBUG_OUTPUT )
		if( libcnotify_verbose != 0 )
		{
			libcnotify_printf(
			 "%s: raw location descriptor data:\n",
			 function );
			libcnotify_print_data(
			 (uint8_t *) &raw_location_descriptor_data,
			 sizeof( vslvm_raw_location_descriptor_t ),
			 0 );
		}
#endif
		result = memory_compare(
		          (uint8_t *) &raw_location_descriptor_data,
		          vslvm_empty_raw_location_descriptor,
		          sizeof( vslvm_raw_location_descriptor_t ) );

		if( result != 0 )
		{
			byte_stream_copy_to_uint64_little_endian(
			 raw_location_descriptor_data.offset,
			 offset );

			byte_stream_copy_to_uint64_little_endian(
			 raw_location_descriptor_data.size,
			 size );

			byte_stream_copy_to_uint32_little_endian(
			 raw_location_descriptor_data.checksum,
			 checksum );

			byte_stream_copy_to_uint32_little_endian(
			 raw_location_descriptor_data.flags,
			 flags );

#if defined( HAVE_DEBUG_OUTPUT )
			if( libcnotify_verbose != 0 )
			{
				libcnotify_printf(
				 "%s: offset\t\t\t\t\t: 0x%08" PRIx64 "\n",
				 function,
				 offset );

				libcnotify_printf(
				 "%s: size\t\t\t\t\t: %" PRIu64 "\n",
				 function,
				 size );

				libcnotify_printf(
				 "%s: checksum\t\t\t\t\t: 0x%08" PRIx32 "\n",
				 function,
				 checksum );

				libcnotify_printf(
				 "%s: flags\t\t\t\t\t: 0x%08" PRIx32 "\n",
				 function,
				 flags );

				libcnotify_printf(
				 "\n" );
			}
#endif
			if( ( flags & LIBVSLVM_RAW_LOCATION_DESCRIPTOR_FLAG_IGNORE ) == 0 )
			{
				if( libvslvm_raw_location_descriptor_initialize(
				     &raw_location_descriptor,
				     error ) != 1 )
				{
					libcerror_error_set(
					 error,
					 LIBCERROR_ERROR_DOMAIN_RUNTIME,
					 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
					 "%s: unable to create raw location descriptor.",
					 function );

					goto on_error;
				}
				if( libvslvm_raw_location_descriptor_set(
				     raw_location_descriptor,
				     (off64_t) ( file_offset + offset ),
				     (size64_t) size,
				     checksum,
				     flags,
				     error ) != 1 )
				{
					libcerror_error_set(
					 error,
					 LIBCERROR_ERROR_DOMAIN_RUNTIME,
					 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
					 "%s: unable to set raw location descriptor.",
					 function );

					goto on_error;
				}
				if( libcdata_array_append_entry(
				     metadata_area->raw_location_descriptors_array,
				     &entry_index,
				     (intptr_t *) raw_location_descriptor,
				     error ) != 1 )
				{
					libcerror_error_set(
					 error,
					 LIBCERROR_ERROR_DOMAIN_RUNTIME,
					 LIBCERROR_RUNTIME_ERROR_APPEND_FAILED,
					 "%s: unable to append entry to raw location descriptors array.",
					 function );

					goto on_error;
				}
				raw_location_descriptor = NULL;
			}
		}
	}
	while( result != 0 );

	return( 1 );

on_error:
	if( raw_location_descriptor != NULL )
	{
		libvslvm_raw_location_descriptor_free(
		 &raw_location_descriptor,
		 NULL );
	}
	libcdata_array_empty(
	 metadata_area->raw_location_descriptors_array,
	 (int (*)(intptr_t **, libcerror_error_t **)) &libvslvm_raw_location_descriptor_free,
	 NULL );

	return( -1 );
}
Пример #5
0
/* Reads a data block header
 * Returns 1 if successful, 0 if no data block signature was found or -1 on error
 */
int libcreg_data_block_read_header(
     libcreg_data_block_t *data_block,
     libbfio_handle_t *file_io_handle,
     libcerror_error_t **error )
{
	creg_data_block_header_t data_block_header;

	static char *function = "libcreg_data_block_read_header";
	ssize_t read_count    = 0;

#if defined( HAVE_DEBUG_OUTPUT )
	uint16_t value_16bit  = 0;
#endif

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

		return( -1 );
	}
	if( libbfio_handle_get_offset(
	     file_io_handle,
	     &( data_block->offset ),
	     error ) != 1 )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
		 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
		 "%s: unable to retrieve file offset.",
		 function );

		return( -1 );
	}
#if defined( HAVE_DEBUG_OUTPUT )
	if( libcnotify_verbose != 0 )
	{
		libcnotify_printf(
		 "%s: reading data block header at offset: %" PRIi64 " (0x%08" PRIx64 ")\n",
		 function,
		 data_block->offset,
		 data_block->offset );
	}
#endif
	read_count = libbfio_handle_read_buffer(
	              file_io_handle,
	              (uint8_t *) &data_block_header,
	              sizeof( creg_data_block_header_t ),
	              error );

	if( read_count != (ssize_t) sizeof( creg_data_block_header_t ) )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_IO,
		 LIBCERROR_IO_ERROR_READ_FAILED,
		 "%s: unable to read data block header data.",
		 function );

		return( -1 );
	}
#if defined( HAVE_DEBUG_OUTPUT )
	if( libcnotify_verbose != 0 )
	{
		libcnotify_printf(
		 "%s: data block header:\n",
		 function );
		libcnotify_print_data(
		 (uint8_t *) &data_block_header,
		 sizeof( creg_data_block_header_t ),
		 0 );
	}
#endif
	if( memory_compare(
	     data_block_header.signature,
	     creg_data_block_signature,
	     4 ) != 0 )
	{
		return( 0 );
	}
	byte_stream_copy_to_uint32_little_endian(
	 data_block_header.size,
	 data_block->size );

	byte_stream_copy_to_uint32_little_endian(
	 data_block_header.unused_size,
	 data_block->unused_size );

	byte_stream_copy_to_uint32_little_endian(
	 data_block_header.used_size,
	 data_block->used_size );

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

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

		libcnotify_printf(
		 "%s: unused size\t\t\t\t: %" PRIu32 "\n",
		 function,
		 data_block->unused_size );

		byte_stream_copy_to_uint16_little_endian(
		 data_block_header.unknown1,
		 value_16bit );
		libcnotify_printf(
		 "%s: unknown1\t\t\t\t: 0x%04" PRIx16 "\n",
		 function,
		 value_16bit );

		byte_stream_copy_to_uint16_little_endian(
		 data_block_header.index,
		 value_16bit );
		libcnotify_printf(
		 "%s: index\t\t\t\t\t: %" PRIu16 "\n",
		 function,
		 value_16bit );

		libcnotify_printf(
		 "%s: used size\t\t\t\t: %" PRIi32 "\n",
		 function,
		 (int32_t) data_block->used_size );

		byte_stream_copy_to_uint16_little_endian(
		 data_block_header.unknown2,
		 value_16bit );
		libcnotify_printf(
		 "%s: unknown2\t\t\t\t: %" PRIu16 "\n",
		 function,
		 value_16bit );

		byte_stream_copy_to_uint16_little_endian(
		 data_block_header.unknown3,
		 value_16bit );
		libcnotify_printf(
		 "%s: unknown3\t\t\t\t: %" PRIu16 "\n",
		 function,
		 value_16bit );

		libcnotify_printf(
		 "%s: unknown3:\n",
		 function );
		libcnotify_print_data(
		 data_block_header.unknown4,
		 8,
		 0 );

		libcnotify_printf(
		 "\n" );
	}
#endif
/* TODO check if unused_size + used_size == size */
	return( 1 );
}
/* Reads a hash table
 * Returns 1 if successful or -1 on error
 */
int libmsiecf_hash_table_read(
     libcdata_array_t *hash_table,
     off64_t *next_hash_table_offset,
     libbfio_handle_t *file_io_handle,
     off64_t hash_table_offset,
     size32_t block_size,
     libcerror_error_t **error )
{
	msiecf_hash_record_header_t hash_record_header;

	uint8_t *hash_record_data                    = NULL;
	uint8_t *entry_data                          = NULL;
	static char *function                        = "libmsiecf_hash_table_read";
	size_t read_size                             = 0;
	size_t table_iterator                        = 0;
	ssize_t read_count                           = 0;
	uint32_t entry_hash                          = 0;
	uint32_t entry_offset                        = 0;
	uint32_t number_of_blocks                    = 0;

#if defined( HAVE_DEBUG_OUTPUT )
	uint32_t value_32bit                         = 0;
	int number_of_items                          = 0;
#endif

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

		return( -1 );
	}
	if( next_hash_table_offset == NULL )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
		 "%s: invalid next hash table offset.",
		 function );

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

		return( -1 );
	}
	if( block_size == 0 )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
		 LIBCERROR_ARGUMENT_ERROR_VALUE_ZERO_OR_LESS,
		 "%s: invalid block size value zero or less.",
		 function );

		return( -1 );
	}
#if defined( HAVE_DEBUG_OUTPUT )
	if( libcnotify_verbose != 0 )
	{
		libcnotify_printf(
		 "%s: reading HASH record at offset: %" PRIi64 " (0x%08" PRIx64 ")\n",
		 function,
		 hash_table_offset,
		 hash_table_offset );
	}
#endif

	if( libbfio_handle_seek_offset(
	     file_io_handle,
	     hash_table_offset,
	     SEEK_SET,
	     error ) == -1 )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_IO,
		 LIBCERROR_IO_ERROR_SEEK_FAILED,
		 "%s: unable to seek HASH record offset: %" PRIi64 ".",
		 function,
		 hash_table_offset );

		return( -1 );
	}
	read_count = libbfio_handle_read_buffer(
	              file_io_handle,
	              (uint8_t *) &hash_record_header,
	              sizeof( msiecf_hash_record_header_t ),
	              error );

	if( read_count != (ssize_t) sizeof( msiecf_hash_record_header_t ) )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_IO,
		 LIBCERROR_IO_ERROR_READ_FAILED,
		 "%s: unable to read HASH record header.",
		 function );

		return( -1 );
	}
#if defined( HAVE_DEBUG_OUTPUT )
	if( libcnotify_verbose != 0 )
	{
		libcnotify_printf(
		 "%s: HASH record header:\n",
		 function );
		libcnotify_print_data(
		 (uint8_t *) &hash_record_header,
		 sizeof( msiecf_hash_record_header_t ),
		 0 );
	}
#endif
	if( memory_compare(
	     hash_record_header.signature,
	     "HASH",
	     4 ) != 0 )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
		 LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
		 "%s: unsupported signature.",
		 function );

		return( -1 );
	}
	byte_stream_copy_to_uint32_little_endian(
	 hash_record_header.number_of_blocks,
	 number_of_blocks );
	byte_stream_copy_to_uint32_little_endian(
	 hash_record_header.next_offset,
	 *next_hash_table_offset );

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

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

		libcnotify_printf(
		 "%s: next offset\t\t\t\t\t: %" PRIi64 " (0x%08" PRIx64 ")\n",
		 function,
		 *next_hash_table_offset,
		 *next_hash_table_offset );

		byte_stream_copy_to_uint32_little_endian(
		 hash_record_header.sequence_number,
		 value_32bit );
		libcnotify_printf(
		 "%s: sequence number\t\t\t\t: %" PRIu32 "\n",
		 function,
		 value_32bit );

		libcnotify_printf(
		 "\n" );
	}
#endif
	read_size = ( number_of_blocks * block_size ) - sizeof( msiecf_hash_record_header_t );

	if( read_size > (size_t) SSIZE_MAX )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
		 LIBCERROR_RUNTIME_ERROR_VALUE_EXCEEDS_MAXIMUM,
		 "%s: invalid read size value exceeds maximum.",
		 function );

		return( -1 );
	}
	if( ( read_size % 8 ) != 0 )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
		 LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
		 "%s: unsupported HASH record data size.",
		 function );

		return( -1 );
	}
	hash_record_data = (uint8_t *) memory_allocate(
	                                read_size );

	if( hash_record_data == NULL )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_MEMORY,
		 LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
		 "%s: unable to create HASH record data.",
		 function );

		return( -1 );
	}
	read_count = libbfio_handle_read_buffer(
	              file_io_handle,
	              hash_record_data,
	              read_size,
	              error );

	if( read_count != (ssize_t) read_size )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_IO,
		 LIBCERROR_IO_ERROR_READ_FAILED,
		 "%s: unable to read HASH record data.",
		 function );

		memory_free(
		 hash_record_data );

		return( -1 );
	}
#if defined( HAVE_DEBUG_OUTPUT )
	if( libcnotify_verbose != 0 )
	{
		libcnotify_printf(
		 "%s: HASH record data:\n",
		 function );
		libcnotify_print_data(
		 hash_record_data,
		 read_size,
		 0 );
	}
#endif
	read_size /= 8;

	entry_data = hash_record_data;

	for( table_iterator = 0;
	     table_iterator < read_size;
	     table_iterator++ )
	{
		byte_stream_copy_to_uint32_little_endian(
		 entry_data,
		 entry_hash );

		entry_data += 4;

		byte_stream_copy_to_uint32_little_endian(
		 entry_data,
		 entry_offset );

		entry_data += 4;

#if defined( HAVE_DEBUG_OUTPUT )
		if( libcnotify_verbose != 0 )
		{
			libcnotify_printf(
			 "%s: entry %03d hash\t\t\t\t: 0x%08" PRIx32 "\n",
			 function,
			 table_iterator,
			 entry_hash );
			libcnotify_printf(
			 "%s: entry %03d offset\t\t\t\t: 0x%08" PRIx32 "\n",
			 function,
			 table_iterator,
			 entry_offset );
		}
#endif

		/* Skip empty entries
		 */
		if( entry_hash == entry_offset )
		{
			continue;
		}
		/* Skip uninitialized entries
		 * These should only appear at the end of the HASH record data
		 */
		if( ( entry_hash == 0x0badf00d )
		 || ( entry_hash == 0xdeadbeef ) )
		{
			continue;
		}
		/* Skip invalid URL entries
		 */
		if( ( entry_hash & 0x0f ) == 0x01 )
		{
			continue;
		}
		/* Check if the entry record offset is block aligned
		 */
		if( ( entry_offset % block_size ) != 0 )
		{
			continue;
		}
#if defined( HAVE_DEBUG_OUTPUT )
		number_of_items++;
#endif
		/* TODO flag hashed items
		 */

	}
	memory_free(
	 hash_record_data );

#if defined( HAVE_DEBUG_OUTPUT )
	if( libcnotify_verbose != 0 )
	{
		libcnotify_printf(
		 "%s: found %d hashed items.\n",
		 function,
		 number_of_items );
		libcnotify_printf(
		 "\n" );
	}
#endif
	return( 1 );
}
Пример #7
0
/* Reads the items into the items array
 * Returns 1 if successful or -1 on error
 */
int libnk2_file_read_items(
     libnk2_internal_file_t *internal_file,
     libbfio_handle_t *file_io_handle,
     uint32_t number_of_items,
     libcerror_error_t **error )
{
	uint8_t number_of_record_entries_data[ 4 ];

	libnk2_item_t *item               = NULL;
	static char *function             = "libnk2_file_read_items";
	ssize_t read_count                = 0;
	uint32_t item_index               = 0;
	uint32_t number_of_record_entries = 0;
	int entry_index                   = 0;

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

		return( -1 );
	}
	if( libcdata_array_empty(
	     internal_file->items_array,
	     (int (*)(intptr_t **, libcerror_error_t **)) &libnk2_internal_item_free,
	     error ) != 1 )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
		 LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
		 "%s: unable to empty items array.",
		 function );

		goto on_error;
	}
	for( item_index = 0;
	     item_index < number_of_items;
	     item_index++ )
	{
		read_count = libbfio_handle_read_buffer(
			      file_io_handle,
			      number_of_record_entries_data,
			      4,
			      error );

		if( read_count != (ssize_t) 4 )
		{
			libcerror_error_set(
			 error,
			 LIBCERROR_ERROR_DOMAIN_IO,
			 LIBCERROR_IO_ERROR_READ_FAILED,
			 "%s: unable to read item: %" PRIu32 " number of record entries data.",
			 function,
			 item_index );

			goto on_error;
		}
		byte_stream_copy_to_uint32_little_endian(
		 number_of_record_entries_data,
		 number_of_record_entries );

		if( number_of_record_entries == 0 )
		{
			break;
		}
#if defined( HAVE_DEBUG_OUTPUT )
		if( libcnotify_verbose != 0 )
		{
			libcnotify_printf(
			 "%s: item: %03" PRIu32 " number of record entries\t\t: %" PRIu32 "\n",
			 function,
			 item_index,
			 number_of_record_entries );

			libcnotify_printf(
			 "\n" );
		}
#endif
		if( libnk2_item_initialize(
		     &item,
		     error ) != 1 )
		{
			libcerror_error_set(
			 error,
			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
			 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
			 "%s: unable to create item.",
			 function );

			goto on_error;
		}
		if( libnk2_item_read_record_entries(
		     (libnk2_internal_item_t *) item,
		     internal_file->io_handle,
		     file_io_handle,
		     item_index,
		     number_of_record_entries,
		     error ) != 1 )
		{
			libcerror_error_set(
			 error,
			 LIBCERROR_ERROR_DOMAIN_IO,
			 LIBCERROR_IO_ERROR_READ_FAILED,
			 "%s: unable to read record entries: %" PRIu32 ".",
			 function,
			 item_index );

			goto on_error;
		}
		if( libcdata_array_append_entry(
		     internal_file->items_array,
		     &entry_index,
		     (intptr_t *) item,
		     error ) != 1 )
		{
			libcerror_error_set(
			 error,
			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
			 LIBCERROR_RUNTIME_ERROR_APPEND_FAILED,
			 "%s: unable to append record entries to items array.",
			 function );

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

on_error:
	if( item != NULL )
	{
		libnk2_item_free(
		 &item,
		 NULL );
	}
	libcdata_array_empty(
	 internal_file->items_array,
	 (int (*)(intptr_t **, libcerror_error_t **)) &libnk2_internal_item_free,
	 NULL );

	return( -1 );
}
Пример #8
0
/* Reads the file header
 * Returns 1 if successful or -1 on error
 */
int libmdmp_io_handle_read_file_header(
     libmdmp_io_handle_t *io_handle,
     libbfio_handle_t *file_io_handle,
     uint32_t *streams_directory_offset,
     uint32_t *number_of_streams,
     libcerror_error_t **error )
{
	mdmp_file_header_t file_header;

	static char *function = "libmdmp_io_handle_read_file_header";
	ssize_t read_count    = 0;

#if defined( HAVE_DEBUG_OUTPUT )
	uint32_t value_32bit  = 0;
	uint16_t value_16bit  = 0;
#endif

	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( streams_directory_offset == NULL )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
		 "%s: invalid streams directory offset.",
		 function );

		return( -1 );
	}
	if( number_of_streams == NULL )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
		 "%s: invalid number of streams.",
		 function );

		return( -1 );
	}
#if defined( HAVE_DEBUG_OUTPUT )
	if( libcnotify_verbose != 0 )
	{
		libcnotify_printf(
		 "%s: reading file header at offset: 0 (0x00000000)\n",
		 function );
	}
#endif
	if( libbfio_handle_seek_offset(
	     file_io_handle,
	     0,
	     SEEK_SET,
	     error ) == -1 )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_IO,
		 LIBCERROR_IO_ERROR_SEEK_FAILED,
		 "%s: unable to seek file header offset: 0.",
		 function );

		return( -1 );
	}
	read_count = libbfio_handle_read_buffer(
	              file_io_handle,
	              (uint8_t *) &file_header,
	              sizeof( mdmp_file_header_t ),
	              error );

	if( read_count != (ssize_t) sizeof( mdmp_file_header_t ) )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_IO,
		 LIBCERROR_IO_ERROR_READ_FAILED,
		 "%s: unable to read file header data.",
		 function );

		return( -1 );
	}
#if defined( HAVE_DEBUG_OUTPUT )
	if( libcnotify_verbose != 0 )
	{
		libcnotify_printf(
		 "%s: file header data:\n",
		 function );
		libcnotify_print_data(
		 (uint8_t *) &file_header,
		 sizeof( mdmp_file_header_t ),
		 0 );
	}
#endif
	if( memory_compare(
	     file_header.signature,
	     mdmp_file_signature,
	     4 ) != 0 )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
		 LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
		 "%s: invalid signature.",
		 function );

		return( -1 );
	}
	byte_stream_copy_to_uint16_little_endian(
	 file_header.version,
	 io_handle->version );

	byte_stream_copy_to_uint32_little_endian(
	 file_header.number_of_streams,
	 *number_of_streams );

	byte_stream_copy_to_uint32_little_endian(
	 file_header.streams_directory_rva,
	 *streams_directory_offset );

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

		libcnotify_printf(
		 "%s: version\t\t\t\t: 0x%04" PRIx16 "\n",
		 function,
		 io_handle->version );

		byte_stream_copy_to_uint16_little_endian(
		 file_header.implementation_version,
		 value_16bit );
		libcnotify_printf(
		 "%s: implementation version\t\t: 0x%04" PRIx16 "\n",
		 function,
		 value_16bit );

		libcnotify_printf(
		 "%s: number of streams\t\t\t: 0x%08" PRIx32 "\n",
		 function,
		 *number_of_streams );

		libcnotify_printf(
		 "%s: streams directory RVA\t\t: 0x%08" PRIx32 "\n",
		 function,
		 *streams_directory_offset );

		byte_stream_copy_to_uint32_little_endian(
		 file_header.checksum,
		 value_32bit );
		libcnotify_printf(
		 "%s: checksum\t\t\t\t: 0x%08" PRIx32 "\n",
		 function,
		 value_32bit );

/* TODO print date time value */
		byte_stream_copy_to_uint32_little_endian(
		 file_header.timestamp,
		 value_32bit );
		libcnotify_printf(
		 "%s: timestamp\t\t\t\t: 0x%08" PRIx32 "\n",
		 function,
		 value_32bit );

		byte_stream_copy_to_uint32_little_endian(
		 file_header.file_flags,
		 value_32bit );
		libcnotify_printf(
		 "%s: file flags\t\t\t\t: 0x%08" PRIx32 "\n",
		 function,
		 value_32bit );
		libmdmp_debug_print_file_flags(
		 value_32bit );
		libcnotify_printf(
		 "\n" );

		libcnotify_printf(
		 "\n" );
	}
#endif
	return( 1 );
}
Пример #9
0
/* Reads the streams directory
 * Returns 1 if successful or -1 on error
 */
int libmdmp_io_handle_read_streams_directory(
     libmdmp_io_handle_t *io_handle,
     libbfio_handle_t *file_io_handle,
     uint32_t streams_directory_offset,
     uint32_t number_of_streams,
     libcdata_array_t *streams_array,
     libcerror_error_t **error )
{
	libmdmp_stream_descriptor_t *stream_descriptor = NULL;
	uint8_t *streams_directory_data                = NULL;
	uint8_t *streams_directory_entry_data          = NULL;
	static char *function                          = "libmdmp_io_handle_read_streams_directory";
	size_t streams_directory_data_size             = 0;
	ssize_t read_count                             = 0;
	uint32_t stream_data_offset                    = 0;
	uint32_t stream_data_size                      = 0;
	uint32_t stream_index                          = 0;
	int entry_index                                = 0;
	int result                                     = 0;

	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 defined( HAVE_DEBUG_OUTPUT )
	if( libcnotify_verbose != 0 )
	{
		libcnotify_printf(
		 "%s: reading streams directory at offset: %" PRIu32 " (0x%08" PRIx32 ")\n",
		 function,
		 streams_directory_offset,
		 streams_directory_offset );
	}
#endif
	if( libbfio_handle_seek_offset(
	     file_io_handle,
	     streams_directory_offset,
	     SEEK_SET,
	     error ) == -1 )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_IO,
		 LIBCERROR_IO_ERROR_SEEK_FAILED,
		 "%s: unable to seek streams directory offset: %" PRIu32 " (0x%08" PRIx32 ").",
		 function );

		goto on_error;
	}
	streams_directory_data_size = sizeof( mdmp_streams_directory_entry_t )
	                            * number_of_streams;

	if( streams_directory_data_size > (size_t) SSIZE_MAX )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
		 LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
		 "%s: invalid streams directory data size value out of bounds.",
		 function );

		goto on_error;
	}
	streams_directory_data = (uint8_t *) memory_allocate(
	                                      sizeof( uint8_t ) * streams_directory_data_size );

	if( streams_directory_data == NULL )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_MEMORY,
		 LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
		 "%s: unable to create streams directory data.",
		 function );

		goto on_error;
	}
	read_count = libbfio_handle_read_buffer(
	              file_io_handle,
	              streams_directory_data,
	              streams_directory_data_size,
	              error );

	if( read_count != (ssize_t) streams_directory_data_size )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_IO,
		 LIBCERROR_IO_ERROR_READ_FAILED,
		 "%s: unable to read streams directory data.",
		 function );

		goto on_error;
	}
#if defined( HAVE_DEBUG_OUTPUT )
	if( libcnotify_verbose != 0 )
	{
		libcnotify_printf(
		 "%s: streams directory data:\n",
		 function );
		libcnotify_print_data(
		 streams_directory_data,
		 streams_directory_data_size,
		 0 );
	}
#endif
	streams_directory_entry_data = streams_directory_data;

	for( stream_index = 0;
	     stream_index < number_of_streams;
	     stream_index++ )
	{
		if( stream_descriptor == NULL )
		{
			if( libmdmp_stream_descriptor_initialize(
			     &stream_descriptor,
			     error ) != 1 )
			{
				libcerror_error_set(
				 error,
				 LIBCERROR_ERROR_DOMAIN_RUNTIME,
				 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
				 "%s: unable to create stream descriptor.",
				 function );

				goto on_error;
			}
		}
		byte_stream_copy_to_uint32_little_endian(
		 ( (mdmp_streams_directory_entry_t *) streams_directory_entry_data )->stream_type,
		 stream_descriptor->type );

		byte_stream_copy_to_uint32_little_endian(
		 ( (mdmp_streams_directory_entry_t *) streams_directory_entry_data )->stream_data_size,
		 stream_data_size );

		byte_stream_copy_to_uint32_little_endian(
		 ( (mdmp_streams_directory_entry_t *) streams_directory_entry_data )->stream_data_rva,
		 stream_data_offset );

#if defined( HAVE_DEBUG_OUTPUT )
		if( libcnotify_verbose != 0 )
		{
			libcnotify_printf(
			 "%s: stream: %02" PRIu32 " type\t\t: %" PRIu32 " (%s)\n",
			 function,
			 stream_index,
			 stream_descriptor->type,
			 libmdmp_debug_get_stream_type(
			  stream_descriptor->type ) );

			libcnotify_printf(
			 "%s: stream: %02" PRIu32 " data size\t\t: %" PRIu32 "\n",
			 function,
			 stream_index,
			 stream_data_size );

			libcnotify_printf(
			 "%s: stream: %02" PRIu32 " RVA\t\t: 0x%08" PRIx32 "\n",
			 function,
			 stream_index,
			 stream_data_offset );
		}
#endif
		result = memory_compare(
		          streams_directory_entry_data,
		          empty_streams_directory_entry,
		          sizeof( mdmp_streams_directory_entry_t ) );

		streams_directory_entry_data += sizeof( mdmp_streams_directory_entry_t );

		if( result != 0 )
		{
			if( libmdmp_stream_descriptor_set_data_range(
			     stream_descriptor,
			     (off64_t) stream_data_offset,
			     (size64_t) stream_data_size,
			     error ) != 1 )
			{
				libcerror_error_set(
				 error,
				 LIBCERROR_ERROR_DOMAIN_RUNTIME,
				 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
				 "%s: unable to set data range in stream descriptor.",
				 function );

				goto on_error;
			}
			if( libcdata_array_append_entry(
			     streams_array,
			     &entry_index,
			     (intptr_t *) stream_descriptor,
			     error ) != 1 )
			{
				libcerror_error_set(
				 error,
				 LIBCERROR_ERROR_DOMAIN_RUNTIME,
				 LIBCERROR_RUNTIME_ERROR_APPEND_FAILED,
				 "%s: unable to append stream descriptor to sections array.",
				 function );

				goto on_error;
			}
			stream_descriptor = NULL;
		}
	}
	if( stream_descriptor != NULL )
	{
		if( libmdmp_stream_descriptor_free(
		     &stream_descriptor,
		     error ) != 1 )
		{
			libcerror_error_set(
			 error,
			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
			 LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
			 "%s: unable to free stream descriptor.",
			 function );

			goto on_error;
		}
	}
	memory_free(
	 streams_directory_data );

	return( 1 );

on_error:
	if( stream_descriptor != NULL )
	{
		libmdmp_stream_descriptor_free(
		 &stream_descriptor,
		 NULL );
	}
	if( streams_directory_data != NULL )
	{
		memory_free(
		 streams_directory_data );
	}
	return( -1 );
}
Пример #10
0
/* Reads the volume header
 * Returns 1 if successful or -1 on error
 */
int libbde_io_handle_read_volume_header(
     libbde_io_handle_t *io_handle,
     libbfio_handle_t *file_io_handle,
     off64_t file_offset,
     libcerror_error_t **error )
{
	uint8_t *volume_header_data      = NULL;
	static char *function            = "libbde_io_handle_read_volume_header";
	size_t read_size                 = 512;
	ssize_t read_count               = 0;
	uint64_t total_number_of_sectors = 0;

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

	libfguid_identifier_t *guid      = NULL;
	uint64_t value_64bit             = 0;
	uint32_t value_32bit             = 0;
	uint16_t value_16bit             = 0;
	int result                       = 0;
#endif

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

		goto on_error;
	}
#if defined( HAVE_DEBUG_OUTPUT )
	if( libcnotify_verbose != 0 )
	{
		libcnotify_printf(
		 "%s: reading volume header at offset: %" PRIi64 " (0x%08" PRIx64 ")\n",
		 function,
		 file_offset,
		 file_offset );
	}
#endif
	if( libbfio_handle_seek_offset(
	     file_io_handle,
	     file_offset,
	     SEEK_SET,
	     error ) == -1 )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_IO,
		 LIBCERROR_IO_ERROR_SEEK_FAILED,
		 "%s: unable to seek volume header offset: %" PRIi64 ".",
		 function,
		 file_offset );

		goto on_error;
	}
	volume_header_data = (uint8_t *) memory_allocate(
	                                  sizeof( uint8_t ) * read_size );

	if( volume_header_data == NULL )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_MEMORY,
		 LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
		 "%s: unable to create volume header data.",
		 function );

		goto on_error;
	}
	read_count = libbfio_handle_read_buffer(
	              file_io_handle,
	              volume_header_data,
	              read_size,
	              error );

	if( read_count != (ssize_t) read_size )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_IO,
		 LIBCERROR_IO_ERROR_READ_FAILED,
		 "%s: unable to read volume header data.",
		 function );

		goto on_error;
	}
#if defined( HAVE_DEBUG_OUTPUT )
	if( libcnotify_verbose != 0 )
	{
		libcnotify_printf(
		 "%s: volume header data:\n",
		 function );
		libcnotify_print_data(
		 volume_header_data,
		 read_size,
		 0 );
	}
#endif
	if( memory_compare(
	     volume_header_data,
	     bde_boot_entry_point_vista,
	     3 ) == 0 )
	{
		io_handle->version = LIBBDE_VERSION_WINDOWS_VISTA;
	}
	else if( memory_compare(
	          volume_header_data,
	          bde_boot_entry_point_win7,
	          3 ) == 0 )
	{
		if( memory_compare(
		     ( (bde_volume_header_windows_7_t *) volume_header_data )->identifier,
		     bde_identifier,
		     16 ) == 0 )
		{
			io_handle->version = LIBBDE_VERSION_WINDOWS_7;
		}
		else if( memory_compare(
		          ( (bde_volume_header_to_go_t *) volume_header_data )->identifier,
		          bde_identifier,
		          16 ) == 0 )
		{
			io_handle->version = LIBBDE_VERSION_TO_GO;
		}
		else
		{
			libcerror_error_set(
			 error,
			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
			 LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
			 "%s: unsupported identifier.",
			 function );

			goto on_error;
		}
	}
	else
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
		 LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
		 "%s: unsupported volume boot entry point.",
		 function );

		goto on_error;
	}
	if( ( io_handle->version == LIBBDE_VERSION_WINDOWS_VISTA )
	 || ( io_handle->version == LIBBDE_VERSION_WINDOWS_7 ) )
	{
		if( memory_compare(
		     &( volume_header_data[ 3 ] ),
		     bde_signature,
		     8 ) != 0 )
		{
			libcerror_error_set(
			 error,
			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
			 LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
			 "%s: invalid volume signature.",
			 function );

			goto on_error;
		}
	}
	byte_stream_copy_to_uint16_little_endian(
	 ( (bde_volume_header_windows_vista_t *) volume_header_data )->bytes_per_sector,
	 io_handle->bytes_per_sector );

	io_handle->sectors_per_cluster_block = ( (bde_volume_header_windows_vista_t *) volume_header_data )->sectors_per_cluster_block;

	byte_stream_copy_to_uint16_little_endian(
	 ( (bde_volume_header_windows_vista_t *) volume_header_data )->total_number_of_sectors_16bit,
	 total_number_of_sectors );

	if( total_number_of_sectors == 0 )
	{
		byte_stream_copy_to_uint32_little_endian(
		 ( (bde_volume_header_windows_vista_t *) volume_header_data )->total_number_of_sectors_32bit,
		 total_number_of_sectors );
	}
	if( io_handle->version == LIBBDE_VERSION_WINDOWS_VISTA )
	{
		byte_stream_copy_to_uint64_little_endian(
		 ( (bde_volume_header_windows_vista_t *) volume_header_data )->first_metadata_cluster_block_number,
		 io_handle->first_metadata_offset );

		if( total_number_of_sectors == 0 )
		{
			byte_stream_copy_to_uint64_little_endian(
			 ( (bde_volume_header_windows_vista_t *) volume_header_data )->total_number_of_sectors_64bit,
			 total_number_of_sectors );
		}
	}
	else if( io_handle->version == LIBBDE_VERSION_WINDOWS_7 )
	{
		byte_stream_copy_to_uint64_little_endian(
		 ( (bde_volume_header_windows_7_t *) volume_header_data )->first_metadata_offset,
		 io_handle->first_metadata_offset );

		byte_stream_copy_to_uint64_little_endian(
		 ( (bde_volume_header_windows_7_t *) volume_header_data )->second_metadata_offset,
		 io_handle->second_metadata_offset );

		byte_stream_copy_to_uint64_little_endian(
		 ( (bde_volume_header_windows_7_t *) volume_header_data )->third_metadata_offset,
		 io_handle->third_metadata_offset );
	}
	else if( io_handle->version == LIBBDE_VERSION_TO_GO )
	{
		byte_stream_copy_to_uint64_little_endian(
		 ( (bde_volume_header_to_go_t *) volume_header_data )->first_metadata_offset,
		 io_handle->first_metadata_offset );

		byte_stream_copy_to_uint64_little_endian(
		 ( (bde_volume_header_to_go_t *) volume_header_data )->second_metadata_offset,
		 io_handle->second_metadata_offset );

		byte_stream_copy_to_uint64_little_endian(
		 ( (bde_volume_header_to_go_t *) volume_header_data )->third_metadata_offset,
		 io_handle->third_metadata_offset );
	}
#if defined( HAVE_DEBUG_OUTPUT )
	if( libcnotify_verbose != 0 )
	{
		libcnotify_printf(
		 "%s: boot entry point:\n",
		 function );
		libcnotify_print_data(
		 volume_header_data,
		 3,
		 0 );

		libcnotify_printf(
		 "%s: signature\t\t\t\t: %c%c%c%c%c%c%c%c\n",
		 function,
		 volume_header_data[ 3 ],
		 volume_header_data[ 4 ],
		 volume_header_data[ 5 ],
		 volume_header_data[ 6 ],
		 volume_header_data[ 7 ],
		 volume_header_data[ 8 ],
		 volume_header_data[ 9 ],
		 volume_header_data[ 10 ] );

		libcnotify_printf(
		 "%s: bytes per sector\t\t\t: %" PRIu16 "\n",
		 function,
		 io_handle->bytes_per_sector );

		libcnotify_printf(
		 "%s: sectors per cluster block\t\t: %" PRIu8 "\n",
		 function,
		 io_handle->sectors_per_cluster_block );

		libcnotify_printf(
		 "%s: unknown1\n",
		 function );
		libcnotify_print_data(
		 ( (bde_volume_header_windows_vista_t *) volume_header_data )->unknown1,
		 5,
		 0 );

		byte_stream_copy_to_uint16_little_endian(
		 ( (bde_volume_header_windows_vista_t *) volume_header_data )->total_number_of_sectors_16bit,
		 value_16bit );
		libcnotify_printf(
		 "%s: total number of sectors (16-bit)\t: %" PRIu16 "\n",
		 function,
		 value_16bit );

		libcnotify_printf(
		 "%s: media descriptor\t\t\t: 0x%02" PRIx8 "\n",
		 function,
		 ( (bde_volume_header_windows_vista_t *) volume_header_data )->media_descriptor );

		byte_stream_copy_to_uint16_little_endian(
		 ( (bde_volume_header_windows_vista_t *) volume_header_data )->unknown2,
		 value_16bit );
		libcnotify_printf(
		 "%s: unknown2\t\t\t\t: %" PRIu16 "\n",
		 function,
		 value_16bit );

		byte_stream_copy_to_uint16_little_endian(
		 ( (bde_volume_header_windows_vista_t *) volume_header_data )->sectors_per_track,
		 value_16bit );
		libcnotify_printf(
		 "%s: sectors per track\t\t\t: %" PRIu16 "\n",
		 function,
		 value_16bit );

		byte_stream_copy_to_uint16_little_endian(
		 ( (bde_volume_header_windows_vista_t *) volume_header_data )->number_of_heads,
		 value_16bit );
		libcnotify_printf(
		 "%s: number of heads\t\t\t: %" PRIu16 "\n",
		 function,
		 value_16bit );

		byte_stream_copy_to_uint32_little_endian(
		 ( (bde_volume_header_windows_vista_t *) volume_header_data )->number_of_hidden_sectors,
		 value_32bit );
		libcnotify_printf(
		 "%s: number of hidden sectors\t\t: %" PRIu32 "\n",
		 function,
		 value_32bit );

		byte_stream_copy_to_uint32_little_endian(
		 ( (bde_volume_header_windows_vista_t *) volume_header_data )->total_number_of_sectors_32bit,
		 value_32bit );
		libcnotify_printf(
		 "%s: total number of sectors (32-bit)\t: %" PRIu32 "\n",
		 function,
		 value_32bit );

		if( io_handle->version == LIBBDE_VERSION_WINDOWS_VISTA )
		{
			byte_stream_copy_to_uint32_little_endian(
			 ( (bde_volume_header_windows_vista_t *) volume_header_data )->unknown4,
			 value_32bit );
			libcnotify_printf(
			 "%s: unknown4\t\t\t\t: 0x%08" PRIx32 " (%" PRIu32 ")\n",
			 function,
			 value_32bit,
			 value_32bit );

			byte_stream_copy_to_uint32_little_endian(
			 ( (bde_volume_header_windows_vista_t *) volume_header_data )->total_number_of_sectors_64bit,
			 value_64bit );
			libcnotify_printf(
			 "%s: total number of sectors (64-bit)\t: %" PRIu64 "\n",
			 function,
			 value_64bit );

			byte_stream_copy_to_uint64_little_endian(
			 ( (bde_volume_header_windows_vista_t *) volume_header_data )->mft_cluster_block_number,
			 value_64bit );
			libcnotify_printf(
			 "%s: MFT cluster block number\t\t: %" PRIu64 "\n",
			 function,
			 value_64bit );

			libcnotify_printf(
			 "%s: first metadata cluster block\t: 0x%08" PRIx64 "\n",
			 function,
			 io_handle->first_metadata_offset );

			byte_stream_copy_to_uint32_little_endian(
			 ( (bde_volume_header_windows_vista_t *) volume_header_data )->mft_entry_size,
			 value_32bit );
			libcnotify_printf(
			 "%s: MFT entry size\t\t\t: %" PRIu32 "\n",
			 function,
			 value_32bit );

			byte_stream_copy_to_uint32_little_endian(
			 ( (bde_volume_header_windows_vista_t *) volume_header_data )->index_entry_size,
			 value_32bit );
			libcnotify_printf(
			 "%s: index entry size\t\t: %" PRIu32 "\n",
			 function,
			 value_32bit );

			byte_stream_copy_to_uint64_little_endian(
			 ( (bde_volume_header_windows_vista_t *) volume_header_data )->volume_serial_number,
			 value_64bit );
			libcnotify_printf(
			 "%s: volume serial number\t\t: 0x%08" PRIx64 "\n",
			 function,
			 value_64bit );

			byte_stream_copy_to_uint32_little_endian(
			 ( (bde_volume_header_windows_vista_t *) volume_header_data )->checksum,
			 value_32bit );
			libcnotify_printf(
			 "%s: checksum\t\t\t: 0x%08" PRIx32 "\n",
			 function,
			 value_32bit );

			libcnotify_printf(
			 "%s: bootcode\n",
			 function );
			libcnotify_print_data(
			 ( (bde_volume_header_windows_vista_t *) volume_header_data )->bootcode,
			 426,
			 0 );
		}
		else if( ( io_handle->version == LIBBDE_VERSION_WINDOWS_7 )
		      || ( io_handle->version == LIBBDE_VERSION_TO_GO ) )
		{
			libcnotify_printf(
			 "%s: unknown4:\n",
			 function );
			libcnotify_print_data(
			 ( (bde_volume_header_windows_7_t *) volume_header_data )->unknown4,
			 31,
			 0 );

			byte_stream_copy_to_uint32_little_endian(
			 ( (bde_volume_header_windows_7_t *) volume_header_data )->volume_serial_number,
			 value_64bit );
			libcnotify_printf(
			 "%s: volume serial number\t\t: 0x%08" PRIx32 "\n",
			 function,
			 value_32bit );

			libcnotify_printf(
			 "%s: volume label\t\t\t: %c%c%c%c%c%c%c%c%c%c%c\n",
			 function,
			 ( (bde_volume_header_windows_7_t *) volume_header_data )->volume_label[ 0 ],
			 ( (bde_volume_header_windows_7_t *) volume_header_data )->volume_label[ 1 ],
			 ( (bde_volume_header_windows_7_t *) volume_header_data )->volume_label[ 2 ],
			 ( (bde_volume_header_windows_7_t *) volume_header_data )->volume_label[ 3 ],
			 ( (bde_volume_header_windows_7_t *) volume_header_data )->volume_label[ 4 ],
			 ( (bde_volume_header_windows_7_t *) volume_header_data )->volume_label[ 5 ],
			 ( (bde_volume_header_windows_7_t *) volume_header_data )->volume_label[ 6 ],
			 ( (bde_volume_header_windows_7_t *) volume_header_data )->volume_label[ 7 ],
			 ( (bde_volume_header_windows_7_t *) volume_header_data )->volume_label[ 8 ],
			 ( (bde_volume_header_windows_7_t *) volume_header_data )->volume_label[ 9 ],
			 ( (bde_volume_header_windows_7_t *) volume_header_data )->volume_label[ 10 ] );

			libcnotify_printf(
			 "%s: file system signature\t\t: %c%c%c%c%c%c%c%c\n",
			 function,
			 ( (bde_volume_header_windows_7_t *) volume_header_data )->file_system_signature[ 0 ],
			 ( (bde_volume_header_windows_7_t *) volume_header_data )->file_system_signature[ 1 ],
			 ( (bde_volume_header_windows_7_t *) volume_header_data )->file_system_signature[ 2 ],
			 ( (bde_volume_header_windows_7_t *) volume_header_data )->file_system_signature[ 3 ],
			 ( (bde_volume_header_windows_7_t *) volume_header_data )->file_system_signature[ 4 ],
			 ( (bde_volume_header_windows_7_t *) volume_header_data )->file_system_signature[ 5 ],
			 ( (bde_volume_header_windows_7_t *) volume_header_data )->file_system_signature[ 6 ],
			 ( (bde_volume_header_windows_7_t *) volume_header_data )->file_system_signature[ 7 ] );
		}
		if( io_handle->version == LIBBDE_VERSION_WINDOWS_7 )
		{
			libcnotify_printf(
			 "%s: bootcode\n",
			 function );
			libcnotify_print_data(
			 ( (bde_volume_header_windows_7_t *) volume_header_data )->bootcode,
			 47,
			 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,
			     ( (bde_volume_header_windows_7_t *) volume_header_data )->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( LIBCSTRING_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: identifier\t\t\t\t: %" PRIs_LIBCSTRING_SYSTEM "\n",
			 function,
			 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;
			}
		}
		else if( io_handle->version == LIBBDE_VERSION_TO_GO )
		{
			libcnotify_printf(
			 "%s: bootcode\n",
			 function );
			libcnotify_print_data(
			 ( (bde_volume_header_to_go_t *) volume_header_data )->bootcode,
			 335,
			 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,
			     ( (bde_volume_header_to_go_t *) volume_header_data )->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( LIBCSTRING_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: identifier\t\t\t\t: %" PRIs_LIBCSTRING_SYSTEM "\n",
			 function,
			 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;
			}
		}
		if( ( io_handle->version == LIBBDE_VERSION_WINDOWS_7 )
		 || ( io_handle->version == LIBBDE_VERSION_TO_GO ) )
		{
			libcnotify_printf(
			 "%s: first metadata offset\t\t: 0x%08" PRIx64 "\n",
			 function,
			 io_handle->first_metadata_offset );

			libcnotify_printf(
			 "%s: second metadata offset\t\t: 0x%08" PRIx64 "\n",
			 function,
			 io_handle->second_metadata_offset );

			libcnotify_printf(
			 "%s: third metadata offset\t\t: 0x%08" PRIx64 "\n",
			 function,
			 io_handle->third_metadata_offset );
		}
		if( io_handle->version == LIBBDE_VERSION_WINDOWS_7 )
		{
			libcnotify_printf(
			 "%s: unknown5:\n",
			 function );
			libcnotify_print_data(
			 ( (bde_volume_header_windows_7_t *) volume_header_data )->unknown5,
			 310,
			 0 );
		}
		else if( io_handle->version == LIBBDE_VERSION_TO_GO )
		{
			libcnotify_printf(
			 "%s: unknown5:\n",
			 function );
			libcnotify_print_data(
			 ( (bde_volume_header_to_go_t *) volume_header_data )->unknown5,
			 46,
			 0 );
		}
		byte_stream_copy_to_uint16_little_endian(
		 ( (bde_volume_header_windows_vista_t *) volume_header_data )->sector_signature,
		 value_16bit );
		libcnotify_printf(
		 "%s: sector signature\t\t\t: 0x%04" PRIx16 "\n",
		 function,
		 value_16bit );

		libcnotify_printf(
		 "\n" );
	}
#endif
	if( total_number_of_sectors != 0 )
	{
		io_handle->volume_size  = total_number_of_sectors;
		io_handle->volume_size *= io_handle->bytes_per_sector;
	}
	if( io_handle->version == LIBBDE_VERSION_WINDOWS_VISTA )
	{
		io_handle->first_metadata_offset *= io_handle->sectors_per_cluster_block;
		io_handle->first_metadata_offset *= io_handle->bytes_per_sector;

		io_handle->metadata_size = 16384;
	}
	else if( ( io_handle->version == LIBBDE_VERSION_WINDOWS_7 )
	      || ( io_handle->version == LIBBDE_VERSION_TO_GO ) )
	{
		io_handle->metadata_size = 65536;
	}
	memory_free(
	 volume_header_data );

	volume_header_data = NULL;

	return( 1 );

on_error:
#if defined( HAVE_DEBUG_OUTPUT )
	if( guid != NULL )
	{
		libfguid_identifier_free(
		 &guid,
		 NULL );
	}
#endif
	if( volume_header_data != NULL )
	{
		memory_free(
		 volume_header_data );
	}
	return( -1 );
}
Пример #11
0
         uint32_t segment_flags LIBMDMP_ATTRIBUTE_UNUSED,
         uint8_t read_flags LIBMDMP_ATTRIBUTE_UNUSED,
         libcerror_error_t **error )
{
	static char *function = "libmdmp_io_handle_read_segment_data";
	ssize_t read_count    = 0;

	LIBMDMP_UNREFERENCED_PARAMETER( data_handle )
	LIBMDMP_UNREFERENCED_PARAMETER( segment_index )
	LIBMDMP_UNREFERENCED_PARAMETER( segment_file_index )
	LIBMDMP_UNREFERENCED_PARAMETER( segment_flags )
	LIBMDMP_UNREFERENCED_PARAMETER( read_flags )

	read_count = libbfio_handle_read_buffer(
		      file_io_handle,
		      segment_data,
		      segment_data_size,
		      error );

	if( read_count != (ssize_t) segment_data_size )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_IO,
		 LIBCERROR_IO_ERROR_READ_FAILED,
		 "%s: unable to read segment data.",
		 function );

		return( -1 );
	}
	return( read_count );
Пример #12
0
/* Determines if a file contains an EWF file signature using a Basic File IO (bfio) handle
 * Returns 1 if true, 0 if not or -1 on error
 */
int libewf_check_file_signature_file_io_handle(
     libbfio_handle_t *file_io_handle,
     libcerror_error_t **error )
{
	uint8_t signature[ 8 ];

	static char *function      = "libewf_check_file_signature_file_io_handle";
	ssize_t read_count         = 0;
	int file_io_handle_is_open = 0;

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

		return( -1 );
	}
	file_io_handle_is_open = libbfio_handle_is_open(
	                          file_io_handle,
	                          error );

	if( file_io_handle_is_open == -1 )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_IO,
		 LIBCERROR_IO_ERROR_OPEN_FAILED,
		 "%s: unable to open file.",
		 function );

		return( -1 );
	}
	else if( file_io_handle_is_open == 0 )
	{
		if( libbfio_handle_open(
		     file_io_handle,
		     LIBBFIO_OPEN_READ,
		     error ) != 1 )
		{
			libcerror_error_set(
			 error,
			 LIBCERROR_ERROR_DOMAIN_IO,
			 LIBCERROR_IO_ERROR_OPEN_FAILED,
			 "%s: unable to open file.",
			 function );

			return( -1 );
		}
	}
	if( libbfio_handle_seek_offset(
	     file_io_handle,
	     0,
	     SEEK_SET,
	     error ) == -1 )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_IO,
		 LIBCERROR_IO_ERROR_SEEK_FAILED,
		 "%s: unable to seek file header offset: 0.",
		 function );

		if( file_io_handle_is_open == 0 )
		{
			libbfio_handle_close(
			 file_io_handle,
			 error );
		}
		return( -1 );
	}
	read_count = libbfio_handle_read_buffer(
	              file_io_handle,
	              signature,
	              8,
	              error );

	if( read_count != 8 )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_IO,
		 LIBCERROR_IO_ERROR_READ_FAILED,
		 "%s: unable to read signature.",
		 function );

		libbfio_handle_close(
		 file_io_handle,
		 NULL );

		return( -1 );
	}
	if( file_io_handle_is_open == 0 )
	{
		if( libbfio_handle_close(
		     file_io_handle,
		     error ) != 0 )
		{
			libcerror_error_set(
			 error,
			 LIBCERROR_ERROR_DOMAIN_IO,
			 LIBCERROR_IO_ERROR_CLOSE_FAILED,
			 "%s: unable to close file.",
			 function );

			return( -1 );
		}
	}
	/* The number of EWF segment files will be the largest
	 */
	if( memory_compare(
	     ewf1_evf_file_signature,
	     signature,
	     8 ) == 0 )
	{
		return( 1 );
	}
	else if( memory_compare(
	          ewf1_lvf_file_signature,
	          signature,
	          8 ) == 0 )
	{
		return( 1 );
	}
	else if( memory_compare(
	          ewf2_evf_file_signature,
	          signature,
	          8 ) == 0 )
	{
		return( 1 );
	}
	else if( memory_compare(
	          ewf2_lef_file_signature,
	          signature,
	          8 ) == 0 )
	{
		return( 1 );
	}
	else if( memory_compare(
	          ewf1_dvf_file_signature,
	          signature,
	          8 ) == 0 )
	{
		return( 1 );
	}
	return( 0 );
}
Пример #13
0
/* Reads the version (resource) values
 * Returns 1 if successful or -1 on error
 */
int libwrc_version_values_read(
     libwrc_language_entry_t *language_entry,
     libwrc_io_handle_t *io_handle,
     libbfio_handle_t *file_io_handle,
     libwrc_data_descriptor_t *data_descriptor,
     libcerror_error_t **error )
{
	libwrc_version_values_t *version_values = NULL;
	libfvalue_value_t *value_identifier     = NULL;
	uint8_t *resource_data                  = NULL;
	uint8_t *version_resource_data          = NULL;
	static char *function                   = "libwrc_version_values_read";
	off64_t file_offset                     = 0;
	size_t alignment_padding_size           = 0;
	size_t resource_data_offset             = 0;
	size_t resource_data_size               = 0;
	ssize_t read_count                      = 0;
	uint32_t value_32bit                    = 0;
	uint16_t value_data_size                = 0;
	uint16_t value_data_type                = 0;
	uint16_t version_resource_data_size     = 0;
	int value_index                         = 0;

	if( language_entry == NULL )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
		 "%s: invalid language entry.",
		 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( data_descriptor == NULL )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
		 "%s: invalid data descriptor.",
		 function );

		return( -1 );
	}
	if( libwrc_version_values_initialize(
	     &version_values,
	     error ) != 1 )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_MEMORY,
		 LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
		 "%s: unable to create version values.",
		 function );

		goto on_error;
	}
	file_offset = data_descriptor->virtual_address
	            - io_handle->virtual_address;

	if( libbfio_handle_seek_offset(
	     file_io_handle,
	     file_offset,
	     SEEK_SET,
	     error ) == -1 )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_IO,
		 LIBCERROR_IO_ERROR_SEEK_FAILED,
		 "%s: unable to seek resource data offset: %" PRIi64 ".",
		 function,
		 file_offset );

		goto on_error;
	}
	resource_data_size = (size_t) data_descriptor->size;

	resource_data = (uint8_t *) memory_allocate(
	                             sizeof( uint8_t ) * resource_data_size );

	if( resource_data == NULL )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_MEMORY,
		 LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
		 "%s: unable to create resource data.",
		 function );

		goto on_error;
	}
	read_count = libbfio_handle_read_buffer(
	              file_io_handle,
	              resource_data,
	              resource_data_size,
	              error );

	if( read_count != (ssize_t) resource_data_size )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_IO,
		 LIBCERROR_IO_ERROR_READ_FAILED,
		 "%s: unable to read resource data.",
		 function );

		goto on_error;
	}
	version_resource_data = resource_data;

#if defined( HAVE_DEBUG_OUTPUT )
	if( libcnotify_verbose != 0 )
	{
		libcnotify_printf(
		 "%s: resource data:\n",
		 function );
		libcnotify_print_data(
		 version_resource_data,
		 resource_data_size,
		 0 );
	}
#endif
	byte_stream_copy_to_uint16_little_endian(
	 ( (wrc_version_value_header_t *) version_resource_data )->size,
	 version_resource_data_size );

	byte_stream_copy_to_uint16_little_endian(
	 ( (wrc_version_value_header_t *) version_resource_data )->value_data_size,
	 value_data_size );

	byte_stream_copy_to_uint16_little_endian(
	 ( (wrc_version_value_header_t *) version_resource_data )->value_data_type,
	 value_data_type );

#if defined( HAVE_DEBUG_OUTPUT )
	if( libcnotify_verbose != 0 )
	{
		libcnotify_printf(
		 "%s: size\t\t\t\t\t: %" PRIu16 "\n",
		 function,
		 version_resource_data_size );

		libcnotify_printf(
		 "%s: value data size\t\t\t\t: %" PRIu16 "\n",
		 function,
		 value_data_size );

		libcnotify_printf(
		 "%s: value data type\t\t\t\t: %" PRIu16 "\n",
		 function,
		 value_data_type );

		libcnotify_printf(
		 "\n" );
	}
#endif
	resource_data_offset += sizeof( wrc_version_value_header_t );

	if( libfvalue_value_type_initialize(
	     &value_identifier,
	     LIBFVALUE_VALUE_TYPE_STRING_UTF16,
	     error ) != 1 )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
		 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
		 "%s: unable to create value identifier value.",
		 function );

		goto on_error;
	}
	read_count = libfvalue_value_type_set_data_string(
	              value_identifier,
	              &( version_resource_data[ resource_data_offset ] ),
	              resource_data_size,
	              LIBFVALUE_CODEPAGE_UTF16_LITTLE_ENDIAN,
	              LIBFVALUE_VALUE_DATA_FLAG_MANAGED,
	              error );

	if( read_count == -1 )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
		 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
		 "%s: unable to set data of value identifier value.",
		 function );

		goto on_error;
	}
#if defined( HAVE_DEBUG_OUTPUT )
	if( libcnotify_verbose != 0 )
	{
		libcnotify_printf(
		 "%s: value identifier\t\t\t\t: ",
		 function );

		if( libfvalue_value_print(
		     value_identifier,
		     0,
		     0,
		     error ) != 1 )
		{
			libcerror_error_set(
			 error,
			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
			 LIBCERROR_RUNTIME_ERROR_PRINT_FAILED,
			 "%s: unable to print value identifier value.",
			 function );

			goto on_error;
		}
		libcnotify_printf(
		 "\n" );
	}
#endif
	if( ( read_count != 32 )
	 || ( memory_compare(
	       &( version_resource_data[ resource_data_offset ] ),
	       libwrc_version_information_value_identifier,
	       32 ) != 0 ) )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
		 LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
		 "%s: unsupported version resource value signature.",
		 function );

		goto on_error;
	}
	if( libfvalue_value_free(
	     &value_identifier,
	     error ) != 1 )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
		 LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
		 "%s: unable to free value identifier value.",
		 function );

		goto on_error;
	}
	resource_data_offset += read_count;

	if( ( resource_data_offset % 4 ) != 0 )
	{
		alignment_padding_size = 4 - ( resource_data_offset % 4 );

#if defined( HAVE_DEBUG_OUTPUT )
		if( libcnotify_verbose != 0 )
		{
			libcnotify_printf(
			 "%s: alignment padding:\n",
			 function );
			libcnotify_print_data(
			 &( version_resource_data[ resource_data_offset ] ),
			 alignment_padding_size,
			 0 );
		}
#endif
		resource_data_offset += alignment_padding_size;
	}
/* TODO refactor to separate function? */
	if( value_data_size > 0 )
	{
		if( value_data_size > resource_data_size )
		{
			libcerror_error_set(
			 error,
			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
			 LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
			 "%s: value data size value out of bounds.",
			 function );

			goto on_error;
		}
#if defined( HAVE_DEBUG_OUTPUT )
		if( libcnotify_verbose != 0 )
		{
			libcnotify_printf(
			 "%s: value data:\n",
			 function );
			libcnotify_print_data(
			 &( version_resource_data[ resource_data_offset ] ),
			 value_data_size,
			 0 );
		}
#endif
		byte_stream_copy_to_uint32_little_endian(
		 &( version_resource_data[ resource_data_offset + 8 ] ),
		 version_values->file_version );

		byte_stream_copy_to_uint32_little_endian(
		 &( version_resource_data[ resource_data_offset + 12 ] ),
		 value_32bit );

		version_values->file_version <<= 32;
		version_values->file_version  |= value_32bit;

		byte_stream_copy_to_uint32_little_endian(
		 &( version_resource_data[ resource_data_offset + 16 ] ),
		 version_values->product_version );

		byte_stream_copy_to_uint32_little_endian(
		 &( version_resource_data[ resource_data_offset + 20 ] ),
		 value_32bit );

		version_values->product_version <<= 32;
		version_values->product_version  |= value_32bit;

#if defined( HAVE_DEBUG_OUTPUT )
		if( libcnotify_verbose != 0 )
		{
			byte_stream_copy_to_uint32_little_endian(
			 &( version_resource_data[ resource_data_offset ] ),
			 value_32bit );
			libcnotify_printf(
			 "%s: signature\t\t\t\t\t: 0x%08" PRIx32 "\n",
			 function,
			 value_32bit );

			byte_stream_copy_to_uint32_little_endian(
			 &( version_resource_data[ resource_data_offset + 4 ] ),
			 value_32bit );
			libcnotify_printf(
			 "%s: version\t\t\t\t\t: %" PRIu32 ".%" PRIu32 "\n",
			 function,
			 value_32bit >> 16,
			 value_32bit & 0x0000ffffUL );

			byte_stream_copy_to_uint32_little_endian(
			 &( version_resource_data[ resource_data_offset + 8 ] ),
			 value_32bit );
			libcnotify_printf(
			 "%s: file version upper\t\t\t\t: %" PRIu32 ".%" PRIu32 "\n",
			 function,
			 value_32bit >> 16,
			 value_32bit & 0x0000ffffUL );

			byte_stream_copy_to_uint32_little_endian(
			 &( version_resource_data[ resource_data_offset + 12 ] ),
			 value_32bit );
			libcnotify_printf(
			 "%s: file version lower\t\t\t\t: %" PRIu32 ".%" PRIu32 "\n",
			 function,
			 value_32bit >> 16,
			 value_32bit & 0x0000ffffUL );

			byte_stream_copy_to_uint32_little_endian(
			 &( version_resource_data[ resource_data_offset + 16 ] ),
			 value_32bit );
			libcnotify_printf(
			 "%s: product version upper\t\t\t: %" PRIu32 ".%" PRIu32 "\n",
			 function,
			 value_32bit >> 16,
			 value_32bit & 0x0000ffffUL );

			byte_stream_copy_to_uint32_little_endian(
			 &( version_resource_data[ resource_data_offset + 20 ] ),
			 value_32bit );
			libcnotify_printf(
			 "%s: product version lower\t\t\t: %" PRIu32 ".%" PRIu32 "\n",
			 function,
			 value_32bit >> 16,
			 value_32bit & 0x0000ffffUL );

			byte_stream_copy_to_uint32_little_endian(
			 &( version_resource_data[ resource_data_offset + 24 ] ),
			 value_32bit );
			libcnotify_printf(
			 "%s: file flags bitmask\t\t\t\t: 0x%08" PRIx32 "\n",
			 function,
			 value_32bit );

			byte_stream_copy_to_uint32_little_endian(
			 &( version_resource_data[ resource_data_offset + 28 ] ),
			 value_32bit );
			libcnotify_printf(
			 "%s: file flags\t\t\t\t\t: 0x%08" PRIx32 "\n",
			 function,
			 value_32bit );

			byte_stream_copy_to_uint32_little_endian(
			 &( version_resource_data[ resource_data_offset + 32 ] ),
			 value_32bit );
			libcnotify_printf(
			 "%s: file operating system\t\t\t: 0x%08" PRIx32 "\n",
			 function,
			 value_32bit );

			byte_stream_copy_to_uint32_little_endian(
			 &( version_resource_data[ resource_data_offset + 36 ] ),
			 value_32bit );
			libcnotify_printf(
			 "%s: file type\t\t\t\t\t: 0x%08" PRIx32 "\n",
			 function,
			 value_32bit );

			byte_stream_copy_to_uint32_little_endian(
			 &( version_resource_data[ resource_data_offset + 40 ] ),
			 value_32bit );
			libcnotify_printf(
			 "%s: file sub type\t\t\t\t: 0x%08" PRIx32 "\n",
			 function,
			 value_32bit );

			byte_stream_copy_to_uint32_little_endian(
			 &( version_resource_data[ resource_data_offset + 44 ] ),
			 value_32bit );
			libcnotify_printf(
			 "%s: file time upper\t\t\t\t: 0x%08" PRIx32 "\n",
			 function,
			 value_32bit );

			byte_stream_copy_to_uint32_little_endian(
			 &( version_resource_data[ resource_data_offset + 48 ] ),
			 value_32bit );
			libcnotify_printf(
			 "%s: file time lower\t\t\t\t: 0x%08" PRIx32 "\n",
			 function,
			 value_32bit );

			libcnotify_printf(
			 "\n" );
		}
#endif
		resource_data_offset += value_data_size;
	}
Пример #14
0
/* Reads the file (or database) header
 * Returns 1 if successful or -1 on error
 */
int libesedb_io_handle_read_file_header(
     libesedb_io_handle_t *io_handle,
     libbfio_handle_t *file_io_handle,
     off64_t file_offset,
     libcerror_error_t **error )
{
	uint8_t *file_header_data          = NULL;
	static char *function              = "libesedb_io_handle_read_file_header";
	size_t read_size                   = 2048;
	ssize_t read_count                 = 0;
	uint32_t calculated_xor32_checksum = 0;
	uint32_t creation_format_revision  = 0;
	uint32_t creation_format_version   = 0;
	uint32_t format_revision           = 0;
	uint32_t format_version            = 0;
	uint32_t page_size                 = 0;
	uint32_t stored_xor32_checksum     = 0;

#if defined( HAVE_DEBUG_OUTPUT )
	uint32_t value_32bit               = 0;
#endif

	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 defined( HAVE_DEBUG_OUTPUT )
	if( libcnotify_verbose != 0 )
	{
		libcnotify_printf(
		 "%s: reading file header at offset: %" PRIi64 " (0x%08" PRIx64 ")\n",
		 function,
		 file_offset,
		 file_offset );
	}
#endif
	if( libbfio_handle_seek_offset(
	     file_io_handle,
	     file_offset,
	     SEEK_SET,
	     error ) == -1 )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_IO,
		 LIBCERROR_IO_ERROR_SEEK_FAILED,
		 "%s: unable to seek file header offset: %" PRIi64 ".",
		 function,
		 file_offset );

		goto on_error;
	}
	file_header_data = (uint8_t *) memory_allocate(
	                                sizeof( uint8_t ) * read_size );

	if( file_header_data == NULL )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_MEMORY,
		 LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
		 "%s: unable to create file header data.",
		 function );

		goto on_error;
	}
	read_count = libbfio_handle_read_buffer(
	              file_io_handle,
	              file_header_data,
	              read_size,
	              error );

	if( read_count != (ssize_t) read_size )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_IO,
		 LIBCERROR_IO_ERROR_READ_FAILED,
		 "%s: unable to read file header.",
		 function );

		goto on_error;
	}
#if defined( HAVE_DEBUG_OUTPUT )
	if( libcnotify_verbose != 0 )
	{
		libcnotify_printf(
		 "%s: file header data:\n",
		 function );
		libcnotify_print_data(
		 file_header_data,
		 sizeof( esedb_file_header_t ),
		 LIBCNOTIFY_PRINT_DATA_FLAG_GROUP_DATA );
	}
#endif
	if( memory_compare(
	     ( (esedb_file_header_t *) file_header_data )->signature,
	     esedb_file_signature,
	     4 ) != 0 )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
		 LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
		 "%s: unsupported file signature.",
		 function );

		goto on_error;
	}
	if( libesedb_checksum_calculate_little_endian_xor32(
	     &calculated_xor32_checksum,
	     &( file_header_data[ 4 ] ),
	     read_size - 4,
	     0x89abcdef,
	     error ) != 1 )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
		 LIBCERROR_RUNTIME_ERROR_GENERIC,
		 "%s: unable to calculate XOR-32 checksum.",
		 function );

		goto on_error;
	}
	byte_stream_copy_to_uint32_little_endian(
	 ( (esedb_file_header_t *) file_header_data )->checksum,
	 stored_xor32_checksum );

	if( stored_xor32_checksum != calculated_xor32_checksum )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_INPUT,
		 LIBCERROR_INPUT_ERROR_CHECKSUM_MISMATCH,
		 "%s: mismatch in file header checksum ( 0x%08" PRIx32 " != 0x%08" PRIx32 " ).",
		 function,
		 stored_xor32_checksum,
		 calculated_xor32_checksum );

		goto on_error;
	}
	byte_stream_copy_to_uint32_little_endian(
	 ( (esedb_file_header_t *) file_header_data )->format_version,
	 format_version );

	byte_stream_copy_to_uint32_little_endian(
	 ( (esedb_file_header_t *) file_header_data )->file_type,
	 io_handle->file_type );

	byte_stream_copy_to_uint32_little_endian(
	 ( (esedb_file_header_t *) file_header_data )->format_revision,
	 format_revision );
	byte_stream_copy_to_uint32_little_endian(
	 ( (esedb_file_header_t *) file_header_data )->page_size,
	 page_size );

	byte_stream_copy_to_uint32_little_endian(
	 ( (esedb_file_header_t *) file_header_data )->creation_format_version,
	 creation_format_version );
	byte_stream_copy_to_uint32_little_endian(
	 ( (esedb_file_header_t *) file_header_data )->creation_format_revision,
	 creation_format_revision );

#if defined( HAVE_DEBUG_OUTPUT )
	if( libcnotify_verbose != 0 )
	{
		libcnotify_printf(
		 "%s: checksum\t\t\t\t: 0x%08" PRIx32 "\n",
		 function,
		 stored_xor32_checksum );

		byte_stream_copy_to_uint32_little_endian(
		 ( (esedb_file_header_t *) file_header_data )->signature,
		 value_32bit );
		libcnotify_printf(
		 "%s: signature\t\t\t\t: 0x%08" PRIx32 "\n",
		 function,
		 value_32bit );

		libcnotify_printf(
		 "%s: format version\t\t\t: 0x%08" PRIx32 "\n",
		 function,
		 format_version );

		libcnotify_printf(
		 "%s: file type\t\t\t\t: %" PRIu32 " (",
		 function,
		 io_handle->file_type );
		libesedb_debug_print_file_type(
		 io_handle->file_type );
		libcnotify_printf(
		 ")\n" );

		libcnotify_printf(
		 "%s: database time:\n",
		 function );
		libcnotify_print_data(
		 ( (esedb_file_header_t *) file_header_data )->database_time,
		 8,
		 0 );

		libcnotify_printf(
		 "%s: database signature:\n",
		 function );
		libcnotify_print_data(
		 ( (esedb_file_header_t *) file_header_data )->database_signature,
		 28,
		 0 );

		byte_stream_copy_to_uint32_little_endian(
		 ( (esedb_file_header_t *) file_header_data )->database_state,
		 value_32bit );
		libcnotify_printf(
		 "%s: database state\t\t\t: %" PRIu32 " ",
		 function,
		 value_32bit );
		libesedb_debug_print_database_state(
		 value_32bit );
		libcnotify_printf(
		 "\n" );

		libcnotify_printf(
		 "%s: consistent position:\n",
		 function );
		libcnotify_print_data(
		 ( (esedb_file_header_t *) file_header_data )->consistent_postition,
		 8,
		 0 );
		libesedb_debug_print_log_time(
		 ( (esedb_file_header_t *) file_header_data )->consistent_time,
		 8,
		 "consistent time",
		 "\t\t\t\t",
		 NULL );

		libesedb_debug_print_log_time(
		 ( (esedb_file_header_t *) file_header_data )->attach_time,
		 8,
		 "attach time",
		 "\t\t\t\t",
		 NULL );
		libcnotify_printf(
		 "%s: attach position:\n",
		 function );
		libcnotify_print_data(
		 ( (esedb_file_header_t *) file_header_data )->attach_postition,
		 8,
		 0 );

		libesedb_debug_print_log_time(
		 ( (esedb_file_header_t *) file_header_data )->detach_time,
		 8,
		 "detach time",
		 "\t\t\t\t",
		 NULL );
		libcnotify_printf(
		 "%s: detach position:\n",
		 function );
		libcnotify_print_data(
		 ( (esedb_file_header_t *) file_header_data )->detach_postition,
		 8,
		 0 );

		libcnotify_printf(
		 "%s: log signature:\n",
		 function );
		libcnotify_print_data(
		 ( (esedb_file_header_t *) file_header_data )->log_signature,
		 28,
		 0 );

		byte_stream_copy_to_uint32_little_endian(
		 ( (esedb_file_header_t *) file_header_data )->unknown1,
		 value_32bit );
		libcnotify_printf(
		 "%s: unknown1\t\t\t\t: 0x%08" PRIx32 " (%" PRIu32 ")\n",
		 function,
		 value_32bit,
		 value_32bit );

		libcnotify_printf(
		 "%s: previous full backup:\n",
		 function );
		libcnotify_print_data(
		 ( (esedb_file_header_t *) file_header_data )->previous_full_backup,
		 24,
		 0 );
		libcnotify_printf(
		 "%s: previous incremental backup:\n",
		 function );
		libcnotify_print_data(
		 ( (esedb_file_header_t *) file_header_data )->previous_incremental_backup,
		 24,
		 0 );
		libcnotify_printf(
		 "%s: current full backup:\n",
		 function );
		libcnotify_print_data(
		 ( (esedb_file_header_t *) file_header_data )->current_full_backup,
		 24,
		 0 );

		byte_stream_copy_to_uint32_little_endian(
		 ( (esedb_file_header_t *) file_header_data )->shadowing_disabled,
		 value_32bit );
		libcnotify_printf(
		 "%s: shadowing disabled\t\t\t: %" PRIu32 "\n",
		 function,
		 value_32bit );

		byte_stream_copy_to_uint32_little_endian(
		 ( (esedb_file_header_t *) file_header_data )->last_object_identifier,
		 value_32bit );
		libcnotify_printf(
		 "%s: last object identifier\t\t: %" PRIu32 "\n",
		 function,
		 value_32bit );

		byte_stream_copy_to_uint32_little_endian(
		 ( (esedb_file_header_t *) file_header_data )->index_update_major_version,
		 value_32bit );
		libcnotify_printf(
		 "%s: index update major version\t\t: %" PRIu32 "\n",
		 function,
		 value_32bit );
		byte_stream_copy_to_uint32_little_endian(
		 ( (esedb_file_header_t *) file_header_data )->index_update_minor_version,
		 value_32bit );
		libcnotify_printf(
		 "%s: index update minor version\t\t: %" PRIu32 "\n",
		 function,
		 value_32bit );
		byte_stream_copy_to_uint32_little_endian(
		 ( (esedb_file_header_t *) file_header_data )->index_update_build_number,
		 value_32bit );
		libcnotify_printf(
		 "%s: index update build number\t\t: %" PRIu32 "\n",
		 function,
		 value_32bit );
		byte_stream_copy_to_uint32_little_endian(
		 ( (esedb_file_header_t *) file_header_data )->index_update_service_pack_number,
		 value_32bit );
		libcnotify_printf(
		 "%s: index update service pack number\t: %" PRIu32 "\n",
		 function,
		 value_32bit );

		libcnotify_printf(
		 "%s: format revision\t\t\t: 0x%08" PRIx32 "\n",
		 function,
		 format_revision );
		libcnotify_printf(
		 "%s: page size\t\t\t\t: %" PRIu32 "\n",
		 function,
		 page_size );

		byte_stream_copy_to_uint32_little_endian(
		 ( (esedb_file_header_t *) file_header_data )->repair_count,
		 value_32bit );
		libcnotify_printf(
		 "%s: repair count\t\t\t: %" PRIu32 "\n",
		 function,
		 value_32bit );
		libesedb_debug_print_log_time(
		 ( (esedb_file_header_t *) file_header_data )->repair_time,
		 8,
		 "repair time",
		 "\t\t\t\t",
		 NULL );

		libcnotify_printf(
		 "%s: unknown2:\n",
		 function );
		libcnotify_print_data(
		 ( (esedb_file_header_t *) file_header_data )->unknown2,
		 28,
		 0 );

		libcnotify_printf(
		 "%s: scrub database time:\n",
		 function );
		libcnotify_print_data(
		 ( (esedb_file_header_t *) file_header_data )->scrub_database_time,
		 8,
		 0 );
		libesedb_debug_print_log_time(
		 ( (esedb_file_header_t *) file_header_data )->scrub_time,
		 8,
		 "scrub time",
		 "\t\t\t\t",
		 NULL );

		libcnotify_printf(
		 "%s: required log:\n",
		 function );
		libcnotify_print_data(
		 ( (esedb_file_header_t *) file_header_data )->required_log,
		 8,
		 0 );

		byte_stream_copy_to_uint32_little_endian(
		 ( (esedb_file_header_t *) file_header_data )->upgrade_exchange5_format,
		 value_32bit );
		libcnotify_printf(
		 "%s: upgrade Exchange 5.5 format\t: %" PRIu32 "\n",
		 function,
		 value_32bit );
		byte_stream_copy_to_uint32_little_endian(
		 ( (esedb_file_header_t *) file_header_data )->upgrade_free_pages,
		 value_32bit );
		libcnotify_printf(
		 "%s: upgrade free pages\t\t\t: %" PRIu32 "\n",
		 function,
		 value_32bit );
		byte_stream_copy_to_uint32_little_endian(
		 ( (esedb_file_header_t *) file_header_data )->upgrade_space_map_pages,
		 value_32bit );
		libcnotify_printf(
		 "%s: upgrade space map pages\t\t: %" PRIu32 "\n",
		 function,
		 value_32bit );

		libcnotify_printf(
		 "%s: current shadow volume backup:\n",
		 function );
		libcnotify_print_data(
		 ( (esedb_file_header_t *) file_header_data )->current_shadow_volume_backup,
		 24,
		 0 );

		libcnotify_printf(
		 "%s: creation format version\t\t: 0x%08" PRIx32 "\n",
		 function,
		 creation_format_version );
		libcnotify_printf(
		 "%s: creation format revision\t\t: 0x%08" PRIx32 "\n",
		 function,
		 creation_format_revision );

		libcnotify_printf(
		 "%s: unknown3:\n",
		 function );
		libcnotify_print_data(
		 ( (esedb_file_header_t *) file_header_data )->unknown3,
		 16,
		 0 );

		byte_stream_copy_to_uint32_little_endian(
		 ( (esedb_file_header_t *) file_header_data )->old_repair_count,
		 value_32bit );
		libcnotify_printf(
		 "%s: old repair count\t\t\t: %" PRIu32 "\n",
		 function,
		 value_32bit );

		byte_stream_copy_to_uint32_little_endian(
		 ( (esedb_file_header_t *) file_header_data )->ecc_fix_success_count,
		 value_32bit );
		libcnotify_printf(
		 "%s: ECC fix success count\t\t: %" PRIu32 "\n",
		 function,
		 value_32bit );
		libesedb_debug_print_log_time(
		 ( (esedb_file_header_t *) file_header_data )->ecc_fix_success_time,
		 8,
		 "ECC fix success time",
		 "\t\t\t",
		 NULL );
		byte_stream_copy_to_uint32_little_endian(
		 ( (esedb_file_header_t *) file_header_data )->old_ecc_fix_success_count,
		 value_32bit );
		libcnotify_printf(
		 "%s: old ECC fix success count\t\t: %" PRIu32 "\n",
		 function,
		 value_32bit );

		byte_stream_copy_to_uint32_little_endian(
		 ( (esedb_file_header_t *) file_header_data )->ecc_fix_error_count,
		 value_32bit );
		libcnotify_printf(
		 "%s: ECC fix error count\t\t: %" PRIu32 "\n",
		 function,
		 value_32bit );
		libesedb_debug_print_log_time(
		 ( (esedb_file_header_t *) file_header_data )->ecc_fix_error_time,
		 8,
		 "ECC fix error time",
		 "\t\t\t",
		 NULL );
		byte_stream_copy_to_uint32_little_endian(
		 ( (esedb_file_header_t *) file_header_data )->old_ecc_fix_error_count,
		 value_32bit );
		libcnotify_printf(
		 "%s: old ECC fix error count\t\t: %" PRIu32 "\n",
		 function,
		 value_32bit );

		byte_stream_copy_to_uint32_little_endian(
		 ( (esedb_file_header_t *) file_header_data )->bad_checksum_error_count,
		 value_32bit );
		libcnotify_printf(
		 "%s: bad checksum error count\t\t: %" PRIu32 "\n",
		 function,
		 value_32bit );
		libesedb_debug_print_log_time(
		 ( (esedb_file_header_t *) file_header_data )->bad_checksum_error_time,
		 8,
		 "bad checksum error time",
		 "\t\t\t",
		 NULL );
		byte_stream_copy_to_uint32_little_endian(
		 ( (esedb_file_header_t *) file_header_data )->old_bad_checksum_error_count,
		 value_32bit );
		libcnotify_printf(
		 "%s: old bad checksum error count\t: %" PRIu32 "\n",
		 function,
		 value_32bit );

		libcnotify_printf(
		 "%s: committed log:\n",
		 function );
		libcnotify_print_data(
		 ( (esedb_file_header_t *) file_header_data )->committed_log,
		 4,
		 0 );

		libcnotify_printf(
		 "%s: previous shadow volume backup:\n",
		 function );
		libcnotify_print_data(
		 ( (esedb_file_header_t *) file_header_data )->previous_shadow_volume_backup,
		 24,
		 0 );
		libcnotify_printf(
		 "%s: previous differential backup:\n",
		 function );
		libcnotify_print_data(
		 ( (esedb_file_header_t *) file_header_data )->previous_differential_backup,
		 24,
		 0 );

		libcnotify_printf(
		 "%s: unknown4:\n",
		 function );
		libcnotify_print_data(
		 ( (esedb_file_header_t *) file_header_data )->unknown4,
		 40,
		 0 );

		byte_stream_copy_to_uint32_little_endian(
		 ( (esedb_file_header_t *) file_header_data )->nls_major_version,
		 value_32bit );
		libcnotify_printf(
		 "%s: NLS major version\t\t\t: 0x%08" PRIx32 "\n",
		 function,
		 value_32bit );
		byte_stream_copy_to_uint32_little_endian(
		 ( (esedb_file_header_t *) file_header_data )->nls_minor_version,
		 value_32bit );
		libcnotify_printf(
		 "%s: NLS minor version\t\t\t: 0x%08" PRIx32 "\n",
		 function,
		 value_32bit );

		libcnotify_printf(
		 "%s: unknown5:\n",
		 function );
		libcnotify_print_data(
		 ( (esedb_file_header_t *) file_header_data )->unknown5,
		 148,
		 LIBCNOTIFY_PRINT_DATA_FLAG_GROUP_DATA );

		byte_stream_copy_to_uint32_little_endian(
		 ( (esedb_file_header_t *) file_header_data )->unknown_flags,
		 value_32bit );
		libcnotify_printf(
		 "%s: unknown flags\t\t\t: 0x%08" PRIx32 " (%" PRIu32 ")\n",
		 function,
		 value_32bit,
		 value_32bit );

		libcnotify_printf(
		 "\n" );
	}
#endif

	memory_free(
	 file_header_data );

	file_header_data = NULL;

	/* TODO add more values to internal structures */

	if( file_offset == 0 )
	{
		io_handle->format_version           = format_version;
		io_handle->format_revision          = format_revision;
		io_handle->page_size                = page_size;
		io_handle->creation_format_version  = creation_format_version;
		io_handle->creation_format_revision = creation_format_revision;
	}
	else
	{
		if( io_handle->format_version == 0 )
		{
			io_handle->format_version = format_version;
		}
		else if( io_handle->format_version != format_version )
		{
#if defined( HAVE_VERBOSE_OUTPUT )
			if( libcnotify_verbose != 0 )
			{
				libcnotify_printf(
				 "%s: mismatch in format version: 0x%" PRIx32 " and backup: 0x%" PRIx32 "\n",
				 function,
				 io_handle->format_version,
				 io_handle->format_version );
			}
#endif
		}
		if( io_handle->format_revision == 0 )
		{
			io_handle->format_revision = format_revision;
		}
		else if( io_handle->format_revision != format_revision )
		{
#if defined( HAVE_VERBOSE_OUTPUT )
			if( libcnotify_verbose != 0 )
			{
				libcnotify_printf(
				 "%s: mismatch in format revision: 0x%" PRIx32 " and backup: 0x%" PRIx32 "\n",
				 function,
				 io_handle->format_revision,
				 io_handle->format_revision );
			}
#endif
		}
		if( io_handle->page_size == 0 )
		{
			io_handle->page_size = page_size;
		}
		else if( io_handle->page_size != page_size )
		{
#if defined( HAVE_VERBOSE_OUTPUT )
			if( libcnotify_verbose != 0 )
			{
				libcnotify_printf(
				 "%s: mismatch in page size: 0x%04" PRIx32 " and backup: 0x%04" PRIx32 "\n",
				 function,
				 io_handle->page_size,
				 page_size );
			}
#endif
			/* The offset of the backup (database) file header
			 * is a good indication of the actual page size
			 */
			io_handle->page_size = (uint32_t) file_offset;
		}
	}
	return( 1 );

on_error:
	if( file_header_data != NULL )
	{
		memory_free(
		 file_header_data );
	}
	return( -1 );
}
/* Reads string values
 * Returns 1 if successful or -1 on error
 */
int libwrc_string_values_read(
     libwrc_language_entry_t *language_entry,
     libwrc_io_handle_t *io_handle,
     libbfio_handle_t *file_io_handle,
     uint32_t identifier,
     libwrc_data_descriptor_t *data_descriptor,
     libcerror_error_t **error )
{
	libfvalue_value_t *string_value = NULL;
	uint8_t *resource_data          = NULL;
	uint8_t *string_resource_data   = NULL;
	static char *function           = "libwrc_string_values_read";
	off64_t file_offset             = 0;
	size_t resource_data_size       = 0;
	ssize_t read_count              = 0;
	uint32_t string_identifier      = 0;
	uint32_t string_index           = 0;
	uint32_t string_size            = 0;
	int value_index                 = 0;

	if( language_entry == NULL )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
		 "%s: invalid language entry.",
		 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( data_descriptor == NULL )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
		 "%s: invalid data descriptor.",
		 function );

		return( -1 );
	}
	file_offset = data_descriptor->virtual_address
	            - io_handle->virtual_address;

	if( libbfio_handle_seek_offset(
	     file_io_handle,
	     file_offset,
	     SEEK_SET,
	     error ) == -1 )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_IO,
		 LIBCERROR_IO_ERROR_SEEK_FAILED,
		 "%s: unable to seek resource data offset: %" PRIi64 ".",
		 function,
		 file_offset );

		goto on_error;
	}
	resource_data_size = (size_t) data_descriptor->size;

	resource_data = (uint8_t *) memory_allocate(
	                             sizeof( uint8_t ) * resource_data_size );

	if( resource_data == NULL )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_MEMORY,
		 LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
		 "%s: unable to create resource data.",
		 function );

		goto on_error;
	}
	read_count = libbfio_handle_read_buffer(
	              file_io_handle,
	              resource_data,
	              resource_data_size,
	              error );

	if( read_count != (ssize_t) resource_data_size )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_IO,
		 LIBCERROR_IO_ERROR_READ_FAILED,
		 "%s: unable to read resource data.",
		 function );

		goto on_error;
	}
	string_resource_data = resource_data;

#if defined( HAVE_DEBUG_OUTPUT )
	if( libcnotify_verbose != 0 )
	{
		libcnotify_printf(
		 "%s: resource data:\n",
		 function );
		libcnotify_print_data(
		 string_resource_data,
		 resource_data_size,
		 0 );
	}
#endif
	while( resource_data_size > 0 )
	{
		byte_stream_copy_to_uint16_little_endian(
		 string_resource_data,
		 string_size );

		string_resource_data += sizeof( uint16_t );
		resource_data_size   -= sizeof( uint16_t );

#if defined( HAVE_DEBUG_OUTPUT )
		if( libcnotify_verbose != 0 )
		{
			libcnotify_printf(
			 "%s: string: %02" PRIu32 " length\t\t\t\t: %" PRIu32 "\n",
			 function,
			 string_index,
			 string_size );
		}
#endif
		if( string_size > 0 )
		{
			string_identifier = ( identifier << 4 ) | string_index;

			string_size *= 2;

			if( string_size > resource_data_size )
			{
				libcerror_error_set(
				 error,
				 LIBCERROR_ERROR_DOMAIN_RUNTIME,
				 LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
				 "%s: string size value out of bound.",
				 function );

				goto on_error;
			}
			if( libfvalue_value_type_initialize(
			     &string_value,
			     LIBFVALUE_VALUE_TYPE_STRING_UTF16,
			     error ) != 1 )
			{
				libcerror_error_set(
				 error,
				 LIBCERROR_ERROR_DOMAIN_RUNTIME,
				 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
				 "%s: unable to create string value.",
				 function );

				goto on_error;
			}
			if( libfvalue_value_set_identifier(
			     string_value,
			     (uint8_t *) &string_identifier,
			     4,
			     LIBFVALUE_VALUE_FLAG_IDENTIFIER_MANAGED,
			     error ) != 1 )
			{
				libcerror_error_set(
				 error,
				 LIBCERROR_ERROR_DOMAIN_RUNTIME,
				 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
				 "%s: unable to set identifier of string value.",
				 function );

				goto on_error;
			}
#if defined( HAVE_DEBUG_OUTPUT )
			if( libcnotify_verbose != 0 )
			{
				libcnotify_printf(
				 "%s: string: %02" PRIu32 " data:\n",
				 function,
				 string_index );
				libcnotify_print_data(
				 string_resource_data,
				 (size_t) string_size,
				 0 );
			}
#endif
			if( libfvalue_value_set_data(
			     string_value,
			     string_resource_data,
			     (size_t) string_size,
			     LIBFVALUE_CODEPAGE_UTF16_LITTLE_ENDIAN,
			     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 of string value.",
				 function );

				goto on_error;
			}
#if defined( HAVE_DEBUG_OUTPUT )
			if( libcnotify_verbose != 0 )
			{
				libcnotify_printf(
				 "%s: string: %02" PRIu32 " value\t\t\t\t: ",
				 function,
				 string_index );

				if( libfvalue_value_print(
				     string_value,
				     0,
				     0,
				     error ) != 1 )
				{
					libcerror_error_set(
					 error,
					 LIBCERROR_ERROR_DOMAIN_RUNTIME,
					 LIBCERROR_RUNTIME_ERROR_PRINT_FAILED,
					 "%s: unable to print string value.",
					 function );

					goto on_error;
				}
				libcnotify_printf(
				 "\n" );
			}
#endif
			string_resource_data += (size_t) string_size;
			resource_data_size   -= (size_t) string_size;

			if( libwrc_language_entry_append_value(
			     language_entry,
			     &value_index,
			     (intptr_t *) string_value,
			     error ) != 1 )
			{
				libcerror_error_set(
				 error,
				 LIBCERROR_ERROR_DOMAIN_RUNTIME,
				 LIBCERROR_RUNTIME_ERROR_APPEND_FAILED,
				 "%s: unable to append string value.",
				 function );

				goto on_error;
			}
			string_value = NULL;
		}
#if defined( HAVE_DEBUG_OUTPUT )
		else if( libcnotify_verbose != 0 )
		{
			libcnotify_printf(
			 "\n" );
		}
#endif
		string_index++;
	}
	memory_free(
	 resource_data );

/* TODO validate if number of strings is 16 ? */

	return( 1 );

on_error:
	if( string_value != NULL )
	{
		libfvalue_value_free(
		 &string_value,
		 NULL );
	}
	if( resource_data != NULL )
	{
		memory_free(
		 resource_data );
	}
	return( -1 );
}
Пример #16
0
/* Reads a record_values
 * Returns the number of bytes read if successful or -1 on error
 */
ssize_t libevt_record_values_read(
         libevt_record_values_t *record_values,
         libbfio_handle_t *file_io_handle,
         libevt_io_handle_t *io_handle,
         off64_t *file_offset,
         uint8_t strict_mode,
         libcerror_error_t **error )
{
	uint8_t record_size_data[ 4 ];

	uint8_t *record_data      = NULL;
	static char *function     = "libevt_record_values_read";
	size_t read_size          = 0;
	size_t record_data_offset = 0;
	ssize_t read_count        = 0;
	ssize_t total_read_count  = 0;
	uint32_t record_data_size = 0;

	if( record_values == NULL )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
		 "%s: invalid record values.",
		 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( file_offset == NULL )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
		 "%s: invalid file offset.",
		 function );

		return( -1 );
	}
	record_values->offset = *file_offset;

	read_count = libbfio_handle_read_buffer(
	              file_io_handle,
	              record_size_data,
	              sizeof( uint32_t ),
	              error );

	if( read_count != (ssize_t) sizeof( uint32_t ) )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_IO,
		 LIBCERROR_IO_ERROR_READ_FAILED,
		 "%s: unable to read record size data.",
		 function );

		goto on_error;
	}
	*file_offset    += read_count;
	total_read_count = read_count;

	byte_stream_copy_to_uint32_little_endian(
	 record_size_data,
	 record_data_size );

	if( record_data_size < 4 )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
		 LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
		 "%s: record data size value out of bounds.",
		 function );

		goto on_error;
	}
#if SIZEOF_SIZE_T <= 4
	if( (size_t) record_data_size > (size_t) SSIZE_MAX )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
		 LIBCERROR_RUNTIME_ERROR_VALUE_EXCEEDS_MAXIMUM,
		 "%s: invalid record data size value exceeds maximum.",
		 function );

		goto on_error;
	}
#endif
	/* Allocating record data as 4 bytes and then using realloc here
	 * corrupts the memory
	 */
	record_data = (uint8_t *) memory_allocate(
	                           sizeof( uint8_t ) * record_data_size );

	if( record_data == NULL )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_MEMORY,
		 LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
		 "%s: unable to create record data.",
		 function );

		goto on_error;
	}
	byte_stream_copy_from_uint32_little_endian(
	 record_data,
	 record_data_size );

	record_data_offset = 4;

	read_size = record_data_size - record_data_offset;

	if( ( (size64_t) *file_offset + read_size ) > io_handle->file_size )
	{
		read_size = (size_t) ( io_handle->file_size - *file_offset );
	}
	read_count = libbfio_handle_read_buffer(
	              file_io_handle,
	              &( record_data[ record_data_offset ] ),
	              read_size,
	              error );

	if( read_count != (ssize_t) read_size )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_IO,
		 LIBCERROR_IO_ERROR_READ_FAILED,
		 "%s: unable to read record data.",
		 function );

		goto on_error;
	}
	*file_offset       += read_count;
	record_data_offset += read_count;
	total_read_count   += read_count;

	if( record_data_offset < (size_t) record_data_size )
	{
		if( libbfio_handle_seek_offset(
		     file_io_handle,
		     (off64_t) sizeof( evt_file_header_t ),
		     SEEK_SET,
		     error ) == -1 )
		{
			libcerror_error_set(
			 error,
			 LIBCERROR_ERROR_DOMAIN_IO,
			 LIBCERROR_IO_ERROR_SEEK_FAILED,
			 "%s: unable to seek file header offset: %" PRIzd ".",
			 function,
			 sizeof( evt_file_header_t ) );

			goto on_error;
		}
		*file_offset = (off64_t) sizeof( evt_file_header_t );

		read_size = (size_t) record_data_size - record_data_offset;

		read_count = libbfio_handle_read_buffer(
		              file_io_handle,
		              &( record_data[ record_data_offset ] ),
		              read_size,
		              error );

		if( read_count != (ssize_t) read_size )
		{
			libcerror_error_set(
			 error,
			 LIBCERROR_ERROR_DOMAIN_IO,
			 LIBCERROR_IO_ERROR_READ_FAILED,
			 "%s: unable to read record data.",
			 function );

			goto on_error;
		}
		*file_offset     += read_count;
		total_read_count += read_count;
	}
#if defined( HAVE_DEBUG_OUTPUT )
	if( libcnotify_verbose != 0 )
	{
		libcnotify_printf(
		 "%s: record data:\n",
		 function );
		libcnotify_print_data(
		 record_data,
		 (size_t) record_data_size,
		 LIBCNOTIFY_PRINT_DATA_FLAG_GROUP_DATA );
	}
#endif
	if( memory_compare(
	     &( record_data[ 4 ] ),
	     evt_file_signature,
	     4 ) == 0 )
	{
		record_values->type = LIBEVT_RECORD_TYPE_EVENT;
	}
	else if( memory_compare(
	          &( record_data[ 4 ] ),
	          evt_end_of_file_record_signature1,
	          4 ) == 0 )
	{
		record_values->type = LIBEVT_RECORD_TYPE_END_OF_FILE;
	}
	else
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
		 LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
		 "%s: unsupported record values signature.",
		 function );

		goto on_error;
	}
	if( record_values->type == LIBEVT_RECORD_TYPE_EVENT )
	{
		if( libevt_record_values_read_event(
		     record_values,
		     record_data,
		     (size_t) record_data_size,
		     strict_mode,
		     error ) != 1 )
		{
			libcerror_error_set(
			 error,
			 LIBCERROR_ERROR_DOMAIN_IO,
			 LIBCERROR_IO_ERROR_READ_FAILED,
			 "%s: unable to read event record values.",
			 function );

			goto on_error;
		}
	}
	else if( record_values->type == LIBEVT_RECORD_TYPE_END_OF_FILE )
	{
		if( libevt_record_values_read_end_of_file(
		     record_values,
		     record_data,
		     (size_t) record_data_size,
		     error ) != 1 )
		{
			libcerror_error_set(
			 error,
			 LIBCERROR_ERROR_DOMAIN_IO,
			 LIBCERROR_IO_ERROR_READ_FAILED,
			 "%s: unable to read end of file record values.",
			 function );

			goto on_error;
		}
	}
	memory_free(
	 record_data );

	return( total_read_count );

on_error:
	if( record_data != NULL )
	{
		memory_free(
		 record_data );
	}
	return( -1 );
}
Пример #17
0
/* Reads a redirected
 * Returns 1 if successful or -1 on error
 */
int libmsiecf_redirected_values_read(
     libmsiecf_redirected_values_t *redirected_values,
     libmsiecf_io_handle_t *io_handle,
     libbfio_handle_t *file_io_handle,
     off64_t redirected_offset,
     size32_t record_size,
     uint8_t item_flags,
     libcerror_error_t **error )
{
	uint8_t *redr_record_data = NULL;
	static char *function     = "libmsiecf_redirected_values_read";
	ssize_t read_count        = 0;
	ssize_t value_size        = 0;

#if defined( HAVE_DEBUG_OUTPUT )
	uint32_t value_32bit      = 0;
#endif

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

		return( -1 );
	}
	if( record_size == 0 )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
		 LIBCERROR_ARGUMENT_ERROR_VALUE_ZERO_OR_LESS,
		 "%s: invalid record size value zero or less.",
		 function );

		return( -1 );
	}
#if SIZEOF_SIZE_T <= 4
	if( record_size > (size32_t) SSIZE_MAX )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
		 LIBCERROR_RUNTIME_ERROR_VALUE_EXCEEDS_MAXIMUM,
		 "%s: invalid record size value exceeds maximum.",
		 function );

		return( -1 );
	}
#endif
	if( ( record_size % 8 ) != 0 )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
		 LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
		 "%s: unsupported REDR record size.",
		 function );

		return( -1 );
	}
#if defined( HAVE_DEBUG_OUTPUT )
	if( libcnotify_verbose != 0 )
	{
		libcnotify_printf(
		 "%s: reading REDR record at offset: %" PRIi64 " (0x%08" PRIx64 ")\n",
		 function,
		 redirected_offset,
		 redirected_offset );
	}
#endif
	if( libbfio_handle_seek_offset(
	     file_io_handle,
	     redirected_offset,
	     SEEK_SET,
	     error ) == -1 )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_IO,
		 LIBCERROR_IO_ERROR_SEEK_FAILED,
		 "%s: unable to seek REDR record offset: %" PRIi64 ".",
		 function,
		 redirected_offset );

		goto on_error;
	}
	redr_record_data = (uint8_t *) memory_allocate(
	                                sizeof( uint8_t ) * record_size );

	if( redr_record_data == NULL )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_MEMORY,
		 LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
		 "%s: unable to create REDR record data.",
		 function );

		goto on_error;
	}
	read_count = libbfio_handle_read_buffer(
	              file_io_handle,
	              redr_record_data,
	              record_size,
	              error );

	if( read_count != (ssize_t) record_size )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_IO,
		 LIBCERROR_IO_ERROR_READ_FAILED,
		 "%s: unable to read REDR record data.",
		 function );

		goto on_error;
	}
#if defined( HAVE_DEBUG_OUTPUT )
	if( libcnotify_verbose != 0 )
	{
		libcnotify_printf(
		 "%s: REDR record data:\n",
		 function );
		libcnotify_print_data(
		 redr_record_data,
		 record_size,
		 0 );
	}
#endif
	if( memory_compare(
	     ( (msiecf_redr_record_header_t *) redr_record_data )->signature,
	     "REDR",
	     4 ) != 0 )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
		 LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
		 "%s: unsupported signature.",
		 function );

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

		byte_stream_copy_to_uint32_little_endian(
		 ( (msiecf_redr_record_header_t *) redr_record_data )->number_of_blocks,
		 value_32bit );
		libcnotify_printf(
		 "%s: number of blocks\t\t\t: %" PRIu32 "\n",
		 function,
		 value_32bit );

		byte_stream_copy_to_uint32_little_endian(
		 ( (msiecf_redr_record_header_t *) redr_record_data )->unknown1,
		 value_32bit );
		libcnotify_printf(
		 "%s: unknown1\t\t\t\t: 0x%08" PRIx32 "\n",
		 function,
		 value_32bit );

		byte_stream_copy_to_uint32_little_endian(
		 ( (msiecf_redr_record_header_t *) redr_record_data )->unknown2,
		 value_32bit );
		libcnotify_printf(
		 "%s: unknown2\t\t\t\t: 0x%08" PRIx32 "\n",
		 function,
		 value_32bit );
	}
#endif
	if( libfvalue_value_type_initialize(
	     &( redirected_values->location ),
	     LIBFVALUE_VALUE_TYPE_STRING_BYTE_STREAM,
	     error ) != 1 )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
		 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
		 "%s: unable to create location value.",
		 function );

		goto on_error;
	}
	value_size = libfvalue_value_type_set_data_string(
	              redirected_values->location,
	              &( redr_record_data[ 16 ] ),
	              record_size - 16,
	              io_handle->ascii_codepage,
	              LIBFVALUE_VALUE_DATA_FLAG_MANAGED,
	              error );

	if( value_size == -1 )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
		 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
		 "%s: unable to set data of location value.",
		 function );

		goto on_error;
	}
#if defined( HAVE_DEBUG_OUTPUT )
	if( libcnotify_verbose != 0 )
	{
		libcnotify_printf(
		 "%s: location\t\t\t\t: ",
		 function );

		if( libfvalue_value_print(
		     redirected_values->location,
		     0,
		     0,
		     error ) != 1 )
		{
			libcerror_error_set(
			 error,
			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
			 LIBCERROR_RUNTIME_ERROR_PRINT_FAILED,
			 "%s: unable to print location value.",
			 function );

			goto on_error;
		}
		libcnotify_printf(
		 "\n" );

		if( libmsiecf_hash_calculate(
		     &value_32bit,
		     &( redr_record_data[ 16 ] ),
		     record_size - 16,
		     error ) != 1 )
		{
			libcerror_error_set(
			 error,
			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
			 LIBCERROR_RUNTIME_ERROR_PRINT_FAILED,
			 "%s: unable to calculate location hash.",
			 function );

			goto on_error;
		}
		libcnotify_printf(
		 "%s: hash value\t\t\t\t: 0x%08" PRIx32 "\n",
		 function,
		 value_32bit );
	}
#endif
	if( ( redr_record_data[ 16 + value_size - 1 ] != 0 )
	 && ( ( item_flags & LIBMSIECF_ITEM_FLAG_PARTIAL ) == 0 ) )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
		 LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
		 "%s: unsupported unterminated location string.",
		 function );

		goto on_error;
	}
	memory_free(
	 redr_record_data );

	redr_record_data = NULL;

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

on_error:
	if( redirected_values->location != NULL )
	{
		libfvalue_value_free(
		 &( redirected_values->location ),
		 NULL );
	}
	if( redr_record_data != NULL )
	{
		memory_free(
		 redr_record_data );
	}
	return( -1 );
}
/* Reads a hive bin header
 * Returns 1 if successful, 0 if no hive bin signature was found or -1 on error
 */
int libregf_hive_bin_read_header(
     libregf_hive_bin_t *hive_bin,
     libbfio_handle_t *file_io_handle,
     libcerror_error_t **error )
{
	regf_hive_bin_header_t hive_bin_header;

	static char *function             = "libregf_hive_bin_read_header";
	ssize_t read_count                = 0;

#if defined( HAVE_DEBUG_OUTPUT )
	libcstring_system_character_t filetime_string[ 32 ];

	libfdatetime_filetime_t *filetime = NULL;
	uint32_t value_32bit              = 0;
	int result                        = 0;
#endif

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

		return( -1 );
	}
	read_count = libbfio_handle_read_buffer(
	              file_io_handle,
	              (uint8_t *) &hive_bin_header,
	              sizeof( regf_hive_bin_header_t ),
	              error );

	if( read_count != (ssize_t) sizeof( regf_hive_bin_header_t ) )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_IO,
		 LIBCERROR_IO_ERROR_READ_FAILED,
		 "%s: unable to read hive bin header data.",
		 function );

		goto on_error;
	}
#if defined( HAVE_DEBUG_OUTPUT )
	if( libcnotify_verbose != 0 )
	{
		libcnotify_printf(
		 "%s: hive bin header:\n",
		 function );
		libcnotify_print_data(
		 (uint8_t *) &hive_bin_header,
		 sizeof( regf_hive_bin_header_t ),
		 0 );
	}
#endif
	if( memory_compare(
	     hive_bin_header.signature,
	     regf_hive_bin_signature,
	     4 ) != 0 )
	{
		return( 0 );
	}
	byte_stream_copy_to_uint32_little_endian(
	 hive_bin_header.hive_bin_offset,
	 hive_bin->offset );

	byte_stream_copy_to_uint32_little_endian(
	 hive_bin_header.size,
	 hive_bin->size );

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

		libcnotify_printf(
		 "%s: hive bin offset\t\t\t\t: %" PRIu32 "\n",
		 function,
		 hive_bin->offset );
		libcnotify_printf(
		 "%s: size\t\t\t\t\t: %" PRIu32 " bytes\n",
		 function,
		 hive_bin->size );

		byte_stream_copy_to_uint32_little_endian(
		 hive_bin_header.unknown1,
		 value_32bit );
		libcnotify_printf(
		 "%s: unknown1\t\t\t\t\t: 0x%08" PRIx32 " (%" PRIu32 ")\n",
		 function,
		 value_32bit,
		 value_32bit );
		byte_stream_copy_to_uint32_little_endian(
		 hive_bin_header.unknown2,
		 value_32bit );
		libcnotify_printf(
		 "%s: unknown2\t\t\t\t\t: 0x%08" PRIx32 " (%" PRIu32 ")\n",
		 function,
		 value_32bit,
		 value_32bit );

		if( libfdatetime_filetime_initialize(
		     &filetime,
		     error ) != 1 )
		{
			libcerror_error_set(
			 error,
			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
			 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
			 "%s: unable to create filetime.",
			 function );

			goto on_error;
		}
		if( libfdatetime_filetime_copy_from_byte_stream(
		     filetime,
		     hive_bin_header.unknown_time,
		     8,
		     LIBFDATETIME_ENDIAN_LITTLE,
		     error ) != 1 )
		{
			libcerror_error_set(
			 error,
			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
			 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
			 "%s: unable to copy filetime from byte stream.",
			 function );

			goto on_error;
		}
#if defined( LIBCSTRING_HAVE_WIDE_SYSTEM_CHARACTER )
		result = libfdatetime_filetime_copy_to_utf16_string(
		          filetime,
		          (uint16_t *) filetime_string,
		          32,
		          LIBFDATETIME_STRING_FORMAT_TYPE_CTIME | LIBFDATETIME_STRING_FORMAT_FLAG_DATE_TIME_NANO_SECONDS,
		          error );
#else
		result = libfdatetime_filetime_copy_to_utf8_string(
		          filetime,
		          (uint8_t *) filetime_string,
		          32,
		          LIBFDATETIME_STRING_FORMAT_TYPE_CTIME | LIBFDATETIME_STRING_FORMAT_FLAG_DATE_TIME_NANO_SECONDS,
		          error );
#endif
		if( result != 1 )
		{
			libcerror_error_set(
			 error,
			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
			 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
			 "%s: unable to copy filetime to string.",
			 function );

			goto on_error;
		}
		libcnotify_printf(
		 "%s: unknown time\t\t\t\t: %" PRIs_LIBCSTRING_SYSTEM " UTC\n",
		 function,
		 filetime_string );

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

			goto on_error;
		}
		byte_stream_copy_to_uint32_little_endian(
		 hive_bin_header.unknown_spare,
		 value_32bit );
		libcnotify_printf(
		 "%s: unknown spare\t\t\t\t: 0x%08" PRIx32 " (%" PRIu32 ")\n",
		 function,
		 value_32bit,
		 value_32bit );

		libcnotify_printf(
		 "\n" );
	}
#endif
	return( 1 );

on_error:
#if defined( HAVE_DEBUG_OUTPUT )
	if( filetime != NULL )
	{
		libfdatetime_filetime_free(
		 &filetime,
		 NULL );
	}
#endif
	return( -1 );
}
Пример #19
0
/* Determines if a file is a Windows Event Log file (check for the EVT file signature) using a Basic File IO (bfio) handle
 * Returns 1 if true, 0 if not or -1 on error
 */
int libevt_check_file_signature_file_io_handle(
     libbfio_handle_t *file_io_handle,
     libcerror_error_t **error )
{
	uint8_t signature[ 8 ];

	static char *function      = "libevt_check_file_signature_file_io_handle";
	ssize_t read_count         = 0;
	int file_io_handle_is_open = 0;

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

		return( -1 );
	}
	file_io_handle_is_open = libbfio_handle_is_open(
	                          file_io_handle,
	                          error );

	if( file_io_handle_is_open == -1 )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_IO,
		 LIBCERROR_IO_ERROR_OPEN_FAILED,
		 "%s: unable to open file.",
		 function );

		return( -1 );
	}
	else if( file_io_handle_is_open == 0 )
	{
		if( libbfio_handle_open(
		     file_io_handle,
		     LIBBFIO_OPEN_READ,
		     error ) != 1 )
		{
			libcerror_error_set(
			 error,
			 LIBCERROR_ERROR_DOMAIN_IO,
			 LIBCERROR_IO_ERROR_OPEN_FAILED,
			 "%s: unable to open file.",
			 function );

			return( -1 );
		}
	}
	read_count = libbfio_handle_read_buffer(
	              file_io_handle,
	              signature,
	              8,
	              error );

	if( read_count != 8 )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_IO,
		 LIBCERROR_IO_ERROR_READ_FAILED,
		 "%s: unable to read signature.",
		 function );

		libbfio_handle_close(
		 file_io_handle,
		 NULL );

		return( -1 );
	}
	if( file_io_handle_is_open == 0 )
	{
		if( libbfio_handle_close(
		     file_io_handle,
		     error ) != 0 )
		{
			libcerror_error_set(
			 error,
			 LIBCERROR_ERROR_DOMAIN_IO,
			 LIBCERROR_IO_ERROR_CLOSE_FAILED,
			 "%s: unable to close file.",
			 function );

			return( -1 );
		}
	}
	if( memory_compare(
	     evt_file_signature,
	     &( signature[ 4 ] ),
	     4 ) == 0 )
	{
		return( 1 );
	}
	return( 0 );
}
/* Reads a hive bin and determines its cells
 * Returns 1 if successful or -1 on error
 */
int libregf_hive_bin_read_cells(
     libregf_hive_bin_t *hive_bin,
     libbfio_handle_t *file_io_handle,
     libcerror_error_t **error )
{
	libregf_hive_bin_cell_t *hive_bin_cell = NULL;
	uint8_t *hive_bin_cells_data           = NULL;
	static char *function                  = "libregf_hive_bin_read_cells";
	ssize_t read_count                     = 0;
	size_t hive_bin_cells_data_size        = 0;
	uint32_t hive_bin_cell_size            = 0;
	uint32_t hive_bin_cells_offset         = 0;
	int hive_bin_cell_index                = 0;

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

		return( -1 );
	}
	if( hive_bin->data != NULL )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
		 LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
		 "%s: invalid hive bin - data already set.",
		 function );

		return( -1 );
	}
#if SIZEOF_SIZE_T <= 4
	if( hive_bin->size > (size_t) SSIZE_MAX )
#else
	if( hive_bin->size > (uint32_t) SSIZE_MAX )
#endif
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
		 LIBCERROR_RUNTIME_ERROR_VALUE_EXCEEDS_MAXIMUM,
		 "%s: invalid hive bin - size value exceeds maximum.",
		 function );

		return( -1 );
	}
	if( hive_bin->cells_array != NULL )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
		 LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
		 "%s: invalid hive bin - cells array already set.",
		 function );

		return( -1 );
	}
	hive_bin->data_size = (size_t) hive_bin->size - sizeof( regf_hive_bin_header_t );

	hive_bin->data = (uint8_t *) memory_allocate(
	                              sizeof( uint8_t ) * hive_bin->data_size );
	
	if( hive_bin->data == NULL )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_MEMORY,
		 LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
		 "%s: unable to create hive cells data.",
		 function );

		goto on_error;
	}
	read_count = libbfio_handle_read_buffer(
	              file_io_handle,
	              hive_bin->data,
	              hive_bin->data_size,
	              error );

	if( read_count != (ssize_t) hive_bin->data_size )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_IO,
		 LIBCERROR_IO_ERROR_READ_FAILED,
		 "%s: unable to read hive bin cells data.",
		 function );

		goto on_error;
	}
	if( libcdata_array_initialize(
	     &( hive_bin->cells_array ),
	     0,
	     error ) != 1 )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
		 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
		 "%s: unable to create hive bin cells array.",
		 function );

		goto on_error;
	}
	hive_bin_cells_data      = hive_bin->data;
	hive_bin_cells_data_size = hive_bin->data_size;
	hive_bin_cells_offset    = hive_bin->offset + sizeof( regf_hive_bin_header_t );

#if defined( HAVE_DEBUG_OUTPUT )
	if( libcnotify_verbose != 0 )
	{
		libcnotify_printf(
		 "%s: hive bin cells:\n",
		 function );
		libcnotify_print_data(
		 hive_bin_cells_data,
		 hive_bin_cells_data_size,
		 0 );
	}
#endif
	while( hive_bin_cells_data_size > 0 )
	{
		if( libregf_hive_bin_cell_initialize(
		     &hive_bin_cell,
		     error ) != 1 )
		{
			libcerror_error_set(
			 error,
			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
			 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
			 "%s: unable to create hive bin cell.",
			 function );

			goto on_error;
		}
#if defined( HAVE_DEBUG_OUTPUT )
		if( libcnotify_verbose != 0 )
		{
			libcnotify_printf(
			 "%s: hive bin cell: %03d offset\t\t\t: 0x%08" PRIx32 "\n",
			 function,
			 hive_bin_cell_index,
			 hive_bin_cells_offset );
		}
#endif
		hive_bin_cell->offset = (uint32_t) hive_bin_cells_offset;

		byte_stream_copy_to_uint32_little_endian(
		 hive_bin_cells_data,
		 hive_bin_cell_size );

		hive_bin_cells_data      += 4;
		hive_bin_cells_offset    += 4;
		hive_bin_cells_data_size -= 4;

#if defined( HAVE_DEBUG_OUTPUT )
		if( libcnotify_verbose != 0 )
		{
			libcnotify_printf(
			 "%s: hive bin cell: %03d size\t\t\t: 0x%08" PRIx32 " (%" PRIi32 ")\n",
			 function,
			 hive_bin_cell_index,
			 hive_bin_cell_size,
			 (int32_t) hive_bin_cell_size );
		}
#endif
		if( (int32_t) hive_bin_cell_size < 0 )
		{
			hive_bin_cell_size = (uint32_t) ( -1 * (int32_t) hive_bin_cell_size );
		}
		else
		{
			hive_bin_cell->flags |= LIBREGF_HIVE_BIN_CELL_FLAG_UNALLOCATED;
		}
		if( ( hive_bin_cell_size % 8 ) != 0 )
		{
			libcerror_error_set(
			 error,
			 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
			 LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
			 "%s: invalid cell size value should be multitude of 8.",
			 function );

			goto on_error;
		}
		/* Remove the size of the cell size value
		 */
		hive_bin_cell_size -= 4;

		if( hive_bin_cell_size > hive_bin_cells_data_size )
		{
			libcerror_error_set(
			 error,
			 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
			 LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
			 "%s: invalid cell size value exceeds hive bin size.",
			 function );

			goto on_error;
		}
#if defined( HAVE_DEBUG_OUTPUT )
		if( libcnotify_verbose != 0 )
		{
			libcnotify_printf(
			 "%s: hive bin cell: %03d data:\n",
			 function,
			 hive_bin_cell_index );
			libcnotify_print_data(
			 hive_bin_cells_data,
			 hive_bin_cell_size,
			 0 );
		}
#endif
		hive_bin_cell->data = hive_bin_cells_data;
		hive_bin_cell->size = hive_bin_cell_size;

		if( libcdata_array_append_entry(
		     hive_bin->cells_array,
		     &hive_bin_cell_index,
		     (intptr_t *) hive_bin_cell,
		     error ) != 1 )
		{
			libcerror_error_set(
			 error,
			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
			 LIBCERROR_RUNTIME_ERROR_APPEND_FAILED,
			 "%s: unable to append hive bin cell: %d.",
			 function,
			 hive_bin_cell_index );

			goto on_error;
		}
		hive_bin_cell = NULL;

		hive_bin_cells_data      += hive_bin_cell_size;
		hive_bin_cells_offset    += hive_bin_cell_size;
		hive_bin_cells_data_size -= hive_bin_cell_size;

		hive_bin_cell_index++;
	}
	return( 1 );

on_error:
	if( hive_bin_cell != NULL )
	{
		libregf_hive_bin_cell_free(
		 &hive_bin_cell,
		 NULL );
	}
	if( hive_bin->data != NULL )
	{
		memory_free(
		 hive_bin->data );

		hive_bin->data = NULL;
	}
	hive_bin->data_size = 0;

	return( -1 );
}
Пример #21
0
/* Reads an index node
 * Returns 1 if successful or -1 on error
 */
int libpff_index_node_read(
     libpff_index_node_t *index_node,
     libpff_io_handle_t *io_handle,
     libbfio_handle_t *file_io_handle,
     off64_t node_offset,
     libcerror_error_t **error )
{
	uint8_t *index_node_footer_data              = NULL;
	static char *function                        = "libpff_index_node_read";
	ssize_t read_count                           = 0;
	uint32_t calculated_checksum                 = 0;
	uint32_t stored_checksum                     = 0;
	uint8_t calculated_entry_size                = 0;
	uint8_t calculated_maximum_number_of_entries = 0;
	uint8_t index_node_type_copy                 = 0;
	int result                                   = 0;

#if defined( HAVE_DEBUG_OUTPUT )
	uint8_t *index_node_entry_data               = NULL;
	uint64_t value_64bit                         = 0;
	uint32_t value_32bit                         = 0;
	uint16_t entry_index                         = 0;
	uint16_t index_node_entry_data_size          = 0;
	uint16_t value_16bit                         = 0;
#endif

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

		return( -1 );
	}
	if( index_node->data != NULL )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
		 LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
		 "%s: invalid index node - data already set.",
		 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( ( io_handle->file_type != LIBPFF_FILE_TYPE_32BIT )
	 && ( io_handle->file_type != LIBPFF_FILE_TYPE_64BIT )
	 && ( io_handle->file_type != LIBPFF_FILE_TYPE_64BIT_4K_PAGE ) )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
		 LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
		 "%s: unsupported file type.",
		 function );

		return( -1 );
	}
	if( io_handle->file_type == LIBPFF_FILE_TYPE_32BIT )
	{
		index_node->data_size                 = 512;
		index_node->maximum_entries_data_size = 512 - sizeof( pff_index_node_32bit_footer_t );
	}
	else if( io_handle->file_type == LIBPFF_FILE_TYPE_64BIT )
	{
		index_node->data_size                 = 512;
		index_node->maximum_entries_data_size = 512 - sizeof( pff_index_node_64bit_footer_t );
	}
	else if( io_handle->file_type == LIBPFF_FILE_TYPE_64BIT_4K_PAGE )
	{
		index_node->data_size                 = 4096;
		index_node->maximum_entries_data_size = 4096 - sizeof( pff_index_node_64bit_4k_page_footer_t );
	}
	index_node->data = (uint8_t *) memory_allocate(
	                                sizeof( uint8_t ) * index_node->data_size );

	if( index_node->data == NULL )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_MEMORY,
		 LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
		 "%s: unable to create index node data.",
		 function );

		goto on_error;
	}
#if defined( HAVE_DEBUG_OUTPUT )
	if( libcnotify_verbose != 0 )
	{
		libcnotify_printf(
		 "%s: reading index node data at offset: %" PRIi64 " (0x%08" PRIx64 ")\n",
		 function,
		 node_offset,
		 node_offset );
	}
#endif
	if( libbfio_handle_seek_offset(
	     file_io_handle,
	     node_offset,
	     SEEK_SET,
	     error ) == -1 )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_IO,
		 LIBCERROR_IO_ERROR_SEEK_FAILED,
		 "%s: unable to seek node offset: %" PRIi64 ".",
		 function,
		 node_offset );

		goto on_error;
	}
	read_count = libbfio_handle_read_buffer(
	              file_io_handle,
	              index_node->data,
	              index_node->data_size,
	              error );

	if( read_count != (ssize_t) index_node->data_size )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_IO,
		 LIBCERROR_IO_ERROR_READ_FAILED,
		 "%s: unable to read index node data.",
		 function );

		goto on_error;
	}
#if defined( HAVE_DEBUG_OUTPUT )
	if( libcnotify_verbose != 0 )
	{
		libcnotify_printf(
		 "%s: index node data:\n",
		 function );
		libcnotify_print_data(
		 index_node->data,
		 index_node->data_size,
		 LIBCNOTIFY_PRINT_DATA_FLAG_GROUP_DATA );
	}
#endif
	index_node_footer_data = &( index_node->data[ index_node->maximum_entries_data_size ] );

	if( io_handle->file_type == LIBPFF_FILE_TYPE_32BIT )
	{
		index_node->type     = ( (pff_index_node_32bit_footer_t *) index_node_footer_data )->type;
		index_node_type_copy = ( (pff_index_node_32bit_footer_t *) index_node_footer_data )->type_copy;

		byte_stream_copy_to_uint32_little_endian(
		 ( (pff_index_node_32bit_footer_t *) index_node_footer_data )->back_pointer,
		 index_node->back_pointer );
		byte_stream_copy_to_uint32_little_endian(
		 ( (pff_index_node_32bit_footer_t *) index_node_footer_data )->checksum,
		 stored_checksum );

		index_node->number_of_entries         = ( (pff_index_node_32bit_footer_t *) index_node_footer_data )->number_of_entries;
		index_node->maximum_number_of_entries = ( (pff_index_node_32bit_footer_t *) index_node_footer_data )->maximum_number_of_entries;
		index_node->entry_size                = ( (pff_index_node_32bit_footer_t *) index_node_footer_data )->entry_size;
		index_node->level                     = ( (pff_index_node_32bit_footer_t *) index_node_footer_data )->level;

		if( ( index_node->type == LIBPFF_INDEX_TYPE_DESCRIPTOR )
		 && ( index_node->level == LIBPFF_INDEX_NODE_LEVEL_LEAF ) )
		{
			calculated_entry_size                = 16;
			calculated_maximum_number_of_entries = 496 / 16;
		}
		else
		{
			calculated_entry_size                = 12;
			calculated_maximum_number_of_entries = 496 / 12;
		}
	}
	else if( io_handle->file_type == LIBPFF_FILE_TYPE_64BIT )
	{
		index_node->type     = ( (pff_index_node_64bit_footer_t *) index_node_footer_data )->type;
		index_node_type_copy = ( (pff_index_node_64bit_footer_t *) index_node_footer_data )->type_copy;

		byte_stream_copy_to_uint32_little_endian(
		 ( (pff_index_node_64bit_footer_t *) index_node_footer_data )->checksum,
		 stored_checksum );
		byte_stream_copy_to_uint64_little_endian(
		 ( (pff_index_node_64bit_footer_t *) index_node_footer_data )->back_pointer,
		 index_node->back_pointer );

		index_node->number_of_entries         = ( (pff_index_node_64bit_footer_t *) index_node_footer_data )->number_of_entries;
		index_node->maximum_number_of_entries = ( (pff_index_node_64bit_footer_t *) index_node_footer_data )->maximum_number_of_entries;
		index_node->entry_size                = ( (pff_index_node_64bit_footer_t *) index_node_footer_data )->entry_size;
		index_node->level                     = ( (pff_index_node_64bit_footer_t *) index_node_footer_data )->level;

		if( ( index_node->type == LIBPFF_INDEX_TYPE_DESCRIPTOR )
		 && ( index_node->level == LIBPFF_INDEX_NODE_LEVEL_LEAF ) )
		{
			calculated_entry_size                = 32;
			calculated_maximum_number_of_entries = 488 / 32;
		}
		else
		{
			calculated_entry_size                = 24;
			calculated_maximum_number_of_entries = 488 / 24;
		}
	}
	else if( io_handle->file_type == LIBPFF_FILE_TYPE_64BIT_4K_PAGE )
	{
		index_node->type     = ( (pff_index_node_64bit_4k_page_footer_t *) index_node_footer_data )->type;
		index_node_type_copy = ( (pff_index_node_64bit_4k_page_footer_t *) index_node_footer_data )->type_copy;

		byte_stream_copy_to_uint32_little_endian(
		 ( (pff_index_node_64bit_4k_page_footer_t *) index_node_footer_data )->checksum,
		 stored_checksum );
		byte_stream_copy_to_uint64_little_endian(
		 ( (pff_index_node_64bit_4k_page_footer_t *) index_node_footer_data )->back_pointer,
		 index_node->back_pointer );

		byte_stream_copy_to_uint16_little_endian(
		 ( (pff_index_node_64bit_4k_page_footer_t *) index_node_footer_data )->number_of_entries,
		 index_node->number_of_entries );
		byte_stream_copy_to_uint16_little_endian(
		 ( (pff_index_node_64bit_4k_page_footer_t *) index_node_footer_data )->maximum_number_of_entries,
		 index_node->maximum_number_of_entries );

		index_node->entry_size = ( (pff_index_node_64bit_4k_page_footer_t *) index_node_footer_data )->entry_size;
		index_node->level      = ( (pff_index_node_64bit_4k_page_footer_t *) index_node_footer_data )->level;

		if( ( index_node->type == LIBPFF_INDEX_TYPE_DESCRIPTOR )
		 && ( index_node->level == LIBPFF_INDEX_NODE_LEVEL_LEAF ) )
		{
			calculated_entry_size                = 32;
			calculated_maximum_number_of_entries = 4056 / 32;
		}
		else
		{
			calculated_entry_size                = 24;
			calculated_maximum_number_of_entries = 4056 / 24;
		}
	}
#if defined( HAVE_DEBUG_OUTPUT )
	if( libcnotify_verbose != 0 )
	{
		libcnotify_printf(
		 "%s: number of entries\t\t\t\t: %" PRIu16 "\n",
		 function,
		 index_node->number_of_entries );

		libcnotify_printf(
		 "%s: maximum number of entries\t\t\t: %" PRIu16 "\n",
		 function,
		 index_node->maximum_number_of_entries );

		libcnotify_printf(
		 "%s: entry size\t\t\t\t\t: %" PRIu8 "\n",
		 function,
		 index_node->entry_size );

		libcnotify_printf(
		 "%s: node level\t\t\t\t\t: %" PRIu8 "\n",
		 function,
		 index_node->level );

		if( io_handle->file_type == LIBPFF_FILE_TYPE_64BIT )
		{
			libcnotify_printf(
			 "%s: padding:\n",
			 function );
			libcnotify_print_data(
			 ( (pff_index_node_64bit_footer_t *) index_node_footer_data )->padding1,
			 4,
			 0 );
		}
		else if( io_handle->file_type == LIBPFF_FILE_TYPE_64BIT_4K_PAGE )
		{
			libcnotify_printf(
			 "%s: padding:\n",
			 function );
			libcnotify_print_data(
			 ( (pff_index_node_64bit_4k_page_footer_t *) index_node_footer_data )->padding1,
			 10,
			 0 );
		}
		libcnotify_printf(
		 "%s: index node type\t\t\t\t\t: 0x%02" PRIx8 "\n",
		 function,
		 index_node->type );
		libcnotify_printf(
		 "%s: index node type copy\t\t\t\t: 0x%02" PRIx8 "\n",
		 function,
		 index_node_type_copy );

		if( io_handle->file_type == LIBPFF_FILE_TYPE_32BIT )
		{
			byte_stream_copy_to_uint16_little_endian(
			 ( (pff_index_node_32bit_footer_t *) index_node_footer_data )->signature,
			 value_16bit );
			libcnotify_printf(
			 "%s: signature\t\t\t\t\t: 0x%04" PRIx16 "\n",
			 function,
			 value_16bit );

			libcnotify_printf(
			 "%s: back pointer\t\t\t\t\t: 0x%08" PRIx64 "\n",
			 function,
			 index_node->back_pointer );
			libcnotify_printf(
			 "%s: checksum\t\t\t\t\t: 0x%08" PRIx32 "\n",
			 function,
			 stored_checksum );
		}
		else if( io_handle->file_type == LIBPFF_FILE_TYPE_64BIT )
		{
			byte_stream_copy_to_uint16_little_endian(
			 ( (pff_index_node_64bit_footer_t *) index_node_footer_data )->signature,
			 value_16bit );
			libcnotify_printf(
			 "%s: signature\t\t\t\t\t: 0x%04" PRIx16 "\n",
			 function,
			 value_16bit );

			libcnotify_printf(
			 "%s: checksum\t\t\t\t\t: 0x%08" PRIx32 "\n",
			 function,
			 stored_checksum );
			libcnotify_printf(
			 "%s: back pointer\t\t\t\t\t: 0x%08" PRIx64 "\n",
			 function,
			 index_node->back_pointer );
		}
		else if( io_handle->file_type == LIBPFF_FILE_TYPE_64BIT_4K_PAGE )
		{
			byte_stream_copy_to_uint16_little_endian(
			 ( (pff_index_node_64bit_4k_page_footer_t *) index_node_footer_data )->signature,
			 value_16bit );
			libcnotify_printf(
			 "%s: signature\t\t\t\t\t: 0x%04" PRIx16 "\n",
			 function,
			 value_16bit );

			libcnotify_printf(
			 "%s: checksum\t\t\t\t\t: 0x%08" PRIx32 "\n",
			 function,
			 stored_checksum );
			libcnotify_printf(
			 "%s: back pointer\t\t\t\t\t: 0x%08" PRIx64 "\n",
			 function,
			 index_node->back_pointer );

			byte_stream_copy_to_uint64_little_endian(
			 ( (pff_index_node_64bit_4k_page_footer_t *) index_node_footer_data )->unknown1,
			 value_64bit );
			libcnotify_printf(
			 "%s: unknown1\t\t\t\t\t: 0x%08" PRIx64 "\n",
			 function,
			 value_64bit );
		}
		libcnotify_printf(
		 "\n" );
	}
#endif

	if( index_node->type != index_node_type_copy )
	{
#if defined( HAVE_DEBUG_OUTPUT )
		if( libcnotify_verbose != 0 )
		{
			libcnotify_printf(
			 "%s: mismatch in index node type (0x%02" PRIx8 " != 0x%02" PRIx8 ").\n",
			 function,
			 index_node->type,
			 index_node_type_copy );
		}
#endif
		if( ( index_node->type != LIBPFF_INDEX_TYPE_DESCRIPTOR )
		 && ( index_node->type != LIBPFF_INDEX_TYPE_OFFSET )
		 && ( ( index_node_type_copy == LIBPFF_INDEX_TYPE_DESCRIPTOR )
		   || ( index_node_type_copy == LIBPFF_INDEX_TYPE_OFFSET ) ) )
		{
			index_node->type = index_node_type_copy;
		}
	}
	if( ( index_node->type != LIBPFF_INDEX_TYPE_DESCRIPTOR )
	 && ( index_node->type != LIBPFF_INDEX_TYPE_OFFSET ) )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
		 LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
		 "%s: unsupported index node type: 0x%02" PRIx8 ".",
		 function,
		 index_node->type );

		goto on_error;
	}
	if( io_handle->file_type == LIBPFF_FILE_TYPE_32BIT )
	{
		result = libfmapi_checksum_calculate_weak_crc32(
		          &calculated_checksum,
		          index_node->data,
		          500,
		          0,
		          error );
	}
	else if( io_handle->file_type == LIBPFF_FILE_TYPE_64BIT )
	{
		result = libfmapi_checksum_calculate_weak_crc32(
		          &calculated_checksum,
		          index_node->data,
		          496,
		          0,
		          error );
	}
	else if( io_handle->file_type == LIBPFF_FILE_TYPE_64BIT_4K_PAGE )
	{
		result = libfmapi_checksum_calculate_weak_crc32(
		          &calculated_checksum,
		          index_node->data,
		          4072,
		          0,
		          error );
	}
	if( result != 1 )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
		 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
		 "%s: unable to calculate weak CRC-32.",
		 function );

		goto on_error;
	}
	if( stored_checksum != calculated_checksum )
	{
#if defined( HAVE_DEBUG_OUTPUT )
		if( libcnotify_verbose != 0 )
		{
			libcnotify_printf(
			 "%s: mismatch in checksum ( 0x%08" PRIx32 " != 0x%08" PRIx32 " ).\n",
			 function,
			 stored_checksum,
			 calculated_checksum );
		}
#endif
		/* TODO smart error handling */
	}
	if( ( index_node->entry_size != 0 )
	 && ( index_node->entry_size != calculated_entry_size ) )
	{
#if defined( HAVE_DEBUG_OUTPUT )
		if( libcnotify_verbose != 0 )
		{
			libcnotify_printf(
			 "%s: entry size mismatch (calculated: %" PRIu8 ", stored: %" PRIu8 ").\n",
			 function,
			 calculated_entry_size,
			 index_node->entry_size );
		}
#endif
		index_node->entry_size = calculated_entry_size;
	}
	if( ( index_node->maximum_number_of_entries != 0 )
	 && ( index_node->maximum_number_of_entries != calculated_maximum_number_of_entries ) )
	{
#if defined( HAVE_DEBUG_OUTPUT )
		if( libcnotify_verbose != 0 )
		{
			libcnotify_printf(
			 "%s: maximum number of entries mismatch (calculated: %" PRIu8 ", stored: %" PRIu8 ").\n",
			 function,
			 calculated_maximum_number_of_entries,
			 index_node->maximum_number_of_entries );
		}
#endif
		index_node->maximum_number_of_entries = calculated_maximum_number_of_entries;
	}
	if( index_node->number_of_entries > index_node->maximum_number_of_entries )
	{
#if defined( HAVE_DEBUG_OUTPUT )
		if( libcnotify_verbose != 0 )
		{
			libcnotify_printf(
			 "%s: number of entries: %" PRIu8 ", exceeds maximum: %" PRIu8 ".",
			 function,
			 index_node->number_of_entries,
			 index_node->maximum_number_of_entries );
		}
#endif
		index_node->number_of_entries = index_node->maximum_number_of_entries;
	}
	if( ( (uint16_t) index_node->number_of_entries * (uint16_t) index_node->entry_size ) > index_node->maximum_entries_data_size )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
		 LIBCERROR_RUNTIME_ERROR_VALUE_EXCEEDS_MAXIMUM,
		 "%s: size of entries: %" PRIu16 ", exceeds maximum: %" PRIu16 ".",
		 function,
		 index_node->number_of_entries * index_node->entry_size,
		 index_node->maximum_entries_data_size );

		goto on_error;
	}
#if defined( HAVE_DEBUG_OUTPUT )
	if( libcnotify_verbose != 0 )
	{
		index_node_entry_data      = index_node->data;
		index_node_entry_data_size = index_node->maximum_entries_data_size;

		/* Print all the entries
		 */
		for( entry_index = 0;
		     entry_index < index_node->maximum_number_of_entries;
		     entry_index++ )
		{
			if( entry_index == index_node->number_of_entries )
			{
				result = libpff_index_node_check_for_empty_block(
					  index_node_entry_data,
					  index_node_entry_data_size,
					  error );

				if( result == -1 )
				{
					libcerror_error_set(
					 error,
					 LIBCERROR_ERROR_DOMAIN_RUNTIME,
					 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
					 "%s: unable to determine if remaining index nodes are empty.",
					 function );

					return( -1 );
				}
				else if( result != 0 )
				{
					break;
				}
				libcnotify_printf(
				 "\n" );
				libcnotify_printf(
				 "%s: remaining node entries\n",
				 function );
			}
			if( io_handle->file_type == LIBPFF_FILE_TYPE_32BIT )
			{
				byte_stream_copy_to_uint32_little_endian(
				 index_node_entry_data,
				 value_64bit );
			}
			else if( ( io_handle->file_type == LIBPFF_FILE_TYPE_64BIT )
			      || ( io_handle->file_type == LIBPFF_FILE_TYPE_64BIT_4K_PAGE ) )
			{
				byte_stream_copy_to_uint64_little_endian(
				 index_node_entry_data,
				 value_64bit );
			}
			libcnotify_printf(
			 "%s: entry: %03" PRIu16 " index node identifier\t\t: 0x%08" PRIx64 " (%" PRIu64 ")\n",
			 function,
			 entry_index,
			 value_64bit,
			 value_64bit );

			/* Process descriptor index node leaf nodes
			 */
			if( ( index_node->type == LIBPFF_INDEX_TYPE_DESCRIPTOR )
			 && ( index_node->level == LIBPFF_INDEX_NODE_LEVEL_LEAF ) )
			{
				if( io_handle->file_type == LIBPFF_FILE_TYPE_32BIT )
				{
					byte_stream_copy_to_uint32_little_endian(
					 ( (pff_index_node_descriptor_entry_32bit_t *) index_node_entry_data )->data_identifier,
					 value_64bit );
				}
				else if( ( io_handle->file_type == LIBPFF_FILE_TYPE_64BIT )
				      || ( io_handle->file_type == LIBPFF_FILE_TYPE_64BIT_4K_PAGE ) )
				{
					byte_stream_copy_to_uint64_little_endian(
					 ( (pff_index_node_descriptor_entry_64bit_t *) index_node_entry_data )->data_identifier,
					 value_64bit );
				}
				libcnotify_printf(
				 "%s: entry: %03" PRIu16 " data identifier\t\t\t: 0x%08" PRIx64 " (%" PRIu64 ")\n",
				 function,
				 entry_index,
				 value_64bit,
				 value_64bit );

				if( io_handle->file_type == LIBPFF_FILE_TYPE_32BIT )
				{
					byte_stream_copy_to_uint32_little_endian(
					 ( (pff_index_node_descriptor_entry_32bit_t *) index_node_entry_data )->local_descriptors_identifier,
					 value_64bit );
				}
				else if( ( io_handle->file_type == LIBPFF_FILE_TYPE_64BIT )
				      || ( io_handle->file_type == LIBPFF_FILE_TYPE_64BIT_4K_PAGE ) )
				{
					byte_stream_copy_to_uint64_little_endian(
					 ( (pff_index_node_descriptor_entry_64bit_t *) index_node_entry_data )->local_descriptors_identifier,
					 value_64bit );
				}
				libcnotify_printf(
				 "%s: entry: %03" PRIu16 " local descriptors identifier\t\t: 0x%08" PRIx64 " (%" PRIu64 ")\n",
				 function,
				 entry_index,
				 value_64bit,
				 value_64bit );

				if( io_handle->file_type == LIBPFF_FILE_TYPE_32BIT )
				{
					byte_stream_copy_to_uint32_little_endian(
					 ( (pff_index_node_descriptor_entry_32bit_t *) index_node_entry_data )->parent_identifier,
					 value_32bit );
				}
				else if( ( io_handle->file_type == LIBPFF_FILE_TYPE_64BIT )
				      || ( io_handle->file_type == LIBPFF_FILE_TYPE_64BIT_4K_PAGE ) )
				{
					byte_stream_copy_to_uint32_little_endian(
					 ( (pff_index_node_descriptor_entry_64bit_t *) index_node_entry_data )->parent_identifier,
					 value_32bit );
				}
				libcnotify_printf(
				 "%s: entry: %03" PRIu16 " parent identifier\t\t\t: 0x%08" PRIx32 " (%" PRIu32 ")\n",
				 function,
				 entry_index,
				 value_32bit,
				 value_32bit );

				if( ( io_handle->file_type == LIBPFF_FILE_TYPE_64BIT )
				 || ( io_handle->file_type == LIBPFF_FILE_TYPE_64BIT_4K_PAGE ) )
				{
					byte_stream_copy_to_uint32_little_endian(
					 ( (pff_index_node_descriptor_entry_64bit_t *) index_node_entry_data )->unknown1,
					 value_32bit );

					libcnotify_printf(
					 "%s: entry: %03" PRIu16 " unknown1\t\t\t\t: 0x%08" PRIx32 " (%" PRIu32 ")\n",
					 function,
					 entry_index,
					 value_32bit,
					 value_32bit );
				}
			}
			/* Process offset and descriptor index node branch nodes and offset index node leaf nodes
			 */
			else
			{
				if( index_node->level != LIBPFF_INDEX_NODE_LEVEL_LEAF )
				{
					if( io_handle->file_type == LIBPFF_FILE_TYPE_32BIT )
					{
						byte_stream_copy_to_uint32_little_endian(
						 ( (pff_index_node_branch_entry_32bit_t *) index_node_entry_data )->back_pointer,
						 value_64bit );
					}
					else if( ( io_handle->file_type == LIBPFF_FILE_TYPE_64BIT )
					      || ( io_handle->file_type == LIBPFF_FILE_TYPE_64BIT_4K_PAGE ) )
					{
						byte_stream_copy_to_uint64_little_endian(
						 ( (pff_index_node_branch_entry_64bit_t *) index_node_entry_data )->back_pointer,
						 value_64bit );
					}
					libcnotify_printf(
					 "%s: entry: %03" PRIu16 " back pointer\t\t\t\t: 0x%08" PRIx64 "\n",
					 function,
					 entry_index,
					 value_64bit );
				}
				if( index_node->level == LIBPFF_INDEX_NODE_LEVEL_LEAF )
				{
					if( io_handle->file_type == LIBPFF_FILE_TYPE_32BIT )
					{
						byte_stream_copy_to_uint32_little_endian(
						 ( (pff_index_node_offset_entry_32bit_t *) index_node_entry_data )->file_offset,
						 value_64bit );
					}
					else if( ( io_handle->file_type == LIBPFF_FILE_TYPE_64BIT )
					      || ( io_handle->file_type == LIBPFF_FILE_TYPE_64BIT_4K_PAGE ) )
					{
						byte_stream_copy_to_uint64_little_endian(
						 ( (pff_index_node_offset_entry_64bit_t *) index_node_entry_data )->file_offset,
						 value_64bit );
					}
				}
				else
				{
					if( io_handle->file_type == LIBPFF_FILE_TYPE_32BIT )
					{
						byte_stream_copy_to_uint32_little_endian(
						 ( (pff_index_node_branch_entry_32bit_t *) index_node_entry_data )->file_offset,
						 value_64bit );
					}
					else if( ( io_handle->file_type == LIBPFF_FILE_TYPE_64BIT )
					      || ( io_handle->file_type == LIBPFF_FILE_TYPE_64BIT_4K_PAGE ) )
					{
						byte_stream_copy_to_uint64_little_endian(
						 ( (pff_index_node_branch_entry_64bit_t *) index_node_entry_data )->file_offset,
						 value_64bit );
					}
				}
				libcnotify_printf(
				 "%s: entry: %03" PRIu16 " file offset\t\t\t\t: 0x%08" PRIx64 " (%" PRIu64 ")\n",
				 function,
				 entry_index,
				 value_64bit,
				 value_64bit );

				if( index_node->level == LIBPFF_INDEX_NODE_LEVEL_LEAF )
				{
					if( io_handle->file_type == LIBPFF_FILE_TYPE_32BIT )
					{
						byte_stream_copy_to_uint16_little_endian(
						 ( (pff_index_node_offset_entry_32bit_t *) index_node_entry_data )->data_size,
						 value_16bit );
					}
					else if( ( io_handle->file_type == LIBPFF_FILE_TYPE_64BIT )
					      || ( io_handle->file_type == LIBPFF_FILE_TYPE_64BIT_4K_PAGE ) )
					{
						byte_stream_copy_to_uint16_little_endian(
						 ( (pff_index_node_offset_entry_64bit_t *) index_node_entry_data )->data_size,
						 value_16bit );
					}
					libcnotify_printf(
					 "%s: entry: %03" PRIu16 " data size\t\t\t\t: %" PRIu16 "\n",
					 function,
					 entry_index,
					 value_16bit );

					if( io_handle->file_type == LIBPFF_FILE_TYPE_32BIT )
					{
						byte_stream_copy_to_uint16_little_endian(
						 ( (pff_index_node_offset_entry_32bit_t *) index_node_entry_data )->reference_count,
						 value_16bit );
					}
					else if( ( io_handle->file_type == LIBPFF_FILE_TYPE_64BIT )
					      || ( io_handle->file_type == LIBPFF_FILE_TYPE_64BIT_4K_PAGE ) )
					{
						byte_stream_copy_to_uint16_little_endian(
						 ( (pff_index_node_offset_entry_64bit_t *) index_node_entry_data )->reference_count,
						 value_16bit );
					}
					libcnotify_printf(
					 "%s: entry: %03" PRIu16 " reference count\t\t\t: %" PRIu16 "\n",
					 function,
					 entry_index,
					 value_16bit );

					if( ( io_handle->file_type == LIBPFF_FILE_TYPE_64BIT )
					 || ( io_handle->file_type == LIBPFF_FILE_TYPE_64BIT_4K_PAGE ) )
					{
						byte_stream_copy_to_uint32_little_endian(
						 ( (pff_index_node_offset_entry_64bit_t *) index_node_entry_data )->data_allocation_table_file_offset,
						 value_32bit );

						libcnotify_printf(
						 "%s: entry: %03" PRIu16 " data allocation table offset\t\t: 0x%08" PRIx32 " (%" PRIu32 ")\n",
						 function,
						 entry_index,
						 value_32bit,
						 value_32bit );
					}
				}
			}
			index_node_entry_data      += index_node->entry_size;
			index_node_entry_data_size -= index_node->entry_size;
		}
		libcnotify_printf(
		 "\n" );
	}
#endif
	index_node->entries_data = index_node->data;

	return( 1 );

on_error:
	if( index_node->data != NULL )
	{
		memory_free(
		 index_node->data );

		index_node->data = NULL;
	}
	return( -1 );
}
Пример #22
0
/* Reads the file header
 * Returns 1 if successful or -1 on error
 */
int libevt_io_handle_read_file_header(
     libevt_io_handle_t *io_handle,
     libbfio_handle_t *file_io_handle,
     uint32_t *first_record_offset,
     uint32_t *end_of_file_record_offset,
     libcerror_error_t **error )
{
	evt_file_header_t file_header;

	static char *function = "libevt_io_handle_read_file_header";
	ssize_t read_count    = 0;
	uint32_t size         = 0;
	uint32_t size_copy    = 0;

#if defined( HAVE_DEBUG_OUTPUT )
	uint32_t value_32bit  = 0;
#endif

	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( first_record_offset == NULL )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
		 "%s: invalid first record offset.",
		 function );

		return( -1 );
	}
	if( end_of_file_record_offset == NULL )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
		 "%s: invalid end of file record offset.",
		 function );

		return( -1 );
	}
	if( libbfio_handle_get_size(
	     file_io_handle,
	     &( io_handle->file_size ),
	     error ) != 1 )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
		 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
		 "%s: unable to retrieve file size.",
		 function );

		return( -1 );
	}
#if defined( HAVE_DEBUG_OUTPUT )
	if( libcnotify_verbose != 0 )
	{
		libcnotify_printf(
		 "%s: reading file header at offset: 0 (0x00000000)\n",
		 function );
	}
#endif
	if( libbfio_handle_seek_offset(
	     file_io_handle,
	     0,
	     SEEK_SET,
	     error ) == -1 )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_IO,
		 LIBCERROR_IO_ERROR_SEEK_FAILED,
		 "%s: unable to seek file header offset: 0.",
		 function );

		return( -1 );
	}
	read_count = libbfio_handle_read_buffer(
	              file_io_handle,
	              (uint8_t *) &file_header,
	              sizeof( evt_file_header_t ),
	              error );

	if( read_count != (ssize_t) sizeof( evt_file_header_t ) )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_IO,
		 LIBCERROR_IO_ERROR_READ_FAILED,
		 "%s: unable to read file header.",
		 function );

		return( -1 );
	}
#if defined( HAVE_DEBUG_OUTPUT )
	if( libcnotify_verbose != 0 )
	{
		libcnotify_printf(
		 "%s: file header:\n",
		 function );
		libcnotify_print_data(
		 (uint8_t *) &file_header,
		 sizeof( evt_file_header_t ),
		 0 );
	}
#endif
	if( memory_compare(
	     file_header.signature,
	     evt_file_signature,
	     4 ) != 0 )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
		 LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
		 "%s: unsupported file signature.",
		 function );

		return( -1 );
	}
	byte_stream_copy_to_uint32_little_endian(
	 file_header.size,
	 size );

	byte_stream_copy_to_uint32_little_endian(
	 file_header.major_version,
	 io_handle->major_version );

	byte_stream_copy_to_uint32_little_endian(
	 file_header.minor_version,
	 io_handle->minor_version );

	byte_stream_copy_to_uint32_little_endian(
	 file_header.first_record_offset,
	 *first_record_offset );

	byte_stream_copy_to_uint32_little_endian(
	 file_header.end_of_file_record_offset,
	 *end_of_file_record_offset );

	byte_stream_copy_to_uint32_little_endian(
	 file_header.file_flags,
	 io_handle->file_flags );

	byte_stream_copy_to_uint32_little_endian(
	 file_header.size_copy,
	 size_copy );

#if defined( HAVE_DEBUG_OUTPUT )
	if( libcnotify_verbose != 0 )
	{
		libcnotify_printf(
		 "%s: size\t\t\t\t\t: %" PRIu32 "\n",
		 function,
		 size );

		libcnotify_printf(
		 "%s: signature\t\t\t\t: %c%c%c%c\n",
		 function,
		 file_header.signature[ 0 ],
		 file_header.signature[ 1 ],
		 file_header.signature[ 2 ],
		 file_header.signature[ 3 ] );

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

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

		libcnotify_printf(
		 "%s: first record offset\t\t\t: 0x%08" PRIx32 "\n",
		 function,
		 *first_record_offset );

		libcnotify_printf(
		 "%s: end of file record offset\t\t: 0x%08" PRIx32 "\n",
		 function,
		 *end_of_file_record_offset );

		byte_stream_copy_to_uint32_little_endian(
		 file_header.last_record_number,
		 value_32bit );
		libcnotify_printf(
		 "%s: last record number\t\t\t: %" PRIu32 "\n",
		 function,
		 value_32bit );

		byte_stream_copy_to_uint32_little_endian(
		 file_header.first_record_number,
		 value_32bit );
		libcnotify_printf(
		 "%s: first record number\t\t\t: %" PRIu32 "\n",
		 function,
		 value_32bit );

		libcnotify_printf(
		 "%s: file flags\t\t\t\t: 0x%08" PRIx32 "\n",
		 function,
		 io_handle->file_flags );
		libevt_debug_print_file_flags(
		 io_handle->file_flags );
		libcnotify_printf(
		 "\n" );

		byte_stream_copy_to_uint32_little_endian(
		 file_header.retention,
		 value_32bit );
		libcnotify_printf(
		 "%s: retention\t\t\t\t: 0x%08" PRIx32 "\n",
		 function,
		 value_32bit );

		libcnotify_printf(
		 "%s: size copy\t\t\t\t: %" PRIu32 "\n",
		 function,
		 size_copy );

		libcnotify_printf(
		 "\n" );
	}
#endif
	if( size != size_copy )
	{
#if defined( HAVE_DEBUG_OUTPUT )
		if( libcnotify_verbose != 0 )
		{
			libcnotify_printf(
			 "%s: value mismatch for size and copy ( %" PRIu32 " != %" PRIu32 " ).\n",
			 function,
			 size,
			 size_copy );
		}
#endif
		/* If the size does not match the header size assume size copy contains
		 * the correct value for the next validation check
		 */
		if( size != sizeof( evt_file_header_t ) )
		{
			size = size_copy;
		}
		io_handle->flags |= LIBEVT_IO_HANDLE_FLAG_IS_CORRUPTED;
	}
	if( (size_t) size != sizeof( evt_file_header_t ) )
	{
#if defined( HAVE_DEBUG_OUTPUT )
		if( libcnotify_verbose != 0 )
		{
			libcnotify_printf(
			 "%s: size: %" PRIu32 " does not match header size.\n",
			 function,
			 size );
		}
#endif
		io_handle->flags |= LIBEVT_IO_HANDLE_FLAG_IS_CORRUPTED;
	}
	return( 1 );
}
Пример #23
0
/* Reads cluster block
 * Returns 1 if successful or -1 on error
 */
int libqcow_cluster_block_read(
     libqcow_cluster_block_t *cluster_block,
     libbfio_handle_t *file_io_handle,
     off64_t cluster_block_offset,
     libcerror_error_t **error )
{
	static char *function = "libqcow_cluster_block_read";
	ssize_t read_count    = 0;

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

		return( -1 );
	}
	if( cluster_block->data == NULL )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
		 LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
		 "%s: invalid cluster block - missing data.",
		 function );

		return( -1 );
	}
#if defined( HAVE_DEBUG_OUTPUT )
	if( libcnotify_verbose != 0 )
	{
		libcnotify_printf(
		 "%s: reading cluster block at offset: %" PRIi64 " (0x%08" PRIx64 ")\n",
		 function,
		 cluster_block_offset,
		 cluster_block_offset );
	}
#endif
	if( libbfio_handle_seek_offset(
	     file_io_handle,
	     cluster_block_offset,
	     SEEK_SET,
	     error ) == -1 )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_IO,
		 LIBCERROR_IO_ERROR_SEEK_FAILED,
		 "%s: unable to seek cluster block offset: %" PRIi64 " (0x%08" PRIx64 ").",
		 function,
		 cluster_block_offset,
		 cluster_block_offset );

		return( -1 );
	}
	read_count = libbfio_handle_read_buffer(
		      file_io_handle,
		      cluster_block->data,
		      cluster_block->data_size,
		      error );

	if( read_count != (ssize_t) cluster_block->data_size )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_IO,
		 LIBCERROR_IO_ERROR_READ_FAILED,
		 "%s: unable to read cluster block.",
		 function );

		return( -1 );
	}
#if defined( HAVE_DEBUG_OUTPUT )
	if( libcnotify_verbose != 0 )
	{
		libcnotify_printf(
		 "%s: cluster block:\n",
		 function );
		libcnotify_print_data(
		 cluster_block->data,
		 cluster_block->data_size,
		 LIBCNOTIFY_PRINT_DATA_FLAG_GROUP_DATA );
	}
#endif
	return( 1 );
}
Пример #24
0
/* Scans for the end-of-file record and adjusts the offsets accordingly
 * Returns 1 if successful, 0 if not or -1 on error
 */
int libevt_io_handle_end_of_file_record_scan(
     libevt_io_handle_t *io_handle,
     libbfio_handle_t *file_io_handle,
     uint32_t *first_record_offset,
     uint32_t *end_of_file_record_offset,
     libcerror_error_t **error )
{
	uint8_t *scan_block         = NULL;
	static char *function       = "libevt_io_handle_end_of_file_record_scan";
	off64_t file_offset         = 0;
	off64_t initial_file_offset = 0;
	size_t read_size            = 0;
	size_t scan_block_offset    = 0;
	size_t scan_block_size      = 8192;
	ssize_t read_count          = 0;
	uint8_t scan_state          = LIBEVT_RECOVER_SCAN_STATE_START;
	uint8_t scan_has_wrapped    = 0;

	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( first_record_offset == NULL )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
		 "%s: invalid first record offset.",
		 function );

		return( -1 );
	}
	if( end_of_file_record_offset == NULL )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
		 "%s: invalid end of file record offset.",
		 function );

		return( -1 );
	}
	scan_block = (uint8_t *) memory_allocate(
				  sizeof( uint8_t ) * scan_block_size );

	if( scan_block == NULL )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_MEMORY,
		 LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
		 "%s: unable to create scan block.",
		 function );

		goto on_error;
	}
	/* If the file has wrapped start looking for the end-of-file record after the end-of-file record offset
	 */
	file_offset = (off64_t) *end_of_file_record_offset;

	if( ( file_offset < (off64_t) sizeof( evt_file_header_t ) )
	 || ( (size64_t) file_offset >= io_handle->file_size ) )
	{
		file_offset = (off64_t) sizeof( evt_file_header_t );
	}
	initial_file_offset = file_offset;

	if( libbfio_handle_seek_offset(
	     file_io_handle,
	     file_offset,
	     SEEK_SET,
	     error ) == -1 )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_IO,
		 LIBCERROR_IO_ERROR_SEEK_FAILED,
		 "%s: unable to seek scan block offset: %" PRIi64 ".",
		 function,
		 file_offset );

		goto on_error;
	}
	do
	{
		if( ( (size64_t) file_offset + scan_block_size ) > io_handle->file_size )
		{
			read_size = (size_t) ( io_handle->file_size - file_offset );
		}
		else
		{
			read_size = scan_block_size;
		}
		read_count = libbfio_handle_read_buffer(
			      file_io_handle,
			      scan_block,
			      read_size,
			      error );

		if( read_count != (ssize_t) read_size )
		{
			libcerror_error_set(
			 error,
			 LIBCERROR_ERROR_DOMAIN_IO,
			 LIBCERROR_IO_ERROR_READ_FAILED,
			 "%s: unable to read scan block at offset: %" PRIi64 ".",
			 function,
			 file_offset );

			goto on_error;
		}
		file_offset += read_count;

		for( scan_block_offset = 0;
		     scan_block_offset < read_size;
		     scan_block_offset += 4 )
		{
			if( scan_state == LIBEVT_RECOVER_SCAN_STATE_START )
			{
				if( memory_compare(
				     &( scan_block[ scan_block_offset ] ),
				     evt_end_of_file_record_signature1,
				     4 ) == 0 )
				{
					scan_state = LIBEVT_RECOVER_SCAN_STATE_FOUND_EOF_SIGNATURE1;
				}
			}
			else if( scan_state == LIBEVT_RECOVER_SCAN_STATE_FOUND_EOF_SIGNATURE1 )
			{
				if( memory_compare(
				     &( scan_block[ scan_block_offset ] ),
				     evt_end_of_file_record_signature2,
				     4 ) == 0 )
				{
					scan_state = LIBEVT_RECOVER_SCAN_STATE_FOUND_EOF_SIGNATURE2;
				}
				else
				{
					scan_state = LIBEVT_RECOVER_SCAN_STATE_START;
				}
			}
			else if( scan_state == LIBEVT_RECOVER_SCAN_STATE_FOUND_EOF_SIGNATURE2 )
			{
				if( memory_compare(
				     &( scan_block[ scan_block_offset ] ),
				     evt_end_of_file_record_signature3,
				     4 ) == 0 )
				{
					scan_state = LIBEVT_RECOVER_SCAN_STATE_FOUND_EOF_SIGNATURE3;
				}
				else
				{
					scan_state = LIBEVT_RECOVER_SCAN_STATE_START;
				}
			}
			else if( scan_state == LIBEVT_RECOVER_SCAN_STATE_FOUND_EOF_SIGNATURE3 )
			{
				if( memory_compare(
				     &( scan_block[ scan_block_offset ] ),
				     evt_end_of_file_record_signature4,
				     4 ) == 0 )
				{
					*end_of_file_record_offset = (uint32_t) ( file_offset - read_count + scan_block_offset - 16 );

					scan_state = LIBEVT_RECOVER_SCAN_STATE_FOUND_EOF_SIGNATURE4;
				}
				else
				{
					scan_state = LIBEVT_RECOVER_SCAN_STATE_START;
				}
			}
			else if( scan_state == LIBEVT_RECOVER_SCAN_STATE_FOUND_EOF_SIGNATURE4 )
			{
				if( memory_compare(
				     &( scan_block[ scan_block_offset ] ),
				     evt_file_signature,
				     4 ) == 0 )
				{
					*first_record_offset = (uint32_t) ( file_offset - read_count + scan_block_offset - 4 );

					scan_state = LIBEVT_RECOVER_SCAN_STATE_FOUND_RECORD_SIGNATURE;

					break;
				}
			}
		}
		if( scan_state == LIBEVT_RECOVER_SCAN_STATE_FOUND_RECORD_SIGNATURE )
		{
			break;
		}
		if( (size64_t) file_offset >= io_handle->file_size )
		{
			if( libbfio_handle_seek_offset(
			     file_io_handle,
			     (off64_t) sizeof( evt_file_header_t ),
			     SEEK_SET,
			     error ) == -1 )
			{
				libcerror_error_set(
				 error,
				 LIBCERROR_ERROR_DOMAIN_IO,
				 LIBCERROR_IO_ERROR_SEEK_FAILED,
				 "%s: unable to seek scan block offset: %" PRIzd ".",
				 function,
				 sizeof( evt_file_header_t ) );

				goto on_error;
			}
			file_offset = (off64_t) sizeof( evt_file_header_t );

			scan_has_wrapped = 1;
		}
	}
	while( ( scan_has_wrapped == 0 )
	    || ( file_offset < initial_file_offset ) );

	memory_free(
	 scan_block );

	scan_block = NULL;

	if( scan_state == LIBEVT_RECOVER_SCAN_STATE_FOUND_RECORD_SIGNATURE )
	{
		return( 1 );
	}
	return( 0 );

on_error:
	if( scan_block != NULL )
	{
		memory_free(
		 scan_block );
	}
	return( -1 );
}
Пример #25
0
/* Reads a data block and determines its entries
 * Returns 1 if successful or -1 on error
 */
int libcreg_data_block_read_entries(
     libcreg_data_block_t *data_block,
     libbfio_handle_t *file_io_handle,
     int (*read_entry_size_function)(
            const uint8_t *data,
            size_t data_size,
            size_t *entry_size,
            libcerror_error_t **error ),
     int ascii_codepage,
     uint8_t have_debug_output LIBCREG_ATTRIBUTE_UNUSED,
     libcerror_error_t **error )
{
	libcreg_data_block_entry_t *data_block_entry = NULL;
	uint8_t *data_block_entry_data               = NULL;
	static char *function                        = "libcreg_data_block_read_entries";
	size_t data_block_data_size                  = 0;
	size_t data_block_entry_offset               = 0;
	ssize_t read_count                           = 0;
	int entry_index                              = 0;
	int data_block_entry_index                   = 0;

#if defined( HAVE_DEBUG_OUTPUT )
	libcreg_key_name_entry_t *key_name_entry     = NULL;
#else
	LIBCREG_UNREFERENCED_PARAMETER( have_debug_output );
#endif

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

		return( -1 );
	}
	if( data_block->data != NULL )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
		 LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
		 "%s: invalid data block - data already set.",
		 function );

		return( -1 );
	}
#if SIZEOF_SIZE_T <= 4
	if( data_block->size > (size_t) SSIZE_MAX )
#else
	if( data_block->size > (uint32_t) SSIZE_MAX )
#endif
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
		 LIBCERROR_RUNTIME_ERROR_VALUE_EXCEEDS_MAXIMUM,
		 "%s: invalid data block - size value exceeds maximum.",
		 function );

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

		return( -1 );
	}
	data_block->data_size = (size_t) data_block->size - sizeof( creg_data_block_header_t );

	data_block->data = (uint8_t *) memory_allocate(
	                                sizeof( uint8_t ) * data_block->data_size );
	
	if( data_block->data == NULL )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_MEMORY,
		 LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
		 "%s: unable to create data block data.",
		 function );

		goto on_error;
	}
	read_count = libbfio_handle_read_buffer(
	              file_io_handle,
	              data_block->data,
	              data_block->data_size,
	              error );

	if( read_count != (ssize_t) data_block->data_size )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_IO,
		 LIBCERROR_IO_ERROR_READ_FAILED,
		 "%s: unable to read data block data.",
		 function );

		goto on_error;
	}
	data_block_entry_data = data_block->data;

	if( (int32_t) data_block->used_size < 0 )
	{
		data_block_data_size = data_block->data_size;
	}
	else
	{
		data_block_data_size = (size_t) data_block->used_size - sizeof( creg_data_block_header_t );
	}
	while( data_block_entry_offset < data_block_data_size )
	{
		if( libcreg_data_block_entry_initialize(
		     &data_block_entry,
		     error ) != 1 )
		{
			libcerror_error_set(
			 error,
			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
			 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
			 "%s: unable to create data block entry.",
			 function );

			goto on_error;
		}
		if( read_entry_size_function(
		     &( data_block_entry_data[ data_block_entry_offset ] ),
		     data_block->data_size - data_block_entry_offset,
		     &( data_block_entry->size ),
		     error ) != 1 )
		{
			libcerror_error_set(
			 error,
			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
			 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
			 "%s: unable to retrieve data block entry size.",
			 function );

			goto on_error;
		}
#if defined( HAVE_DEBUG_OUTPUT )
		if( libcnotify_verbose != 0 )
		{
			libcnotify_printf(
			 "%s: data block entry: %03d offset\t\t: %" PRIzd "\n",
			 function,
			 data_block_entry_index,
			 data_block_entry_offset );

			libcnotify_printf(
			 "%s: data block entry: %03d size\t\t: %" PRIzd "\n",
			 function,
			 data_block_entry_index,
			 data_block_entry->size );
		}
#endif
		data_block_entry->offset = data_block_entry_offset;

#if defined( HAVE_DEBUG_OUTPUT )
		if( ( libcnotify_verbose != 0 )
		 && ( have_debug_output != 0 ) )
		{
			if( libcreg_key_name_entry_initialize(
			     &key_name_entry,
			     error ) != 1 )
			{
				libcerror_error_set(
				 error,
				 LIBCERROR_ERROR_DOMAIN_RUNTIME,
				 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
				 "%s: unable to create key name entry.",
				 function );

				goto on_error;
			}
			if( libcreg_key_name_entry_read_data(
			     key_name_entry,
			     &( ( data_block->data )[ data_block_entry->offset ] ),
			     data_block_entry->size,
			     ascii_codepage,
			     error ) != 1 )
			{
				libcerror_error_set(
				 error,
				 LIBCERROR_ERROR_DOMAIN_IO,
				 LIBCERROR_IO_ERROR_READ_FAILED,
				 "%s: unable to read key name entry: %d.",
				 function,
				 data_block_entry_index );

				goto on_error;
			}
			if( libcreg_key_name_entry_free(
			     &key_name_entry,
			     error ) != 1 )
			{
				libcerror_error_set(
				 error,
				 LIBCERROR_ERROR_DOMAIN_RUNTIME,
				 LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
				 "%s: unable to free key name entry.",
				 function );

				goto on_error;
			}
		}
#endif
		data_block_entry_offset += (size_t) data_block_entry->size;

		if( libcdata_array_append_entry(
		     data_block->entries_array,
		     &entry_index,
		     (intptr_t *) data_block_entry,
		     error ) != 1 )
		{
			libcerror_error_set(
			 error,
			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
			 LIBCERROR_RUNTIME_ERROR_APPEND_FAILED,
			 "%s: unable to append data block entry: %d.",
			 function,
			 data_block_entry_index );

			goto on_error;
		}
		data_block_entry = NULL;

		data_block_entry_index++;
	}
#if defined( HAVE_DEBUG_OUTPUT )
	if( ( libcnotify_verbose != 0 )
	 && ( have_debug_output != 0 ) )
	{
		if( data_block_entry_offset < data_block->data_size )
		{
			libcnotify_printf(
			 "%s: trailing data:\n",
			 function );
			libcnotify_print_data(
			 &( ( data_block->data )[ data_block_entry_offset ] ),
			 data_block->data_size - data_block_entry_offset,
			 LIBCNOTIFY_PRINT_DATA_FLAG_GROUP_DATA );
		}
		else
		{
			libcnotify_printf(
			 "\n" );
		}
	}
#endif
	return( 1 );

on_error:
#if defined( HAVE_DEBUG_OUTPUT )
	if( key_name_entry != NULL )
	{
		libcreg_key_name_entry_free(
		 &key_name_entry,
		 NULL );
	}
#endif
	if( data_block_entry != NULL )
	{
		libcreg_data_block_entry_free(
		 &data_block_entry,
		 NULL );
	}
	if( data_block->entries_array != NULL )
	{
		libcdata_array_clear(
		 data_block->entries_array,
		 (int (*)(intptr_t **, libcerror_error_t **)) &libcreg_data_block_entry_free,
		 NULL );
	}
	if( data_block->data != NULL )
	{
		memory_free(
		 data_block->data );

		data_block->data = NULL;
	}
	data_block->data_size = 0;

	return( -1 );
}
Пример #26
0
/* Scans for the event record and adds them to the recovered records array
 * Returns 1 if successful, 0 if not or -1 on error
 */
int libevt_io_handle_event_record_scan(
     libevt_io_handle_t *io_handle,
     libbfio_handle_t *file_io_handle,
     off64_t file_offset,
     size64_t size,
     libfdata_list_t *recovered_records_list,
     libcerror_error_t **error )
{
	libevt_record_values_t *record_values = NULL;
	uint8_t *scan_block                   = NULL;
	static char *function                 = "libevt_io_handle_event_record_scan";
	off64_t record_offset                 = 0;
	size_t read_size                      = 0;
	size_t scan_block_offset              = 0;
	size_t scan_block_size                = 8192;
	ssize_t read_count                    = 0;
	int element_index                     = 0;

	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( file_offset < 0 )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
		 LIBCERROR_ARGUMENT_ERROR_VALUE_LESS_THAN_ZERO,
		 "%s: invalid file offset value less than zero.",
		 function );

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

		return( -1 );
	}
	scan_block = (uint8_t *) memory_allocate(
				  sizeof( uint8_t ) * scan_block_size );

	if( scan_block == NULL )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_MEMORY,
		 LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
		 "%s: unable to create scan block.",
		 function );

		goto on_error;
	}
	while( size > 0 )
	{
		if( libbfio_handle_seek_offset(
		     file_io_handle,
		     file_offset,
		     SEEK_SET,
		     error ) == -1 )
		{
			libcerror_error_set(
			 error,
			 LIBCERROR_ERROR_DOMAIN_IO,
			 LIBCERROR_IO_ERROR_SEEK_FAILED,
			 "%s: unable to seek scan block offset: %" PRIi64 ".",
			 function,
			 file_offset );

			goto on_error;
		}
		if( scan_block_size > size )
		{
			read_size = (size_t) size;
		}
		else
		{
			read_size = scan_block_size;
		}
		read_count = libbfio_handle_read_buffer(
			      file_io_handle,
			      scan_block,
			      read_size,
			      error );

		if( read_count != (ssize_t) read_size )
		{
			libcerror_error_set(
			 error,
			 LIBCERROR_ERROR_DOMAIN_IO,
			 LIBCERROR_IO_ERROR_READ_FAILED,
			 "%s: unable to read scan block at offset: %" PRIi64 ".",
			 function,
			 file_offset );

			goto on_error;
		}
		scan_block_offset = 0;

		while( scan_block_offset < read_size )
		{
			if( memory_compare(
			     &( scan_block[ scan_block_offset ] ),
			     evt_file_signature,
			     4 ) != 0 )
			{
				scan_block_offset += 4;

				continue;
			}
			record_offset = file_offset + scan_block_offset - 4;

#if defined( HAVE_DEBUG_OUTPUT )
			if( libcnotify_verbose != 0 )
			{
				libcnotify_printf(
				 "%s: reading recovered record at offset: %" PRIi64 " (0x%08" PRIx64 ")\n",
				 function,
				 record_offset,
				 record_offset );
			}
#endif
			if( libbfio_handle_seek_offset(
			     file_io_handle,
			     record_offset,
			     SEEK_SET,
			     error ) == -1 )
			{
				libcerror_error_set(
				 error,
				 LIBCERROR_ERROR_DOMAIN_IO,
				 LIBCERROR_IO_ERROR_SEEK_FAILED,
				 "%s: unable to seek record offset: %" PRIi64 ".",
				 function,
				 record_offset );

				goto on_error;
			}
			if( record_values == NULL )
			{
				if( libevt_record_values_initialize(
				     &record_values,
				     error ) != 1 )
				{
					libcerror_error_set(
					 error,
					 LIBCERROR_ERROR_DOMAIN_RUNTIME,
					 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
					 "%s: unable to create record values.",
					 function );

					goto on_error;
				}
			}
			read_count = libevt_record_values_read(
				      record_values,
				      file_io_handle,
				      io_handle,
				      &record_offset,
				      0,
				      error );

			if( read_count == -1 )
			{
				libcerror_error_set(
				 error,
				 LIBCERROR_ERROR_DOMAIN_IO,
				 LIBCERROR_IO_ERROR_READ_FAILED,
				 "%s: unable to read record at offset: %" PRIi64 ".",
				 function,
				 record_offset );

#if defined( HAVE_DEBUG_OUTPUT )
				if( libcnotify_verbose != 0 )
				{
					if( ( error != NULL )
					 && ( *error != NULL ) )
					{
						libcnotify_print_error_backtrace(
						 *error );
					}
				}
#endif
				libcerror_error_free(
				 error );

				scan_block_offset += 4;

				continue;
			}
			if( record_values->type == LIBEVT_RECORD_TYPE_EVENT )
			{
				if( libfdata_list_append_element(
				     recovered_records_list,
				     &element_index,
				     0,
				     file_offset + scan_block_offset - 4,
				     (size64_t) read_count,
				     0,
				     error ) != 1 )
				{
					libcerror_error_set(
					 error,
					 LIBCERROR_ERROR_DOMAIN_RUNTIME,
					 LIBCERROR_RUNTIME_ERROR_APPEND_FAILED,
					 "%s: unable to append recovered record to records list.",
					 function );

					goto on_error;
				}
			}
			if( libevt_record_values_free(
			     &record_values,
			     error ) != 1 )
			{
				libcerror_error_set(
				 error,
				 LIBCERROR_ERROR_DOMAIN_RUNTIME,
				 LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
				 "%s: unable to free record values.",
				 function );

				goto on_error;
			}
			scan_block_offset += read_count - 4;

			if( ( scan_block_offset + read_count - 4 ) > read_size )
			{
				break;
			}
		}
		file_offset += scan_block_offset;
		size        -= scan_block_offset;
	}
	if( record_values != NULL )
	{
		if( libevt_record_values_free(
		     &record_values,
		     error ) != 1 )
		{
			libcerror_error_set(
			 error,
			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
			 LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
			 "%s: unable to free record values.",
			 function );

			goto on_error;
		}
	}
	memory_free(
	 scan_block );

	scan_block = NULL;

	return( 1 );

on_error:
	if( record_values != NULL )
	{
		libevt_record_values_free(
		 &record_values,
		 NULL );
	}
	if( scan_block != NULL )
	{
		memory_free(
		 scan_block );
	}
	return( -1 );
}
/* Reads the debug data
 * Returns 1 if successful or -1 on error
 */
int libexe_debug_data_read(
     libexe_debug_data_t *debug_data,
     libbfio_handle_t *file_io_handle,
     uint32_t file_offset,
     uint32_t size,
     libcerror_error_t **error )
{
	uint8_t *data         = NULL;
	static char *function = "libexe_debug_data_read";
	size_t read_count     = 0;

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

		return( -1 );
	}
#if SIZEOF_SIZE_T <= 4
	if( size > (uint32_t) SSIZE_MAX )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
		 LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
		 "%s: invalid size value exceeds maximum.",
		 function );

		return( -1 );
	}
#endif
#if defined( HAVE_DEBUG_OUTPUT )
	if( libcnotify_verbose != 0 )
	{
		libcnotify_printf(
		 "%s: reading debug data at offset: %" PRIu32 " (0x%08" PRIx32 ")\n",
		 function,
		 file_offset,
		 file_offset );
	}
#endif
	if( libbfio_handle_seek_offset(
	     file_io_handle,
	     (off64_t) file_offset,
	     SEEK_SET,
	     error ) == -1 )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_IO,
		 LIBCERROR_IO_ERROR_SEEK_FAILED,
		 "%s: unable to seek debug data offset: %" PRIx32 ".",
		 function,
		 file_offset );

		goto on_error;
	}
	data = (uint8_t *) memory_allocate(
	                    sizeof( uint8_t ) * size );

	if( data == NULL )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_MEMORY,
		 LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
		 "%s: unable to create debug data.",
		 function );

		goto on_error;
	}
	read_count = libbfio_handle_read_buffer(
	              file_io_handle,
	              data,
	              size,
	              error );

	if( read_count != (ssize_t) size )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_IO,
		 LIBCERROR_IO_ERROR_READ_FAILED,
		 "%s: unable to read debug data.",
		 function );

		goto on_error;
	}
#if defined( HAVE_DEBUG_OUTPUT )
	if( libcnotify_verbose != 0 )
	{
		libcnotify_printf(
		 "%s: debug data:\n",
		 function );
		libcnotify_print_data(
		 data,
		 (size_t) size,
		 0 );
	}
#endif
	/* TODO extract values */

	memory_free(
	 data );

	return( 1 );

on_error:
	if( data != NULL )
	{
		memory_free(
		 data );
	}
	return( -1 );
}
Пример #28
0
/* Reads the file header
 * Returns 1 if successful or -1 on error
 */
int libqcow_io_handle_read_file_header(
     libqcow_io_handle_t *io_handle,
     libbfio_handle_t *file_io_handle,
     uint32_t *encryption_method,
     libcerror_error_t **error )
{
	uint8_t *file_header_data                  = NULL;
	static char *function                      = "libqcow_io_handle_read_file_header";
	size_t read_size                           = 512;
	ssize_t read_count                         = 0;
	uint64_t backing_filename_offset           = 0;
	uint32_t number_of_level1_table_references = 0;

#if defined( HAVE_DEBUG_OUTPUT )
	uint64_t value_64bit                       = 0;
	uint32_t value_32bit                       = 0;
	uint16_t value_16bit                       = 0;
#endif

	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( io_handle->backing_filename != NULL )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
		 LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
		 "%s: invalid IO handle - backing filename value already set.",
		 function );

		return( -1 );
	}
	if( encryption_method == NULL )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
		 "%s: invalid encryption method.",
		 function );

		return( -1 );
	}
#if defined( HAVE_DEBUG_OUTPUT )
	if( libcnotify_verbose != 0 )
	{
		libcnotify_printf(
		 "%s: reading file header at offset: 0 (0x00000000)\n",
		 function );
	}
#endif
	if( libbfio_handle_seek_offset(
	     file_io_handle,
	     0,
	     SEEK_SET,
	     error ) == -1 )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_IO,
		 LIBCERROR_IO_ERROR_SEEK_FAILED,
		 "%s: unable to seek file header offset: 0.",
		 function );

		goto on_error;
	}
	file_header_data = (uint8_t *) memory_allocate(
	                                sizeof( uint8_t ) * read_size );

	if( file_header_data == NULL )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_MEMORY,
		 LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
		 "%s: unable to create file header data.",
		 function );

		goto on_error;
	}
	read_count = libbfio_handle_read_buffer(
	              file_io_handle,
	              file_header_data,
	              read_size,
	              error );

	if( read_count != (ssize_t) read_size )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_IO,
		 LIBCERROR_IO_ERROR_READ_FAILED,
		 "%s: unable to read file header.",
		 function );

		goto on_error;
	}
#if defined( HAVE_DEBUG_OUTPUT )
	if( libcnotify_verbose != 0 )
	{
		libcnotify_printf(
		 "%s: file header data:\n",
		 function );
		libcnotify_print_data(
		 file_header_data,
		 sizeof( qcow_file_header_v1_t ),
		 0 );
	}
#endif
	if( memory_compare(
	     ( (qcow_file_header_v1_t *) file_header_data )->signature,
	     qcow_file_signature,
	     4 ) != 0 )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
		 LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
		 "%s: unsupported file signature.",
		 function );

		goto on_error;
	}
	byte_stream_copy_to_uint32_big_endian(
	 ( (qcow_file_header_v1_t *) file_header_data )->format_version,
	 io_handle->format_version );

	byte_stream_copy_to_uint64_big_endian(
	 ( (qcow_file_header_v1_t *) file_header_data )->backing_filename_offset,
	 backing_filename_offset );

	byte_stream_copy_to_uint32_big_endian(
	 ( (qcow_file_header_v1_t *) file_header_data )->backing_filename_size,
	 io_handle->backing_filename_size );

#if defined( HAVE_DEBUG_OUTPUT )
	if( libcnotify_verbose != 0 )
	{
		byte_stream_copy_to_uint32_big_endian(
		 ( (qcow_file_header_v1_t *) file_header_data )->signature,
		 value_32bit );
		libcnotify_printf(
		 "%s: signature\t\t\t\t: 0x%08" PRIx32 "\n",
		 function,
		 value_32bit );

		libcnotify_printf(
		 "%s: format version\t\t\t: %" PRIu32 "\n",
		 function,
		 io_handle->format_version );

		libcnotify_printf(
		 "%s: backing filename offset\t\t: %" PRIu32 "\n",
		 function,
		 backing_filename_offset );

		libcnotify_printf(
		 "%s: backing filename size\t\t: %" PRIu32 "\n",
		 function,
		 io_handle->backing_filename_size );
	}
#endif
	if( ( io_handle->format_version != 1 )
	 && ( io_handle->format_version != 2 )
	 && ( io_handle->format_version != 3 ) )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
		 LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
		 "%s: unsupported format version: %" PRIu32 ".",
		 function,
		 io_handle->format_version );

		goto on_error;
	}
	if( io_handle->format_version == 1 )
	{
		byte_stream_copy_to_uint64_big_endian(
		 ( (qcow_file_header_v1_t *) file_header_data )->media_size,
		 io_handle->media_size );

		io_handle->number_of_cluster_block_bits = (uint32_t) ( (qcow_file_header_v1_t *) file_header_data )->number_of_cluster_block_bits;

		io_handle->number_of_level2_table_bits = (uint32_t) ( (qcow_file_header_v1_t *) file_header_data )->number_of_level2_table_bits;

		byte_stream_copy_to_uint32_big_endian(
		 ( (qcow_file_header_v1_t *) file_header_data )->encryption_method,
		 *encryption_method );

		byte_stream_copy_to_uint64_big_endian(
		 ( (qcow_file_header_v2_t *) file_header_data )->level1_table_offset,
		 io_handle->level1_table_offset );

#if defined( HAVE_DEBUG_OUTPUT )
		if( libcnotify_verbose != 0 )
		{
			byte_stream_copy_to_uint32_big_endian(
			 ( (qcow_file_header_v1_t *) file_header_data )->modification_time,
			 value_32bit );
			libcnotify_printf(
			 "%s: modification time\t\t\t: %" PRIu32 "\n",
			 function,
			 value_32bit );

			libcnotify_printf(
			 "%s: media size\t\t\t\t: %" PRIu64 "\n",
			 function,
			 io_handle->media_size );

			libcnotify_printf(
			 "%s: number of cluster block bits\t: %" PRIu32 "\n",
			 function,
			 io_handle->number_of_cluster_block_bits );

			libcnotify_printf(
			 "%s: number of level 2 table bits\t: %" PRIu32 "\n",
			 function,
			 io_handle->number_of_level2_table_bits );

			byte_stream_copy_to_uint16_big_endian(
			 ( (qcow_file_header_v1_t *) file_header_data )->unknown1,
			 value_16bit );
			libcnotify_printf(
			 "%s: unknown1\t\t\t\t: 0x%04" PRIx16 "\n",
			 function,
			 value_16bit );

			libcnotify_printf(
			 "%s: encryption method\t\t\t: %" PRIu32 "\n",
			 function,
			 *encryption_method );

			libcnotify_printf(
			 "%s: level 1 table offset\t\t: 0x%08" PRIx64 "\n",
			 function,
			 io_handle->level1_table_offset );
		}
#endif
	}
	else if( ( io_handle->format_version == 2 )
	      || ( io_handle->format_version == 3 ) )
	{
		byte_stream_copy_to_uint32_big_endian(
		 ( (qcow_file_header_v2_t *) file_header_data )->number_of_cluster_block_bits,
		 io_handle->number_of_cluster_block_bits );

		byte_stream_copy_to_uint32_big_endian(
		 ( (qcow_file_header_v2_t *) file_header_data )->number_of_level1_table_references,
		 number_of_level1_table_references );

		byte_stream_copy_to_uint64_big_endian(
		 ( (qcow_file_header_v2_t *) file_header_data )->level1_table_offset,
		 io_handle->level1_table_offset );

		byte_stream_copy_to_uint64_big_endian(
		 ( (qcow_file_header_v2_t *) file_header_data )->media_size,
		 io_handle->media_size );

		byte_stream_copy_to_uint32_big_endian(
		 ( (qcow_file_header_v2_t *) file_header_data )->encryption_method,
		 *encryption_method );

#if defined( HAVE_DEBUG_OUTPUT )
		if( libcnotify_verbose != 0 )
		{
			libcnotify_printf(
			 "%s: number of cluster block bits\t: %" PRIu32 "\n",
			 function,
			 io_handle->number_of_cluster_block_bits );

			libcnotify_printf(
			 "%s: media size\t\t\t\t: %" PRIu64 "\n",
			 function,
			 io_handle->media_size );

			libcnotify_printf(
			 "%s: encryption method\t\t\t: %" PRIu32 "\n",
			 function,
			 *encryption_method );

			libcnotify_printf(
			 "%s: number of level 1 table references\t: %" PRIu32 "\n",
			 function,
			 number_of_level1_table_references );

			libcnotify_printf(
			 "%s: level 1 table offset\t\t: 0x%08" PRIx64 "\n",
			 function,
			 io_handle->level1_table_offset );

			byte_stream_copy_to_uint64_big_endian(
			 ( (qcow_file_header_v2_t *) file_header_data )->reference_count_table_offset,
			 value_64bit );
			libcnotify_printf(
			 "%s: reference count table offset\t: 0x%08" PRIx64 "\n",
			 function,
			 value_64bit );

			byte_stream_copy_to_uint32_big_endian(
			 ( (qcow_file_header_v2_t *) file_header_data )->reference_count_table_clusters,
			 value_32bit );
			libcnotify_printf(
			 "%s: reference count table clusters\t: %" PRIu32 "\n",
			 function,
			 value_32bit );

			byte_stream_copy_to_uint32_big_endian(
			 ( (qcow_file_header_v2_t *) file_header_data )->number_of_snapshots,
			 value_32bit );
			libcnotify_printf(
			 "%s: number of snapshots\t\t\t: %" PRIu32 "\n",
			 function,
			 value_32bit );

			byte_stream_copy_to_uint64_big_endian(
			 ( (qcow_file_header_v2_t *) file_header_data )->snapshots_offset,
			 value_64bit );
			libcnotify_printf(
			 "%s: snapshots offset\t\t\t: 0x%08" PRIx64 "\n",
			 function,
			 value_64bit );
		}
#endif
	}
#if defined( HAVE_DEBUG_OUTPUT )
	if( libcnotify_verbose != 0 )
	{
		libcnotify_printf(
		 "\n" );
	}
#endif
	memory_free(
	 file_header_data );

	file_header_data = NULL;

	if( io_handle->format_version == 1 )
	{
		io_handle->offset_bit_mask           = 0x7fffffffffffffffULL;
		io_handle->compression_flag_bit_mask = (uint64_t) 1 << 63;
		io_handle->compression_bit_shift     = 63 - io_handle->number_of_cluster_block_bits;
	}
	else if( ( io_handle->format_version == 2 )
	      || ( io_handle->format_version == 3 ) )
	{
		if( io_handle->number_of_cluster_block_bits <= 8 )
		{
			libcerror_error_set(
			 error,
			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
			 LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
			 "%s: invalid number of cluster block bits value out of bounds.",
			 function );

			goto on_error;
		}
		io_handle->number_of_level2_table_bits = io_handle->number_of_cluster_block_bits - 3;
		io_handle->offset_bit_mask             = 0x3fffffffffffffffULL;
		io_handle->compression_flag_bit_mask   = (uint64_t) 1 << 62;
		io_handle->compression_bit_shift       = 62 - ( io_handle->number_of_cluster_block_bits - 8 );
	}
	io_handle->level1_index_bit_shift = io_handle->number_of_cluster_block_bits
	                                  + io_handle->number_of_level2_table_bits;

	io_handle->level2_index_bit_mask  = ~( (uint64_t) -1 << io_handle->number_of_level2_table_bits );
	io_handle->cluster_block_bit_mask = ~( (uint64_t) -1 << io_handle->number_of_cluster_block_bits );
	io_handle->compression_bit_mask   = ~( (uint64_t) -1 << io_handle->compression_bit_shift );
	io_handle->level2_table_size      = (size_t) 1 << io_handle->number_of_level2_table_bits;
	io_handle->cluster_block_size     = (size_t) 1 << io_handle->number_of_cluster_block_bits;

	if( io_handle->format_version == 1 )
	{
		io_handle->level1_table_size = (uint32_t) ( io_handle->cluster_block_size * io_handle->level2_table_size );

		if( ( io_handle->media_size % io_handle->level1_table_size ) != 0 )
		{
			io_handle->level1_table_size = (uint32_t) ( ( io_handle->media_size / io_handle->level1_table_size ) + 1 );
		}
		else
		{
			io_handle->level1_table_size = (uint32_t) ( io_handle->media_size / io_handle->level1_table_size );
		}
	}
	else if( ( io_handle->format_version == 2 )
	      || ( io_handle->format_version == 3 ) )
	{
		io_handle->level1_table_size = number_of_level1_table_references;
	}
	io_handle->level1_table_size *= 8;
	io_handle->level2_table_size *= 8;

#if UINT32_MAX > SSIZE_MAX
	if( io_handle->level1_table_size > (uint32_t) SSIZE_MAX )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
		 LIBCERROR_RUNTIME_ERROR_VALUE_EXCEEDS_MAXIMUM,
		 "%s: invalid level 1 table size value exceeds maximum.",
		 function );

		goto on_error;
	}
#endif
#if defined( HAVE_DEBUG_OUTPUT )
	if( libcnotify_verbose != 0 )
	{
		libcnotify_printf(
		 "%s: level 1 table size\t\t\t: %" PRIzd "\n",
		 function,
		 io_handle->level1_table_size );

		libcnotify_printf(
		 "%s: level 2 table size\t\t\t: %" PRIzd "\n",
		 function,
		 io_handle->level2_table_size );

		libcnotify_printf(
		 "%s: cluster block size\t\t\t: %" PRIzd "\n",
		 function,
		 io_handle->cluster_block_size );
	}
#endif
	if( ( backing_filename_offset > 0 )
	 && ( io_handle->backing_filename_size > 0 ) )
	{
#if defined( HAVE_DEBUG_OUTPUT )
		if( libcnotify_verbose != 0 )
		{
			libcnotify_printf(
			 "%s: reading backing filename at offset: %" PRIu64 " (0x%08" PRIx64 ")\n",
			 function,
			 backing_filename_offset,
			 backing_filename_offset );
		}
#endif
		if( libbfio_handle_seek_offset(
		     file_io_handle,
		     backing_filename_offset,
		     SEEK_SET,
		     error ) == -1 )
		{
			libcerror_error_set(
			 error,
			 LIBCERROR_ERROR_DOMAIN_IO,
			 LIBCERROR_IO_ERROR_SEEK_FAILED,
			 "%s: unable to seek file header offset: %" PRIu64 ".",
			 function,
			 backing_filename_offset );

			goto on_error;
		}
		io_handle->backing_filename = (uint8_t *) memory_allocate(
		                                           sizeof( uint8_t ) * io_handle->backing_filename_size );

		if( io_handle->backing_filename == NULL )
		{
			libcerror_error_set(
			 error,
			 LIBCERROR_ERROR_DOMAIN_MEMORY,
			 LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
			 "%s: unable to create backing filename.",
			 function );

			goto on_error;
		}
		read_count = libbfio_handle_read_buffer(
			      file_io_handle,
			      io_handle->backing_filename,
			      io_handle->backing_filename_size,
			      error );

		if( read_count != (ssize_t) io_handle->backing_filename_size )
		{
			libcerror_error_set(
			 error,
			 LIBCERROR_ERROR_DOMAIN_IO,
			 LIBCERROR_IO_ERROR_READ_FAILED,
			 "%s: unable to read file header.",
			 function );

			goto on_error;
		}
#if defined( HAVE_DEBUG_OUTPUT )
		if( libcnotify_verbose != 0 )
		{
			libcnotify_printf(
			 "%s: backing filename data:\n",
			 function );
			libcnotify_print_data(
			 io_handle->backing_filename,
			 (size_t) io_handle->backing_filename_size,
			 0 );
		}
#endif
	}
	return( 1 );

on_error:
	if( io_handle->backing_filename != NULL )
	{
		memory_free(
		 io_handle->backing_filename );

		io_handle->backing_filename      = NULL;
		io_handle->backing_filename_size = 0;
	}
	if( file_header_data != NULL )
	{
		memory_free(
		 file_header_data );
	}
	return( -1 );
}
Пример #29
0
/* Opens a file for reading
 * Returns 1 if successful or -1 on error
 */
int libevtx_file_open_read(
     libevtx_internal_file_t *internal_file,
     libbfio_handle_t *file_io_handle,
     libcerror_error_t **error )
{
	libevtx_chunk_t *chunk                 = NULL;
	libevtx_record_values_t *record_values = NULL;
	libevtx_chunks_table_t *chunks_table   = NULL;
	static char *function                  = "libevtx_file_open_read";
	off64_t file_offset                    = 0;
	size64_t file_size                     = 0;
	uint16_t chunk_index                   = 0;
	uint16_t number_of_chunks              = 0;
	uint16_t number_of_records             = 0;
	uint16_t record_index                  = 0;
	int element_index                      = 0;
	int result                             = 0;
	int segment_index                      = 0;

#if defined( HAVE_VERBOSE_OUTPUT )
	uint64_t previous_record_identifier    = 0;
#endif
#if defined( HAVE_DEBUG_OUTPUT )
	uint8_t *trailing_data                 = NULL;
	size_t trailing_data_size              = 0;
	ssize_t read_count                     = 0;
#endif

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

		return( -1 );
	}
	if( internal_file->io_handle == NULL )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
		 LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
		 "%s: invalid file - missing IO handle.",
		 function );

		return( -1 );
	}
	if( internal_file->chunks_vector != NULL )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
		 LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
		 "%s: invalid file - chunks vector already set.",
		 function );

		return( -1 );
	}
	if( internal_file->chunks_cache != NULL )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
		 LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
		 "%s: invalid file - chunks cache already set.",
		 function );

		return( -1 );
	}
	if( internal_file->records_list != NULL )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
		 LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
		 "%s: invalid file - records list already set.",
		 function );

		return( -1 );
	}
	if( internal_file->recovered_records_list != NULL )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
		 LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
		 "%s: invalid file - recovered records list already set.",
		 function );

		return( -1 );
	}
	if( internal_file->records_cache != NULL )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
		 LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
		 "%s: invalid file - records cache already set.",
		 function );

		return( -1 );
	}
	if( libbfio_handle_get_size(
	     file_io_handle,
	     &file_size,
	     error ) != 1 )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
		 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
		 "%s: unable to retrieve file size.",
		 function );

		goto on_error;
	}
#if defined( HAVE_DEBUG_OUTPUT )
	if( libcnotify_verbose != 0 )
	{
		libcnotify_printf(
		 "Reading file header:\n" );
	}
#endif
	if( libevtx_io_handle_read_file_header(
	     internal_file->io_handle,
	     file_io_handle,
	     0,
	     error ) != 1 )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_IO,
		 LIBCERROR_IO_ERROR_READ_FAILED,
		 "%s: unable to read file header.",
		 function );

		goto on_error;
	}
	internal_file->io_handle->chunks_data_size = file_size
	                                           - internal_file->io_handle->chunks_data_offset;

/* TODO clone function ? */
	if( libfdata_vector_initialize(
	     &( internal_file->chunks_vector ),
	     (size64_t) internal_file->io_handle->chunk_size,
	     (intptr_t *) internal_file->io_handle,
	     NULL,
	     NULL,
	     (int (*)(intptr_t *, intptr_t *, libfdata_vector_t *, libfcache_cache_t *, int, int, off64_t, size64_t, uint32_t, uint8_t, libcerror_error_t **)) &libevtx_io_handle_read_chunk,
	     NULL,
	     LIBFDATA_DATA_HANDLE_FLAG_NON_MANAGED,
	     error ) != 1 )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
		 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
		 "%s: unable to create chunks vector.",
		 function );

		goto on_error;
	}
	if( libfdata_vector_append_segment(
	     internal_file->chunks_vector,
	     &segment_index,
	     0,
	     internal_file->io_handle->chunks_data_offset,
	     internal_file->io_handle->chunks_data_size,
	     0,
	     error ) != 1 )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
		 LIBCERROR_RUNTIME_ERROR_APPEND_FAILED,
		 "%s: unable to append segment to chunks vector.",
		 function );

		goto on_error;
	}
	if( libfcache_cache_initialize(
	     &( internal_file->chunks_cache ),
	     LIBEVTX_MAXIMUM_CACHE_ENTRIES_CHUNKS,
	     error ) != 1 )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
		 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
		 "%s: unable to create chunks cache.",
		 function );

		goto on_error;
	}
#if defined( HAVE_DEBUG_OUTPUT )
	if( libcnotify_verbose != 0 )
	{
		libcnotify_printf(
		 "Reading chunks:\n" );
	}
#endif
	if( libevtx_chunks_table_initialize(
	     &chunks_table,
	     internal_file->io_handle,
	     internal_file->chunks_vector,
	     internal_file->chunks_cache,
	     error ) != 1 )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
		 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
		 "%s: unable to create chunks table.",
		 function );

		goto on_error;
	}
/* TODO clone function ? */
	if( libfdata_list_initialize(
	     &( internal_file->records_list ),
	     (intptr_t *) chunks_table,
	     (int (*)(intptr_t **, libcerror_error_t **)) &libevtx_chunks_table_free,
	     NULL,
	     (int (*)(intptr_t *, intptr_t *, libfdata_list_element_t *, libfcache_cache_t *, int, off64_t, size64_t, uint32_t, uint8_t, libcerror_error_t **)) &libevtx_chunks_table_read_record,
	     NULL,
	     LIBFDATA_DATA_HANDLE_FLAG_MANAGED,
	     error ) != 1 )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
		 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
		 "%s: unable to create records list.",
		 function );

		goto on_error;
	}
	/* The chunks_table is managed by the list */

	if( libfdata_list_initialize(
	     &( internal_file->recovered_records_list ),
	     (intptr_t *) chunks_table,
	     NULL,
	     NULL,
	     (int (*)(intptr_t *, intptr_t *, libfdata_list_element_t *, libfcache_cache_t *, int, off64_t, size64_t, uint32_t, uint8_t, libcerror_error_t **)) &libevtx_chunks_table_read_record,
	     NULL,
	     LIBFDATA_DATA_HANDLE_FLAG_NON_MANAGED,
	     error ) != 1 )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
		 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
		 "%s: unable to create recovered records list.",
		 function );

		chunks_table = NULL;

		goto on_error;
	}
	chunks_table = NULL;

	if( libfcache_cache_initialize(
	     &( internal_file->records_cache ),
	     LIBEVTX_MAXIMUM_CACHE_ENTRIES_RECORDS,
	     error ) != 1 )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
		 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
		 "%s: unable to create records cache.",
		 function );

		goto on_error;
	}
	file_offset = internal_file->io_handle->chunks_data_offset;

	while( ( file_offset + internal_file->io_handle->chunk_size ) <= (off64_t) file_size )
	{
		if( libevtx_chunk_initialize(
		     &chunk,
		     error ) != 1 )
		{
			libcerror_error_set(
			 error,
			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
			 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
			 "%s: unable to create chunk: %" PRIu16 ".",
			 function,
			 chunk_index );

			goto on_error;
		}
		result = libevtx_chunk_read(
		          chunk,
		          internal_file->io_handle,
		          file_io_handle,
		          file_offset,
		          error );

		if( result == -1 )
		{
			libcerror_error_set(
			 error,
			 LIBCERROR_ERROR_DOMAIN_IO,
			 LIBCERROR_IO_ERROR_READ_FAILED,
			 "%s: unable to read chunk: %" PRIu16 ".",
			 function,
			 chunk_index );

			goto on_error;
		}
		else if( result == 0 )
		{
			if( chunk_index < internal_file->io_handle->number_of_chunks )
			{
#if defined( HAVE_VERBOSE_OUTPUT )
				if( libcnotify_verbose != 0 )
				{
					libcnotify_printf(
					 "%s: corruption detected in chunk: %" PRIu16 ".\n",
					 function,
					 chunk_index );
				}
#endif
				internal_file->io_handle->flags |= LIBEVTX_IO_HANDLE_FLAG_IS_CORRUPTED;
			}
		}
		else
		{
			if( ( chunk->flags & LIBEVTX_CHUNK_FLAG_IS_CORRUPTED ) != 0 )
			{
#if defined( HAVE_VERBOSE_OUTPUT )
				if( libcnotify_verbose != 0 )
				{
					libcnotify_printf(
					 "%s: corruption detected in chunk: %" PRIu16 ".\n",
					 function,
					 chunk_index );
				}
#endif
				if( chunk_index < internal_file->io_handle->number_of_chunks )
				{
					internal_file->io_handle->flags |= LIBEVTX_IO_HANDLE_FLAG_IS_CORRUPTED;
				}
			}
			if( ( chunk_index < internal_file->io_handle->number_of_chunks )
			 || ( ( chunk->flags & LIBEVTX_CHUNK_FLAG_IS_CORRUPTED ) == 0 ) )
			{
				number_of_chunks++;
			}
			if( libevtx_chunk_get_number_of_records(
			     chunk,
			     &number_of_records,
			     error ) != 1 )
			{
				libcerror_error_set(
				 error,
				 LIBCERROR_ERROR_DOMAIN_RUNTIME,
				 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
				 "%s: unable to retrieve chunk: %" PRIu16 " number of records.",
				 function,
				 chunk_index );

				goto on_error;
			}
			for( record_index = 0;
			     record_index < number_of_records;
			     record_index++ )
			{
				if( libevtx_chunk_get_record(
				     chunk,
				     record_index,
				     &record_values,
				     error ) != 1 )
				{
					libcerror_error_set(
					 error,
					 LIBCERROR_ERROR_DOMAIN_RUNTIME,
					 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
					 "%s: unable to retrieve chunk: %" PRIu16 " record: %" PRIu16 ".",
					 function,
					 chunk_index,
					 record_index );

					goto on_error;
				}
				if( record_values == NULL )
				{
					libcerror_error_set(
					 error,
					 LIBCERROR_ERROR_DOMAIN_RUNTIME,
					 LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
					 "%s: missing chunk: %" PRIu16 " record: %" PRIu16 ".",
					 function,
					 chunk_index,
					 record_index );

					goto on_error;
				}
				if( record_values->identifier < internal_file->io_handle->first_record_identifier )
				{
					internal_file->io_handle->first_record_identifier = record_values->identifier;
				}
				if( record_values->identifier > internal_file->io_handle->last_record_identifier )
				{
					internal_file->io_handle->last_record_identifier = record_values->identifier;
				}
#if defined( HAVE_VERBOSE_OUTPUT )
				if( ( chunk_index == 0 )
				 && ( record_index == 0 ) )
				{
					previous_record_identifier = record_values->identifier;
				}
				else
				{
					previous_record_identifier++;

					if( record_values->identifier != previous_record_identifier )
					{
						if( libcnotify_verbose != 0 )
						{
							libcnotify_printf(
							 "%s: detected gap in record identifier ( %" PRIu64 " != %" PRIu64 " ).\n",
							 function,
							 previous_record_identifier,
							 record_values->identifier );
						}
						previous_record_identifier = record_values->identifier;
					}
				}
#endif
				/* The chunk index is stored in the element data size
				 */
				if( ( chunk_index < internal_file->io_handle->number_of_chunks )
				 || ( ( internal_file->io_handle->file_flags & LIBEVTX_FILE_FLAG_IS_DIRTY ) != 0 ) )
				{
					if( libfdata_list_append_element(
					     internal_file->records_list,
					     &element_index,
					     0,
					     file_offset + record_values->chunk_data_offset,
					     (size64_t) chunk_index,
					     0,
					     error ) != 1 )
					{
						libcerror_error_set(
						 error,
						 LIBCERROR_ERROR_DOMAIN_RUNTIME,
						 LIBCERROR_RUNTIME_ERROR_APPEND_FAILED,
						 "%s: unable to append element to records list.",
						 function );

						goto on_error;
					}
				}
				else
				{
					/* If the file is not dirty, records found in chunks outside the indicated
					 * range are considered recovered
					 */
					if( libfdata_list_append_element(
					     internal_file->recovered_records_list,
					     &element_index,
					     0,
					     file_offset + record_values->chunk_data_offset,
					     (size64_t) chunk_index,
					     0,
					     error ) != 1 )
					{
						libcerror_error_set(
						 error,
						 LIBCERROR_ERROR_DOMAIN_RUNTIME,
						 LIBCERROR_RUNTIME_ERROR_APPEND_FAILED,
						 "%s: unable to append element to recovered records list.",
						 function );

						goto on_error;
					}
				}
/* TODO cache record values ? */
			}
			if( libevtx_chunk_get_number_of_recovered_records(
			     chunk,
			     &number_of_records,
			     error ) != 1 )
			{
				libcerror_error_set(
				 error,
				 LIBCERROR_ERROR_DOMAIN_RUNTIME,
				 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
				 "%s: unable to retrieve chunk: %" PRIu16 " number of recovered records.",
				 function,
				 chunk_index );

				goto on_error;
			}
			for( record_index = 0;
			     record_index < number_of_records;
			     record_index++ )
			{
				if( libevtx_chunk_get_recovered_record(
				     chunk,
				     record_index,
				     &record_values,
				     error ) != 1 )
				{
					libcerror_error_set(
					 error,
					 LIBCERROR_ERROR_DOMAIN_RUNTIME,
					 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
					 "%s: unable to retrieve chunk: %" PRIu16 " recovered record: %" PRIu16 ".",
					 function,
					 chunk_index,
					 record_index );

					goto on_error;
				}
				if( record_values == NULL )
				{
					libcerror_error_set(
					 error,
					 LIBCERROR_ERROR_DOMAIN_RUNTIME,
					 LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
					 "%s: missing chunk: %" PRIu16 " recovered record: %" PRIu16 ".",
					 function,
					 chunk_index,
					 record_index );

					goto on_error;
				}
/* TODO check for and remove duplicate identifiers ? */
				/* The chunk index is stored in the element data size
				 */
				if( libfdata_list_append_element(
				     internal_file->recovered_records_list,
				     &element_index,
				     0,
				     file_offset + record_values->chunk_data_offset,
				     (size64_t) chunk_index,
				     0,
				     error ) != 1 )
				{
					libcerror_error_set(
					 error,
					 LIBCERROR_ERROR_DOMAIN_RUNTIME,
					 LIBCERROR_RUNTIME_ERROR_APPEND_FAILED,
					 "%s: unable to append element to recovered records list.",
					 function );

					goto on_error;
				}
			}
		}
		file_offset += chunk->data_size;

		if( libevtx_chunk_free(
		     &chunk,
		     error ) != 1 )
		{
			libcerror_error_set(
			 error,
			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
			 LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
			 "%s: unable to free chunk: %" PRIu16 ".",
			 function,
			 chunk_index );

			goto on_error;
		}
		chunk_index++;
	}
	internal_file->io_handle->chunks_data_size = file_offset
	                                           - internal_file->io_handle->chunks_data_offset;

	if( number_of_chunks != internal_file->io_handle->number_of_chunks )
	{
#if defined( HAVE_VERBOSE_OUTPUT )
		if( libcnotify_verbose != 0 )
		{
			libcnotify_printf(
			 "%s: mismatch in number of chunks ( %" PRIu16 " != %" PRIu16 " ).\n",
			 function,
			 internal_file->io_handle->number_of_chunks,
			 chunk_index );
		}
#endif
		internal_file->io_handle->flags |= LIBEVTX_IO_HANDLE_FLAG_IS_CORRUPTED;
	}
#if defined( HAVE_DEBUG_OUTPUT )
	if( libcnotify_verbose != 0 )
	{
		if( file_offset < (off64_t) file_size )
		{
			trailing_data_size = (size_t) ( file_size - file_offset );

			trailing_data = (uint8_t *) memory_allocate(
			                             sizeof( uint8_t ) * trailing_data_size );

			if( trailing_data == NULL )
			{
				libcerror_error_set(
				 error,
				 LIBCERROR_ERROR_DOMAIN_MEMORY,
				 LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
				 "%s: unable to create trailing data.",
				 function );

				goto on_error;
			}
			read_count = libbfio_handle_read_buffer(
				      file_io_handle,
				      trailing_data,
				      trailing_data_size,
				      error );

			if( read_count != (ssize_t) trailing_data_size )
			{
				libcerror_error_set(
				 error,
				 LIBCERROR_ERROR_DOMAIN_IO,
				 LIBCERROR_IO_ERROR_READ_FAILED,
				 "%s: unable to read trailing data.",
				 function );

				memory_free(
				 trailing_data );

				goto on_error;
			}
			file_offset += read_count;

			libcnotify_printf(
			 "%s: trailing data:\n",
			 function );
			libcnotify_print_data(
			 trailing_data,
			 trailing_data_size,
			 LIBCNOTIFY_PRINT_DATA_FLAG_GROUP_DATA );

			memory_free(
			 trailing_data );

			trailing_data = NULL;
		}
	}
#endif
	return( 1 );

on_error:
#if defined( HAVE_DEBUG_OUTPUT )
	if( trailing_data != NULL )
	{
		memory_free(
		 trailing_data );
	}
#endif
	if( chunk != NULL )
	{
		libevtx_chunk_free(
		 &chunk,
		 NULL );
	}
	if( internal_file->records_cache != NULL )
	{
		libfcache_cache_free(
		 &( internal_file->records_cache ),
		 NULL );
	}
	if( internal_file->records_list != NULL )
	{
		libfdata_list_free(
		 &( internal_file->records_list ),
		 NULL );
	}
	if( chunks_table != NULL )
	{
		libevtx_chunks_table_free(
		 &chunks_table,
		 NULL );
	}
	if( internal_file->chunks_cache != NULL )
	{
		libfcache_cache_free(
		 &( internal_file->chunks_cache ),
		 NULL );
	}
	if( internal_file->chunks_vector != NULL )
	{
		libfdata_vector_free(
		 &( internal_file->chunks_vector ),
		 NULL );
	}
	return( -1 );
}
Пример #30
0
/* Reads the memory image information
 * Returns 1 if successful or -1 on error
 */
int libhibr_io_handle_read_memory_image_information(
     libhibr_io_handle_t *io_handle,
     libbfio_handle_t *file_io_handle,
     libcerror_error_t **error )
{
	uint8_t *page_data                          = NULL;
	static char *function                       = "libhibr_io_handle_read_memory_image_information";
	ssize_t read_count                          = 0;
	uint64_t page_size                          = 0;
	uint32_t memory_image_information_data_size = 0;

#if defined( HAVE_DEBUG_OUTPUT )
	libcstring_system_character_t filetime_string[ 32 ];

	libfdatetime_filetime_t *filetime           = NULL;
	uint64_t value_64bit                        = 0;
	uint32_t value_32bit                        = 0;
	uint8_t value_8bit                          = 0;
	int result                                  = 0;
#endif

	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 defined( HAVE_DEBUG_OUTPUT )
	if( libcnotify_verbose != 0 )
	{
		libcnotify_printf(
		 "%s: reading memory image information at offset: 0.\n",
		 function );
	}
#endif
	if( libbfio_handle_seek_offset(
	     file_io_handle,
	     0,
	     SEEK_SET,
	     error ) == -1 )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_IO,
		 LIBCERROR_IO_ERROR_SEEK_FAILED,
		 "%s: unable to seek memory image information offset: 0.",
		 function );

		goto on_error;
	}
	page_data = (uint8_t *) memory_allocate(
	                         sizeof( uint8_t ) * io_handle->page_size );

	if( page_data == NULL )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_MEMORY,
		 LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
		 "%s: unable to create memory image information data.",
		 function );

		goto on_error;
	}
	read_count = libbfio_handle_read_buffer(
	              file_io_handle,
	              page_data,
	              io_handle->page_size,
	              error );

	if( read_count != (ssize_t) io_handle->page_size )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_IO,
		 LIBCERROR_IO_ERROR_READ_FAILED,
		 "%s: unable to read memory image information.",
		 function );

		goto on_error;
	}
/* TODO do empty page test */

	byte_stream_copy_to_uint32_little_endian(
	 ( (hibr_memory_image_information_t *) page_data )->size,
	 memory_image_information_data_size );

	if( memory_image_information_data_size > 0 )
	{
#if defined( HAVE_DEBUG_OUTPUT )
		if( libcnotify_verbose != 0 )
		{
			libcnotify_printf(
			 "%s: memory image information data:\n",
			 function );
			libcnotify_print_data(
			 page_data,
			 (size_t) memory_image_information_data_size,
			 0 );
		}
#endif
/* TODO
		if( memory_compare(
		     ( (hibr_memory_image_information_t *) page_data )->signature,
		     hibr_file_signature,
		     8 ) != 0 )
		{
			libcerror_error_set(
			 error,
			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
			 LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
			 "%s: unsupported file signature.",
			 function );

			goto on_error;
		}
*/
		if( memory_image_information_data_size == sizeof( hibr_memory_image_information_winxp_32bit_t ) )
		{
			io_handle->file_type = LIBHIBR_FILE_TYPE_WINDOWS_XP_32BIT;
		}
		else if( memory_image_information_data_size == sizeof( hibr_memory_image_information_winxp_64bit_t ) )
		{
			io_handle->file_type = LIBHIBR_FILE_TYPE_WINDOWS_XP_64BIT;
		}
		else if( memory_image_information_data_size == sizeof( hibr_memory_image_information_win7_32bit_t ) )
		{
			io_handle->file_type = LIBHIBR_FILE_TYPE_WINDOWS_7_32BIT;
		}
		else if( memory_image_information_data_size == sizeof( hibr_memory_image_information_win7_64bit_t ) )
		{
			io_handle->file_type = LIBHIBR_FILE_TYPE_WINDOWS_7_64BIT;
		}
		if( io_handle->file_type == LIBHIBR_FILE_TYPE_WINDOWS_XP_32BIT )
		{
			byte_stream_copy_to_uint32_little_endian(
			 ( (hibr_memory_image_information_winxp_32bit_t *) page_data )->page_size,
			 page_size );
		}
		else if( io_handle->file_type == LIBHIBR_FILE_TYPE_WINDOWS_XP_64BIT )
		{
			byte_stream_copy_to_uint32_little_endian(
			 ( (hibr_memory_image_information_winxp_64bit_t *) page_data )->page_size,
			 page_size );
		}
		else if( io_handle->file_type == LIBHIBR_FILE_TYPE_WINDOWS_7_32BIT )
		{
			byte_stream_copy_to_uint32_little_endian(
			 ( (hibr_memory_image_information_win7_32bit_t *) page_data )->page_size,
			 page_size );
		}
		else if( io_handle->file_type == LIBHIBR_FILE_TYPE_WINDOWS_7_64BIT )
		{
			byte_stream_copy_to_uint32_little_endian(
			 ( (hibr_memory_image_information_win7_64bit_t *) page_data )->page_size,
			 page_size );
		}
#if defined( HAVE_DEBUG_OUTPUT )
		if( libcnotify_verbose != 0 )
		{
			libcnotify_printf(
			 "%s: signature\t\t: %c%c%c%c\n",
			 function,
			 ( (hibr_memory_image_information_t *) page_data )->signature[ 0 ],
			 ( (hibr_memory_image_information_t *) page_data )->signature[ 1 ],
			 ( (hibr_memory_image_information_t *) page_data )->signature[ 2 ],
			 ( (hibr_memory_image_information_t *) page_data )->signature[ 3 ] );

			if( ( io_handle->file_type == LIBHIBR_FILE_TYPE_WINDOWS_XP_32BIT )
			 || ( io_handle->file_type == LIBHIBR_FILE_TYPE_WINDOWS_XP_64BIT ) )
			{
				byte_stream_copy_to_uint32_little_endian(
				 ( (hibr_memory_image_information_winxp_32bit_t *) page_data )->version,
				 value_32bit );
				libcnotify_printf(
				 "%s: version\t\t: %" PRIu32 "\n",
				 function,
				 value_32bit );
			}
			else if( ( io_handle->file_type == LIBHIBR_FILE_TYPE_WINDOWS_7_32BIT )
			      || ( io_handle->file_type == LIBHIBR_FILE_TYPE_WINDOWS_7_64BIT ) )
			{
				byte_stream_copy_to_uint32_little_endian(
				 ( (hibr_memory_image_information_win7_32bit_t *) page_data )->image_type,
				 value_32bit );
				libcnotify_printf(
				 "%s: image type\t\t: %" PRIu32 "\n",
				 function,
				 value_32bit );
			}
			byte_stream_copy_to_uint32_little_endian(
			 ( (hibr_memory_image_information_t *) page_data )->checksum,
			 value_32bit );
			libcnotify_printf(
			 "%s: checksum\t\t: 0x%08" PRIx32 "\n",
			 function,
			 value_32bit );

			libcnotify_printf(
			 "%s: size\t\t\t: %" PRIu32 "\n",
			 function,
			 memory_image_information_data_size );

			if( io_handle->file_type == LIBHIBR_FILE_TYPE_WINDOWS_XP_32BIT )
			{
				byte_stream_copy_to_uint32_little_endian(
				 ( (hibr_memory_image_information_winxp_32bit_t *) page_data )->page_number,
				 value_64bit );
			}
			else if( io_handle->file_type == LIBHIBR_FILE_TYPE_WINDOWS_XP_64BIT )
			{
				byte_stream_copy_to_uint64_little_endian(
				 ( (hibr_memory_image_information_winxp_64bit_t *) page_data )->page_number,
				 value_64bit );
			}
			else if( io_handle->file_type == LIBHIBR_FILE_TYPE_WINDOWS_7_32BIT )
			{
				byte_stream_copy_to_uint32_little_endian(
				 ( (hibr_memory_image_information_win7_32bit_t *) page_data )->page_number,
				 value_64bit );
			}
			else if( io_handle->file_type == LIBHIBR_FILE_TYPE_WINDOWS_7_64BIT )
			{
				byte_stream_copy_to_uint64_little_endian(
				 ( (hibr_memory_image_information_win7_64bit_t *) page_data )->page_number,
				 value_64bit );
			}
			libcnotify_printf(
			 "%s: page number\t\t: %" PRIu64 "\n",
			 function,
			 value_64bit );

			libcnotify_printf(
			 "%s: page size\t\t: %" PRIu64 "\n",
			 function,
			 page_size );

			if( ( io_handle->file_type == LIBHIBR_FILE_TYPE_WINDOWS_XP_32BIT )
			 || ( io_handle->file_type == LIBHIBR_FILE_TYPE_WINDOWS_XP_64BIT ) )
			{
				if( io_handle->file_type == LIBHIBR_FILE_TYPE_WINDOWS_XP_32BIT )
				{
					byte_stream_copy_to_uint32_little_endian(
					 ( (hibr_memory_image_information_winxp_32bit_t *) page_data )->image_type,
					 value_32bit );
				}
				else
				{
					byte_stream_copy_to_uint32_little_endian(
					 ( (hibr_memory_image_information_winxp_64bit_t *) page_data )->image_type,
					 value_32bit );
				}
				libcnotify_printf(
				 "%s: image type\t\t: %" PRIu32 "\n",
				 function,
				 value_32bit );
			}
			if( io_handle->file_type == LIBHIBR_FILE_TYPE_WINDOWS_XP_32BIT )
			{
				byte_stream_copy_to_uint32_little_endian(
				 ( (hibr_memory_image_information_winxp_32bit_t *) page_data )->unknown1,
				 value_32bit );
				libcnotify_printf(
				 "%s: unknown1\t\t: 0x%08" PRIx32 "\n",
				 function,
				 value_32bit );
			}
			if( ( io_handle->file_type == LIBHIBR_FILE_TYPE_WINDOWS_XP_32BIT )
			 || ( io_handle->file_type == LIBHIBR_FILE_TYPE_WINDOWS_XP_64BIT ) )
			{
				byte_stream_copy_to_uint64_little_endian(
				 ( (hibr_memory_image_information_winxp_32bit_t *) page_data )->system_time,
				 value_64bit );
			}
			else if( io_handle->file_type == LIBHIBR_FILE_TYPE_WINDOWS_7_32BIT )
			{
				byte_stream_copy_to_uint64_little_endian(
				 ( (hibr_memory_image_information_win7_32bit_t *) page_data )->system_time,
				 value_64bit );
			}
			else if( io_handle->file_type == LIBHIBR_FILE_TYPE_WINDOWS_7_64BIT )
			{
				byte_stream_copy_to_uint64_little_endian(
				 ( (hibr_memory_image_information_win7_64bit_t *) page_data )->system_time,
				 value_64bit );
			}
			if( libfdatetime_filetime_initialize(
			     &filetime,
			     error ) != 1 )
			{
				libcerror_error_set(
				 error,
				 LIBCERROR_ERROR_DOMAIN_RUNTIME,
				 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
				 "%s: unable to create filetime.",
				 function );

				goto on_error;
			}
			if( libfdatetime_filetime_copy_from_64bit(
			     filetime,
			     value_64bit,
			     error ) != 1 )
			{
				libcerror_error_set(
				 error,
				 LIBCERROR_ERROR_DOMAIN_RUNTIME,
				 LIBCERROR_RUNTIME_ERROR_COPY_FAILED,
				 "%s: unable to copy byte stream to filetime.",
				 function );

				goto on_error;
			}
#if defined( LIBCSTRING_HAVE_WIDE_SYSTEM_CHARACTER )
			result = libfdatetime_filetime_copy_to_utf16_string(
				  filetime,
				  (uint16_t *) filetime_string,
				  32,
				  LIBFDATETIME_STRING_FORMAT_TYPE_CTIME | LIBFDATETIME_STRING_FORMAT_FLAG_DATE_TIME_NANO_SECONDS,
				  error );
#else
			result = libfdatetime_filetime_copy_to_utf8_string(
				  filetime,
				  (uint8_t *) filetime_string,
				  32,
				  LIBFDATETIME_STRING_FORMAT_TYPE_CTIME | LIBFDATETIME_STRING_FORMAT_FLAG_DATE_TIME_NANO_SECONDS,
				  error );
#endif
			if( result != 1 )
			{
				libcerror_error_set(
				 error,
				 LIBCERROR_ERROR_DOMAIN_RUNTIME,
				 LIBCERROR_RUNTIME_ERROR_COPY_FAILED,
				 "%s: unable to copy filetime to string.",
				 function );

				goto on_error;
			}
			libcnotify_printf(
			 "%s: system time\t\t: %" PRIs_LIBCSTRING_SYSTEM " UTC\n",
			 function,
			 filetime_string );

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

				goto on_error;
			}
			if( ( io_handle->file_type == LIBHIBR_FILE_TYPE_WINDOWS_XP_32BIT )
			 || ( io_handle->file_type == LIBHIBR_FILE_TYPE_WINDOWS_XP_64BIT ) )
			{
				byte_stream_copy_to_uint64_little_endian(
				 ( (hibr_memory_image_information_winxp_32bit_t *) page_data )->interrupt_time,
				 value_64bit );
			}
			libcnotify_printf(
			 "%s: interrupt time\t\t: 0x%08" PRIx64 "\n",
			 function,
			 value_64bit );

			if( ( io_handle->file_type == LIBHIBR_FILE_TYPE_WINDOWS_XP_32BIT )
			 || ( io_handle->file_type == LIBHIBR_FILE_TYPE_WINDOWS_XP_64BIT ) )
			{
				byte_stream_copy_to_uint32_little_endian(
				 ( (hibr_memory_image_information_winxp_32bit_t *) page_data )->feature_flags,
				 value_32bit );
			}
			libcnotify_printf(
			 "%s: feature flags\t\t: 0x%08" PRIx32 "\n",
			 function,
			 value_32bit );

			if( ( io_handle->file_type == LIBHIBR_FILE_TYPE_WINDOWS_XP_32BIT )
			 || ( io_handle->file_type == LIBHIBR_FILE_TYPE_WINDOWS_XP_64BIT ) )
			{
				value_8bit = ( (hibr_memory_image_information_winxp_32bit_t *) page_data )->hibernation_flags;
			}
			libcnotify_printf(
			 "%s: hibernation flags\t: 0x%02" PRIx8 "\n",
			 function,
			 value_8bit );

			if( io_handle->file_type == LIBHIBR_FILE_TYPE_WINDOWS_XP_32BIT )
			{
				libcnotify_printf(
				 "%s: unknown2:\n",
				 function );
				libcnotify_print_data(
				 ( (hibr_memory_image_information_winxp_32bit_t *) page_data )->unknown2,
				 3,
				 0 );
			}
			else if( io_handle->file_type == LIBHIBR_FILE_TYPE_WINDOWS_XP_64BIT )
			{
				libcnotify_printf(
				 "%s: unknown1:\n",
				 function );
				libcnotify_print_data(
				 ( (hibr_memory_image_information_winxp_64bit_t *) page_data )->unknown1,
				 3,
				 0 );

				byte_stream_copy_to_uint32_little_endian(
				 ( (hibr_memory_image_information_winxp_64bit_t *) page_data )->unknown2,
				 value_32bit );
				libcnotify_printf(
				 "%s: unknown2\t\t: 0x%08" PRIx32 "\n",
				 function,
				 value_32bit );
			}
			if( ( io_handle->file_type == LIBHIBR_FILE_TYPE_WINDOWS_XP_32BIT )
			 || ( io_handle->file_type == LIBHIBR_FILE_TYPE_WINDOWS_XP_64BIT ) )
			{
				byte_stream_copy_to_uint32_little_endian(
				 ( (hibr_memory_image_information_winxp_32bit_t *) page_data )->unknown3,
				 value_32bit );
			}
			libcnotify_printf(
			 "%s: unknown3\t\t: 0x%08" PRIx32 "\n",
			 function,
			 value_32bit );

			if( ( io_handle->file_type == LIBHIBR_FILE_TYPE_WINDOWS_XP_32BIT )
			 || ( io_handle->file_type == LIBHIBR_FILE_TYPE_WINDOWS_XP_64BIT ) )
			{
				byte_stream_copy_to_uint32_little_endian(
				 ( (hibr_memory_image_information_winxp_32bit_t *) page_data )->unknown4,
				 value_32bit );
			}
			libcnotify_printf(
			 "%s: unknown4\t\t: 0x%08" PRIx32 "\n",
			 function,
			 value_32bit );

			if( ( io_handle->file_type == LIBHIBR_FILE_TYPE_WINDOWS_XP_32BIT )
			 || ( io_handle->file_type == LIBHIBR_FILE_TYPE_WINDOWS_XP_64BIT ) )
			{
				byte_stream_copy_to_uint64_little_endian(
				 ( (hibr_memory_image_information_winxp_32bit_t *) page_data )->unknown5,
				 value_64bit );
			}
			libcnotify_printf(
			 "%s: unknown5\t\t: 0x%08" PRIx64 "\n",
			 function,
			 value_64bit );

			if( ( io_handle->file_type == LIBHIBR_FILE_TYPE_WINDOWS_XP_32BIT )
			 || ( io_handle->file_type == LIBHIBR_FILE_TYPE_WINDOWS_XP_64BIT ) )
			{
				byte_stream_copy_to_uint32_little_endian(
				 ( (hibr_memory_image_information_winxp_32bit_t *) page_data )->number_of_free_pages,
				 value_32bit );
			}
			libcnotify_printf(
			 "%s: number of free pages\t: %" PRIu32 "\n",
			 function,
			 value_32bit );

			if( ( io_handle->file_type == LIBHIBR_FILE_TYPE_WINDOWS_XP_32BIT )
			 || ( io_handle->file_type == LIBHIBR_FILE_TYPE_WINDOWS_XP_64BIT ) )
			{
				byte_stream_copy_to_uint32_little_endian(
				 ( (hibr_memory_image_information_winxp_32bit_t *) page_data )->unknown6,
				 value_32bit );
			}
			libcnotify_printf(
			 "%s: unknown6\t\t: 0x%08" PRIx32 "\n",
			 function,
			 value_32bit );

			if( ( io_handle->file_type == LIBHIBR_FILE_TYPE_WINDOWS_XP_32BIT )
			 || ( io_handle->file_type == LIBHIBR_FILE_TYPE_WINDOWS_XP_64BIT ) )
			{
				byte_stream_copy_to_uint32_little_endian(
				 ( (hibr_memory_image_information_winxp_32bit_t *) page_data )->unknown7,
				 value_32bit );
			}
			libcnotify_printf(
			 "%s: unknown7\t\t: 0x%08" PRIx32 "\n",
			 function,
			 value_32bit );

			if( io_handle->file_type == LIBHIBR_FILE_TYPE_WINDOWS_XP_64BIT )
			{
				byte_stream_copy_to_uint32_little_endian(
				 ( (hibr_memory_image_information_winxp_64bit_t *) page_data )->unknown8,
				 value_32bit );
				libcnotify_printf(
				 "%s: unknown8\t\t: 0x%08" PRIx32 "\n",
				 function,
				 value_32bit );
			}
			if( ( io_handle->file_type == LIBHIBR_FILE_TYPE_WINDOWS_XP_32BIT )
			 || ( io_handle->file_type == LIBHIBR_FILE_TYPE_WINDOWS_XP_64BIT ) )
			{
				byte_stream_copy_to_uint32_little_endian(
				 ( (hibr_memory_image_information_winxp_32bit_t *) page_data )->number_of_pages,
				 value_32bit );
			}
			libcnotify_printf(
			 "%s: number of pages\t: %" PRIu32 "\n",
			 function,
			 value_32bit );

			if( io_handle->file_type == LIBHIBR_FILE_TYPE_WINDOWS_XP_32BIT )
			{
				byte_stream_copy_to_uint32_little_endian(
				 ( (hibr_memory_image_information_winxp_32bit_t *) page_data )->unknown8,
				 value_32bit );
				libcnotify_printf(
				 "%s: unknown8\t\t: 0x%08" PRIx32 "\n",
				 function,
				 value_32bit );

				byte_stream_copy_to_uint32_little_endian(
				 ( (hibr_memory_image_information_winxp_32bit_t *) page_data )->unknown9,
				 value_32bit );
				libcnotify_printf(
				 "%s: unknown9\t\t: 0x%08" PRIx32 "\n",
				 function,
				 value_32bit );

				libcnotify_printf(
				 "%s: unknown10:\n",
				 function );
				libcnotify_print_data(
				 ( (hibr_memory_image_information_winxp_32bit_t *) page_data )->unknown10,
				 72,
				 0 );
			}
			else if( io_handle->file_type == LIBHIBR_FILE_TYPE_WINDOWS_XP_64BIT )
			{
				byte_stream_copy_to_uint32_little_endian(
				 ( (hibr_memory_image_information_winxp_64bit_t *) page_data )->unknown8,
				 value_32bit );
				libcnotify_printf(
				 "%s: unknown8\t\t: 0x%08" PRIx32 "\n",
				 function,
				 value_32bit );

				byte_stream_copy_to_uint32_little_endian(
				 ( (hibr_memory_image_information_winxp_64bit_t *) page_data )->unknown9,
				 value_32bit );
				libcnotify_printf(
				 "%s: unknown9\t\t: 0x%08" PRIx32 "\n",
				 function,
				 value_32bit );

				libcnotify_printf(
				 "%s: unknown10:\n",
				 function );
				libcnotify_print_data(
				 ( (hibr_memory_image_information_winxp_64bit_t *) page_data )->unknown10,
				 72,
				 0 );
			}
			else
			{
				libcnotify_printf(
				 "\n" );
			}
		}
#endif
	}
#if defined( HAVE_DEBUG_OUTPUT )
	else if( libcnotify_verbose != 0 )
	{
		libcnotify_printf(
		 "%s: page data:\n",
		 function );
		libcnotify_print_data(
		 page_data,
		 io_handle->page_size,
		 LIBCNOTIFY_PRINT_DATA_FLAG_GROUP_DATA );
	}
#endif
/* TODO print trailing data */

/* TODO page size sanity check */
	io_handle->page_size = (size_t) page_size;

/* TODO memory blocks page number sanity check */

	memory_free(
	 page_data );

	page_data = NULL;

	return( 1 );

on_error:
#if defined( HAVE_DEBUG_OUTPUT )
	if( filetime != NULL )
	{
		libfdatetime_filetime_free(
		 &filetime,
		 NULL );
	}
#endif
	if( page_data != NULL )
	{
		memory_free(
		 page_data );
	}
	return( -1 );
}