Example #1
0
/* Empties the area
 * Returns 1 if successful or -1 on error
 */
int libfdata_area_empty(
     libfdata_area_t *area,
     libcerror_error_t **error )
{
	libfdata_internal_area_t *internal_area = NULL;
	static char *function                   = "libfdata_area_empty";

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

		return( -1 );
	}
	internal_area = (libfdata_internal_area_t *) area;

	if( libcdata_array_empty(
	     internal_area->segments_array,
	     (int (*)(intptr_t **, libcerror_error_t **)) &libfdata_range_free,
	     error ) != 1 )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
		 LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
		 "%s: unable to empty segments array.",
		 function );

		return( -1 );
	}
	if( libcdata_array_empty(
	     internal_area->mapped_ranges_array,
	     (int (*)(intptr_t **, libcerror_error_t **)) &libfdata_mapped_range_free,
	     error ) != 1 )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
		 LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
		 "%s: unable to empty mapped ranges array.",
		 function );

		return( -1 );
	}
	internal_area->size = 0;

	return( 1 );
}
Example #2
0
/* Closes the mount handle
 * Returns the 0 if succesful or -1 on error
 */
int mount_handle_close_input(
     mount_handle_t *mount_handle,
     libcerror_error_t **error )
{
	static char *function = "mount_handle_close_input";
	int result            = 0;

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

		return( -1 );
	}
	if( libcdata_array_empty(
	     mount_handle->logical_volumes_array,
	     (int (*)(intptr_t **, libcerror_error_t **)) &libvslvm_logical_volume_free,
	     error ) != 1 )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
		 LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
		 "%s: unable to empty logical volumes array.",
		 function );

		result = -1;
	}
	if( libvslvm_volume_group_free(
	     &( mount_handle->volume_group ),
	     error ) != 1 )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
		 LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
		 "%s: unable to free volume group.",
		 function );

		result = -1;
	}
	if( libvslvm_handle_close(
	     mount_handle->input_handle,
	     error ) != 0 )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_IO,
		 LIBCERROR_IO_ERROR_CLOSE_FAILED,
		 "%s: unable to close input handle.",
		 function );

		result = -1;
	}
	return( result );
}
Example #3
0
/* Opens the input of the mount handle
 * Returns 1 if successful, 0 if the keys could not be read or -1 on error
 */
int mount_handle_open_input(
     mount_handle_t *mount_handle,
     const libcstring_system_character_t *filename,
     libcerror_error_t **error )
{
	libcstring_system_character_t *basename_end = NULL;
	libvhdi_file_t *input_file                  = NULL;
	static char *function                       = "mount_handle_open_input";
	size_t basename_length                      = 0;
	size_t filename_length                      = 0;
	int entry_index                             = 0;

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

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

		return( -1 );
	}
	filename_length = libcstring_system_string_length(
	                   filename );

	basename_end = libcstring_system_string_search_character_reverse(
	                filename,
	                (libcstring_system_character_t) LIBCPATH_SEPARATOR,
	                filename_length + 1 );

	if( basename_end != NULL )
	{
		basename_length = (size_t) ( basename_end - filename ) + 1;
	}
	if( basename_length > 0 )
	{
		if( mount_handle_set_basename(
		     mount_handle,
		     filename,
		     basename_length,
		     error ) != 1 )
		{
			libcerror_error_set(
			 error,
			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
			 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
			 "%s: unable to set basename.",
			 function );

			goto on_error;
		}
	}
	if( libvhdi_file_initialize(
	     &input_file,
	     error ) != 1 )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
		 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
		 "%s: unable to initialize input file.",
		 function );

		goto on_error;
	}
#if defined( LIBCSTRING_HAVE_WIDE_SYSTEM_CHARACTER )
	if( libvhdi_file_open_wide(
	     input_file,
	     filename,
	     LIBVHDI_OPEN_READ,
	     error ) != 1 )
#else
	if( libvhdi_file_open(
	     input_file,
	     filename,
	     LIBVHDI_OPEN_READ,
	     error ) != 1 )
#endif
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_IO,
		 LIBCERROR_IO_ERROR_OPEN_FAILED,
		 "%s: unable to open input file.",
		 function );

		goto on_error;
	}
	if( mount_handle_open_input_parent_file(
	     mount_handle,
	     input_file,
	     error ) == -1 )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_IO,
		 LIBCERROR_IO_ERROR_OPEN_FAILED,
		 "%s: unable to open parent input file.",
		 function );

		goto on_error;
	}
	if( libcdata_array_append_entry(
	     mount_handle->input_files_array,
	     &entry_index,
	     (intptr_t *) input_file,
	     error ) != 1 )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
		 LIBCERROR_RUNTIME_ERROR_APPEND_FAILED,
		 "%s: unable to append input file to array.",
		 function );

		goto on_error;
	}
	return( 1 );

on_error:
	if( input_file != NULL )
	{
		libvhdi_file_free(
		 &input_file,
		 NULL );
	}
	libcdata_array_empty(
	 mount_handle->input_files_array,
	 (int (*)(intptr_t **, libcerror_error_t **)) &libvhdi_file_free,
	 NULL );

	return( -1 );
}
/* 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 );
}
Example #5
0
/* Closes a handle
 * Returns 0 if successful or -1 on error
 */
int libvsmbr_handle_close(
     libvsmbr_handle_t *handle,
     libcerror_error_t **error )
{
	libvsmbr_internal_handle_t *internal_handle = NULL;
	static char *function                       = "libvsmbr_handle_close";
	int result                                  = 0;

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

		return( -1 );
	}
	internal_handle = (libvsmbr_internal_handle_t *) handle;

	if( internal_handle->file_io_handle == NULL )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
		 LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
		 "%s: invalid handle - missing file IO handle.",
		 function );

		return( -1 );
	}
	if( internal_handle->file_io_handle_created_in_library != 0 )
	{
#if defined( HAVE_DEBUG_OUTPUT )
		if( libcnotify_verbose != 0 )
		{
			if( libvsmbr_debug_print_read_offsets(
			     internal_handle->file_io_handle,
			     error ) != 1 )
			{
				libcerror_error_set(
				 error,
				 LIBCERROR_ERROR_DOMAIN_RUNTIME,
				 LIBCERROR_RUNTIME_ERROR_PRINT_FAILED,
				 "%s: unable to print the read offsets.",
				 function );

				result = -1;
			}
		}
#endif
		if( libbfio_handle_close(
		     internal_handle->file_io_handle,
		     error ) != 0 )
		{
			libcerror_error_set(
			 error,
			 LIBCERROR_ERROR_DOMAIN_IO,
			 LIBCERROR_IO_ERROR_CLOSE_FAILED,
			 "%s: unable to close file IO handle.",
			 function );

			result = -1;
		}
		if( libbfio_handle_free(
		     &( internal_handle->file_io_handle ),
		     error ) != 1 )
		{
			libcerror_error_set(
			 error,
			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
			 LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
			 "%s: unable to free file IO handle.",
			 function );

			result = -1;
		}
	}
	internal_handle->file_io_handle                    = NULL;
	internal_handle->file_io_handle_created_in_library = 0;

	if( libcdata_array_empty(
	     internal_handle->partitions_array,
	     (int (*)(intptr_t **, libcerror_error_t **)) &libvsmbr_partition_values_free,
	     error ) != 1 )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
		 LIBCERROR_RUNTIME_ERROR_RESIZE_FAILED,
		 "%s: unable to empty the partitions array.",
		 function );

		result = -1;
	}
	if( libcdata_array_empty(
	     internal_handle->sections_array,
	     (int (*)(intptr_t **, libcerror_error_t **)) &libvsmbr_section_values_free,
	     error ) != 1 )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
		 LIBCERROR_RUNTIME_ERROR_RESIZE_FAILED,
		 "%s: unable to empty the sections array.",
		 function );

		result = -1;
	}
	return( result );
}
Example #6
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 );
}
Example #7
0
/* Opens a file for reading
 * Returns 1 if successful or -1 on error
 */
int libnk2_file_open_read(
     libnk2_internal_file_t *internal_file,
     libbfio_handle_t *file_io_handle,
     libcerror_error_t **error )
{
	libnk2_file_footer_t *file_footer = NULL;
	libnk2_file_header_t *file_header = NULL;
	static char *function             = "libnk2_file_open_read";

	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( internal_file->io_handle == NULL )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
		 LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
		 "%s: invalid internal file - missing IO handle.",
		 function );

		return( -1 );
	}
	internal_file->io_handle->abort = 0;

