/* Reads a external key from the metadata entry * Returns 1 if successful or -1 on error */ int libbde_external_key_read( libbde_external_key_t *external_key, libbde_metadata_entry_t *metadata_entry, libcerror_error_t **error ) { libbde_key_t *key = NULL; libbde_metadata_entry_t *property_metadata_entry = NULL; uint8_t *value_data = NULL; static char *function = "libbde_external_key_read"; size_t value_data_size = 0; ssize_t read_count = 0; int property_metadata_entry_index = 0; #if defined( HAVE_DEBUG_OUTPUT ) libcstring_system_character_t filetime_string[ 32 ]; libcstring_system_character_t guid_string[ 48 ]; libfdatetime_filetime_t *filetime = NULL; libfguid_identifier_t *guid = NULL; int result = 0; #endif if( external_key == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid external key.", function ); return( -1 ); } if( metadata_entry == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid metadata entry.", function ); return( -1 ); } if( metadata_entry->value_type != LIBBDE_VALUE_TYPE_EXTERNAL_KEY ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE, "%s: invalid metadata entry - unsupported value type: 0x%04" PRIx16 ".", function, metadata_entry->value_type ); return( -1 ); } value_data = metadata_entry->value_data; value_data_size = metadata_entry->value_data_size; if( value_data_size < sizeof( bde_metadata_entry_external_key_header_t ) ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS, "%s: value data size value out of bounds.", function ); return( -1 ); } if( memory_copy( external_key->identifier, ( (bde_metadata_entry_external_key_header_t *) value_data )->identifier, 16 ) == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_MEMORY, LIBCERROR_MEMORY_ERROR_COPY_FAILED, "%s: unable to copy volume identifier.", function ); goto on_error; } #if defined( HAVE_DEBUG_OUTPUT ) if( libcnotify_verbose != 0 ) { if( libfguid_identifier_initialize( &guid, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, "%s: unable to create GUID.", function ); goto on_error; } if( libfguid_identifier_copy_from_byte_stream( guid, ( (bde_metadata_entry_external_key_header_t *) value_data )->identifier, 16, LIBFGUID_ENDIAN_LITTLE, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_COPY_FAILED, "%s: unable to copy byte stream to GUID.", function ); goto on_error; } #if defined( LIBCSTRING_HAVE_WIDE_SYSTEM_CHARACTER ) result = libfguid_identifier_copy_to_utf16_string( guid, (uint16_t *) guid_string, 48, LIBFGUID_STRING_FORMAT_FLAG_USE_LOWER_CASE, error ); #else result = libfguid_identifier_copy_to_utf8_string( guid, (uint8_t *) guid_string, 48, LIBFGUID_STRING_FORMAT_FLAG_USE_LOWER_CASE, error ); #endif if( result != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_COPY_FAILED, "%s: unable to copy GUID to string.", function ); goto on_error; } libcnotify_printf( "%s: identifier\t\t\t\t\t: %" PRIs_LIBCSTRING_SYSTEM "\n", function, guid_string ); if( libfguid_identifier_free( &guid, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED, "%s: unable to free GUID.", function ); goto on_error; } if( libfdatetime_filetime_initialize( &filetime, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, "%s: unable to create filetime.", function ); goto on_error; } if( libfdatetime_filetime_copy_from_byte_stream( filetime, ( (bde_metadata_entry_external_key_header_t *) value_data )->modification_time, 8, LIBFDATETIME_ENDIAN_LITTLE, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_SET_FAILED, "%s: unable to copy filetime from byte stream.", function ); goto on_error; } #if defined( LIBCSTRING_HAVE_WIDE_SYSTEM_CHARACTER ) result = libfdatetime_filetime_copy_to_utf16_string( filetime, (uint16_t *) filetime_string, 32, LIBFDATETIME_STRING_FORMAT_TYPE_CTIME | LIBFDATETIME_STRING_FORMAT_FLAG_DATE_TIME_NANO_SECONDS, error ); #else result = libfdatetime_filetime_copy_to_utf8_string( filetime, (uint8_t *) filetime_string, 32, LIBFDATETIME_STRING_FORMAT_TYPE_CTIME | LIBFDATETIME_STRING_FORMAT_FLAG_DATE_TIME_NANO_SECONDS, error ); #endif if( result != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_SET_FAILED, "%s: unable to copy filetime to string.", function ); goto on_error; } libcnotify_printf( "%s: modification time\t\t\t\t: %" PRIs_LIBCSTRING_SYSTEM " UTC\n", function, filetime_string ); if( libfdatetime_filetime_free( &filetime, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED, "%s: unable to free filetime.", function ); goto on_error; } libcnotify_printf( "\n" ); } #endif value_data += sizeof( bde_metadata_entry_external_key_header_t ); value_data_size -= sizeof( bde_metadata_entry_external_key_header_t ); while( value_data_size >= sizeof( bde_metadata_entry_v1_t ) ) { if( memory_compare( value_data, libbde_metadata_entry_empty, sizeof( bde_metadata_entry_v1_t ) ) == 0 ) { break; } if( libbde_metadata_entry_initialize( &property_metadata_entry, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, "%s: unable to create property metadata entry.", function ); goto on_error; } read_count = libbde_metadata_entry_read( property_metadata_entry, value_data, value_data_size, error ); if( read_count == -1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_IO, LIBCERROR_IO_ERROR_READ_FAILED, "%s: unable to read property metadata entry.", function ); goto on_error; } value_data += read_count; value_data_size -= read_count; if( property_metadata_entry->value_type == LIBBDE_VALUE_TYPE_KEY ) { if( libbde_key_initialize( &key, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, "%s: unable to create key.", function ); goto on_error; } if( libbde_key_read( key, property_metadata_entry, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_IO, LIBCERROR_IO_ERROR_READ_FAILED, "%s: unable to read key metadata entry.", function ); goto on_error; } if( external_key->key == NULL ) { external_key->key = key; key = NULL; } if( key != NULL ) { if( libbde_key_free( &key, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED, "%s: unable to free key.", function ); goto on_error; } } } else if( property_metadata_entry->value_type == LIBBDE_VALUE_TYPE_UNICODE_STRING ) { #if defined( HAVE_DEBUG_OUTPUT ) if( libbde_metadata_entry_read_string( property_metadata_entry, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_IO, LIBCERROR_IO_ERROR_READ_FAILED, "%s: unable to read string from property metadata entry.", function ); goto on_error; } #endif if( external_key->string_entry == NULL ) { external_key->string_entry = property_metadata_entry; } } if( libcdata_array_append_entry( external_key->entries_array, &property_metadata_entry_index, (intptr_t *) property_metadata_entry, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, "%s: unable to append property metadata entry to entries array.", function ); goto on_error; } property_metadata_entry = NULL; } #if defined( HAVE_DEBUG_OUTPUT ) if( libcnotify_verbose != 0 ) { if( value_data_size > 0 ) { libcnotify_printf( "%s: trailing data:\n", function ); libcnotify_print_data( value_data, value_data_size, LIBCNOTIFY_PRINT_DATA_FLAG_GROUP_DATA ); } } #endif return( 1 ); on_error: #if defined( HAVE_DEBUG_OUTPUT ) if( guid != NULL ) { libfguid_identifier_free( &guid, NULL ); } if( filetime != NULL ) { libfdatetime_filetime_free( &filetime, NULL ); } #endif if( key != NULL ) { libbde_key_free( &key, NULL ); } if( property_metadata_entry != NULL ) { libbde_metadata_entry_free( &property_metadata_entry, NULL ); } return( -1 ); }
/* Prints a FILETIME value * Returns 1 if successful or -1 on error */ int libregf_debug_print_filetime_value( const char *function_name, const char *value_name, const uint8_t *byte_stream, size_t byte_stream_size, int byte_order, uint32_t string_format_flags, libcerror_error_t **error ) { char date_time_string[ 32 ]; libfdatetime_filetime_t *filetime = NULL; static char *function = "libregf_debug_print_filetime_value"; if( libfdatetime_filetime_initialize( &filetime, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, "%s: unable to create filetime.", function ); goto on_error; } if( libfdatetime_filetime_copy_from_byte_stream( filetime, byte_stream, byte_stream_size, byte_order, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_COPY_FAILED, "%s: unable to copy byte stream to filetime.", function ); goto on_error; } if( libfdatetime_filetime_copy_to_utf8_string( filetime, (uint8_t *) date_time_string, 32, string_format_flags, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_COPY_FAILED, "%s: unable to copy filetime to string.", function ); goto on_error; } libcnotify_printf( "%s: %s: %s UTC\n", function_name, value_name, date_time_string ); if( libfdatetime_filetime_free( &filetime, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED, "%s: unable to free filetime.", function ); goto on_error; } return( 1 ); on_error: if( filetime != NULL ) { libfdatetime_filetime_free( &filetime, NULL ); } return( -1 ); }
/* Prints the store information to a stream * Returns 1 if successful or -1 on error */ int info_handle_store_fprint( info_handle_t *info_handle, int store_index, libvshadow_store_t *store, libcerror_error_t **error ) { uint8_t guid_buffer[ 16 ]; libcstring_system_character_t filetime_string[ 32 ]; libcstring_system_character_t guid_string[ 48 ]; libfdatetime_filetime_t *filetime = NULL; libfguid_identifier_t *guid = NULL; libvshadow_block_t *block = NULL; static char *function = "info_handle_store_fprint"; size64_t volume_size = 0; uint64_t value_64bit = 0; uint32_t attribute_flags = 0; int block_index = 0; int number_of_blocks = 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, "Store: %d\n", store_index + 1 ); if( libfdatetime_filetime_initialize( &filetime, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, "%s: unable to create filetime.", function ); goto on_error; } if( 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( libvshadow_store_get_identifier( store, guid_buffer, 16, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve store: %d identifier.", function, store_index ); goto on_error; } if( libfguid_identifier_copy_from_byte_stream( guid, guid_buffer, 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 ); if( libvshadow_store_get_copy_set_identifier( store, guid_buffer, 16, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve store: %d shadow copy set identifier.", function, store_index ); goto on_error; } if( libfguid_identifier_copy_from_byte_stream( guid, guid_buffer, 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, "\tShadow copy set ID\t: %" PRIs_LIBCSTRING_SYSTEM "\n", guid_string ); if( libvshadow_store_get_creation_time( store, &value_64bit, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve store: %d creation time.", function, store_index ); goto on_error; } if( libfdatetime_filetime_copy_from_64bit( filetime, value_64bit, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_CONVERSION, LIBCERROR_CONVERSION_ERROR_GENERIC, "%s: unable to create filetime.", function ); goto on_error; } #if defined( LIBCSTRING_HAVE_WIDE_SYSTEM_CHARACTER ) result = libfdatetime_filetime_copy_to_utf16_string( filetime, (uint16_t *) filetime_string, 32, LIBFDATETIME_STRING_FORMAT_TYPE_CTIME | LIBFDATETIME_STRING_FORMAT_FLAG_DATE_TIME_NANO_SECONDS, error ); #else result = libfdatetime_filetime_copy_to_utf8_string( filetime, (uint8_t *) filetime_string, 32, LIBFDATETIME_STRING_FORMAT_TYPE_CTIME | LIBFDATETIME_STRING_FORMAT_FLAG_DATE_TIME_NANO_SECONDS, error ); #endif if( result != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_COPY_FAILED, "%s: unable to copy filetime to string.", function ); goto on_error; } fprintf( info_handle->notify_stream, "\tCreation time\t\t: %" PRIs_LIBCSTRING_SYSTEM " UTC\n", filetime_string ); if( libvshadow_store_get_copy_identifier( store, guid_buffer, 16, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve store: %d shadow copy identifier.", function, store_index ); goto on_error; } if( libfguid_identifier_copy_from_byte_stream( guid, guid_buffer, 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, "\tShadow copy ID\t\t: %" PRIs_LIBCSTRING_SYSTEM "\n", guid_string ); if( libvshadow_store_get_volume_size( store, &volume_size, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve store: %d volume size.", function, store_index ); goto on_error; } fprintf( info_handle->notify_stream, "\tVolume size\t\t: %" PRIu64 " bytes\n", volume_size ); if( libvshadow_store_get_attribute_flags( store, &attribute_flags, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve store: %d attribute flags.", function, store_index ); goto on_error; } /* TODO print a description of the flags */ fprintf( info_handle->notify_stream, "\tAttribute flags\t\t: 0x%08" PRIx32 "\n", attribute_flags ); 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( libfdatetime_filetime_free( &filetime, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED, "%s: unable to free filetime.", function ); goto on_error; } if( info_handle->show_allocation_information != 0 ) { if( libvshadow_store_get_number_of_blocks( store, &number_of_blocks, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve store: %d number of blocks.", function, store_index ); goto on_error; } fprintf( info_handle->notify_stream, "\tNumber of blocks\t: %d\n", number_of_blocks ); for( block_index = 0; block_index < number_of_blocks; block_index++ ) { if( libvshadow_store_get_block_by_index( store, block_index, &block, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve block: %d.", function, block_index ); goto on_error; } if( info_handle_block_fprint( info_handle, block_index, block, error ) != 1 ) { goto on_error; } if( libvshadow_block_free( &block, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED, "%s: unable to free block: %d.", function, block_index ); goto on_error; } } } fprintf( info_handle->notify_stream, "\n" ); return( 1 ); on_error: if( block != NULL ) { libvshadow_block_free( &block, NULL ); } if( guid != NULL ) { libfguid_identifier_free( &guid, NULL ); } if( filetime != NULL ) { libfdatetime_filetime_free( &filetime, NULL ); } return( -1 ); }
/* Reads the record * Returns 1 if successful or -1 on error */ int libftxf_record_read( libftxf_record_t *record, const uint8_t *record_data, size_t record_data_size, libcerror_error_t **error ) { libftxf_internal_record_t *internal_record = NULL; static char *function = "libftxf_record_read"; size_t record_data_offset = 0; uint16_t record_type = 0; uint16_t name_offset = 0; uint16_t name_size = 0; #if defined( HAVE_DEBUG_OUTPUT ) libcstring_system_character_t date_time_string[ 32 ]; libcstring_system_character_t guid_string[ 48 ]; libcstring_system_character_t *value_string = NULL; libfdatetime_filetime_t *filetime = NULL; libfguid_identifier_t *guid = NULL; size_t value_string_size = 0; uint64_t value_64bit = 0; uint32_t value_32bit = 0; uint16_t value_16bit = 0; int result = 0; #endif if( record == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid record.", function ); return( -1 ); } internal_record = (libftxf_internal_record_t *) record; if( record_data == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid record data.", function ); return( -1 ); } if( record_data_size > (size_t) SSIZE_MAX ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM, "%s: invalid record data size value exceeds maximum.", function ); return( -1 ); } if( record_data_size < sizeof( ftxf_record_header_t ) ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL, "%s: invalid record data value too small.", function ); return( -1 ); } #if defined( HAVE_DEBUG_OUTPUT ) if( libcnotify_verbose != 0 ) { libcnotify_printf( "%s: record header data:\n", function ); libcnotify_print_data( record_data, sizeof( ftxf_record_header_t ), 0 ); } #endif byte_stream_copy_to_uint16_little_endian( ( (ftxf_record_header_t *) record_data )->record_type, record_type ); byte_stream_copy_to_uint32_little_endian( ( (ftxf_record_header_t *) record_data )->record_size, internal_record->size ); #if defined( HAVE_DEBUG_OUTPUT ) if( libcnotify_verbose != 0 ) { byte_stream_copy_to_uint32_little_endian( ( (ftxf_record_header_t *) record_data )->unknown1, value_32bit ); libcnotify_printf( "%s: unknown1\t\t\t\t\t\t: 0x%08" PRIx32 "\n", function, value_32bit ); libcnotify_printf( "%s: record type\t\t\t\t\t: 0x%04" PRIx16 "\n", function, record_type ); byte_stream_copy_to_uint16_little_endian( ( (ftxf_record_header_t *) record_data )->unknown2, value_16bit ); libcnotify_printf( "%s: unknown2\t\t\t\t\t\t: 0x%04" PRIx16 "\n", function, value_16bit ); byte_stream_copy_to_uint64_little_endian( ( (ftxf_record_header_t *) record_data )->file_identifier, value_64bit ); libcnotify_printf( "%s: file identifier\t\t\t\t\t: 0x%08" PRIx64 "\n", function, value_64bit ); byte_stream_copy_to_uint64_little_endian( ( (ftxf_record_header_t *) record_data )->file_reference, value_64bit ); libcnotify_printf( "%s: file reference\t\t\t\t\t: MFT entry: %" PRIu64 ", sequence: %" PRIu64 "\n", function, value_64bit & 0xffffffffffffUL, value_64bit >> 48 ); byte_stream_copy_to_uint32_little_endian( ( (ftxf_record_header_t *) record_data )->unknown4, value_32bit ); libcnotify_printf( "%s: unknown4\t\t\t\t\t\t: 0x%08" PRIx32 "\n", function, value_32bit ); byte_stream_copy_to_uint32_little_endian( ( (ftxf_record_header_t *) record_data )->unknown5, value_32bit ); libcnotify_printf( "%s: unknown5\t\t\t\t\t\t: 0x%08" PRIx32 "\n", function, value_32bit ); if( libfguid_identifier_initialize( &guid, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, "%s: unable to create GUID.", function ); goto on_error; } if( libfguid_identifier_copy_from_byte_stream( guid, ( (ftxf_record_header_t *) record_data )->unknown6, 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; } if( libfguid_identifier_free( &guid, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED, "%s: unable to free GUID.", function ); goto on_error; } libcnotify_printf( "%s: unknown6 guid\t\t\t\t\t: %" PRIs_LIBCSTRING_SYSTEM "\n", function, guid_string ); byte_stream_copy_to_uint64_little_endian( ( (ftxf_record_header_t *) record_data )->unknown7, value_64bit ); libcnotify_printf( "%s: unknown7\t\t\t\t\t\t: 0x%08" PRIx64 "\n", function, value_64bit ); if( libfdatetime_filetime_initialize( &filetime, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, "%s: unable to create filetime.", function ); goto on_error; } if( libfdatetime_filetime_copy_from_byte_stream( filetime, ( (ftxf_record_header_t *) record_data )->unknown8, 8, LIBFDATETIME_ENDIAN_LITTLE, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_SET_FAILED, "%s: unable to copy filetime from byte stream.", function ); goto on_error; } #if defined( LIBCSTRING_HAVE_WIDE_SYSTEM_CHARACTER ) result = libfdatetime_filetime_copy_to_utf16_string( filetime, (uint16_t *) date_time_string, 32, LIBFDATETIME_STRING_FORMAT_TYPE_CTIME | LIBFDATETIME_STRING_FORMAT_FLAG_DATE_TIME_NANO_SECONDS, error ); #else result = libfdatetime_filetime_copy_to_utf8_string( filetime, (uint8_t *) date_time_string, 32, LIBFDATETIME_STRING_FORMAT_TYPE_CTIME | LIBFDATETIME_STRING_FORMAT_FLAG_DATE_TIME_NANO_SECONDS, error ); #endif if( result != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_SET_FAILED, "%s: unable to copy filetime to date time string.", function ); goto on_error; } libcnotify_printf( "%s: unknown8 filetime\t\t\t\t\t: %" PRIs_LIBCSTRING_SYSTEM " UTC\n", function, date_time_string ); if( libfdatetime_filetime_free( &filetime, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED, "%s: unable to free filetime.", function ); goto on_error; } libcnotify_printf( "%s: record size\t\t\t\t\t: %" PRIu32 "\n", function, internal_record->size ); byte_stream_copy_to_uint32_little_endian( ( (ftxf_record_header_t *) record_data )->unknown9, value_32bit ); libcnotify_printf( "%s: unknown9\t\t\t\t\t\t: 0x%08" PRIx32 "\n", function, value_32bit ); byte_stream_copy_to_uint64_little_endian( ( (ftxf_record_header_t *) record_data )->unknown10, value_64bit ); libcnotify_printf( "%s: unknown10\t\t\t\t\t\t: 0x%08" PRIx64 "\n", function, value_64bit ); libcnotify_printf( "\n" ); }
/* Reads a hive bin header * Returns 1 if successful, 0 if no hive bin signature was found or -1 on error */ int libregf_hive_bin_read_header( libregf_hive_bin_t *hive_bin, libbfio_handle_t *file_io_handle, libcerror_error_t **error ) { regf_hive_bin_header_t hive_bin_header; static char *function = "libregf_hive_bin_read_header"; ssize_t read_count = 0; #if defined( HAVE_DEBUG_OUTPUT ) libcstring_system_character_t filetime_string[ 32 ]; libfdatetime_filetime_t *filetime = NULL; uint32_t value_32bit = 0; int result = 0; #endif if( hive_bin == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid hive bin.", function ); return( -1 ); } read_count = libbfio_handle_read_buffer( file_io_handle, (uint8_t *) &hive_bin_header, sizeof( regf_hive_bin_header_t ), error ); if( read_count != (ssize_t) sizeof( regf_hive_bin_header_t ) ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_IO, LIBCERROR_IO_ERROR_READ_FAILED, "%s: unable to read hive bin header data.", function ); goto on_error; } #if defined( HAVE_DEBUG_OUTPUT ) if( libcnotify_verbose != 0 ) { libcnotify_printf( "%s: hive bin header:\n", function ); libcnotify_print_data( (uint8_t *) &hive_bin_header, sizeof( regf_hive_bin_header_t ), 0 ); } #endif if( memory_compare( hive_bin_header.signature, regf_hive_bin_signature, 4 ) != 0 ) { return( 0 ); } byte_stream_copy_to_uint32_little_endian( hive_bin_header.hive_bin_offset, hive_bin->offset ); byte_stream_copy_to_uint32_little_endian( hive_bin_header.size, hive_bin->size ); #if defined( HAVE_DEBUG_OUTPUT ) if( libcnotify_verbose != 0 ) { libcnotify_printf( "%s: signature\t\t\t\t\t: %c%c%c%c\n", function, hive_bin_header.signature[ 0 ], hive_bin_header.signature[ 1 ], hive_bin_header.signature[ 2 ], hive_bin_header.signature[ 3 ] ); libcnotify_printf( "%s: hive bin offset\t\t\t\t: %" PRIu32 "\n", function, hive_bin->offset ); libcnotify_printf( "%s: size\t\t\t\t\t: %" PRIu32 " bytes\n", function, hive_bin->size ); byte_stream_copy_to_uint32_little_endian( hive_bin_header.unknown1, value_32bit ); libcnotify_printf( "%s: unknown1\t\t\t\t\t: 0x%08" PRIx32 " (%" PRIu32 ")\n", function, value_32bit, value_32bit ); byte_stream_copy_to_uint32_little_endian( hive_bin_header.unknown2, value_32bit ); libcnotify_printf( "%s: unknown2\t\t\t\t\t: 0x%08" PRIx32 " (%" PRIu32 ")\n", function, value_32bit, value_32bit ); if( libfdatetime_filetime_initialize( &filetime, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, "%s: unable to create filetime.", function ); goto on_error; } if( libfdatetime_filetime_copy_from_byte_stream( filetime, hive_bin_header.unknown_time, 8, LIBFDATETIME_ENDIAN_LITTLE, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_SET_FAILED, "%s: unable to copy filetime from byte stream.", function ); goto on_error; } #if defined( LIBCSTRING_HAVE_WIDE_SYSTEM_CHARACTER ) result = libfdatetime_filetime_copy_to_utf16_string( filetime, (uint16_t *) filetime_string, 32, LIBFDATETIME_STRING_FORMAT_TYPE_CTIME | LIBFDATETIME_STRING_FORMAT_FLAG_DATE_TIME_NANO_SECONDS, error ); #else result = libfdatetime_filetime_copy_to_utf8_string( filetime, (uint8_t *) filetime_string, 32, LIBFDATETIME_STRING_FORMAT_TYPE_CTIME | LIBFDATETIME_STRING_FORMAT_FLAG_DATE_TIME_NANO_SECONDS, error ); #endif if( result != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_SET_FAILED, "%s: unable to copy filetime to string.", function ); goto on_error; } libcnotify_printf( "%s: unknown time\t\t\t\t: %" PRIs_LIBCSTRING_SYSTEM " UTC\n", function, filetime_string ); if( libfdatetime_filetime_free( &filetime, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED, "%s: unable to free filetime.", function ); goto on_error; } byte_stream_copy_to_uint32_little_endian( hive_bin_header.unknown_spare, value_32bit ); libcnotify_printf( "%s: unknown spare\t\t\t\t: 0x%08" PRIx32 " (%" PRIu32 ")\n", function, value_32bit, value_32bit ); libcnotify_printf( "\n" ); } #endif return( 1 ); on_error: #if defined( HAVE_DEBUG_OUTPUT ) if( filetime != NULL ) { libfdatetime_filetime_free( &filetime, NULL ); } #endif return( -1 ); }
/* Reads the memory image information * Returns 1 if successful or -1 on error */ int libhibr_io_handle_read_memory_image_information( libhibr_io_handle_t *io_handle, libbfio_handle_t *file_io_handle, libcerror_error_t **error ) { uint8_t *page_data = NULL; static char *function = "libhibr_io_handle_read_memory_image_information"; ssize_t read_count = 0; uint64_t page_size = 0; uint32_t memory_image_information_data_size = 0; #if defined( HAVE_DEBUG_OUTPUT ) libcstring_system_character_t filetime_string[ 32 ]; libfdatetime_filetime_t *filetime = NULL; uint64_t value_64bit = 0; uint32_t value_32bit = 0; uint8_t value_8bit = 0; int result = 0; #endif if( io_handle == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid IO handle.", function ); return( -1 ); } #if defined( HAVE_DEBUG_OUTPUT ) if( libcnotify_verbose != 0 ) { libcnotify_printf( "%s: reading memory image information at offset: 0.\n", function ); } #endif if( libbfio_handle_seek_offset( file_io_handle, 0, SEEK_SET, error ) == -1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_IO, LIBCERROR_IO_ERROR_SEEK_FAILED, "%s: unable to seek memory image information offset: 0.", function ); goto on_error; } page_data = (uint8_t *) memory_allocate( sizeof( uint8_t ) * io_handle->page_size ); if( page_data == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_MEMORY, LIBCERROR_MEMORY_ERROR_INSUFFICIENT, "%s: unable to create memory image information data.", function ); goto on_error; } read_count = libbfio_handle_read_buffer( file_io_handle, page_data, io_handle->page_size, error ); if( read_count != (ssize_t) io_handle->page_size ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_IO, LIBCERROR_IO_ERROR_READ_FAILED, "%s: unable to read memory image information.", function ); goto on_error; } /* TODO do empty page test */ byte_stream_copy_to_uint32_little_endian( ( (hibr_memory_image_information_t *) page_data )->size, memory_image_information_data_size ); if( memory_image_information_data_size > 0 ) { #if defined( HAVE_DEBUG_OUTPUT ) if( libcnotify_verbose != 0 ) { libcnotify_printf( "%s: memory image information data:\n", function ); libcnotify_print_data( page_data, (size_t) memory_image_information_data_size, 0 ); } #endif /* TODO if( memory_compare( ( (hibr_memory_image_information_t *) page_data )->signature, hibr_file_signature, 8 ) != 0 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE, "%s: unsupported file signature.", function ); goto on_error; } */ if( memory_image_information_data_size == sizeof( hibr_memory_image_information_winxp_32bit_t ) ) { io_handle->file_type = LIBHIBR_FILE_TYPE_WINDOWS_XP_32BIT; } else if( memory_image_information_data_size == sizeof( hibr_memory_image_information_winxp_64bit_t ) ) { io_handle->file_type = LIBHIBR_FILE_TYPE_WINDOWS_XP_64BIT; } else if( memory_image_information_data_size == sizeof( hibr_memory_image_information_win7_32bit_t ) ) { io_handle->file_type = LIBHIBR_FILE_TYPE_WINDOWS_7_32BIT; } else if( memory_image_information_data_size == sizeof( hibr_memory_image_information_win7_64bit_t ) ) { io_handle->file_type = LIBHIBR_FILE_TYPE_WINDOWS_7_64BIT; } if( io_handle->file_type == LIBHIBR_FILE_TYPE_WINDOWS_XP_32BIT ) { byte_stream_copy_to_uint32_little_endian( ( (hibr_memory_image_information_winxp_32bit_t *) page_data )->page_size, page_size ); } else if( io_handle->file_type == LIBHIBR_FILE_TYPE_WINDOWS_XP_64BIT ) { byte_stream_copy_to_uint32_little_endian( ( (hibr_memory_image_information_winxp_64bit_t *) page_data )->page_size, page_size ); } else if( io_handle->file_type == LIBHIBR_FILE_TYPE_WINDOWS_7_32BIT ) { byte_stream_copy_to_uint32_little_endian( ( (hibr_memory_image_information_win7_32bit_t *) page_data )->page_size, page_size ); } else if( io_handle->file_type == LIBHIBR_FILE_TYPE_WINDOWS_7_64BIT ) { byte_stream_copy_to_uint32_little_endian( ( (hibr_memory_image_information_win7_64bit_t *) page_data )->page_size, page_size ); } #if defined( HAVE_DEBUG_OUTPUT ) if( libcnotify_verbose != 0 ) { libcnotify_printf( "%s: signature\t\t: %c%c%c%c\n", function, ( (hibr_memory_image_information_t *) page_data )->signature[ 0 ], ( (hibr_memory_image_information_t *) page_data )->signature[ 1 ], ( (hibr_memory_image_information_t *) page_data )->signature[ 2 ], ( (hibr_memory_image_information_t *) page_data )->signature[ 3 ] ); if( ( io_handle->file_type == LIBHIBR_FILE_TYPE_WINDOWS_XP_32BIT ) || ( io_handle->file_type == LIBHIBR_FILE_TYPE_WINDOWS_XP_64BIT ) ) { byte_stream_copy_to_uint32_little_endian( ( (hibr_memory_image_information_winxp_32bit_t *) page_data )->version, value_32bit ); libcnotify_printf( "%s: version\t\t: %" PRIu32 "\n", function, value_32bit ); } else if( ( io_handle->file_type == LIBHIBR_FILE_TYPE_WINDOWS_7_32BIT ) || ( io_handle->file_type == LIBHIBR_FILE_TYPE_WINDOWS_7_64BIT ) ) { byte_stream_copy_to_uint32_little_endian( ( (hibr_memory_image_information_win7_32bit_t *) page_data )->image_type, value_32bit ); libcnotify_printf( "%s: image type\t\t: %" PRIu32 "\n", function, value_32bit ); } byte_stream_copy_to_uint32_little_endian( ( (hibr_memory_image_information_t *) page_data )->checksum, value_32bit ); libcnotify_printf( "%s: checksum\t\t: 0x%08" PRIx32 "\n", function, value_32bit ); libcnotify_printf( "%s: size\t\t\t: %" PRIu32 "\n", function, memory_image_information_data_size ); if( io_handle->file_type == LIBHIBR_FILE_TYPE_WINDOWS_XP_32BIT ) { byte_stream_copy_to_uint32_little_endian( ( (hibr_memory_image_information_winxp_32bit_t *) page_data )->page_number, value_64bit ); } else if( io_handle->file_type == LIBHIBR_FILE_TYPE_WINDOWS_XP_64BIT ) { byte_stream_copy_to_uint64_little_endian( ( (hibr_memory_image_information_winxp_64bit_t *) page_data )->page_number, value_64bit ); } else if( io_handle->file_type == LIBHIBR_FILE_TYPE_WINDOWS_7_32BIT ) { byte_stream_copy_to_uint32_little_endian( ( (hibr_memory_image_information_win7_32bit_t *) page_data )->page_number, value_64bit ); } else if( io_handle->file_type == LIBHIBR_FILE_TYPE_WINDOWS_7_64BIT ) { byte_stream_copy_to_uint64_little_endian( ( (hibr_memory_image_information_win7_64bit_t *) page_data )->page_number, value_64bit ); } libcnotify_printf( "%s: page number\t\t: %" PRIu64 "\n", function, value_64bit ); libcnotify_printf( "%s: page size\t\t: %" PRIu64 "\n", function, page_size ); if( ( io_handle->file_type == LIBHIBR_FILE_TYPE_WINDOWS_XP_32BIT ) || ( io_handle->file_type == LIBHIBR_FILE_TYPE_WINDOWS_XP_64BIT ) ) { if( io_handle->file_type == LIBHIBR_FILE_TYPE_WINDOWS_XP_32BIT ) { byte_stream_copy_to_uint32_little_endian( ( (hibr_memory_image_information_winxp_32bit_t *) page_data )->image_type, value_32bit ); } else { byte_stream_copy_to_uint32_little_endian( ( (hibr_memory_image_information_winxp_64bit_t *) page_data )->image_type, value_32bit ); } libcnotify_printf( "%s: image type\t\t: %" PRIu32 "\n", function, value_32bit ); } if( io_handle->file_type == LIBHIBR_FILE_TYPE_WINDOWS_XP_32BIT ) { byte_stream_copy_to_uint32_little_endian( ( (hibr_memory_image_information_winxp_32bit_t *) page_data )->unknown1, value_32bit ); libcnotify_printf( "%s: unknown1\t\t: 0x%08" PRIx32 "\n", function, value_32bit ); } if( ( io_handle->file_type == LIBHIBR_FILE_TYPE_WINDOWS_XP_32BIT ) || ( io_handle->file_type == LIBHIBR_FILE_TYPE_WINDOWS_XP_64BIT ) ) { byte_stream_copy_to_uint64_little_endian( ( (hibr_memory_image_information_winxp_32bit_t *) page_data )->system_time, value_64bit ); } else if( io_handle->file_type == LIBHIBR_FILE_TYPE_WINDOWS_7_32BIT ) { byte_stream_copy_to_uint64_little_endian( ( (hibr_memory_image_information_win7_32bit_t *) page_data )->system_time, value_64bit ); } else if( io_handle->file_type == LIBHIBR_FILE_TYPE_WINDOWS_7_64BIT ) { byte_stream_copy_to_uint64_little_endian( ( (hibr_memory_image_information_win7_64bit_t *) page_data )->system_time, value_64bit ); } if( libfdatetime_filetime_initialize( &filetime, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, "%s: unable to create filetime.", function ); goto on_error; } if( libfdatetime_filetime_copy_from_64bit( filetime, value_64bit, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_COPY_FAILED, "%s: unable to copy byte stream to filetime.", function ); goto on_error; } #if defined( LIBCSTRING_HAVE_WIDE_SYSTEM_CHARACTER ) result = libfdatetime_filetime_copy_to_utf16_string( filetime, (uint16_t *) filetime_string, 32, LIBFDATETIME_STRING_FORMAT_TYPE_CTIME | LIBFDATETIME_STRING_FORMAT_FLAG_DATE_TIME_NANO_SECONDS, error ); #else result = libfdatetime_filetime_copy_to_utf8_string( filetime, (uint8_t *) filetime_string, 32, LIBFDATETIME_STRING_FORMAT_TYPE_CTIME | LIBFDATETIME_STRING_FORMAT_FLAG_DATE_TIME_NANO_SECONDS, error ); #endif if( result != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_COPY_FAILED, "%s: unable to copy filetime to string.", function ); goto on_error; } libcnotify_printf( "%s: system time\t\t: %" PRIs_LIBCSTRING_SYSTEM " UTC\n", function, filetime_string ); if( libfdatetime_filetime_free( &filetime, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED, "%s: unable to free filetime.", function ); goto on_error; } if( ( io_handle->file_type == LIBHIBR_FILE_TYPE_WINDOWS_XP_32BIT ) || ( io_handle->file_type == LIBHIBR_FILE_TYPE_WINDOWS_XP_64BIT ) ) { byte_stream_copy_to_uint64_little_endian( ( (hibr_memory_image_information_winxp_32bit_t *) page_data )->interrupt_time, value_64bit ); } libcnotify_printf( "%s: interrupt time\t\t: 0x%08" PRIx64 "\n", function, value_64bit ); if( ( io_handle->file_type == LIBHIBR_FILE_TYPE_WINDOWS_XP_32BIT ) || ( io_handle->file_type == LIBHIBR_FILE_TYPE_WINDOWS_XP_64BIT ) ) { byte_stream_copy_to_uint32_little_endian( ( (hibr_memory_image_information_winxp_32bit_t *) page_data )->feature_flags, value_32bit ); } libcnotify_printf( "%s: feature flags\t\t: 0x%08" PRIx32 "\n", function, value_32bit ); if( ( io_handle->file_type == LIBHIBR_FILE_TYPE_WINDOWS_XP_32BIT ) || ( io_handle->file_type == LIBHIBR_FILE_TYPE_WINDOWS_XP_64BIT ) ) { value_8bit = ( (hibr_memory_image_information_winxp_32bit_t *) page_data )->hibernation_flags; } libcnotify_printf( "%s: hibernation flags\t: 0x%02" PRIx8 "\n", function, value_8bit ); if( io_handle->file_type == LIBHIBR_FILE_TYPE_WINDOWS_XP_32BIT ) { libcnotify_printf( "%s: unknown2:\n", function ); libcnotify_print_data( ( (hibr_memory_image_information_winxp_32bit_t *) page_data )->unknown2, 3, 0 ); } else if( io_handle->file_type == LIBHIBR_FILE_TYPE_WINDOWS_XP_64BIT ) { libcnotify_printf( "%s: unknown1:\n", function ); libcnotify_print_data( ( (hibr_memory_image_information_winxp_64bit_t *) page_data )->unknown1, 3, 0 ); byte_stream_copy_to_uint32_little_endian( ( (hibr_memory_image_information_winxp_64bit_t *) page_data )->unknown2, value_32bit ); libcnotify_printf( "%s: unknown2\t\t: 0x%08" PRIx32 "\n", function, value_32bit ); } if( ( io_handle->file_type == LIBHIBR_FILE_TYPE_WINDOWS_XP_32BIT ) || ( io_handle->file_type == LIBHIBR_FILE_TYPE_WINDOWS_XP_64BIT ) ) { byte_stream_copy_to_uint32_little_endian( ( (hibr_memory_image_information_winxp_32bit_t *) page_data )->unknown3, value_32bit ); } libcnotify_printf( "%s: unknown3\t\t: 0x%08" PRIx32 "\n", function, value_32bit ); if( ( io_handle->file_type == LIBHIBR_FILE_TYPE_WINDOWS_XP_32BIT ) || ( io_handle->file_type == LIBHIBR_FILE_TYPE_WINDOWS_XP_64BIT ) ) { byte_stream_copy_to_uint32_little_endian( ( (hibr_memory_image_information_winxp_32bit_t *) page_data )->unknown4, value_32bit ); } libcnotify_printf( "%s: unknown4\t\t: 0x%08" PRIx32 "\n", function, value_32bit ); if( ( io_handle->file_type == LIBHIBR_FILE_TYPE_WINDOWS_XP_32BIT ) || ( io_handle->file_type == LIBHIBR_FILE_TYPE_WINDOWS_XP_64BIT ) ) { byte_stream_copy_to_uint64_little_endian( ( (hibr_memory_image_information_winxp_32bit_t *) page_data )->unknown5, value_64bit ); } libcnotify_printf( "%s: unknown5\t\t: 0x%08" PRIx64 "\n", function, value_64bit ); if( ( io_handle->file_type == LIBHIBR_FILE_TYPE_WINDOWS_XP_32BIT ) || ( io_handle->file_type == LIBHIBR_FILE_TYPE_WINDOWS_XP_64BIT ) ) { byte_stream_copy_to_uint32_little_endian( ( (hibr_memory_image_information_winxp_32bit_t *) page_data )->number_of_free_pages, value_32bit ); } libcnotify_printf( "%s: number of free pages\t: %" PRIu32 "\n", function, value_32bit ); if( ( io_handle->file_type == LIBHIBR_FILE_TYPE_WINDOWS_XP_32BIT ) || ( io_handle->file_type == LIBHIBR_FILE_TYPE_WINDOWS_XP_64BIT ) ) { byte_stream_copy_to_uint32_little_endian( ( (hibr_memory_image_information_winxp_32bit_t *) page_data )->unknown6, value_32bit ); } libcnotify_printf( "%s: unknown6\t\t: 0x%08" PRIx32 "\n", function, value_32bit ); if( ( io_handle->file_type == LIBHIBR_FILE_TYPE_WINDOWS_XP_32BIT ) || ( io_handle->file_type == LIBHIBR_FILE_TYPE_WINDOWS_XP_64BIT ) ) { byte_stream_copy_to_uint32_little_endian( ( (hibr_memory_image_information_winxp_32bit_t *) page_data )->unknown7, value_32bit ); } libcnotify_printf( "%s: unknown7\t\t: 0x%08" PRIx32 "\n", function, value_32bit ); if( io_handle->file_type == LIBHIBR_FILE_TYPE_WINDOWS_XP_64BIT ) { byte_stream_copy_to_uint32_little_endian( ( (hibr_memory_image_information_winxp_64bit_t *) page_data )->unknown8, value_32bit ); libcnotify_printf( "%s: unknown8\t\t: 0x%08" PRIx32 "\n", function, value_32bit ); } if( ( io_handle->file_type == LIBHIBR_FILE_TYPE_WINDOWS_XP_32BIT ) || ( io_handle->file_type == LIBHIBR_FILE_TYPE_WINDOWS_XP_64BIT ) ) { byte_stream_copy_to_uint32_little_endian( ( (hibr_memory_image_information_winxp_32bit_t *) page_data )->number_of_pages, value_32bit ); } libcnotify_printf( "%s: number of pages\t: %" PRIu32 "\n", function, value_32bit ); if( io_handle->file_type == LIBHIBR_FILE_TYPE_WINDOWS_XP_32BIT ) { byte_stream_copy_to_uint32_little_endian( ( (hibr_memory_image_information_winxp_32bit_t *) page_data )->unknown8, value_32bit ); libcnotify_printf( "%s: unknown8\t\t: 0x%08" PRIx32 "\n", function, value_32bit ); byte_stream_copy_to_uint32_little_endian( ( (hibr_memory_image_information_winxp_32bit_t *) page_data )->unknown9, value_32bit ); libcnotify_printf( "%s: unknown9\t\t: 0x%08" PRIx32 "\n", function, value_32bit ); libcnotify_printf( "%s: unknown10:\n", function ); libcnotify_print_data( ( (hibr_memory_image_information_winxp_32bit_t *) page_data )->unknown10, 72, 0 ); } else if( io_handle->file_type == LIBHIBR_FILE_TYPE_WINDOWS_XP_64BIT ) { byte_stream_copy_to_uint32_little_endian( ( (hibr_memory_image_information_winxp_64bit_t *) page_data )->unknown8, value_32bit ); libcnotify_printf( "%s: unknown8\t\t: 0x%08" PRIx32 "\n", function, value_32bit ); byte_stream_copy_to_uint32_little_endian( ( (hibr_memory_image_information_winxp_64bit_t *) page_data )->unknown9, value_32bit ); libcnotify_printf( "%s: unknown9\t\t: 0x%08" PRIx32 "\n", function, value_32bit ); libcnotify_printf( "%s: unknown10:\n", function ); libcnotify_print_data( ( (hibr_memory_image_information_winxp_64bit_t *) page_data )->unknown10, 72, 0 ); } else { libcnotify_printf( "\n" ); } } #endif } #if defined( HAVE_DEBUG_OUTPUT ) else if( libcnotify_verbose != 0 ) { libcnotify_printf( "%s: page data:\n", function ); libcnotify_print_data( page_data, io_handle->page_size, LIBCNOTIFY_PRINT_DATA_FLAG_GROUP_DATA ); } #endif /* TODO print trailing data */ /* TODO page size sanity check */ io_handle->page_size = (size_t) page_size; /* TODO memory blocks page number sanity check */ memory_free( page_data ); page_data = NULL; return( 1 ); on_error: #if defined( HAVE_DEBUG_OUTPUT ) if( filetime != NULL ) { libfdatetime_filetime_free( &filetime, NULL ); } #endif if( page_data != NULL ) { memory_free( page_data ); } return( -1 ); }
/* Tests the libfvalue_filetime_copy_from_integer function * Returns 1 if successful or 0 if not */ int fvalue_test_filetime_copy_from_integer( void ) { libcerror_error_t *error = NULL; libfdatetime_filetime_t *filetime = NULL; int result = 0; /* Initialize test */ result = libfdatetime_filetime_initialize( &filetime, &error ); FVALUE_TEST_ASSERT_EQUAL_INT( "result", result, 1 ); FVALUE_TEST_ASSERT_IS_NOT_NULL( "filetime", filetime ); FVALUE_TEST_ASSERT_IS_NULL( "error", error ); /* Test regular cases */ result = libfvalue_filetime_copy_from_integer( filetime, 0x01cb3a623d0a17ceUL, 64, &error ); FVALUE_TEST_ASSERT_EQUAL_INT( "result", result, 1 ); FVALUE_TEST_ASSERT_IS_NULL( "error", error ); /* Test error cases */ result = libfvalue_filetime_copy_from_integer( NULL, 0x01cb3a623d0a17ceUL, 64, &error ); FVALUE_TEST_ASSERT_EQUAL_INT( "result", result, -1 ); FVALUE_TEST_ASSERT_IS_NOT_NULL( "error", error ); libcerror_error_free( &error ); result = libfvalue_filetime_copy_from_integer( filetime, 0x01cb3a623d0a17ceUL, 8, &error ); FVALUE_TEST_ASSERT_EQUAL_INT( "result", result, -1 ); FVALUE_TEST_ASSERT_IS_NOT_NULL( "error", error ); libcerror_error_free( &error ); /* Clean up */ result = libfdatetime_filetime_free( &filetime, &error ); FVALUE_TEST_ASSERT_EQUAL_INT( "result", result, 1 ); FVALUE_TEST_ASSERT_IS_NULL( "filetime", filetime ); FVALUE_TEST_ASSERT_IS_NULL( "error", error ); return( 1 ); on_error: if( error != NULL ) { libcerror_error_free( &error ); } if( filetime != NULL ) { libfdatetime_filetime_free( &filetime, NULL ); } return( 0 ); }
/* Tests the libfvalue_filetime_copy_to_integer function * Returns 1 if successful or 0 if not */ int fvalue_test_filetime_copy_to_integer( void ) { libcerror_error_t *error = NULL; libfdatetime_filetime_t *filetime = NULL; size_t integer_value_size = 0; uint64_t integer_value = 0; int result = 0; /* Initialize test */ result = libfdatetime_filetime_initialize( &filetime, &error ); FVALUE_TEST_ASSERT_EQUAL_INT( "result", result, 1 ); FVALUE_TEST_ASSERT_IS_NOT_NULL( "filetime", filetime ); FVALUE_TEST_ASSERT_IS_NULL( "error", error ); /* Test regular cases */ integer_value = 0; integer_value_size = 0; result = libfvalue_filetime_copy_to_integer( filetime, &integer_value, &integer_value_size, &error ); FVALUE_TEST_ASSERT_EQUAL_INT( "result", result, 1 ); FVALUE_TEST_ASSERT_EQUAL_UINT64( "integer_value", integer_value, (uint64_t) 0 ); FVALUE_TEST_ASSERT_EQUAL_SIZE( "integer_value_size", integer_value_size, (size_t) 64 ); FVALUE_TEST_ASSERT_IS_NULL( "error", error ); /* Test error cases */ integer_value = 0; integer_value_size = 0; result = libfvalue_filetime_copy_to_integer( NULL, &integer_value, &integer_value_size, &error ); FVALUE_TEST_ASSERT_EQUAL_INT( "result", result, -1 ); FVALUE_TEST_ASSERT_EQUAL_UINT64( "integer_value", integer_value, (uint64_t) 0 ); FVALUE_TEST_ASSERT_EQUAL_SIZE( "integer_value_size", integer_value_size, (size_t) 0 ); FVALUE_TEST_ASSERT_IS_NOT_NULL( "error", error ); libcerror_error_free( &error ); result = libfvalue_filetime_copy_to_integer( filetime, NULL, &integer_value_size, &error ); FVALUE_TEST_ASSERT_EQUAL_INT( "result", result, -1 ); FVALUE_TEST_ASSERT_EQUAL_UINT64( "integer_value", integer_value, (uint64_t) 0 ); FVALUE_TEST_ASSERT_EQUAL_SIZE( "integer_value_size", integer_value_size, (size_t) 0 ); FVALUE_TEST_ASSERT_IS_NOT_NULL( "error", error ); libcerror_error_free( &error ); result = libfvalue_filetime_copy_to_integer( filetime, &integer_value, NULL, &error ); FVALUE_TEST_ASSERT_EQUAL_INT( "result", result, -1 ); FVALUE_TEST_ASSERT_EQUAL_UINT64( "integer_value", integer_value, (uint64_t) 0 ); FVALUE_TEST_ASSERT_EQUAL_SIZE( "integer_value_size", integer_value_size, (size_t) 0 ); FVALUE_TEST_ASSERT_IS_NOT_NULL( "error", error ); libcerror_error_free( &error ); /* Clean up */ result = libfdatetime_filetime_free( &filetime, &error ); FVALUE_TEST_ASSERT_EQUAL_INT( "result", result, 1 ); FVALUE_TEST_ASSERT_IS_NULL( "filetime", filetime ); FVALUE_TEST_ASSERT_IS_NULL( "error", error ); return( 1 ); on_error: if( error != NULL ) { libcerror_error_free( &error ); } if( filetime != NULL ) { libfdatetime_filetime_free( &filetime, NULL ); } return( 0 ); }
/* Reads the URL values from an URL record * Returns 1 if successful or -1 on error */ int libmsiecf_url_values_read( libmsiecf_url_values_t *url_values, libmsiecf_io_handle_t *io_handle, libbfio_handle_t *file_io_handle, off64_t url_record_offset, size32_t record_size, uint8_t item_flags, libcerror_error_t **error ) { uint8_t *url_record_data = NULL; static char *function = "libmsiecf_url_values_read"; ssize_t read_count = 0; ssize_t value_size = 0; uint32_t data_offset = 0; uint32_t data_size = 0; uint32_t filename_offset = 0; uint32_t location_offset = 0; uint32_t cache_entry_flags = 0; uint32_t unknown_offset = 0; uint16_t first_year = 0; uint16_t second_year = 0; uint8_t first_day_of_month = 0; uint8_t first_month = 0; uint8_t number_of_days = 0; uint8_t second_day_of_month = 0; uint8_t second_month = 0; #if defined( HAVE_DEBUG_OUTPUT ) system_character_t date_time_string[ 32 ]; libfdatetime_filetime_t *filetime = NULL; libfdatetime_fat_date_time_t *fat_date_time = NULL; uint8_t *visited_entry_data = NULL; size_t string_index = 0; uint32_t value_32bit = 0; uint16_t value_16bit = 0; int result = 0; int visited_entry_index = 0; #endif if( url_values == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid URL values.", function ); return( -1 ); } if( io_handle == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid IO handle.", function ); return( -1 ); } if( file_io_handle == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid file IO handle.", function ); return( -1 ); } if( record_size == 0 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_VALUE_ZERO_OR_LESS, "%s: invalid record size value zero or less.", function ); return( -1 ); } #if SIZEOF_SIZE_T <= 4 if( record_size > (size32_t) SSIZE_MAX ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_VALUE_EXCEEDS_MAXIMUM, "%s: invalid record size value exceeds maximum.", function ); return( -1 ); } #endif if( ( record_size % 8 ) != 0 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE, "%s: unsupported URL record size.", function ); return( -1 ); } #if defined( HAVE_DEBUG_OUTPUT ) if( libcnotify_verbose != 0 ) { libcnotify_printf( "%s: reading URL record at offset: %" PRIi64 " (0x%08" PRIx64 ")\n", function, url_record_offset, url_record_offset ); } #endif if( libbfio_handle_seek_offset( file_io_handle, url_record_offset, SEEK_SET, error ) == -1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_IO, LIBCERROR_IO_ERROR_SEEK_FAILED, "%s: unable to seek URL record offset: %" PRIi64 ".", function, url_record_offset ); goto on_error; } /* Add one block for tainted records */ if( ( item_flags & LIBMSIECF_ITEM_FLAG_TAINTED ) != 0 ) { record_size += LIBMSIECF_DEFAULT_BLOCK_SIZE; } url_record_data = (uint8_t *) memory_allocate( record_size ); if( url_record_data == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_MEMORY, LIBCERROR_MEMORY_ERROR_INSUFFICIENT, "%s: unable to create URL record data.", function ); goto on_error; } read_count = libbfio_handle_read_buffer( file_io_handle, url_record_data, record_size, error ); if( read_count != (ssize_t) record_size ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_IO, LIBCERROR_IO_ERROR_READ_FAILED, "%s: unable to read URL record data.", function ); goto on_error; } #if defined( HAVE_DEBUG_OUTPUT ) if( libcnotify_verbose != 0 ) { libcnotify_printf( "%s: URL record data:\n", function ); libcnotify_print_data( url_record_data, record_size, 0 ); } #endif if( memory_compare( url_record_data, "URL ", 4 ) != 0 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE, "%s: unsupported signature.", function ); goto on_error; } if( ( io_handle->major_version == 4 ) && ( io_handle->minor_version == 7 ) ) { byte_stream_copy_to_uint64_little_endian( ( (msiecf_url_record_header_v47_t *) url_record_data )->secondary_filetime, url_values->secondary_time ); byte_stream_copy_to_uint64_little_endian( ( (msiecf_url_record_header_v47_t *) url_record_data )->primary_filetime, url_values->primary_time ); byte_stream_copy_to_uint64_little_endian( ( (msiecf_url_record_header_v47_t *) url_record_data )->expiration_time, url_values->expiration_time ); byte_stream_copy_to_uint32_little_endian( ( (msiecf_url_record_header_v47_t *) url_record_data )->cached_file_size, url_values->cached_file_size ); byte_stream_copy_to_uint32_little_endian( ( (msiecf_url_record_header_v47_t *) url_record_data )->unknown_offset, unknown_offset ); byte_stream_copy_to_uint32_little_endian( ( (msiecf_url_record_header_v47_t *) url_record_data )->location_offset, location_offset ); url_values->cache_directory_index = ( (msiecf_url_record_header_v47_t *) url_record_data )->cache_directory_index; byte_stream_copy_to_uint32_little_endian( ( (msiecf_url_record_header_v47_t *) url_record_data )->filename_offset, filename_offset ); byte_stream_copy_to_uint32_little_endian( ( (msiecf_url_record_header_v47_t *) url_record_data )->data_offset, data_offset ); byte_stream_copy_to_uint32_little_endian( ( (msiecf_url_record_header_v47_t *) url_record_data )->data_size, data_size ); byte_stream_copy_to_uint32_little_endian( ( (msiecf_url_record_header_v47_t *) url_record_data )->last_checked_time, url_values->last_checked_time ); byte_stream_copy_to_uint32_little_endian( ( (msiecf_url_record_header_v47_t *) url_record_data )->number_of_hits, url_values->number_of_hits ); byte_stream_copy_to_uint32_little_endian( ( (msiecf_url_record_header_v47_t *) url_record_data )->cache_entry_flags, cache_entry_flags ); } else if( ( io_handle->major_version == 5 ) && ( io_handle->minor_version == 2 ) ) { byte_stream_copy_to_uint64_little_endian( ( (msiecf_url_record_header_v52_t *) url_record_data )->secondary_filetime, url_values->secondary_time ); byte_stream_copy_to_uint64_little_endian( ( (msiecf_url_record_header_v52_t *) url_record_data )->primary_filetime, url_values->primary_time ); byte_stream_copy_to_uint32_little_endian( ( (msiecf_url_record_header_v52_t *) url_record_data )->expiration_time, url_values->expiration_time ); byte_stream_copy_to_uint32_little_endian( ( (msiecf_url_record_header_v52_t *) url_record_data )->cached_file_size, url_values->cached_file_size ); byte_stream_copy_to_uint32_little_endian( ( (msiecf_url_record_header_v52_t *) url_record_data )->unknown_offset, unknown_offset ); byte_stream_copy_to_uint32_little_endian( ( (msiecf_url_record_header_v52_t *) url_record_data )->location_offset, location_offset ); url_values->cache_directory_index = ( (msiecf_url_record_header_v52_t *) url_record_data )->cache_directory_index; byte_stream_copy_to_uint32_little_endian( ( (msiecf_url_record_header_v52_t *) url_record_data )->filename_offset, filename_offset ); byte_stream_copy_to_uint32_little_endian( ( (msiecf_url_record_header_v52_t *) url_record_data )->data_offset, data_offset ); byte_stream_copy_to_uint32_little_endian( ( (msiecf_url_record_header_v52_t *) url_record_data )->data_size, data_size ); byte_stream_copy_to_uint32_little_endian( ( (msiecf_url_record_header_v52_t *) url_record_data )->last_checked_time, url_values->last_checked_time ); byte_stream_copy_to_uint32_little_endian( ( (msiecf_url_record_header_v52_t *) url_record_data )->number_of_hits, url_values->number_of_hits ); byte_stream_copy_to_uint32_little_endian( ( (msiecf_url_record_header_v52_t *) url_record_data )->cache_entry_flags, cache_entry_flags ); } #if defined( HAVE_DEBUG_OUTPUT ) if( libcnotify_verbose != 0 ) { if( libfdatetime_fat_date_time_initialize( &fat_date_time, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, "%s: unable to create FAT date time.", function ); goto on_error; } if( libfdatetime_filetime_initialize( &filetime, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, "%s: unable to create filetime.", function ); goto on_error; } libcnotify_printf( "%s: signature\t\t\t\t\t: %c%c%c%c\n", function, url_record_data[ 0 ], url_record_data[ 1 ], url_record_data[ 2 ], url_record_data[ 3 ] ); byte_stream_copy_to_uint32_little_endian( ( (msiecf_url_record_header_v47_t *) url_record_data )->number_of_blocks, value_32bit ); libcnotify_printf( "%s: number of blocks\t\t\t\t: %" PRIu32 "\n", function, value_32bit ); if( libfdatetime_filetime_copy_from_byte_stream( filetime, ( (msiecf_url_record_header_v47_t *) url_record_data )->secondary_filetime, 8, LIBFDATETIME_ENDIAN_LITTLE, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_SET_FAILED, "%s: unable to copy filetime from byte stream.", function ); goto on_error; } #if defined( HAVE_WIDE_SYSTEM_CHARACTER ) result = libfdatetime_filetime_copy_to_utf16_string( filetime, (uint16_t *) date_time_string, 32, LIBFDATETIME_STRING_FORMAT_TYPE_CTIME | LIBFDATETIME_STRING_FORMAT_FLAG_DATE_TIME_NANO_SECONDS, error ); #else result = libfdatetime_filetime_copy_to_utf8_string( filetime, (uint8_t *) date_time_string, 32, LIBFDATETIME_STRING_FORMAT_TYPE_CTIME | LIBFDATETIME_STRING_FORMAT_FLAG_DATE_TIME_NANO_SECONDS, error ); #endif if( result != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_SET_FAILED, "%s: unable to copy filetime to date time string.", function ); goto on_error; } libcnotify_printf( "%s: secondary time\t\t\t\t: %" PRIs_SYSTEM "\n", function, date_time_string ); if( libfdatetime_filetime_copy_from_byte_stream( filetime, ( (msiecf_url_record_header_v47_t *) url_record_data )->primary_filetime, 8, LIBFDATETIME_ENDIAN_LITTLE, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_SET_FAILED, "%s: unable to copy filetime from byte stream.", function ); goto on_error; } #if defined( HAVE_WIDE_SYSTEM_CHARACTER ) result = libfdatetime_filetime_copy_to_utf16_string( filetime, (uint16_t *) date_time_string, 32, LIBFDATETIME_STRING_FORMAT_TYPE_CTIME | LIBFDATETIME_STRING_FORMAT_FLAG_DATE_TIME_NANO_SECONDS, error ); #else result = libfdatetime_filetime_copy_to_utf8_string( filetime, (uint8_t *) date_time_string, 32, LIBFDATETIME_STRING_FORMAT_TYPE_CTIME | LIBFDATETIME_STRING_FORMAT_FLAG_DATE_TIME_NANO_SECONDS, error ); #endif if( result != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_SET_FAILED, "%s: unable to copy filetime to date time string.", function ); goto on_error; } libcnotify_printf( "%s: primary time\t\t\t\t\t: %" PRIs_SYSTEM "\n", function, date_time_string ); if( ( io_handle->major_version == 4 ) && ( io_handle->minor_version == 7 ) ) { if( libfdatetime_filetime_copy_from_byte_stream( filetime, ( (msiecf_url_record_header_v47_t *) url_record_data )->expiration_time, 8, LIBFDATETIME_ENDIAN_LITTLE, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_SET_FAILED, "%s: unable to copy filetime from byte stream.", function ); goto on_error; } #if defined( HAVE_WIDE_SYSTEM_CHARACTER ) result = libfdatetime_filetime_copy_to_utf16_string( filetime, (uint16_t *) date_time_string, 32, LIBFDATETIME_STRING_FORMAT_TYPE_CTIME | LIBFDATETIME_STRING_FORMAT_FLAG_DATE_TIME_NANO_SECONDS, error ); #else result = libfdatetime_filetime_copy_to_utf8_string( filetime, (uint8_t *) date_time_string, 32, LIBFDATETIME_STRING_FORMAT_TYPE_CTIME | LIBFDATETIME_STRING_FORMAT_FLAG_DATE_TIME_NANO_SECONDS, error ); #endif if( result != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_SET_FAILED, "%s: unable to copy filetime to date time string.", function ); goto on_error; } } else if( ( io_handle->major_version == 5 ) && ( io_handle->minor_version == 2 ) ) { if( libfdatetime_fat_date_time_copy_from_byte_stream( fat_date_time, ( (msiecf_url_record_header_v52_t *) url_record_data )->expiration_time, 4, LIBFDATETIME_ENDIAN_LITTLE, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_CONVERSION, LIBCERROR_CONVERSION_ERROR_GENERIC, "%s: unable to copy FAT date time from byte stream.", function ); goto on_error; } #if defined( HAVE_WIDE_SYSTEM_CHARACTER ) result = libfdatetime_fat_date_time_copy_to_utf16_string( fat_date_time, (uint16_t *) date_time_string, 32, LIBFDATETIME_STRING_FORMAT_TYPE_CTIME | LIBFDATETIME_STRING_FORMAT_FLAG_DATE_TIME, LIBFDATETIME_DATE_TIME_FORMAT_CTIME, error ); #else result = libfdatetime_fat_date_time_copy_to_utf8_string( fat_date_time, (uint8_t *) date_time_string, 32, LIBFDATETIME_STRING_FORMAT_TYPE_CTIME | LIBFDATETIME_STRING_FORMAT_FLAG_DATE_TIME, error ); #endif if( result != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_CONVERSION, LIBCERROR_CONVERSION_ERROR_GENERIC, "%s: unable to copy FAT date time to date time string.", function ); goto on_error; } } libcnotify_printf( "%s: expiration time\t\t\t\t: %" PRIs_SYSTEM "\n", function, date_time_string ); if( ( io_handle->major_version == 5 ) && ( io_handle->minor_version == 2 ) ) { byte_stream_copy_to_uint32_little_endian( ( (msiecf_url_record_header_v52_t *) url_record_data )->unknown1, value_32bit ); libcnotify_printf( "%s: unknown1\t\t\t\t\t: 0x%08" PRIx32 "\n", function, value_32bit ); } libcnotify_printf( "%s: cached file size\t\t\t\t: %" PRIu32 " bytes\n", function, url_values->cached_file_size ); if( ( io_handle->major_version == 4 ) && ( io_handle->minor_version == 7 ) ) { byte_stream_copy_to_uint32_little_endian( ( (msiecf_url_record_header_v47_t *) url_record_data )->unknown1, value_32bit ); libcnotify_printf( "%s: unknown1\t\t\t\t\t: 0x%08" PRIx32 "\n", function, value_32bit ); } if( ( io_handle->major_version == 4 ) && ( io_handle->minor_version == 7 ) ) { byte_stream_copy_to_uint32_little_endian( ( (msiecf_url_record_header_v47_t *) url_record_data )->unknown3, value_32bit ); } else if( ( io_handle->major_version == 5 ) && ( io_handle->minor_version == 2 ) ) { byte_stream_copy_to_uint32_little_endian( ( (msiecf_url_record_header_v52_t *) url_record_data )->unknown3, value_32bit ); } libcnotify_printf( "%s: unknown3\t\t\t\t\t: 0x%08" PRIx32 "\n", function, value_32bit ); if( ( io_handle->major_version == 4 ) && ( io_handle->minor_version == 7 ) ) { byte_stream_copy_to_uint32_little_endian( ( (msiecf_url_record_header_v47_t *) url_record_data )->unknown4, value_32bit ); } else if( ( io_handle->major_version == 5 ) && ( io_handle->minor_version == 2 ) ) { byte_stream_copy_to_uint32_little_endian( ( (msiecf_url_record_header_v52_t *) url_record_data )->unknown4, value_32bit ); } libcnotify_printf( "%s: unknown4\t\t\t\t\t: 0x%08" PRIx32 "\n", function, value_32bit ); if( ( io_handle->major_version == 4 ) && ( io_handle->minor_version == 7 ) ) { byte_stream_copy_to_uint32_little_endian( ( (msiecf_url_record_header_v47_t *) url_record_data )->non_releasable_time_delta, value_32bit ); } else if( ( io_handle->major_version == 5 ) && ( io_handle->minor_version == 2 ) ) { byte_stream_copy_to_uint32_little_endian( ( (msiecf_url_record_header_v52_t *) url_record_data )->non_releasable_time_delta, value_32bit ); } libcnotify_printf( "%s: non-releasable time delta\t\t\t: %" PRIu32 " seconds\n", function, value_32bit ); libcnotify_printf( "%s: unknown offset\t\t\t\t: %" PRIu32 "\n", function, unknown_offset ); libcnotify_printf( "%s: location offset\t\t\t\t: %" PRIu32 "\n", function, location_offset ); libcnotify_printf( "%s: cache directory index\t\t\t: %" PRIu8 "\n", function, url_values->cache_directory_index ); if( ( io_handle->major_version == 4 ) && ( io_handle->minor_version == 7 ) ) { libcnotify_printf( "%s: unknown6\t\t\t\t\t: 0x%02" PRIx8 " 0x%02" PRIx8 " 0x%02" PRIx8 "\n", function, ( (msiecf_url_record_header_v47_t *) url_record_data )->unknown6[ 0 ], ( (msiecf_url_record_header_v47_t *) url_record_data )->unknown6[ 1 ], ( (msiecf_url_record_header_v47_t *) url_record_data )->unknown6[ 2 ] ); } else if( ( io_handle->major_version == 5 ) && ( io_handle->minor_version == 2 ) ) { libcnotify_printf( "%s: unknown6\t\t\t\t\t: 0x%02" PRIx8 " 0x%02" PRIx8 " 0x%02" PRIx8 "\n", function, ( (msiecf_url_record_header_v52_t *) url_record_data )->unknown6[ 0 ], ( (msiecf_url_record_header_v52_t *) url_record_data )->unknown6[ 1 ], ( (msiecf_url_record_header_v52_t *) url_record_data )->unknown6[ 2 ] ); } libcnotify_printf( "%s: filename offset\t\t\t\t: %" PRIu32 "\n", function, filename_offset ); libcnotify_printf( "%s: cache entry flags\t\t\t\t: 0x%08" PRIx32 "\n", function, cache_entry_flags ); libmsiecf_debug_print_cache_entry_flags( cache_entry_flags ); libcnotify_printf( "\n" ); libcnotify_printf( "%s: data offset\t\t\t\t\t: %" PRIu32 "\n", function, data_offset ); libcnotify_printf( "%s: data size\t\t\t\t\t: %" PRIu32 "\n", function, data_size ); if( ( io_handle->major_version == 4 ) && ( io_handle->minor_version == 7 ) ) { byte_stream_copy_to_uint32_little_endian( ( (msiecf_url_record_header_v47_t *) url_record_data )->unknown8, value_32bit ); } else if( ( io_handle->major_version == 5 ) && ( io_handle->minor_version == 2 ) ) { byte_stream_copy_to_uint32_little_endian( ( (msiecf_url_record_header_v52_t *) url_record_data )->unknown8, value_32bit ); } libcnotify_printf( "%s: unknown8\t\t\t\t\t: 0x%08" PRIx32 "\n", function, value_32bit ); if( ( io_handle->major_version == 4 ) && ( io_handle->minor_version == 7 ) ) { result = libfdatetime_fat_date_time_copy_from_byte_stream( fat_date_time, ( (msiecf_url_record_header_v47_t *) url_record_data )->last_checked_time, 4, LIBFDATETIME_ENDIAN_LITTLE, error ); } else if( ( io_handle->major_version == 5 ) && ( io_handle->minor_version == 2 ) ) { result = libfdatetime_fat_date_time_copy_from_byte_stream( fat_date_time, ( (msiecf_url_record_header_v52_t *) url_record_data )->last_checked_time, 4, LIBFDATETIME_ENDIAN_LITTLE, error ); } if( result != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_CONVERSION, LIBCERROR_CONVERSION_ERROR_GENERIC, "%s: unable to copy FAT date time from byte stream.", function ); goto on_error; } #if defined( HAVE_WIDE_SYSTEM_CHARACTER ) result = libfdatetime_fat_date_time_copy_to_utf16_string( fat_date_time, (uint16_t *) date_time_string, 32, LIBFDATETIME_STRING_FORMAT_TYPE_CTIME | LIBFDATETIME_STRING_FORMAT_FLAG_DATE_TIME, error ); #else result = libfdatetime_fat_date_time_copy_to_utf8_string( fat_date_time, (uint8_t *) date_time_string, 32, LIBFDATETIME_STRING_FORMAT_TYPE_CTIME | LIBFDATETIME_STRING_FORMAT_FLAG_DATE_TIME, error ); #endif if( result != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_CONVERSION, LIBCERROR_CONVERSION_ERROR_GENERIC, "%s: unable to copy FAT date time to date time string.", function ); goto on_error; } libcnotify_printf( "%s: last checked time\t\t\t\t: %" PRIs_SYSTEM "\n", function, date_time_string ); libcnotify_printf( "%s: number of hits\t\t\t\t: %" PRIu32 "\n", function, url_values->number_of_hits ); if( ( io_handle->major_version == 4 ) && ( io_handle->minor_version == 7 ) ) { byte_stream_copy_to_uint32_little_endian( ( (msiecf_url_record_header_v47_t *) url_record_data )->unknown9, value_32bit ); } else if( ( io_handle->major_version == 5 ) && ( io_handle->minor_version == 2 ) ) { byte_stream_copy_to_uint32_little_endian( ( (msiecf_url_record_header_v52_t *) url_record_data )->unknown9, value_32bit ); } libcnotify_printf( "%s: unknown9\t\t\t\t\t: 0x%08" PRIx32 "\n", function, value_32bit ); if( ( io_handle->major_version == 4 ) && ( io_handle->minor_version == 7 ) ) { result = libfdatetime_fat_date_time_copy_from_byte_stream( fat_date_time, ( (msiecf_url_record_header_v47_t *) url_record_data )->unknown_time, 4, LIBFDATETIME_ENDIAN_LITTLE, error ); } else if( ( io_handle->major_version == 5 ) && ( io_handle->minor_version == 2 ) ) { result = libfdatetime_fat_date_time_copy_from_byte_stream( fat_date_time, ( (msiecf_url_record_header_v52_t *) url_record_data )->unknown_time, 4, LIBFDATETIME_ENDIAN_LITTLE, error ); } if( result != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_CONVERSION, LIBCERROR_CONVERSION_ERROR_GENERIC, "%s: unable to copy FAT date time from byte stream.", function ); goto on_error; } #if defined( HAVE_WIDE_SYSTEM_CHARACTER ) result = libfdatetime_fat_date_time_copy_to_utf16_string( fat_date_time, (uint16_t *) date_time_string, 32, LIBFDATETIME_STRING_FORMAT_TYPE_CTIME | LIBFDATETIME_STRING_FORMAT_FLAG_DATE_TIME, error ); #else result = libfdatetime_fat_date_time_copy_to_utf8_string( fat_date_time, (uint8_t *) date_time_string, 32, LIBFDATETIME_STRING_FORMAT_TYPE_CTIME | LIBFDATETIME_STRING_FORMAT_FLAG_DATE_TIME, error ); #endif if( result != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_CONVERSION, LIBCERROR_CONVERSION_ERROR_GENERIC, "%s: unable to create FAT date time string.", function ); goto on_error; } libcnotify_printf( "%s: unknown time\t\t\t\t\t: %" PRIs_SYSTEM "\n", function, date_time_string ); if( libfdatetime_filetime_free( &filetime, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED, "%s: unable to free filetime.", function ); goto on_error; } if( libfdatetime_fat_date_time_free( &fat_date_time, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED, "%s: unable to free FAT date time.", function ); goto on_error; } } #endif if( unknown_offset > 0 ) { if( unknown_offset > record_size ) { if( ( item_flags & LIBMSIECF_ITEM_FLAG_PARTIAL ) == 0 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS, "%s: unknown offset exceeds URL record data.", function ); goto on_error; } else { memory_free( url_record_data ); return( 1 ); } } #if defined( HAVE_DEBUG_OUTPUT ) if( libcnotify_verbose != 0 ) { libcnotify_printf( "%s: unknown:\n", function ); libcnotify_print_data( &( url_record_data[ unknown_offset ] ), 8, 0 ); } #endif } if( location_offset > 0 ) { if( location_offset > record_size ) { if( ( item_flags & LIBMSIECF_ITEM_FLAG_PARTIAL ) == 0 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS, "%s: location offset exceeds size of URL record data.", function ); return( -1 ); } } else { if( libfvalue_value_type_initialize( &( url_values->location ), LIBFVALUE_VALUE_TYPE_STRING_BYTE_STREAM, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, "%s: unable to create location value.", function ); goto on_error; } value_size = libfvalue_value_type_set_data_string( url_values->location, &( url_record_data[ location_offset ] ), record_size - location_offset, io_handle->ascii_codepage, LIBFVALUE_VALUE_DATA_FLAG_MANAGED, error ); if( value_size == -1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_SET_FAILED, "%s: unable to set data of location value.", function ); goto on_error; } #if defined( HAVE_DEBUG_OUTPUT ) if( libcnotify_verbose != 0 ) { libcnotify_printf( "%s: location\t\t\t\t\t: ", function ); if( libfvalue_value_print( url_values->location, 0, 0, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_PRINT_FAILED, "%s: unable to print location value.", function ); goto on_error; } libcnotify_printf( "\n" ); if( libmsiecf_hash_calculate( &value_32bit, &( url_record_data[ location_offset ] ), record_size - location_offset, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_PRINT_FAILED, "%s: unable to calculate location hash.", function ); goto on_error; } libcnotify_printf( "%s: hash value\t\t\t\t\t: 0x%08" PRIx32 "\n", function, value_32bit ); } #endif if( ( url_record_data[ location_offset + value_size - 1 ] != 0 ) && ( ( item_flags & LIBMSIECF_ITEM_FLAG_PARTIAL ) == 0 ) ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE, "%s: unsupported unterminated location string.", function ); goto on_error; } if( url_values->type == LIBMSIECF_URL_ITEM_TYPE_UNDEFINED ) { if( value_size >= 18 ) { if( ( url_record_data[ location_offset ] == (uint8_t) ':' ) && ( url_record_data[ location_offset + 1 ] >= (uint8_t) '0' ) && ( url_record_data[ location_offset + 1 ] <= (uint8_t) '9' ) && ( url_record_data[ location_offset + 2 ] >= (uint8_t) '0' ) && ( url_record_data[ location_offset + 2 ] <= (uint8_t) '9' ) && ( url_record_data[ location_offset + 3 ] >= (uint8_t) '0' ) && ( url_record_data[ location_offset + 3 ] <= (uint8_t) '9' ) && ( url_record_data[ location_offset + 4 ] >= (uint8_t) '0' ) && ( url_record_data[ location_offset + 4 ] <= (uint8_t) '9' ) && ( url_record_data[ location_offset + 5 ] >= (uint8_t) '0' ) && ( url_record_data[ location_offset + 5 ] <= (uint8_t) '9' ) && ( url_record_data[ location_offset + 6 ] >= (uint8_t) '0' ) && ( url_record_data[ location_offset + 6 ] <= (uint8_t) '9' ) && ( url_record_data[ location_offset + 7 ] >= (uint8_t) '0' ) && ( url_record_data[ location_offset + 7 ] <= (uint8_t) '9' ) && ( url_record_data[ location_offset + 8 ] >= (uint8_t) '0' ) && ( url_record_data[ location_offset + 8 ] <= (uint8_t) '9' ) && ( url_record_data[ location_offset + 9 ] >= (uint8_t) '0' ) && ( url_record_data[ location_offset + 9 ] <= (uint8_t) '9' ) && ( url_record_data[ location_offset + 10 ] >= (uint8_t) '0' ) && ( url_record_data[ location_offset + 10 ] <= (uint8_t) '9' ) && ( url_record_data[ location_offset + 11 ] >= (uint8_t) '0' ) && ( url_record_data[ location_offset + 11 ] <= (uint8_t) '9' ) && ( url_record_data[ location_offset + 12 ] >= (uint8_t) '0' ) && ( url_record_data[ location_offset + 12 ] <= (uint8_t) '9' ) && ( url_record_data[ location_offset + 13 ] >= (uint8_t) '0' ) && ( url_record_data[ location_offset + 13 ] <= (uint8_t) '9' ) && ( url_record_data[ location_offset + 14 ] >= (uint8_t) '0' ) && ( url_record_data[ location_offset + 14 ] <= (uint8_t) '9' ) && ( url_record_data[ location_offset + 15 ] >= (uint8_t) '0' ) && ( url_record_data[ location_offset + 15 ] <= (uint8_t) '9' ) && ( url_record_data[ location_offset + 16 ] >= (uint8_t) '0' ) && ( url_record_data[ location_offset + 16 ] <= (uint8_t) '9' ) && ( url_record_data[ location_offset + 17 ] == (uint8_t) ':' ) ) { first_year = (uint16_t) url_record_data[ location_offset + 1 ] - (uint8_t) '0'; first_year *= 10; first_year += (uint16_t) url_record_data[ location_offset + 2 ] - (uint8_t) '0'; first_year *= 10; first_year += (uint16_t) url_record_data[ location_offset + 3 ] - (uint8_t) '0'; first_year *= 10; first_year += (uint16_t) url_record_data[ location_offset + 4 ] - (uint8_t) '0'; first_month = url_record_data[ location_offset + 5 ] - (uint8_t) '0'; first_month *= 10; first_month += url_record_data[ location_offset + 6 ] - (uint8_t) '0'; first_day_of_month = url_record_data[ location_offset + 7 ] - (uint8_t) '0'; first_day_of_month *= 10; first_day_of_month += url_record_data[ location_offset + 8 ] - (uint8_t) '0'; second_year = (uint16_t) url_record_data[ location_offset + 9 ] - (uint8_t) '0'; second_year *= 10; second_year += (uint16_t) url_record_data[ location_offset + 10 ] - (uint8_t) '0'; second_year *= 10; second_year += (uint16_t) url_record_data[ location_offset + 11 ] - (uint8_t) '0'; second_year *= 10; second_year += (uint16_t) url_record_data[ location_offset + 12 ] - (uint8_t) '0'; second_month = url_record_data[ location_offset + 13 ] - (uint8_t) '0'; second_month *= 10; second_month += url_record_data[ location_offset + 14 ] - (uint8_t) '0'; second_day_of_month = url_record_data[ location_offset + 15 ] - (uint8_t) '0'; second_day_of_month *= 10; second_day_of_month += url_record_data[ location_offset + 16 ] - (uint8_t) '0'; number_of_days = 0; if( first_year == second_year ) { if( first_month == second_month ) { if( first_day_of_month < second_day_of_month ) { number_of_days = second_day_of_month - first_day_of_month; } } else if( ( first_month + 1 ) == second_month ) { switch( first_month ) { case 3: case 5: case 7: case 8: case 10: case 12: number_of_days = ( 31 + second_day_of_month ) - first_day_of_month; break; case 2: if( ( ( ( first_year % 4 ) == 0 ) && ( ( first_year % 100 ) != 0 ) ) || ( ( first_year % 400 ) == 0 ) ) { number_of_days = ( 29 + second_day_of_month ) - first_day_of_month; } else { number_of_days = ( 28 + second_day_of_month ) - first_day_of_month; } break; case 4: case 6: case 9: case 11: number_of_days = ( 30 + second_day_of_month ) - first_day_of_month; break; } } } else if( ( first_year + 1 ) == second_year ) { if( ( first_month == 12 ) && ( second_month == 1 ) ) { number_of_days = ( 31 + second_day_of_month ) - first_day_of_month; } } if( number_of_days == 1 ) { url_values->type = LIBMSIECF_URL_ITEM_TYPE_HISTORY_DAILY; } else if( number_of_days == 7 ) { url_values->type = LIBMSIECF_URL_ITEM_TYPE_HISTORY_WEEKLY; } } } } if( url_values->type == LIBMSIECF_URL_ITEM_TYPE_UNDEFINED ) { if( value_size >= 11 ) { if( memory_compare( &( url_record_data[ location_offset ] ), "iedownload:", 11 ) == 0 ) { url_values->type = LIBMSIECF_URL_ITEM_TYPE_DOWNLOAD; } } } if( url_values->type == LIBMSIECF_URL_ITEM_TYPE_UNDEFINED ) { if( value_size >= 9 ) { if( memory_compare( &( url_record_data[ location_offset ] ), "DOMStore:", 9 ) == 0 ) { url_values->type = LIBMSIECF_URL_ITEM_TYPE_DOM_STORE; } else if( memory_compare( &( url_record_data[ location_offset ] ), "feedplat:", 9 ) == 0 ) { url_values->type = LIBMSIECF_URL_ITEM_TYPE_RSS_FEED; } else if( memory_compare( &( url_record_data[ location_offset ] ), "iecompat:", 9 ) == 0 ) { url_values->type = LIBMSIECF_URL_ITEM_TYPE_COMPATIBILITY; } else if( memory_compare( &( url_record_data[ location_offset ] ), "PrivacIE:", 9 ) == 0 ) { url_values->type = LIBMSIECF_URL_ITEM_TYPE_INPRIVATE_FILTERING; } else if( memory_compare( &( url_record_data[ location_offset ] ), "userdata:", 9 ) == 0 ) { url_values->type = LIBMSIECF_URL_ITEM_TYPE_USER_DATA; } } } if( url_values->type == LIBMSIECF_URL_ITEM_TYPE_UNDEFINED ) { if( value_size >= 8 ) { if( memory_compare( &( url_record_data[ location_offset ] ), "Visited:", 8 ) == 0 ) { url_values->type = LIBMSIECF_URL_ITEM_TYPE_HISTORY; } } } if( url_values->type == LIBMSIECF_URL_ITEM_TYPE_UNDEFINED ) { if( value_size >= 7 ) { if( memory_compare( &( url_record_data[ location_offset ] ), "Cookie:", 7 ) == 0 ) { url_values->type = LIBMSIECF_URL_ITEM_TYPE_COOKIE; } } } if( url_values->type == LIBMSIECF_URL_ITEM_TYPE_UNDEFINED ) { if( value_size >= 6 ) { if( memory_compare( &( url_record_data[ location_offset ] ), "ietld:", 6 ) == 0 ) { url_values->type = LIBMSIECF_URL_ITEM_TYPE_TLD; } } } if( url_values->type == LIBMSIECF_URL_ITEM_TYPE_UNDEFINED ) { url_values->type = LIBMSIECF_URL_ITEM_TYPE_CACHE; /* TODO way to determine unknown url_values->type = LIBMSIECF_URL_ITEM_TYPE_UNKNOWN; */ } } } if( filename_offset > 0 ) { if( filename_offset > record_size ) { if( ( item_flags & LIBMSIECF_ITEM_FLAG_PARTIAL ) == 0 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS, "%s: filename offset exceeds size of URL record data.", function ); goto on_error; } } else { if( libfvalue_value_type_initialize( &( url_values->filename ), LIBFVALUE_VALUE_TYPE_STRING_BYTE_STREAM, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, "%s: unable to create filename value.", function ); goto on_error; } value_size = libfvalue_value_type_set_data_string( url_values->filename, &( url_record_data[ filename_offset ] ), record_size - filename_offset, io_handle->ascii_codepage, LIBFVALUE_VALUE_DATA_FLAG_MANAGED, error ); if( value_size == -1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_SET_FAILED, "%s: unable to set data of filename value.", function ); goto on_error; } #if defined( HAVE_DEBUG_OUTPUT ) if( libcnotify_verbose != 0 ) { libcnotify_printf( "%s: filename\t\t\t\t\t: ", function ); if( libfvalue_value_print( url_values->filename, 0, 0, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_PRINT_FAILED, "%s: unable to print filename value.", function ); goto on_error; } libcnotify_printf( "\n" ); } #endif if( ( url_record_data[ filename_offset + value_size - 1 ] != 0 ) && ( ( item_flags & LIBMSIECF_ITEM_FLAG_PARTIAL ) == 0 ) ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE, "%s: unsupported unterminated filename string.", function ); goto on_error; } } } if( data_offset > 0 ) { if( data_offset > record_size ) { if( ( item_flags & LIBMSIECF_ITEM_FLAG_PARTIAL ) == 0 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS, "%s: data offset exceeds size of URL record data.", function ); goto on_error; } } else { if( ( data_offset + data_size ) > record_size ) { if( ( item_flags & LIBMSIECF_ITEM_FLAG_PARTIAL ) == 0 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS, "%s: data size exceeds size of URL record data.", function ); goto on_error; } else { data_size = record_size - data_offset; } } url_values->data_size = (size_t) data_size; url_values->data = (uint8_t *) memory_allocate( sizeof( uint8_t ) * url_values->data_size ); if( url_values->data == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_MEMORY, LIBCERROR_MEMORY_ERROR_INSUFFICIENT, "%s: unable to create data.", function ); goto on_error; } if( memory_copy( url_values->data, &( url_record_data[ data_offset ] ), url_values->data_size ) == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_MEMORY, LIBCERROR_MEMORY_ERROR_INSUFFICIENT, "%s: unable to copy data.", function ); goto on_error; } #if defined( HAVE_DEBUG_OUTPUT ) if( libcnotify_verbose != 0 ) { libcnotify_printf( "%s: data:\n", function ); libcnotify_print_data( &( url_record_data[ data_offset ] ), data_size, 0 ); if( url_values->type == LIBMSIECF_URL_ITEM_TYPE_CACHE ) { /* The data string in not necessarily terminated by an end-of-string character */ libcnotify_printf( "%s: data string\t\t\t\t\t: ", function ); for( string_index = 0; string_index < data_size; string_index++ ) { libcnotify_printf( "%c", url_record_data[ data_offset + string_index ] ); } libcnotify_printf( "\n" ); } else if( url_values->type == LIBMSIECF_URL_ITEM_TYPE_HISTORY ) { visited_entry_data = &( url_record_data[ data_offset ] ); do { visited_entry_index++; byte_stream_copy_to_uint16_little_endian( visited_entry_data, value_16bit ); visited_entry_data += 2; libcnotify_printf( "%s: data entry: %02d size\t\t\t\t: %" PRIu16 "\n", function, visited_entry_index, value_16bit ); libcnotify_printf( "%s: data entry: %02d type\t\t\t\t: 0x%02" PRIx8 " (%s : %s)\n", function, visited_entry_index, visited_entry_data[ 0 ], libmsiecf_property_type_get_identifier( NULL, (uint32_t) visited_entry_data[ 0 ], (uint32_t) visited_entry_data[ 1 ] ), libmsiecf_property_type_get_description( NULL, (uint32_t) visited_entry_data[ 0 ], (uint32_t) visited_entry_data[ 1 ] ) ); libcnotify_printf( "%s: data entry: %02d value type\t\t\t: 0x%02" PRIx8 " (%s : %s)\n", function, visited_entry_index, visited_entry_data[ 1 ], libfole_value_type_get_identifier( (uint32_t) visited_entry_data[ 1 ] ), libfole_value_type_get_description( (uint32_t) visited_entry_data[ 1 ] ) ); visited_entry_data += 2; if( value_16bit > 4 ) { value_16bit -= 4; libcnotify_printf( "%s: data entry: %02d value:\n", function, visited_entry_index ); libcnotify_print_data( visited_entry_data, value_16bit, 0 ); visited_entry_data += value_16bit; } } while( value_16bit > 0 ); } } #endif } } memory_free( url_record_data ); url_record_data = NULL; #if defined( HAVE_DEBUG_OUTPUT ) if( libcnotify_verbose != 0 ) { libcnotify_printf( "\n" ); } #endif #if defined( HAVE_VERBOSE_OUTPUT ) switch( url_values->type ) { case LIBMSIECF_URL_ITEM_TYPE_COOKIE: if ( ( cache_entry_flags & LIBMSIECF_CACHE_ENTRY_FLAG_COOKIE ) == 0 ) { libcnotify_printf( "%s: detected type cookie but corresponding cache entry flag (COOKIE_CACHE_ENTRY) is not set.\n", function ); } break; case LIBMSIECF_URL_ITEM_TYPE_HISTORY: if ( ( cache_entry_flags & LIBMSIECF_CACHE_ENTRY_FLAG_URLHISTORY ) == 0 ) { libcnotify_printf( "%s: detected type history but corresponding cache entry flag (URLHISTORY_CACHE_ENTRY) is not set.\n", function ); } break; case LIBMSIECF_URL_ITEM_TYPE_HISTORY_DAILY: case LIBMSIECF_URL_ITEM_TYPE_HISTORY_WEEKLY: if ( ( cache_entry_flags & LIBMSIECF_CACHE_ENTRY_FLAG_URLHISTORY ) == 0 ) { libcnotify_printf( "%s: detected type history periodic but corresponding cache entry flag (URLHISTORY_CACHE_ENTRY) is not set.\n", function ); } break; } #endif return( 1 ); on_error: #if defined( HAVE_DEBUG_OUTPUT ) if( filetime != NULL ) { libfdatetime_filetime_free( &filetime, NULL ); } if( fat_date_time != NULL ) { libfdatetime_fat_date_time_free( &fat_date_time, NULL ); } #endif if( url_record_data != NULL ) { memory_free( url_record_data ); } return( -1 ); }