/* Reads the known folder location * Returns the number of bytes read if successful or -1 on error */ int liblnk_known_folder_location_read( liblnk_known_folder_location_t *known_folder_location, liblnk_data_block_t *data_block, libcerror_error_t **error ) { lnk_data_block_known_folder_location_t *known_folder_location_data = NULL; static char *function = "liblnk_data_block_strings_read"; #if defined( HAVE_DEBUG_OUTPUT ) libcstring_system_character_t guid_string[ 48 ]; libfguid_identifier_t *guid = NULL; int result = 0; #endif if( known_folder_location == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid known folder location.", function ); return( -1 ); } if( data_block == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid data block.", function ); return( -1 ); } if( data_block->data == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_VALUE_MISSING, "%s: invalid data block - missing data.", function ); return( -1 ); } if( data_block->data_size < sizeof( lnk_data_block_known_folder_location_t ) ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS, "%s: invalid data block - data size too small.", function ); return( -1 ); } known_folder_location_data = (lnk_data_block_known_folder_location_t *) data_block->data; if( memory_copy( known_folder_location->folder_identifier, known_folder_location_data->folder_identifier, 16 ) == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_MEMORY, LIBCERROR_MEMORY_ERROR_COPY_FAILED, "%s: unable to copy folder identifier.", function ); goto on_error; } byte_stream_copy_to_uint32_little_endian( known_folder_location_data->first_child_segment_offset, known_folder_location->first_child_segment_offset ); #if defined( HAVE_DEBUG_OUTPUT ) if( libcnotify_verbose != 0 ) { if( libfguid_identifier_initialize( &guid, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, "%s: unable to create GUID.", function ); goto on_error; } if( libfguid_identifier_copy_from_byte_stream( guid, known_folder_location->folder_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: known folder identifier\t\t: %" PRIs_LIBCSTRING_SYSTEM "\n", function, guid_string ); libcnotify_printf( "%s: known folder name\t\t\t: %s\n", function, libfwsi_known_folder_identifier_get_name( known_folder_location->folder_identifier ) ); libcnotify_printf( "%s: first child segment offset\t\t: %" PRIu32 "\n", function, known_folder_location->first_child_segment_offset ); libcnotify_printf( "\n" ); 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; } } #endif #if defined( HAVE_DEBUG_OUTPUT ) if( libcnotify_verbose != 0 ) { if( data_block->data_size > sizeof( lnk_data_block_known_folder_location_t ) ) { libcnotify_printf( "%s: trailing data:\n", function ); libcnotify_print_data( &( data_block->data[ sizeof( lnk_data_block_known_folder_location_t ) ] ), data_block->data_size - sizeof( lnk_data_block_known_folder_location_t ), 0 ); } } #endif return( 1 ); on_error: #if defined( HAVE_DEBUG_OUTPUT ) if( guid != NULL ) { libfguid_identifier_free( &guid, NULL ); } #endif return( -1 ); }
/* Reads the users property view values * Returns 1 if successful, 0 if not supported or -1 on error */ int libfwsi_users_property_view_values_read_data( libfwsi_users_property_view_values_t *users_property_view_values, const uint8_t *data, size_t data_size, int ascii_codepage, libcerror_error_t **error ) { static char *function = "libfwsi_users_property_view_values_read_data"; size_t data_offset = 0; uint32_t signature = 0; uint16_t identifier_size = 0; uint16_t item_data_size = 0; uint16_t property_store_size = 0; #if defined( HAVE_DEBUG_OUTPUT ) uint32_t value_32bit = 0; uint16_t value_16bit = 0; #endif if( users_property_view_values == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid users property view values.", function ); return( -1 ); } if( data == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid data.", function ); return( -1 ); } if( data_size > (size_t) SSIZE_MAX ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM, "%s: data size exceeds maximum.", function ); return( -1 ); } /* Do not try to parse unsupported data sizes */ if( data_size < 14 ) { return( 0 ); } /* Do not try to parse unsupported shell item signatures */ byte_stream_copy_to_uint32_little_endian( &( data[ 6 ] ), signature ); switch( signature ) { case 0x10141981UL: case 0x23a3dfd5UL: case 0x23febbeeUL: case 0x3b93afbbUL: case 0xbeebee00UL: break; default: return( 0 ); } byte_stream_copy_to_uint32_little_endian( &( data[ 4 ] ), item_data_size ); byte_stream_copy_to_uint16_little_endian( &( data[ 10 ] ), property_store_size ); byte_stream_copy_to_uint16_little_endian( &( data[ 12 ] ), identifier_size ); #if defined( HAVE_DEBUG_OUTPUT ) if( libcnotify_verbose != 0 ) { libcnotify_printf( "%s: class type indicator\t\t: 0x%02" PRIx8 "\n", function, data[ 2 ] ); libcnotify_printf( "%s: unknown1\t\t\t: 0x%02" PRIx8 "\n", function, data[ 3 ] ); libcnotify_printf( "%s: data size\t\t\t: %" PRIu16 "\n", function, item_data_size ); libcnotify_printf( "%s: data signature\t\t\t: 0x%08" PRIx32 "\n", function, signature ); libcnotify_printf( "%s: property store size\t\t: %" PRIu16 "\n", function, property_store_size ); libcnotify_printf( "%s: identifier size\t\t: %" PRIu16 "\n", function, identifier_size ); } #endif data_offset = 14; if( item_data_size != 0 ) { if( item_data_size <= 2 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS, "%s: invalid data size value out of bounds.", function ); return( -1 ); } } /* TODO add identifier_size bounds check */ #if defined( HAVE_DEBUG_OUTPUT ) if( libcnotify_verbose != 0 ) { libcnotify_printf( "%s: identifier data:\n", function ); libcnotify_print_data( &( data[ data_offset ] ), identifier_size, 0 ); } #endif switch( signature ) { case 0x23a3dfd5UL: case 0x3b93afbbUL: case 0xbeebee00UL: if( identifier_size == 4 ) { #if defined( HAVE_DEBUG_OUTPUT ) if( libcnotify_verbose != 0 ) { byte_stream_copy_to_uint32_little_endian( &( data[ data_offset ] ), value_32bit ); libcnotify_printf( "%s: identifier\t\t\t: 0x%08" PRIx32 "\n", function, value_32bit ); } #endif data_offset += 4; } break; case 0x23febbeeUL: if( identifier_size == 16 ) { #if defined( HAVE_DEBUG_OUTPUT ) if( libcnotify_verbose != 0 ) { if( libfwsi_debug_print_guid_value( function, "known folder identifier\t", &( data[ data_offset ] ), 16, LIBFGUID_ENDIAN_LITTLE, LIBFGUID_STRING_FORMAT_FLAG_USE_UPPER_CASE | LIBFGUID_STRING_FORMAT_FLAG_USE_SURROUNDING_BRACES, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_PRINT_FAILED, "%s: unable to print GUID value.", function ); return( -1 ); } libcnotify_printf( "%s: known folder name\t\t: %s\n", function, libfwsi_known_folder_identifier_get_name( &( data[ data_offset ] ) ) ); } #endif data_offset += 16; } break; default: data_offset += identifier_size; break; } /* TODO add property store size bounds check */ #if defined( HAVE_DEBUG_OUTPUT ) if( libcnotify_verbose != 0 ) { libcnotify_printf( "%s: property store data:\n", function ); libcnotify_print_data( &( data[ data_offset ] ), property_store_size, LIBCNOTIFY_PRINT_DATA_FLAG_GROUP_DATA ); } #endif if( property_store_size > 0 ) { /* TODO look for multiple stores */ #if defined( HAVE_DEBUG_OUTPUT ) if( libcnotify_verbose != 0 ) { if( libfwsi_debug_print_property_storage_value( &( data[ data_offset ] ), property_store_size, ascii_codepage, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_PRINT_FAILED, "%s: unable to print property storage value.", function ); return( -1 ); } } #endif data_offset += property_store_size; } #if defined( HAVE_DEBUG_OUTPUT ) if( libcnotify_verbose != 0 ) { byte_stream_copy_to_uint16_little_endian( &( data[ data_offset ] ), value_16bit ); libcnotify_printf( "%s: unknown1 size\t\t\t: %" PRIu16 "\n", function, value_16bit ); } #endif data_offset += 2; if( signature == 0x23a3dfd5UL ) { if( data_offset > data_size - 32 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS, "%s: invalid data size value out of bounds.", function ); return( -1 ); } #if defined( HAVE_DEBUG_OUTPUT ) if( libcnotify_verbose != 0 ) { if( libfwsi_debug_print_guid_value( function, "delegate item identifier\t", &( data[ data_offset ] ), 16, LIBFGUID_ENDIAN_LITTLE, LIBFGUID_STRING_FORMAT_FLAG_USE_UPPER_CASE | LIBFGUID_STRING_FORMAT_FLAG_USE_SURROUNDING_BRACES, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_PRINT_FAILED, "%s: unable to print GUID value.", function ); return( -1 ); } } #endif data_offset += 16; #if defined( HAVE_DEBUG_OUTPUT ) if( libcnotify_verbose != 0 ) { if( libfwsi_debug_print_guid_value( function, "item class identifier\t\t", &( data[ data_offset ] ), 16, LIBFGUID_ENDIAN_LITTLE, LIBFGUID_STRING_FORMAT_FLAG_USE_UPPER_CASE | LIBFGUID_STRING_FORMAT_FLAG_USE_SURROUNDING_BRACES, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_PRINT_FAILED, "%s: unable to print GUID value.", function ); return( -1 ); } libcnotify_printf( "%s: shell folder name\t\t: %s\n", function, libfwsi_shell_folder_identifier_get_name( &( data[ data_offset ] ) ) ); } #endif data_offset += 16; } #if defined( HAVE_DEBUG_OUTPUT ) if( libcnotify_verbose != 0 ) { libcnotify_printf( "\n" ); } #endif return( 1 ); }