#if defined( HAVE_DEBUG_OUTPUT )
	if( libcnotify_verbose != 0 )
	{
		libcnotify_printf(
		 "Reading file header:\n" );
	}
#endif
	if( libnk2_file_header_initialize(
	     &file_header,
	     error ) != 1 )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
		 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
		 "%s: unable to create file header.",
		 function );

		goto on_error;
	}
	if( libnk2_file_header_read_file_io_handle(
	     file_header,
	     file_io_handle,
	     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;
	}
#if defined( HAVE_DEBUG_OUTPUT )
	if( libcnotify_verbose != 0 )
	{
		libcnotify_printf(
		 "Reading items:\n" );
	}
#endif
	if( libnk2_file_read_items(
	     internal_file,
	     file_io_handle,
	     file_header->number_of_items,
	     error ) != 1 )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_IO,
		 LIBCERROR_IO_ERROR_READ_FAILED,
		 "%s: unable to read items.",
		 function );

		goto on_error;
	}
	if( libnk2_file_header_free(
	     &file_header,
	     error ) != 1 )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
		 LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
		 "%s: unable to free file header.",
		 function );

		goto on_error;
	}
#if defined( HAVE_DEBUG_OUTPUT )
	if( libcnotify_verbose != 0 )
	{
		libcnotify_printf(
		 "Reading file footer:\n" );
	}
#endif
	if( libnk2_file_footer_initialize(
	     &file_footer,
	     error ) != 1 )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
		 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
		 "%s: unable to create file footer.",
		 function );

		goto on_error;
	}
	if( libnk2_file_footer_read_file_io_handle(
	     file_footer,
	     file_io_handle,
	     error ) != 1 )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_IO,
		 LIBCERROR_IO_ERROR_READ_FAILED,
		 "%s: unable to read file footer.",
		 function );

		goto on_error;
	}
	internal_file->modification_time = file_footer->modification_time;

	if( libnk2_file_footer_free(
	     &file_footer,
	     error ) != 1 )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
		 LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
		 "%s: unable to free file footer.",
		 function );

		goto on_error;
	}
	internal_file->io_handle->abort = 0;

	return( 1 );

on_error:
	if( file_footer != NULL )
	{
		libnk2_file_footer_free(
		 &file_footer,
		 NULL );
	}
	if( file_header != NULL )
	{
		libnk2_file_header_free(
		 &file_header,
		 NULL );
	}
	libcdata_array_empty(
	 internal_file->items_array,
	 (int (*)(intptr_t **, libcerror_error_t **)) &libnk2_internal_item_free,
	 NULL );

	internal_file->io_handle->abort = 0;

	return( -1 );
}
Example #8
0
/* Opens a volume for reading
 * Returns 1 if successful or -1 on error
 */
int libvshadow_volume_open_read(
     libvshadow_internal_volume_t *internal_volume,
     libbfio_handle_t *file_io_handle,
     libcerror_error_t **error )
{
	libvshadow_store_descriptor_t *last_store_descriptor = NULL;
	libvshadow_store_descriptor_t *store_descriptor      = NULL;
	static char *function                                = "libvshadow_volume_open_read";
	off64_t catalog_offset                               = 0;
	int number_of_store_descriptors                      = 0;
	int store_descriptor_index                           = 0;

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

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

		return( -1 );
	}
#if defined( HAVE_LIBVSHADOW_MULTI_THREAD_SUPPORT )
	if( libcthreads_read_write_lock_grab_for_write(
	     internal_volume->read_write_lock,
	     error ) != 1 )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
		 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
		 "%s: unable to grab read/write lock for writing.",
		 function );

		return( -1 );
	}
#endif
#if defined( HAVE_DEBUG_OUTPUT )
	if( libcnotify_verbose != 0 )
	{
		libcnotify_printf(
		 "Reading NTFS volume header:\n" );
	}
#endif
	if( libvshadow_io_handle_read_ntfs_volume_header(
	     internal_volume->io_handle,
	     file_io_handle,
	     &( internal_volume->size ),
	     error ) == -1 )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_IO,
		 LIBCERROR_IO_ERROR_READ_FAILED,
		 "%s: unable to read NTFS volume header.",
		 function );

		goto on_error;
	}
#if defined( HAVE_DEBUG_OUTPUT )
	if( libcnotify_verbose != 0 )
	{
		libcnotify_printf(
		 "Reading VSS volume header:\n" );
	}
#endif
	if( libvshadow_io_handle_read_volume_header(
	     internal_volume->io_handle,
	     file_io_handle,
	     (off64_t) 0x1e00,
	     &catalog_offset,
	     error ) != 1 )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_IO,
		 LIBCERROR_IO_ERROR_READ_FAILED,
		 "%s: unable to read volume header.",
		 function );

		goto on_error;
	}
	if( catalog_offset > 0 )
	{
#if defined( HAVE_DEBUG_OUTPUT )
		if( libcnotify_verbose != 0 )
		{
			libcnotify_printf(
			 "Reading VSS catalog:\n" );
		}
#endif
		if( libvshadow_io_handle_read_catalog(
		     internal_volume->io_handle,
		     file_io_handle,
		     catalog_offset,
		     &( internal_volume->size ),
		     internal_volume->store_descriptors_array,
		     error ) != 1 )
		{
			libcerror_error_set(
			 error,
			 LIBCERROR_ERROR_DOMAIN_IO,
			 LIBCERROR_IO_ERROR_READ_FAILED,
			 "%s: unable to read catalog.",
			 function );

			goto on_error;
		}
		if( libcdata_array_get_number_of_entries(
		     internal_volume->store_descriptors_array,
		     &number_of_store_descriptors,
		     error ) != 1 )
		{
			libcerror_error_set(
			 error,
			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
			 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
			 "%s: unable to retrieve number of store descriptors from array.",
			 function );

			goto on_error;
		}
		for( store_descriptor_index = 0;
		     store_descriptor_index < number_of_store_descriptors;
		     store_descriptor_index++ )
		{
			if( libcdata_array_get_entry_by_index(
			     internal_volume->store_descriptors_array,
			     store_descriptor_index,
			     (intptr_t **) &store_descriptor,
			     error ) != 1 )
			{
				libcerror_error_set(
				 error,
				 LIBCERROR_ERROR_DOMAIN_RUNTIME,
				 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
				 "%s: unable to retrieve store descriptor: %d.",
				 function,
				 store_descriptor_index );

				goto on_error;
			}
			store_descriptor->index = store_descriptor_index;

#if defined( HAVE_DEBUG_OUTPUT )
			if( libcnotify_verbose != 0 )
			{
				libcnotify_printf(
				 "Reading VSS store: %02d:\n",
				 store_descriptor->index );
			}
#endif
			if( libvshadow_store_descriptor_read_store_header(
			     store_descriptor,
			     file_io_handle,
			     error ) != 1 )
			{
				libcerror_error_set(
				 error,
				 LIBCERROR_ERROR_DOMAIN_IO,
				 LIBCERROR_IO_ERROR_READ_FAILED,
				 "%s: unable to read store: %d header.",
				 function,
				 store_descriptor->index );

				goto on_error;
			}
			store_descriptor->previous_store_descriptor = last_store_descriptor;

			if( last_store_descriptor != NULL )
			{
				last_store_descriptor->next_store_descriptor = store_descriptor;
			}
			last_store_descriptor = store_descriptor;

			store_descriptor = NULL;
		}
	}
#if defined( HAVE_LIBVSHADOW_MULTI_THREAD_SUPPORT )
	if( libcthreads_read_write_lock_release_for_write(
	     internal_volume->read_write_lock,
	     error ) != 1 )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
		 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
		 "%s: unable to release read/write lock for writing.",
		 function );

		return( -1 );
	}
#endif
	return( 1 );

on_error:
	internal_volume->size = 0;

	libcdata_array_empty(
	 internal_volume->store_descriptors_array,
	 (int (*)(intptr_t **, libcerror_error_t **)) &libvshadow_store_descriptor_free,
	 NULL );

#if defined( HAVE_LIBVSHADOW_MULTI_THREAD_SUPPORT )
	libcthreads_read_write_lock_release_for_write(
	 internal_volume->read_write_lock,
	 NULL );
#endif
	return( -1 );
}
Example #9
0
/* Closes a volume
 * Returns 0 if successful or -1 on error
 */
int libvshadow_volume_close(
     libvshadow_volume_t *volume,
     libcerror_error_t **error )
{
	libvshadow_internal_volume_t *internal_volume = NULL;
	static char *function                         = "libvshadow_volume_close";
	int result                                    = 0;

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

		return( -1 );
	}
	internal_volume = (libvshadow_internal_volume_t *) volume;

	if( internal_volume->io_handle == NULL )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
		 LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
		 "%s: invalid volume - missing IO handle.",
		 function );

		return( -1 );
	}
