/* Opens the parent input file * Returns 1 if successful, 0 if no parent or -1 on error */ int mount_handle_open_input_parent_file( mount_handle_t *mount_handle, libvhdi_file_t *input_file, libcerror_error_t **error ) { uint8_t guid[ 16 ]; libcstring_system_character_t *parent_basename_end = NULL; libcstring_system_character_t *parent_filename = NULL; libcstring_system_character_t *parent_path = NULL; libvhdi_file_t *parent_input_file = NULL; static char *function = "mount_handle_open_input_parent_file"; size_t parent_basename_length = 0; size_t parent_filename_size = 0; size_t parent_path_size = 0; int entry_index = 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 ); } result = libvhdi_file_get_parent_identifier( input_file, guid, 16, error ); if( result == -1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve parent content identifier.", function ); goto on_error; } else if( result != 1 ) { return( 0 ); } #if defined( LIBCSTRING_HAVE_WIDE_SYSTEM_CHARACTER ) result = libvhdi_file_get_utf16_parent_filename_size( input_file, &parent_filename_size, error ); #else result = libvhdi_file_get_utf8_parent_filename_size( input_file, &parent_filename_size, error ); #endif if( result != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve parent filename size.", function ); goto on_error; } if( parent_filename_size == 0 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_VALUE_MISSING, "%s: missing parent filename.", function ); goto on_error; } if( ( parent_filename_size > (size_t) SSIZE_MAX ) || ( ( sizeof( libcstring_system_character_t ) * parent_filename_size ) > (size_t) SSIZE_MAX ) ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_VALUE_EXCEEDS_MAXIMUM, "%s: invalid parent filename size value exceeds maximum.", function ); goto on_error; } parent_filename = libcstring_system_string_allocate( parent_filename_size ); if( parent_filename == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_MEMORY, LIBCERROR_MEMORY_ERROR_INSUFFICIENT, "%s: unable to create parent filename string.", function ); goto on_error; } #if defined( LIBCSTRING_HAVE_WIDE_SYSTEM_CHARACTER ) result = libvhdi_file_get_utf16_parent_filename( input_file, (uint16_t *) parent_filename, parent_filename_size, error ); #else result = libvhdi_file_get_utf8_parent_filename( input_file, (uint8_t *) parent_filename, parent_filename_size, error ); #endif if( result != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve parent filename.", function ); goto on_error; } parent_basename_end = libcstring_system_string_search_character_reverse( parent_filename, (libcstring_system_character_t) '\\', parent_filename_size ); if( parent_basename_end != NULL ) { parent_basename_length = (size_t) ( parent_basename_end - parent_filename ) + 1; } if( mount_handle->basename == NULL ) { parent_path = &( parent_filename[ parent_basename_length ] ); parent_path_size = parent_filename_size - ( parent_basename_length + 1 ); } else { #if defined( LIBCSTRING_HAVE_WIDE_SYSTEM_CHARACTER ) if( libcpath_path_join_wide( &parent_path, &parent_path_size, mount_handle->basename, mount_handle->basename_size - 1, &( parent_filename[ parent_basename_length ] ), parent_filename_size - ( parent_basename_length + 1 ), error ) != 1 ) #else if( libcpath_path_join( &parent_path, &parent_path_size, mount_handle->basename, mount_handle->basename_size - 1, &( parent_filename[ parent_basename_length ] ), parent_filename_size - ( parent_basename_length + 1 ), error ) != 1 ) #endif { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, "%s: unable to create parent path.", function ); goto on_error; } } if( libvhdi_file_initialize( &parent_input_file, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, "%s: unable to initialize parent input file.", function ); goto on_error; } #if defined( LIBCSTRING_HAVE_WIDE_SYSTEM_CHARACTER ) if( libvhdi_file_open_wide( parent_input_file, parent_path, LIBVHDI_OPEN_READ, error ) != 1 ) #else if( libvhdi_file_open( parent_input_file, parent_path, LIBVHDI_OPEN_READ, error ) != 1 ) #endif { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_IO, LIBCERROR_IO_ERROR_OPEN_FAILED, "%s: unable to open parent input file: %" PRIs_LIBCSTRING_SYSTEM ".", function, parent_path ); goto on_error; } if( mount_handle_open_input_parent_file( mount_handle, parent_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 ); return( -1 ); } if( libvhdi_file_set_parent_file( input_file, parent_input_file, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_SET_FAILED, "%s: unable to set parent input file.", function ); goto on_error; } if( libcdata_array_append_entry( mount_handle->input_files_array, &entry_index, (intptr_t *) parent_input_file, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_APPEND_FAILED, "%s: unable to append parent input file to array.", function ); goto on_error; } if( parent_path != NULL ) { if( mount_handle->basename != NULL ) { memory_free( parent_path ); } parent_path = NULL; } if( parent_filename != NULL ) { memory_free( parent_filename ); parent_filename = NULL; } return( 1 ); on_error: if( parent_input_file != NULL ) { libvhdi_file_free( &parent_input_file, NULL ); } if( ( parent_path != NULL ) && ( mount_handle->basename != NULL ) ) { memory_free( parent_path ); } if( parent_filename != NULL ) { memory_free( parent_filename ); } return( -1 ); }
/* Prints the file information to a stream * Returns 1 if successful or -1 on error */ int info_handle_file_fprint( info_handle_t *info_handle, libcerror_error_t **error ) { uint8_t guid_data[ 16 ]; libcstring_system_character_t guid_string[ 48 ]; libfguid_identifier_t *guid = NULL; libcstring_system_character_t *value_string = NULL; static char *function = "info_handle_file_fprint"; size_t value_string_size = 0; size64_t media_size = 0; uint32_t disk_type = 0; uint16_t major_version = 0; uint16_t minor_version = 0; int result = 0; if( info_handle == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid info handle.", function ); return( -1 ); } fprintf( info_handle->notify_stream, "Virtual Hard Disk (VHD) image information:\n" ); if( libvhdi_file_get_format_version( info_handle->input_file, &major_version, &minor_version, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve format version.", function ); goto on_error; } fprintf( info_handle->notify_stream, "\tFormat:\t\t\t%" PRIu16 ".%" PRIu16 "\n", major_version, minor_version ); if( libvhdi_file_get_disk_type( info_handle->input_file, &disk_type, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve disk type.", function ); goto on_error; } fprintf( info_handle->notify_stream, "\tDisk type:\t\t" ); switch( disk_type ) { case LIBVHDI_DISK_TYPE_FIXED: fprintf( info_handle->notify_stream, "Fixed" ); break; case LIBVHDI_DISK_TYPE_DYNAMIC: fprintf( info_handle->notify_stream, "Dynamic" ); break; case LIBVHDI_DISK_TYPE_DIFFERENTIAL: fprintf( info_handle->notify_stream, "Differential" ); break; default: fprintf( info_handle->notify_stream, "Unknown" ); break; } fprintf( info_handle->notify_stream, "\n" ); if( libvhdi_file_get_media_size( info_handle->input_file, &media_size, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve media size.", function ); goto on_error; } fprintf( info_handle->notify_stream, "\tMedia size:\t\t%" PRIu64 " bytes\n", media_size ); 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( libvhdi_file_get_identifier( info_handle->input_file, guid_data, 16, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve identifier.", function ); goto on_error; } if( libfguid_identifier_copy_from_byte_stream( guid, guid_data, 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; } fprintf( info_handle->notify_stream, "\tIdentifier:\t\t%" PRIs_LIBCSTRING_SYSTEM "\n", guid_string ); result = libvhdi_file_get_parent_identifier( info_handle->input_file, guid_data, 16, error ); if( result == -1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve parent identifier.", function ); goto on_error; } else if( result != 0 ) { if( libfguid_identifier_copy_from_byte_stream( guid, guid_data, 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; } fprintf( info_handle->notify_stream, "\tParent identifier:\t%" PRIs_LIBCSTRING_SYSTEM "\n", 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 defined( LIBCSTRING_HAVE_WIDE_SYSTEM_CHARACTER ) result = libvhdi_file_get_utf16_parent_filename_size( info_handle->input_file, &value_string_size, error ); #else result = libvhdi_file_get_utf8_parent_filename_size( info_handle->input_file, &value_string_size, error ); #endif if( result == -1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve parent filename string size.", function ); goto on_error; } else if( result != 0 ) { if( ( value_string_size > (size_t) SSIZE_MAX ) || ( ( sizeof( libcstring_system_character_t ) * value_string_size ) > (size_t) SSIZE_MAX ) ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_VALUE_EXCEEDS_MAXIMUM, "%s: invalid parent filename size value exceeds maximum.", function ); goto on_error; } value_string = libcstring_system_string_allocate( value_string_size ); if( value_string == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_MEMORY, LIBCERROR_MEMORY_ERROR_INSUFFICIENT, "%s: unable to create parent filename string.", function ); goto on_error; } #if defined( LIBCSTRING_HAVE_WIDE_SYSTEM_CHARACTER ) result = libvhdi_file_get_utf16_parent_filename( info_handle->input_file, (uint16_t *) value_string, value_string_size, error ); #else result = libvhdi_file_get_utf8_parent_filename( info_handle->input_file, (uint8_t *) value_string, value_string_size, error ); #endif if( result != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve parent filename.", function ); goto on_error; } fprintf( info_handle->notify_stream, "\tParent filename:\t%s\n", value_string ); memory_free( value_string ); value_string = NULL; } /* TODO add more info */ fprintf( info_handle->notify_stream, "\n" ); return( 1 ); on_error: if( value_string != NULL ) { memory_free( value_string ); } if( guid != NULL ) { libfguid_identifier_free( &guid, NULL ); } return( -1 ); }