#if defined( HAVE_LIBVSHADOW_MULTI_THREAD_SUPPORT )
	if( libcthreads_read_write_lock_grab_for_write(
	     internal_volume->read_write_lock,
	     error ) != 1 )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
		 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
		 "%s: unable to grab read/write lock for writing.",
		 function );

		return( -1 );
	}
#endif
#if defined( HAVE_DEBUG_OUTPUT )
	if( libcnotify_verbose != 0 )
	{
		if( internal_volume->file_io_handle_created_in_library != 0 )
		{
			if( libvshadow_debug_print_read_offsets(
			     internal_volume->file_io_handle,
			     error ) != 1 )
			{
				libcerror_error_set(
				 error,
				 LIBCERROR_ERROR_DOMAIN_RUNTIME,
				 LIBCERROR_RUNTIME_ERROR_PRINT_FAILED,
				 "%s: unable to print the read offsets.",
				 function );
			}
		}
	}
#endif
	if( internal_volume->file_io_handle_opened_in_library != 0 )
	{
		if( libbfio_handle_close(
		     internal_volume->file_io_handle,
		     error ) != 0 )
		{
			libcerror_error_set(
			 error,
			 LIBCERROR_ERROR_DOMAIN_IO,
			 LIBCERROR_IO_ERROR_CLOSE_FAILED,
			 "%s: unable to close file IO handle.",
			 function );

			result = -1;
		}
		internal_volume->file_io_handle_opened_in_library = 0;
	}
	if( internal_volume->file_io_handle_created_in_library != 0 )
	{
		if( libbfio_handle_free(
		     &( internal_volume->file_io_handle ),
		     error ) != 1 )
		{
			libcerror_error_set(
			 error,
			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
			 LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
			 "%s: unable to free file IO handle.",
			 function );

			result = -1;
		}
		internal_volume->file_io_handle_created_in_library = 0;
	}
	internal_volume->file_io_handle = NULL;
	internal_volume->size           = 0;

	if( libvshadow_io_handle_clear(
	     internal_volume->io_handle,
	     error ) != 1 )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
		 LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
		 "%s: unable to clear IO handle.",
		 function );

		result = -1;
	}
	if( libcdata_array_empty(
	     internal_volume->store_descriptors_array,
	     (int (*)(intptr_t **, libcerror_error_t **)) &libvshadow_store_descriptor_free,
	     error ) != 1 )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
		 LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
		 "%s: unable to empty store descriptors array.",
		 function );

		result = -1;
	}
#if defined( HAVE_LIBVSHADOW_MULTI_THREAD_SUPPORT )
	if( libcthreads_read_write_lock_release_for_write(
	     internal_volume->read_write_lock,
	     error ) != 1 )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
		 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
		 "%s: unable to release read/write lock for writing.",
		 function );

		return( -1 );
	}
#endif
	return( result );
}
/* Retrieves the table of contents from the optical disk using IOCTL
 * Returns 1 if successful, 0 if not or -1 on error
 */
int libsmdev_optical_disc_get_table_of_contents_ioctl(
     libcfile_file_t *device_file,
     libsmdev_internal_handle_t *internal_handle,
     libcerror_error_t **error )
{
	struct cdrom_tochdr toc_header;
	struct cdrom_tocentry toc_entry;

	static char *function        = "libsmdev_optical_disc_get_table_of_contents_ioctl";
	ssize_t read_count           = 0;
	uint32_t last_session_size   = 0;
	uint32_t last_session_offset = 0;
	uint32_t last_track_size     = 0;
	uint32_t last_track_offset   = 0;
	uint32_t offset              = 0;
	uint16_t entry_index         = 0;
	uint8_t first_entry          = 0;
	uint8_t last_entry           = 0;
	uint8_t last_track_type      = 0;
	uint8_t session_index        = 0;
	uint8_t track_index          = 0;
	uint8_t track_type           = 0;
	int result                   = 0;

	read_count = libcfile_file_io_control_read(
	              device_file,
	              CDROMREADTOCHDR,
	              NULL,
	              0,
	              (uint8_t *) &toc_header,
	              sizeof( struct cdrom_tochdr ),
	              error );

	if( read_count == -1 )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_IO,
		 LIBCERROR_IO_ERROR_IOCTL_FAILED,
		 "%s: unable to query device for: CDROMREADTOCHDR.",
		 function );

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

		return( 0 );
	}
	first_entry = toc_header.cdth_trk0;
	last_entry  = toc_header.cdth_trk1;

#if defined( HAVE_DEBUG_OUTPUT )
	if( libcnotify_verbose != 0 )
	{
		libcnotify_printf(
		 "%s: number of entries\t: %" PRIu8 "\n",
		 function,
		 last_entry );
	}
#endif
	for( entry_index = (uint16_t) first_entry;
	     entry_index <= (uint16_t) last_entry;
	     entry_index++ )
	{
		if( memory_set(
		     &toc_entry,
		     0,
		     sizeof( struct cdrom_tocentry ) ) == NULL )
		{
			libcerror_error_set(
			 error,
			 LIBCERROR_ERROR_DOMAIN_MEMORY,
			 LIBCERROR_MEMORY_ERROR_SET_FAILED,
			 "%s: unable to clear TOC entry.",
			 function );

			goto on_error;
		}
		toc_entry.cdte_track  = (uint8_t) entry_index;
		toc_entry.cdte_format = CDROM_LBA;

		read_count = libcfile_file_io_control_read(
		              device_file,
		              CDROMREADTOCENTRY,
		              NULL,
		              0,
		              (uint8_t *) &toc_entry,
		              sizeof( struct cdrom_tocentry ),
		              error );

		if( read_count == -1 )
		{
			libcerror_error_set(
			 error,
			 LIBCERROR_ERROR_DOMAIN_IO,
			 LIBCERROR_IO_ERROR_IOCTL_FAILED,
			 "%s: unable to query device for: CDROMREADTOCENTRY.",
			 function );

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

			break;
		}
		if( toc_entry.cdte_format == CDROM_LBA )
		{
			offset = (uint32_t) toc_entry.cdte_addr.lba;
		}
		else if( toc_entry.cdte_format == CDROM_MSF )
		{
			libsmdev_optical_disc_copy_msf_to_lba(
			 toc_entry.cdte_addr.msf.minute,
			 toc_entry.cdte_addr.msf.second,
			 toc_entry.cdte_addr.msf.frame,
			 offset );
		}
		else
		{
			libcerror_error_set(
			 error,
			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
			 LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
			 "%s: unsupported CDTE format.",
			 function );

			goto on_error;
		}
		if( ( toc_entry.cdte_ctrl & CDROM_DATA_TRACK ) == 0 )
		{
			track_type = LIBSMDEV_TRACK_TYPE_AUDIO;
		}
		else
		{
			track_type = LIBSMDEV_TRACK_TYPE_MODE1_2048;
		}
#if defined( HAVE_DEBUG_OUTPUT )
		if( libcnotify_verbose != 0 )
		{
			libcnotify_printf(
			 "%s: entry: %" PRIu16 "",
			 function,
			 entry_index );

			if( ( toc_entry.cdte_ctrl & CDROM_DATA_TRACK ) == 0 )
			{
				libcnotify_printf(
				 " (audio)" );
			}
			else
			{
				libcnotify_printf(
				 " (data)" );
			}
			if( toc_entry.cdte_format == CDROM_LBA )
			{
				libcnotify_printf(
				 " start\t: %" PRIu32 "",
				 toc_entry.cdte_addr.lba );
			}
			else if( toc_entry.cdte_format == CDROM_MSF )
			{
				libcnotify_printf(
				 " start\t: %02" PRIu8 ":%02" PRIu8 ".%02" PRIu8 "",
				 toc_entry.cdte_addr.msf.minute,
				 toc_entry.cdte_addr.msf.second,
				 toc_entry.cdte_addr.msf.frame );
			}
			libcnotify_printf(
			 " (offset: %" PRIu32 ")\n",
			 offset );
		}
#endif
		if( entry_index > first_entry )
		{
			if( ( offset < last_track_offset )
			 || ( offset < last_session_offset ) )
			{
				libcerror_error_set(
				 error,
				 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
				 LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
				 "%s: invalid offset value out of bounds.",
				 function );

				goto on_error;
			}
			last_track_size = offset - last_track_offset;

			if( ( last_track_type == LIBSMDEV_TRACK_TYPE_MODE1_2048 )
			 || ( last_track_type != track_type ) )
			{
				if( session_index == 0 )
				{
					if( last_track_size < 11400 )
					{
						libcerror_error_set(
						 error,
						 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
						 LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
						 "%s: invalid last track size value out of bounds.",
						 function );

						goto on_error;
					}
					last_track_size -= 11400;
				}
				else
				{
					if( last_track_size < 6900 )
					{
						libcerror_error_set(
						 error,
						 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
						 LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
						 "%s: invalid last track size value out of bounds.",
						 function );

						goto on_error;
					}
					last_track_size -= 6900;
				}
			}
			if( libsmdev_handle_append_track(
			     internal_handle,
			     last_track_offset,
			     last_track_size,
			     last_track_type,
			     error ) != 1 )
			{
				libcerror_error_set(
				 error,
				 LIBCERROR_ERROR_DOMAIN_RUNTIME,
				 LIBCERROR_RUNTIME_ERROR_APPEND_FAILED,
				 "%s: unable to append track: %" PRIu8 ".",
				 function,
				 track_index );

				goto on_error;
			}
			track_index++;

			if( ( last_track_type == LIBSMDEV_TRACK_TYPE_MODE1_2048 )
			 || ( last_track_type != track_type ) )
			{
				last_session_size = offset - last_session_offset;

				if( libsmdev_handle_append_session(
				     internal_handle,
				     last_session_offset,
				     last_session_size,
				     error ) != 1 )
				{
					libcerror_error_set(
					 error,
					 LIBCERROR_ERROR_DOMAIN_RUNTIME,
					 LIBCERROR_RUNTIME_ERROR_APPEND_FAILED,
					 "%s: unable to append session: %" PRIu8 ".",
					 function,
					 session_index );

					goto on_error;
				}
				session_index++;

				last_session_offset = offset;
			}
		}
		last_track_offset = offset;
		last_track_type   = track_type;
	}
	if( read_count != -1 )
	{
		if( memory_set(
		     &toc_entry,
		     0,
		     sizeof( struct cdrom_tocentry ) ) == NULL )
		{
			libcerror_error_set(
			 error,
			 LIBCERROR_ERROR_DOMAIN_MEMORY,
			 LIBCERROR_MEMORY_ERROR_SET_FAILED,
			 "%s: unable to clear TOC entry.",
			 function );

			goto on_error;
		}
		toc_entry.cdte_track  = CDROM_LEADOUT;
		toc_entry.cdte_format = CDROM_LBA;

		read_count = libcfile_file_io_control_read(
			      device_file,
			      CDROMREADTOCENTRY,
			      NULL,
			      0,
			      (uint8_t *) &toc_entry,
			      sizeof( struct cdrom_tocentry ),
			      error );

		if( read_count == -1 )
		{
			libcerror_error_set(
			 error,
			 LIBCERROR_ERROR_DOMAIN_IO,
			 LIBCERROR_IO_ERROR_IOCTL_FAILED,
			 "%s: unable to query device for: CDROMREADTOCENTRY.",
			 function );

#if defined( HAVE_DEBUG_OUTPUT )
			if( libcnotify_verbose != 0 )
			{
				if( ( error != NULL )
				 && ( *error != NULL ) )
				{
					libcnotify_print_error_backtrace(
					 *error );
				}
			}
#endif
			libcerror_error_free(
			 error );
		}
		else
		{
			if( toc_entry.cdte_format == CDROM_LBA )
			{
				offset = (uint32_t) toc_entry.cdte_addr.lba;
			}
			else if( toc_entry.cdte_format == CDROM_MSF )
			{
				libsmdev_optical_disc_copy_msf_to_lba(
				 toc_entry.cdte_addr.msf.minute,
				 toc_entry.cdte_addr.msf.second,
				 toc_entry.cdte_addr.msf.frame,
				 offset );
			}
			else
			{
				libcerror_error_set(
				 error,
				 LIBCERROR_ERROR_DOMAIN_RUNTIME,
				 LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
				 "%s: unsupported CDTE format.",
				 function );

				goto on_error;
			}
#if defined( HAVE_DEBUG_OUTPUT )
			if( libcnotify_verbose != 0 )
			{
				libcnotify_printf(
				 "\tLead out" );

				if( ( toc_entry.cdte_ctrl & CDROM_DATA_TRACK ) == 0 )
				{
					libcnotify_printf(
					 " (audio)" );
				}
				else
				{
					libcnotify_printf(
					 " (data)" );
				}
				if( toc_entry.cdte_format == CDROM_LBA )
				{
					libcnotify_printf(
					 " start:\t%" PRIu32 "",
					 toc_entry.cdte_addr.lba );
				}
				else if( toc_entry.cdte_format == CDROM_MSF )
				{
					libcnotify_printf(
					 " start:\t%02" PRIu8 ":%02" PRIu8 ".02%" PRIu8 "",
					 toc_entry.cdte_addr.msf.minute,
					 toc_entry.cdte_addr.msf.second,
					 toc_entry.cdte_addr.msf.frame );
				}
				libcnotify_printf(
				 " (offset: %" PRIu32 ")\n\n",
				 offset );
			}
#endif
			if( ( offset < last_track_offset )
			 || ( offset < last_session_offset ) )
			{
				libcerror_error_set(
				 error,
				 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
				 LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
				 "%s: invalid offset value out of bounds.",
				 function );

				goto on_error;
			}
			last_track_size = offset - last_track_offset;

			if( libsmdev_handle_append_track(
			     internal_handle,
			     last_track_offset,
			     last_track_size,
			     last_track_type,
			     error ) != 1 )
			{
				libcerror_error_set(
				 error,
				 LIBCERROR_ERROR_DOMAIN_RUNTIME,
				 LIBCERROR_RUNTIME_ERROR_APPEND_FAILED,
				 "%s: unable to append last track: %" PRIu8 ".",
				 function,
				 track_index );

				goto on_error;
			}
			last_session_size = offset - last_session_offset;

			if( libsmdev_handle_append_session(
			     internal_handle,
			     last_session_offset,
			     last_session_size,
			     error ) != 1 )
			{
				libcerror_error_set(
				 error,
				 LIBCERROR_ERROR_DOMAIN_RUNTIME,
				 LIBCERROR_RUNTIME_ERROR_APPEND_FAILED,
				 "%s: unable to append session: %" PRIu8 ".",
				 function,
				 session_index );

				goto on_error;
			}
			result = 1;
		}
	}
	if( result == 0 )
	{
		if( libcdata_array_empty(
		     internal_handle->tracks_array,
		     (int (*)(intptr_t **, libcerror_error_t **)) &libsmdev_track_value_free,
		     error ) != 1 )
		{
			libcerror_error_set(
			 error,
			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
			 LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
			 "%s: unable to empty tracks array.",
			 function );

			goto on_error;
		}
		if( libcdata_array_empty(
		     internal_handle->sessions_array,
		     (int (*)(intptr_t **, libcerror_error_t **)) &libsmdev_sector_range_free,
		     error ) != 1 )
		{
			libcerror_error_set(
			 error,
			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
			 LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
			 "%s: unable to empty sessions array.",
			 function );

			goto on_error;
		}
	}
	return( result );

on_error:
	libcdata_array_empty(
	 internal_handle->tracks_array,
	 (int (*)(intptr_t **, libcerror_error_t **)) &libsmdev_track_value_free,
	 NULL );

	libcdata_array_empty(
	 internal_handle->sessions_array,
	 (int (*)(intptr_t **, libcerror_error_t **)) &libsmdev_sector_range_free,
	 NULL );

	return( -1 );
}
/* Retrieves the table of contents from the optical disk using the SCSI READ TOC command
 * Returns 1 if successful, 0 if not or -1 on error
 */
int libsmdev_optical_disc_get_table_of_contents_scsi(
     libcfile_file_t *device_file,
     libsmdev_internal_handle_t *internal_handle,
     libcerror_error_t **error )
{
	uint8_t track_info_data[ 64 ];

	uint8_t *toc_data            = NULL;
	uint8_t *toc_entries         = NULL;
	static char *function        = "libsmdev_optical_disc_get_table_of_contents_scsi";
	void *reallocation           = NULL;
	size_t toc_data_offset       = 0;
	size_t toc_data_size         = 0;
	ssize_t read_count           = 0;
	uint32_t lead_out_size       = 0;
	uint32_t lead_out_offset     = 0;
	uint32_t last_track_offset   = 0;
	uint32_t track_offset        = 0;
	uint32_t session_size        = 0;
	uint32_t session_offset      = 0;
	uint32_t next_session_offset = 0;
	uint16_t entry_index         = 0;
	uint8_t first_track_number   = 0;
	uint8_t last_track_number    = 0;
	uint8_t lead_out_index       = 0;
	uint8_t number_of_sessions   = 0;
	uint8_t session_index        = 0;
	uint8_t track_index          = 0;
	uint8_t track_number         = 0;
	uint8_t track_type           = 0;
	int result                   = 0;

	toc_data_size = 1024;

	toc_data = (uint8_t *) memory_allocate(
	                        sizeof( uint8_t ) * toc_data_size );

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

		goto on_error;
	}
	if( memory_set(
	     toc_data,
	     0,
	     sizeof( uint8_t ) * toc_data_size ) == NULL )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_MEMORY,
		 LIBCERROR_MEMORY_ERROR_SET_FAILED,
		 "%s: unable to clear TOC data.",
		 function );

		goto on_error;
	}
	read_count = libsmdev_scsi_read_toc(
	              device_file,
	              LIBSMDEV_SCSI_TOC_CDB_FORMAT_RAW_TOC,
	              toc_data,
	              toc_data_size,
	              error );

	if( read_count == -1 )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
		 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
		 "%s: unable to retrieve TOC.",
		 function );

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

		byte_stream_copy_to_uint16_big_endian(
		 toc_data,
		 toc_data_size );

		if( toc_data_size > 1024 )
		{
			reallocation = memory_reallocate(
					toc_data,
					sizeof( uint8_t ) * toc_data_size );

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

				goto on_error;
			}
			toc_data = (uint8_t *) reallocation;

			read_count = libsmdev_scsi_read_toc(
			              device_file,
			              LIBSMDEV_SCSI_TOC_CDB_FORMAT_RAW_TOC,
			              toc_data,
			              toc_data_size,
			              error );

			if( read_count == -1 )
			{
				libcerror_error_set(
				 error,
				 LIBCERROR_ERROR_DOMAIN_RUNTIME,
				 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
				 "%s: unable to retrieve TOC.",
				 function );

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

	if( toc_data_size > 4 )
	{
#if defined( HAVE_DEBUG_OUTPUT )
		if( libcnotify_verbose != 0 )
		{
			libcnotify_printf(
			 "%s: header:\n",
			 function );
			libcnotify_print_data(
			 toc_data,
			 4,
			 0 );
		}
#endif
		number_of_sessions = (uint16_t) toc_data[ 3 ];

#if defined( HAVE_DEBUG_OUTPUT )
		if( libcnotify_verbose != 0 )
		{
			libcnotify_printf(
			 "%s: number of sessions\t\t\t: %" PRIu8 "\n",
			 function,
			 number_of_sessions );

			libcnotify_printf(
			 "\n" );
		}
#endif
		toc_entries     = &( toc_data[ 4 ] );
		toc_data_offset = 4;

		while( toc_data_offset < (size_t) toc_data_size )
		{
#if defined( HAVE_DEBUG_OUTPUT )
			if( libcnotify_verbose != 0 )
			{
				libcnotify_printf(
				 "%s: entry: %02" PRIu16 ":\n",
				 function,
				 entry_index );
				libcnotify_print_data(
				 toc_entries,
				 11,
				 0 );
			}
#endif
			if( toc_entries[ 3 ] <= 0x63 )
			{
				libsmdev_optical_disc_copy_msf_to_lba(
				 toc_entries[ 8 ],
				 toc_entries[ 9 ],
				 toc_entries[ 10 ],
				 track_offset );
			}
			else if( toc_entries[ 3 ] == 0xa0 )
			{
				first_track_number = toc_entries[ 8 ];
			}
			else if( toc_entries[ 3 ] == 0xa1 )
			{
				last_track_number = toc_entries[ 8 ];
			}
			else if( toc_entries[ 3 ] == 0xa2 )
			{
				libsmdev_optical_disc_copy_msf_to_lba(
				 toc_entries[ 8 ],
				 toc_entries[ 9 ],
				 toc_entries[ 10 ],
				 lead_out_offset );
			}
			else if( toc_entries[ 3 ] == 0xb0 )
			{
				libsmdev_optical_disc_copy_absolute_msf_to_lba(
				 toc_entries[ 4 ],
				 toc_entries[ 5 ],
				 toc_entries[ 6 ],
				 next_session_offset );
			}
#if defined( HAVE_DEBUG_OUTPUT )
			if( libcnotify_verbose != 0 )
			{
				if( toc_entries[ 3 ] <= 0x63 )
				{
					libcnotify_printf(
					 "%s: session: %02" PRIu16 " track: %02" PRIu8 "\t\t\t: %02" PRIu8 ":%02" PRIu8 ".%02" PRIu8 " (offset: %" PRIu32 ")\n",
					 function,
					 toc_entries[ 0 ],
					 toc_entries[ 3 ],
					 toc_entries[ 4 ],
					 toc_entries[ 5 ],
					 toc_entries[ 6 ],
					 track_offset );
				}
				else if( toc_entries[ 3 ] == 0xa0 )
				{
					libcnotify_printf(
					 "%s: session: %02" PRIu8 " first track number\t: %" PRIu8 "\n",
					 function,
					 toc_entries[ 0 ],
					 first_track_number );
				}
				else if( toc_entries[ 3 ] == 0xa1 )
				{
					libcnotify_printf(
					 "%s: session: %02" PRIu8 " last track number\t\t: %" PRIu8 "\n",
					 function,
					 toc_entries[ 0 ],
					 last_track_number );
				}
				else if( toc_entries[ 3 ] == 0xa2 )
				{
					libcnotify_printf(
					 "%s: session: %02" PRIu8 " lead out\t\t\t: %02" PRIu8 ":%02" PRIu8 ".%02" PRIu8 " (offset: %" PRIu32 ")\n",
					 function,
					 toc_entries[ 0 ],
					 toc_entries[ 8 ],
					 toc_entries[ 9 ],
					 toc_entries[ 10 ],
					 lead_out_offset );
				}
				else if( toc_entries[ 3 ] == 0xb0 )
				{
					libcnotify_printf(
					 "%s: session: %02" PRIu16 " end\t\t\t: %02" PRIu8 ":%02" PRIu8 ".%02" PRIu8 " (offset: %" PRIu32 ")\n",
					 function,
					 toc_entries[ 0 ],
					 toc_entries[ 4 ],
					 toc_entries[ 5 ],
					 toc_entries[ 6 ],
					 next_session_offset );
				}
				libcnotify_printf(
				 "\n" );
			}
#endif
			if( ( toc_entries[ 3 ] <= 0x63 )
			 || ( toc_entries[ 3 ] == 0xb0 ) )
			{
				if( track_number >= first_track_number )
				{
			 		if( toc_entries[ 3 ] == 0xb0 )
					{
						track_offset = lead_out_offset;
					}
					if( track_offset < last_track_offset )
					{
						libcerror_error_set(
						 error,
						 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
						 LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
						 "%s: invalid track offset value out of bounds.",
						 function );

						goto on_error;
					}
					if( ( track_index + 1 ) != track_number )
					{
						libcerror_error_set(
						 error,
						 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
						 LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
						 "%s: invalid track number value out of bounds.",
						 function );

						goto on_error;
					}
			 		if( toc_entries[ 3 ] == 0xa2 )
					{
						if( track_number != last_track_number )
						{
							libcerror_error_set(
							 error,
							 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
							 LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
							 "%s: invalid track number value out of bounds.",
							 function );

							goto on_error;
						}
					}
					if( memory_set(
					     track_info_data,
					     0,
					     64 ) == NULL )
					{
						libcerror_error_set(
						 error,
						 LIBCERROR_ERROR_DOMAIN_MEMORY,
						 LIBCERROR_MEMORY_ERROR_SET_FAILED,
						 "%s: unable to clear track info data.",
						 function );

						goto on_error;
					}
					read_count = libsmdev_scsi_read_track_information(
					              device_file,
					              last_track_offset,
					              track_info_data,
					              64,
					              error );

					if( read_count == -1 )
					{
						libcerror_error_set(
						 error,
						 LIBCERROR_ERROR_DOMAIN_RUNTIME,
						 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
						 "%s: unable to retrieve track info data: %d.",
						 function,
						 track_index );

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

						break;
					}
#if defined( HAVE_DEBUG_OUTPUT )
					if( libcnotify_verbose != 0 )
					{
						libcnotify_printf(
						 "%s: track information data: %d:\n",
						 function,
						 track_index );
						libcnotify_print_data(
						 track_info_data,
						 (size_t) read_count,
						 0 );
					}
#endif
					if( track_info_data[ 2 ] != toc_entries[ 0 ] )
					{
						libcerror_error_set(
						 error,
						 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
						 LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
						 "%s: invalid track information data - session number value out of bounds.",
						 function );

						goto on_error;
					}
					if( track_info_data[ 3 ] != track_number )
					{
						libcerror_error_set(
						 error,
						 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
						 LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
						 "%s: invalid track information data - track number value out of bounds.",
						 function );

						goto on_error;
					}
					track_type = LIBSMDEV_TRACK_TYPE_UNKNOWN;

					if( ( track_info_data[ 5 ] & 0x04 ) != 0 )
					{
						if( ( track_info_data[ 5 ] & 0x08 ) == 0 )
						{
							if( ( track_info_data[ 6 ] & 0x0f ) == 1 )
							{
								track_type = LIBSMDEV_TRACK_TYPE_MODE1_2048;
							}
							else if( ( track_info_data[ 6 ] & 0x0f ) == 2 )
							{
								track_type = LIBSMDEV_TRACK_TYPE_MODE2_2048;
							}
						}
					}
					else
					{
						track_type = LIBSMDEV_TRACK_TYPE_AUDIO;
					}
					if( libsmdev_handle_append_track(
					     internal_handle,
					     last_track_offset,
					     track_offset - last_track_offset,
					     track_type,
					     error ) != 1 )
					{
						libcerror_error_set(
						 error,
						 LIBCERROR_ERROR_DOMAIN_RUNTIME,
						 LIBCERROR_RUNTIME_ERROR_APPEND_FAILED,
						 "%s: unable to append track: %d.",
						 function,
						 track_index );

						goto on_error;
					}
					track_index++;
				}
				last_track_offset = track_offset;

			 	if( toc_entries[ 3 ] != 0xb0 )
				{
					track_number = toc_entries[ 3 ];
				}
			}
			if( toc_entries[ 3 ] == 0xb0 )
			{
				if( session_offset >= next_session_offset )
				{
					libcerror_error_set(
					 error,
					 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
					 LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
					 "%s: invalid session offset value out of bounds.",
					 function );

					goto on_error;
				}
				if( ( session_index + 1 ) != toc_entries[ 0 ] )
				{
					libcerror_error_set(
					 error,
					 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
					 LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
					 "%s: invalid session number value out of bounds.",
					 function );

					goto on_error;
				}
				lead_out_size = 0;

				if( ( lead_out_offset >= session_offset )
				 && ( lead_out_offset < next_session_offset ) )
				{
					lead_out_size = next_session_offset - lead_out_offset;

					if( libsmdev_handle_append_lead_out(
					     internal_handle,
					     lead_out_offset,
					     lead_out_size,
					     error ) != 1 )
					{
						libcerror_error_set(
						 error,
						 LIBCERROR_ERROR_DOMAIN_RUNTIME,
						 LIBCERROR_RUNTIME_ERROR_APPEND_FAILED,
						 "%s: unable to append lead_out: %d.",
						 function,
						 lead_out_index );

						goto on_error;
					}
					lead_out_index++;
				}
				session_size = next_session_offset - session_offset;

				if( ( session_index + 1 ) == number_of_sessions )
				{
					session_size -= lead_out_size;
				}
				if( libsmdev_handle_append_session(
				     internal_handle,
				     session_offset,
				     session_size,
				     error ) != 1 )
				{
					libcerror_error_set(
					 error,
					 LIBCERROR_ERROR_DOMAIN_RUNTIME,
					 LIBCERROR_RUNTIME_ERROR_APPEND_FAILED,
					 "%s: unable to append session: %d.",
					 function,
					 session_index );

					goto on_error;
				}
				session_offset = next_session_offset;

				session_index++;
			}
			toc_entries     += 11;
			toc_data_offset += 11;

			entry_index++;
		}
		if( ( track_index + 1 ) == track_number )
		{
			if( track_offset < last_track_offset )
			{
				libcerror_error_set(
				 error,
				 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
				 LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
				 "%s: invalid track offset value out of bounds.",
				 function );

				goto on_error;
			}
			if( memory_set(
			     track_info_data,
			     0,
			     64 ) == NULL )
			{
				libcerror_error_set(
				 error,
				 LIBCERROR_ERROR_DOMAIN_MEMORY,
				 LIBCERROR_MEMORY_ERROR_SET_FAILED,
				 "%s: unable to clear track info data.",
				 function );

				goto on_error;
			}
			read_count = libsmdev_scsi_read_track_information(
			              device_file,
			              last_track_offset,
			              track_info_data,
			              64,
			              error );

			if( read_count == -1 )
			{
				libcerror_error_set(
				 error,
				 LIBCERROR_ERROR_DOMAIN_RUNTIME,
				 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
				 "%s: unable to retrieve track info data: %d.",
				 function,
				 track_index );

#if defined( HAVE_DEBUG_OUTPUT )
				if( libcnotify_verbose != 0 )
				{
					if( ( error != NULL )
					 && ( *error != NULL ) )
					{
						libcnotify_print_error_backtrace(
						 *error );
					}
				}
#endif
				libcerror_error_free(
				 error );
			}
			else
			{
#if defined( HAVE_DEBUG_OUTPUT )
				if( libcnotify_verbose != 0 )
				{
					libcnotify_printf(
					 "%s: track information data: %d:\n",
					 function,
					 track_index );
					libcnotify_print_data(
					 track_info_data,
					 (size_t) read_count,
					 0 );
				}
#endif
				if( track_info_data[ 2 ] != toc_entries[ 0 ] )
				{
					libcerror_error_set(
					 error,
					 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
					 LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
					 "%s: invalid track information data - session number value out of bounds.",
					 function );

					goto on_error;
				}
				if( track_info_data[ 3 ] != toc_entries[ 3 ] )
				{
					libcerror_error_set(
					 error,
					 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
					 LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
					 "%s: invalid track information data - track number value out of bounds.",
					 function );

					goto on_error;
				}
				track_type = LIBSMDEV_TRACK_TYPE_UNKNOWN;

				if( ( track_info_data[ 5 ] & 0x04 ) != 0 )
				{
					if( ( track_info_data[ 5 ] & 0x08 ) == 0 )
					{
						if( ( track_info_data[ 6 ] & 0x0f ) == 1 )
						{
							track_type = LIBSMDEV_TRACK_TYPE_MODE1_2048;
						}
						else if( ( track_info_data[ 6 ] & 0x0f ) == 2 )
						{
							track_type = LIBSMDEV_TRACK_TYPE_MODE2_2048;
						}
					}
				}
				else
				{
					track_type = LIBSMDEV_TRACK_TYPE_AUDIO;
				}
				if( libsmdev_handle_append_track(
				     internal_handle,
				     last_track_offset,
				     track_offset - last_track_offset,
				     track_type,
				     error ) != 1 )
				{
					libcerror_error_set(
					 error,
					 LIBCERROR_ERROR_DOMAIN_RUNTIME,
					 LIBCERROR_RUNTIME_ERROR_APPEND_FAILED,
					 "%s: unable to append last track: %d.",
					 function,
					 track_index );

					goto on_error;
				}
			}
			if( session_index != number_of_sessions )
			{
				libcerror_error_set(
				 error,
				 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
				 LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
				 "%s: invalid session index value out of bounds.",
				 function );

				goto on_error;
			}
			result = 1;
		}
	}
	if( result == 0 )
	{
		if( libcdata_array_empty(
		     internal_handle->tracks_array,
		     (int (*)(intptr_t **, libcerror_error_t **)) &libsmdev_track_value_free,
		     error ) != 1 )
		{
			libcerror_error_set(
			 error,
			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
			 LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
			 "%s: unable to empty tracks array.",
			 function );

			goto on_error;
		}
		if( libcdata_array_empty(
		     internal_handle->lead_outs_array,
		     (int (*)(intptr_t **, libcerror_error_t **)) &libsmdev_sector_range_free,
		     error ) != 1 )
		{
			libcerror_error_set(
			 error,
			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
			 LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
			 "%s: unable to empty lead outs array.",
			 function );

			goto on_error;
		}
		if( libcdata_array_empty(
		     internal_handle->sessions_array,
		     (int (*)(intptr_t **, libcerror_error_t **)) &libsmdev_sector_range_free,
		     error ) != 1 )
		{
			libcerror_error_set(
			 error,
			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
			 LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
			 "%s: unable to empty sessions array.",
			 function );

			goto on_error;
		}
	}
	memory_free(
	 toc_data );

	toc_data = NULL;

	return( result );

on_error:
	if( toc_data != NULL )
	{
		memory_free(
		 toc_data );
	}
	libcdata_array_empty(
	 internal_handle->tracks_array,
	 (int (*)(intptr_t **, libcerror_error_t **)) &libsmdev_track_value_free,
	 NULL );

	libcdata_array_empty(
	 internal_handle->lead_outs_array,
	 (int (*)(intptr_t **, libcerror_error_t **)) &libsmdev_sector_range_free,
	 NULL );

	libcdata_array_empty(
	 internal_handle->sessions_array,
	 (int (*)(intptr_t **, libcerror_error_t **)) &libsmdev_sector_range_free,
	 NULL );

	return( -1 );
}
Example #12
0
/* Opens the mount handle
 * Returns 1 if successful or -1 on error
 */
int mount_handle_open_input(
     mount_handle_t *mount_handle,
     const libcstring_system_character_t *filename,
     libcerror_error_t **error )
{
	libbfio_handle_t *file_io_handle          = NULL;
	libvslvm_logical_volume_t *logical_volume = NULL;
	static char *function                     = "mount_handle_open_input";
	size_t filename_length                    = 0;
	int entry_index                           = 0;
	int logical_volume_index                  = 0;
	int number_of_logical_volumes             = 0;
	int result                                = 0;

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

		return( -1 );
	}
	if( libbfio_file_range_initialize(
	     &file_io_handle,
	     error ) != 1 )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
		 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
		 "%s: unable to initialize file IO handle.",
		 function );

		goto on_error;
	}
	filename_length = libcstring_system_string_length(
	                   filename );

#if defined( LIBCSTRING_HAVE_WIDE_SYSTEM_CHARACTER )
	if( libbfio_file_range_set_name_wide(
	     file_io_handle,
	     filename,
	     filename_length,
	     error ) != 1 )
#else
	if( libbfio_file_range_set_name(
	     file_io_handle,
	     filename,
	     filename_length,
	     error ) != 1 )
#endif
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_IO,
		 LIBCERROR_IO_ERROR_OPEN_FAILED,
		 "%s: unable to open set file name.",
		 function );

		goto on_error;
	}
	if( libbfio_file_range_set(
	     file_io_handle,
	     mount_handle->volume_offset,
	     0,
	     error ) != 1 )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_IO,
		 LIBCERROR_IO_ERROR_OPEN_FAILED,
		 "%s: unable to open set volume offset.",
		 function );

		goto on_error;
	}
	if( libvslvm_handle_open_file_io_handle(
	     mount_handle->input_handle,
	     file_io_handle,
	     LIBVSLVM_OPEN_READ,
	     error ) != 1 )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_IO,
		 LIBCERROR_IO_ERROR_OPEN_FAILED,
		 "%s: unable to open input handle.",
		 function );

		goto on_error;
	}
	if( libbfio_pool_append_handle(
	     mount_handle->physical_volume_file_io_pool,
	     &entry_index,
	     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 input handle.",
		 function );

		goto on_error;
	}
	/* The takes over management of the file IO handle
	 */
	file_io_handle = NULL;

/* TODO determine if the first file is a metadata only file and change filenames accordingly
 */
	if( libvslvm_handle_open_physical_volume_files_file_io_pool(
	     mount_handle->input_handle,
	     mount_handle->physical_volume_file_io_pool,
	     error ) != 1 )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_IO,
		 LIBCERROR_IO_ERROR_OPEN_FAILED,
		 "%s: unable to open physical volume files.",
		 function );

		goto on_error;
	}
	if( libvslvm_handle_get_volume_group(
	     mount_handle->input_handle,
	     &( mount_handle->volume_group ),
	     error ) != 1 )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
		 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
		 "%s: unable to retrieve volume group.",
		 function );

		goto on_error;
	}
	if( libvslvm_volume_group_get_number_of_logical_volumes(
	     mount_handle->volume_group,
	     &number_of_logical_volumes,
	     error ) != 1 )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
		 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
		 "%s: unable to retrieve number of logical volumes.",
		 function );

		goto on_error;
	}
	for( logical_volume_index = 0;
	     logical_volume_index < number_of_logical_volumes;
	     logical_volume_index++ )
	{
		if( libvslvm_volume_group_get_logical_volume(
		     mount_handle->volume_group,
		     logical_volume_index,
		     &logical_volume,
		     error ) != 1 )
		{
			libcerror_error_set(
			 error,
			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
			 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
			 "%s: unable to retrieve logical volume: %d.",
			 function,
			 logical_volume_index );

			goto on_error;
		}
		if( libcdata_array_append_entry(
		     mount_handle->logical_volumes_array,
		     &entry_index,
		     (intptr_t *) logical_volume,
		     error ) != 1 )
		{
			libcerror_error_set(
			 error,
			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
			 LIBCERROR_RUNTIME_ERROR_APPEND_FAILED,
			 "%s: unable to append logical volume to array.",
			 function );

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

on_error:
	if( logical_volume != NULL )
	{
		libvslvm_logical_volume_free(
		 &logical_volume,
		 NULL );
	}
	if( mount_handle->volume_group != NULL )
	{
		libvslvm_volume_group_free(
		 &( mount_handle->volume_group ),
		 NULL );
	}
	if( mount_handle->input_handle != NULL )
	{
		libvslvm_handle_free(
		 &( mount_handle->input_handle ),
		 NULL );
	}
	if( file_io_handle != NULL )
	{
		libbfio_handle_free(
		 &file_io_handle,
		 NULL );
	}
	libcdata_array_empty(
	 mount_handle->logical_volumes_array,
	 (int (*)(intptr_t **, libcerror_error_t **)) &libvslvm_logical_volume_free,
	 NULL );

	return( -1 );
}
/* Reads a physical volume label
 * Returns 1 if successful, 0 if not found or -1 on error
 */
int libvslvm_physical_volume_read_label(
     libvslvm_physical_volume_t *physical_volume,
     libbfio_pool_t *file_io_pool,
     int file_io_pool_entry,
     off64_t file_offset,
     libcerror_error_t **error )
{
	vslvm_data_area_descriptor_t data_area_descriptor_data;
	vslvm_physical_volume_label_header_t physical_volume_label_header;
	vslvm_physical_volume_header_t physical_volume_header;

	libvslvm_data_area_descriptor_t *data_area_descriptor         = NULL;
	libvslvm_internal_physical_volume_t *internal_physical_volume = NULL;
	static char *function                                         = "libvslvm_physical_volume_read_label";
	ssize_t read_count                                            = 0;
	uint64_t offset                                               = 0;
	uint64_t size                                                 = 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( physical_volume == NULL )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
		 "%s: invalid physical volume.",
		 function );

		return( -1 );
	}
	internal_physical_volume = (libvslvm_internal_physical_volume_t *) physical_volume;

#if defined( HAVE_DEBUG_OUTPUT )
	if( libcnotify_verbose != 0 )
	{
		libcnotify_printf(
		 "%s: reading physical volume label at offset: %" PRIi64 "\n",
		 function,
		 file_offset );
	}
#endif
	if( libbfio_pool_seek_offset(
	     file_io_pool,
	     file_io_pool_entry,
	     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_pool_read_buffer(
	              file_io_pool,
	              file_io_pool_entry,
	              (uint8_t *) &physical_volume_label_header,
	              sizeof( vslvm_physical_volume_label_header_t ),
	              error );

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

		goto on_error;
	}
#if defined( HAVE_DEBUG_OUTPUT )
	if( libcnotify_verbose != 0 )
	{
		libcnotify_printf(
		 "%s: physical volume label header data:\n",
		 function );
		libcnotify_print_data(
		 (uint8_t *) &physical_volume_label_header,
		 sizeof( vslvm_physical_volume_label_header_t ),
		 0 );
	}
#endif
	if( memory_compare(
	     physical_volume_label_header.signature,
	     vslvm_physical_volume_label_signature,
	     8 ) != 0 )
	{
		return( 0 );
	}
#if defined( HAVE_DEBUG_OUTPUT )
	if( libcnotify_verbose != 0 )
	{
		libcnotify_printf(
		 "%s: signature\t\t\t\t: %c%c%c%c%c%c%c%c\n",
		 function,
		 physical_volume_label_header.signature[ 0 ],
		 physical_volume_label_header.signature[ 1 ],
		 physical_volume_label_header.signature[ 2 ],
		 physical_volume_label_header.signature[ 3 ],
		 physical_volume_label_header.signature[ 4 ],
		 physical_volume_label_header.signature[ 5 ],
		 physical_volume_label_header.signature[ 6 ],
		 physical_volume_label_header.signature[ 7 ] );

		byte_stream_copy_to_uint64_little_endian(
		 physical_volume_label_header.sector_number,
		 value_64bit );
		libcnotify_printf(
		 "%s: sector number\t\t\t: %" PRIu64 "\n",
		 function,
		 value_64bit );

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

		byte_stream_copy_to_uint32_little_endian(
		 physical_volume_label_header.data_offset,
		 value_32bit );
		libcnotify_printf(
		 "%s: data offset\t\t\t: 0x%08" PRIx32 "\n",
		 function,
		 value_32bit );

		libcnotify_printf(
		 "%s: type indicator\t\t\t: %c%c%c%c%c%c%c%c\n",
		 function,
		 physical_volume_label_header.type_indicator[ 0 ],
		 physical_volume_label_header.type_indicator[ 1 ],
		 physical_volume_label_header.type_indicator[ 2 ],
		 physical_volume_label_header.type_indicator[ 3 ],
		 physical_volume_label_header.type_indicator[ 4 ],
		 physical_volume_label_header.type_indicator[ 5 ],
		 physical_volume_label_header.type_indicator[ 6 ],
		 physical_volume_label_header.type_indicator[ 7 ] );

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

	read_count = libbfio_pool_read_buffer(
	              file_io_pool,
	              file_io_pool_entry,
	              (uint8_t *) &physical_volume_header,
	              sizeof( vslvm_physical_volume_header_t ),
	              error );

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

		goto on_error;
	}
#if defined( HAVE_DEBUG_OUTPUT )
	if( libcnotify_verbose != 0 )
	{
		libcnotify_printf(
		 "%s: physical volume header data:\n",
		 function );
		libcnotify_print_data(
		 (uint8_t *) &physical_volume_header,
		 sizeof( vslvm_physical_volume_header_t ),
		 0 );
	}
#endif
#if defined( HAVE_DEBUG_OUTPUT )
	if( libcnotify_verbose != 0 )
	{
		libcnotify_printf(
		 "%s: identifier\t\t\t\t: %c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c\n",
		 function,
		 physical_volume_header.identifier[ 0 ],
		 physical_volume_header.identifier[ 1 ],
		 physical_volume_header.identifier[ 2 ],
		 physical_volume_header.identifier[ 3 ],
		 physical_volume_header.identifier[ 4 ],
		 physical_volume_header.identifier[ 5 ],
		 physical_volume_header.identifier[ 6 ],
		 physical_volume_header.identifier[ 7 ],
		 physical_volume_header.identifier[ 8 ],
		 physical_volume_header.identifier[ 9 ],
		 physical_volume_header.identifier[ 10 ],
		 physical_volume_header.identifier[ 11 ],
		 physical_volume_header.identifier[ 12 ],
		 physical_volume_header.identifier[ 13 ],
		 physical_volume_header.identifier[ 14 ],
		 physical_volume_header.identifier[ 15 ],
		 physical_volume_header.identifier[ 16 ],
		 physical_volume_header.identifier[ 17 ],
		 physical_volume_header.identifier[ 18 ],
		 physical_volume_header.identifier[ 19 ],
		 physical_volume_header.identifier[ 20 ],
		 physical_volume_header.identifier[ 21 ],
		 physical_volume_header.identifier[ 22 ],
		 physical_volume_header.identifier[ 23 ],
		 physical_volume_header.identifier[ 24 ],
		 physical_volume_header.identifier[ 25 ],
		 physical_volume_header.identifier[ 26 ],
		 physical_volume_header.identifier[ 27 ],
		 physical_volume_header.identifier[ 28 ],
		 physical_volume_header.identifier[ 29 ],
		 physical_volume_header.identifier[ 30 ],
		 physical_volume_header.identifier[ 31 ] );

		byte_stream_copy_to_uint64_little_endian(
		 physical_volume_header.volume_size,
		 value_64bit );
		libcnotify_printf(
		 "%s: volume size\t\t\t: %" PRIu64 "\n",
		 function,
		 value_64bit );

		libcnotify_printf(
		 "\n" );
	}
#endif
	do
	{
		read_count = libbfio_pool_read_buffer(
		              file_io_pool,
		              file_io_pool_entry,
		              (uint8_t *) &data_area_descriptor_data,
		              sizeof( vslvm_data_area_descriptor_t ),
		              error );

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

			goto on_error;
		}
#if defined( HAVE_DEBUG_OUTPUT )
		if( libcnotify_verbose != 0 )
		{
			libcnotify_printf(
			 "%s: data area descriptor data:\n",
			 function );
			libcnotify_print_data(
			 (uint8_t *) &data_area_descriptor_data,
			 sizeof( vslvm_data_area_descriptor_t ),
			 0 );
		}
#endif
		result = memory_compare(
		          (uint8_t *) &data_area_descriptor_data,
		          vslvm_empty_data_area_descriptor,
		          sizeof( vslvm_data_area_descriptor_t ) );

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

			byte_stream_copy_to_uint64_little_endian(
			 data_area_descriptor_data.size,
			 size );

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

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

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

				goto on_error;
			}
			if( libvslvm_data_area_descriptor_set(
			     data_area_descriptor,
			     (off64_t) offset,
			     (size64_t) size,
			     error ) != 1 )
			{
				libcerror_error_set(
				 error,
				 LIBCERROR_ERROR_DOMAIN_RUNTIME,
				 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
				 "%s: unable to set data area descriptor.",
				 function );

				goto on_error;
			}
			if( libcdata_array_append_entry(
			     internal_physical_volume->data_area_descriptors_array,
			     &entry_index,
			     (intptr_t *) data_area_descriptor,
			     error ) != 1 )
			{
				libcerror_error_set(
				 error,
				 LIBCERROR_ERROR_DOMAIN_RUNTIME,
				 LIBCERROR_RUNTIME_ERROR_APPEND_FAILED,
				 "%s: unable to append entry to data area descriptors array.",
				 function );

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

	do
	{
		read_count = libbfio_pool_read_buffer(
		              file_io_pool,
		              file_io_pool_entry,
		              (uint8_t *) &data_area_descriptor_data,
		              sizeof( vslvm_data_area_descriptor_t ),
		              error );

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

			goto on_error;
		}
#if defined( HAVE_DEBUG_OUTPUT )
		if( libcnotify_verbose != 0 )
		{
			libcnotify_printf(
			 "%s: metadata area descriptor data:\n",
			 function );
			libcnotify_print_data(
			 (uint8_t *) &data_area_descriptor_data,
			 sizeof( vslvm_data_area_descriptor_t ),
			 0 );
		}
#endif
		result = memory_compare(
		          (uint8_t *) &data_area_descriptor_data,
		          vslvm_empty_data_area_descriptor,
		          sizeof( vslvm_data_area_descriptor_t ) );

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

			byte_stream_copy_to_uint64_little_endian(
			 data_area_descriptor_data.size,
			 size );

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

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

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

				goto on_error;
			}
			if( libvslvm_data_area_descriptor_set(
			     data_area_descriptor,
			     (off64_t) offset,
			     (size64_t) size,
			     error ) != 1 )
			{
				libcerror_error_set(
				 error,
				 LIBCERROR_ERROR_DOMAIN_RUNTIME,
				 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
				 "%s: unable to set data area descriptor.",
				 function );

				goto on_error;
			}
			if( libcdata_array_append_entry(
			     internal_physical_volume->metadata_area_descriptors_array,
			     &entry_index,
			     (intptr_t *) data_area_descriptor,
			     error ) != 1 )
			{
				libcerror_error_set(
				 error,
				 LIBCERROR_ERROR_DOMAIN_RUNTIME,
				 LIBCERROR_RUNTIME_ERROR_APPEND_FAILED,
				 "%s: unable to append entry to metadata area descriptors array.",
				 function );

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

	return( 1 );

on_error:
	if( data_area_descriptor != NULL )
	{
		libvslvm_data_area_descriptor_free(
		 &data_area_descriptor,
		 NULL );
	}
	libcdata_array_empty(
	 internal_physical_volume->metadata_area_descriptors_array,
	 (int (*)(intptr_t **, libcerror_error_t **)) &libvslvm_data_area_descriptor_free,
	 NULL );

	libcdata_array_empty(
	 internal_physical_volume->data_area_descriptors_array,
	 (int (*)(intptr_t **, libcerror_error_t **)) &libvslvm_data_area_descriptor_free,
	 NULL );

	return( -1 );
}