/* * Record (row) functions * * Copyright (C) 2009-2023, Joachim Metz * * Refer to AUTHORS for acknowledgements. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #include #include #include #include "libesedb_compression.h" #include "libesedb_data_definition.h" #include "libesedb_data_segment.h" #include "libesedb_definitions.h" #include "libesedb_io_handle.h" #include "libesedb_libbfio.h" #include "libesedb_libcdata.h" #include "libesedb_libcerror.h" #include "libesedb_libcnotify.h" #include "libesedb_libfcache.h" #include "libesedb_libfdata.h" #include "libesedb_libfvalue.h" #include "libesedb_long_value.h" #include "libesedb_multi_value.h" #include "libesedb_page_tree.h" #include "libesedb_page_tree_key.h" #include "libesedb_record.h" #include "libesedb_record_value.h" #include "libesedb_table_definition.h" #include "libesedb_types.h" /* Creates a record * Make sure the value record is referencing, is set to NULL * Returns 1 if successful or -1 on error */ int libesedb_record_initialize( libesedb_record_t **record, libbfio_handle_t *file_io_handle, libesedb_io_handle_t *io_handle, libesedb_table_definition_t *table_definition, libesedb_table_definition_t *template_table_definition, libfdata_vector_t *pages_vector, libfcache_cache_t *pages_cache, libfdata_vector_t *long_values_pages_vector, libfcache_cache_t *long_values_pages_cache, libesedb_data_definition_t *data_definition, libesedb_page_tree_t *long_values_page_tree, libcerror_error_t **error ) { libesedb_internal_record_t *internal_record = NULL; static char *function = "libesedb_record_initialize"; if( record == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid record.", function ); return( -1 ); } if( *record != NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET, "%s: invalid record value already set.", function ); return( -1 ); } if( table_definition == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid table definition.", function ); return( -1 ); } if( table_definition->table_catalog_definition == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_VALUE_MISSING, "%s: invalid table definition - missing table catalog definition.", function ); return( -1 ); } internal_record = memory_allocate_structure( libesedb_internal_record_t ); if( internal_record == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_MEMORY, LIBCERROR_MEMORY_ERROR_INSUFFICIENT, "%s: unable to create record.", function ); goto on_error; } if( memory_set( internal_record, 0, sizeof( libesedb_internal_record_t ) ) == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_MEMORY, LIBCERROR_MEMORY_ERROR_SET_FAILED, "%s: unable to clear record.", function ); memory_free( internal_record ); return( -1 ); } if( libcdata_array_initialize( &( internal_record->values_array ), 0, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, "%s: unable to create values array.", function ); goto on_error; } if( libesedb_data_definition_read_record( data_definition, file_io_handle, io_handle, pages_vector, pages_cache, table_definition, template_table_definition, internal_record->values_array, &( internal_record->flags ), error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_IO, LIBCERROR_IO_ERROR_READ_FAILED, "%s: unable to read data definition record.", function ); goto on_error; } internal_record->file_io_handle = file_io_handle; internal_record->io_handle = io_handle; internal_record->table_definition = table_definition; internal_record->template_table_definition = template_table_definition; internal_record->pages_vector = pages_vector; internal_record->pages_cache = pages_cache; internal_record->long_values_pages_vector = long_values_pages_vector; internal_record->long_values_pages_cache = long_values_pages_cache; internal_record->data_definition = data_definition; internal_record->long_values_page_tree = long_values_page_tree; *record = (libesedb_record_t *) internal_record; return( 1 ); on_error: if( internal_record != NULL ) { if( internal_record->values_array != NULL ) { /* Note that if libesedb_data_definition_read_record fails values_array * can contain values that need to be freed with libfvalue_value_free. */ libcdata_array_free( &( internal_record->values_array ), (int (*)(intptr_t **, libcerror_error_t **)) &libfvalue_value_free, NULL ); } memory_free( internal_record ); } return( -1 ); } /* Frees a record * Returns 1 if successful or -1 on error */ int libesedb_record_free( libesedb_record_t **record, libcerror_error_t **error ) { libesedb_internal_record_t *internal_record = NULL; static char *function = "libesedb_record_free"; int result = 1; if( record == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid record.", function ); return( -1 ); } if( *record != NULL ) { internal_record = (libesedb_internal_record_t *) *record; *record = NULL; /* The io_handle, file_io_handle, table_definition, template_table_definition, pages_vector, * pages_cache, * long_values_pages_vector, long_values_pages_cache and long_values_page_tree * references are freed elsewhere */ if( internal_record->data_definition != NULL ) { if( libesedb_data_definition_free( &( internal_record->data_definition ), error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED, "%s: unable to free data definition.", function ); result = -1; } } if( libcdata_array_free( &( internal_record->values_array ), (int (*)(intptr_t **, libcerror_error_t **)) &libfvalue_value_free, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED, "%s: unable to free values array.", function ); result = -1; } memory_free( internal_record ); } return( result ); } /* Retrieves the number of values in the record * Returns 1 if successful or -1 on error */ int libesedb_record_get_number_of_values( libesedb_record_t *record, int *number_of_values, libcerror_error_t **error ) { libesedb_internal_record_t *internal_record = NULL; static char *function = "libesedb_record_get_number_of_values"; if( record == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid record.", function ); return( -1 ); } internal_record = (libesedb_internal_record_t *) record; if( libcdata_array_get_number_of_entries( internal_record->values_array, number_of_values, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve number of entries from values array.", function ); return( -1 ); } return( 1 ); } /* Retrieves a specific column catalog definition * Returns 1 if successful or -1 on error */ int libesedb_record_get_column_catalog_definition( libesedb_internal_record_t *internal_record, int value_entry, libesedb_catalog_definition_t **column_catalog_definition, libcerror_error_t **error ) { static char *function = "libesedb_record_get_column_identifier"; int template_table_number_of_columns = 0; if( internal_record == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid record.", function ); return( -1 ); } if( internal_record->table_definition == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_VALUE_MISSING, "%s: invalid record - missing table definition.", function ); return( -1 ); } if( internal_record->template_table_definition != NULL ) { if( libesedb_table_definition_get_number_of_column_catalog_definitions( internal_record->template_table_definition, &template_table_number_of_columns, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve number of columns from template table.", function ); return( -1 ); } } if( value_entry < template_table_number_of_columns ) { if( libesedb_table_definition_get_column_catalog_definition_by_index( internal_record->template_table_definition, value_entry, column_catalog_definition, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve column catalog definition from template table.", function ); return( -1 ); } } else { if( libesedb_table_definition_get_column_catalog_definition_by_index( internal_record->table_definition, value_entry - template_table_number_of_columns, column_catalog_definition, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve column catalog definition from table.", function ); return( -1 ); } } return( 1 ); } /* Retrieves the column identifier of the specific entry * Returns 1 if successful or -1 on error */ int libesedb_record_get_column_identifier( libesedb_record_t *record, int value_entry, uint32_t *column_identifier, libcerror_error_t **error ) { libesedb_catalog_definition_t *column_catalog_definition = NULL; libesedb_internal_record_t *internal_record = NULL; static char *function = "libesedb_record_get_column_identifier"; if( record == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid record.", function ); return( -1 ); } internal_record = (libesedb_internal_record_t *) record; if( libesedb_record_get_column_catalog_definition( internal_record, value_entry, &column_catalog_definition, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve column catalog definition.", function ); return( -1 ); } if( libesedb_catalog_definition_get_identifier( column_catalog_definition, column_identifier, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve catalog definition identifier.", function ); return( -1 ); } return( 1 ); } /* Retrieves the column type of the specific entry * Returns 1 if successful or -1 on error */ int libesedb_record_get_column_type( libesedb_record_t *record, int value_entry, uint32_t *column_type, libcerror_error_t **error ) { libesedb_catalog_definition_t *column_catalog_definition = NULL; libesedb_internal_record_t *internal_record = NULL; static char *function = "libesedb_record_get_column_type"; if( record == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid record.", function ); return( -1 ); } internal_record = (libesedb_internal_record_t *) record; if( libesedb_record_get_column_catalog_definition( internal_record, value_entry, &column_catalog_definition, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve column catalog definition.", function ); return( -1 ); } if( libesedb_catalog_definition_get_column_type( column_catalog_definition, column_type, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve catalog definition column type.", function ); return( -1 ); } return( 1 ); } /* Retrieves the size of the UTF-8 encoded string of the column name of the specific entry * The returned size includes the end of string character * Returns 1 if successful or -1 on error */ int libesedb_record_get_utf8_column_name_size( libesedb_record_t *record, int value_entry, size_t *utf8_string_size, libcerror_error_t **error ) { libesedb_catalog_definition_t *column_catalog_definition = NULL; libesedb_internal_record_t *internal_record = NULL; static char *function = "libesedb_record_get_utf8_column_name_size"; if( record == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid record.", function ); return( -1 ); } internal_record = (libesedb_internal_record_t *) record; if( internal_record->io_handle == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_VALUE_MISSING, "%s: invalid record - missing IO handle.", function ); return( -1 ); } if( libesedb_record_get_column_catalog_definition( internal_record, value_entry, &column_catalog_definition, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve column catalog definition.", function ); return( -1 ); } if( libesedb_catalog_definition_get_utf8_name_size( column_catalog_definition, utf8_string_size, internal_record->io_handle->ascii_codepage, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve UTF-8 string size.", function ); return( -1 ); } return( 1 ); } /* Retrieves the UTF-8 encoded string of the column name of the specific entry * The size should include the end of string character * Returns 1 if successful or -1 on error */ int libesedb_record_get_utf8_column_name( libesedb_record_t *record, int value_entry, uint8_t *utf8_string, size_t utf8_string_size, libcerror_error_t **error ) { libesedb_catalog_definition_t *column_catalog_definition = NULL; libesedb_internal_record_t *internal_record = NULL; static char *function = "libesedb_record_get_utf8_column_name"; if( record == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid record.", function ); return( -1 ); } internal_record = (libesedb_internal_record_t *) record; if( internal_record->io_handle == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_VALUE_MISSING, "%s: invalid record - missing IO handle.", function ); return( -1 ); } if( libesedb_record_get_column_catalog_definition( internal_record, value_entry, &column_catalog_definition, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve column catalog definition.", function ); return( -1 ); } if( libesedb_catalog_definition_get_utf8_name( column_catalog_definition, utf8_string, utf8_string_size, internal_record->io_handle->ascii_codepage, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_CONVERSION, LIBCERROR_CONVERSION_ERROR_GENERIC, "%s: unable to retrieve UTF-8 string.", function ); return( -1 ); } return( 1 ); } /* Retrieves the size of the UTF-16 encoded string of the column name of the specific entry * The returned size includes the end of string character * Returns 1 if successful or -1 on error */ int libesedb_record_get_utf16_column_name_size( libesedb_record_t *record, int value_entry, size_t *utf16_string_size, libcerror_error_t **error ) { libesedb_catalog_definition_t *column_catalog_definition = NULL; libesedb_internal_record_t *internal_record = NULL; static char *function = "libesedb_record_get_utf16_column_name_size"; if( record == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid record.", function ); return( -1 ); } internal_record = (libesedb_internal_record_t *) record; if( internal_record->io_handle == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_VALUE_MISSING, "%s: invalid record - missing IO handle.", function ); return( -1 ); } if( libesedb_record_get_column_catalog_definition( internal_record, value_entry, &column_catalog_definition, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve column catalog definition.", function ); return( -1 ); } if( libesedb_catalog_definition_get_utf16_name_size( column_catalog_definition, utf16_string_size, internal_record->io_handle->ascii_codepage, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve UTF-16 string size.", function ); return( -1 ); } return( 1 ); } /* Retrieves the UTF-16 encoded string of the column name of the specific entry * The size should include the end of string character * Returns 1 if successful or -1 on error */ int libesedb_record_get_utf16_column_name( libesedb_record_t *record, int value_entry, uint16_t *utf16_string, size_t utf16_string_size, libcerror_error_t **error ) { libesedb_catalog_definition_t *column_catalog_definition = NULL; libesedb_internal_record_t *internal_record = NULL; static char *function = "libesedb_record_get_utf16_column_name"; if( record == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid record.", function ); return( -1 ); } internal_record = (libesedb_internal_record_t *) record; if( internal_record->io_handle == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_VALUE_MISSING, "%s: invalid record - missing IO handle.", function ); return( -1 ); } if( libesedb_record_get_column_catalog_definition( internal_record, value_entry, &column_catalog_definition, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve column catalog definition.", function ); return( -1 ); } if( libesedb_catalog_definition_get_utf16_name( column_catalog_definition, utf16_string, utf16_string_size, internal_record->io_handle->ascii_codepage, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_CONVERSION, LIBCERROR_CONVERSION_ERROR_GENERIC, "%s: unable to retrieve UTF-16 string.", function ); return( -1 ); } return( 1 ); } /* Retrieves the value of the specific entry * Returns 1 if successful or -1 on error */ int libesedb_record_get_value( libesedb_record_t *record, int value_entry, uint8_t **value_data, size_t *value_data_size, uint8_t *value_flags, libcerror_error_t **error ) { libesedb_internal_record_t *internal_record = NULL; libfvalue_value_t *record_value = NULL; static char *function = "libesedb_record_get_value"; uint32_t data_flags = 0; int encoding = 0; if( record == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid record.", function ); return( -1 ); } internal_record = (libesedb_internal_record_t *) record; if( value_flags == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid value flags.", function ); return( -1 ); } if( libcdata_array_get_entry_by_index( internal_record->values_array, value_entry, (intptr_t **) &record_value, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve value: %d from values array.", function, value_entry ); return( -1 ); } if( libfvalue_value_get_data( record_value, value_data, value_data_size, &encoding, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve value: %d data.", function, value_entry ); return( -1 ); } if( libfvalue_value_get_data_flags( record_value, &data_flags, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve value: %d data flags.", function, value_entry ); return( -1 ); } *value_flags = (uint8_t) data_flags; return( 1 ); } /* Retrieves the value data flags of the specific entry * Returns 1 if successful or -1 on error */ int libesedb_record_get_value_data_flags( libesedb_record_t *record, int value_entry, uint8_t *value_data_flags, libcerror_error_t **error ) { libesedb_internal_record_t *internal_record = NULL; libfvalue_value_t *record_value = NULL; static char *function = "libesedb_record_get_value_data_flags"; uint32_t data_flags = 0; if( record == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid record.", function ); return( -1 ); } internal_record = (libesedb_internal_record_t *) record; if( value_data_flags == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid value data flags.", function ); return( -1 ); } if( libcdata_array_get_entry_by_index( internal_record->values_array, value_entry, (intptr_t **) &record_value, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve value: %d from values array.", function, value_entry ); return( -1 ); } if( libfvalue_value_get_data_flags( record_value, &data_flags, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve value: %d data flags.", function, value_entry ); return( -1 ); } *value_data_flags = (uint8_t) data_flags; return( 1 ); } /* Retrieves the value data size of the specific entry * Returns 1 if successful or -1 on error */ int libesedb_record_get_value_data_size( libesedb_record_t *record, int value_entry, size_t *value_data_size, libcerror_error_t **error ) { libesedb_internal_record_t *internal_record = NULL; libfvalue_value_t *record_value = NULL; static char *function = "libesedb_record_get_value_data_size"; if( record == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid record.", function ); return( -1 ); } internal_record = (libesedb_internal_record_t *) record; if( libcdata_array_get_entry_by_index( internal_record->values_array, value_entry, (intptr_t **) &record_value, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve value: %d from values array.", function, value_entry ); return( -1 ); } if( libfvalue_value_get_data_size( record_value, value_data_size, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve value: %d data size.", function, value_entry ); return( -1 ); } return( 1 ); } /* Retrieves the value data of the specific entry * Returns 1 if successful or -1 on error */ int libesedb_record_get_value_data( libesedb_record_t *record, int value_entry, uint8_t *value_data, size_t value_data_size, libcerror_error_t **error ) { libesedb_internal_record_t *internal_record = NULL; libfvalue_value_t *record_value = NULL; static char *function = "libesedb_record_get_value_data"; if( record == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid record.", function ); return( -1 ); } internal_record = (libesedb_internal_record_t *) record; if( libcdata_array_get_entry_by_index( internal_record->values_array, value_entry, (intptr_t **) &record_value, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve value: %d from values array.", function, value_entry ); return( -1 ); } if( libfvalue_value_copy_data( record_value, value_data, value_data_size, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_COPY_FAILED, "%s: unable to copy value: %d data.", function, value_entry ); return( -1 ); } return( 1 ); } /* Retrieves the boolean value of a specific entry * Returns 1 if successful, 0 if value is NULL or -1 on error */ int libesedb_record_get_value_boolean( libesedb_record_t *record, int value_entry, uint8_t *value_boolean, libcerror_error_t **error ) { libesedb_catalog_definition_t *column_catalog_definition = NULL; libesedb_internal_record_t *internal_record = NULL; libfvalue_value_t *record_value = NULL; static char *function = "libesedb_record_get_value_boolean"; uint32_t column_type = 0; int result = 0; if( record == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid record.", function ); return( -1 ); } internal_record = (libesedb_internal_record_t *) record; if( libesedb_record_get_column_catalog_definition( internal_record, value_entry, &column_catalog_definition, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve column catalog definition.", function ); return( -1 ); } if( libesedb_catalog_definition_get_column_type( column_catalog_definition, &column_type, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve catalog definition column type.", function ); return( -1 ); } if( column_type != LIBESEDB_COLUMN_TYPE_BOOLEAN ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE, "%s: unsupported column type: %" PRIu32 ".", function, column_type ); return( -1 ); } if( libcdata_array_get_entry_by_index( internal_record->values_array, value_entry, (intptr_t **) &record_value, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve value: %d from values array.", function, value_entry ); return( -1 ); } result = libfvalue_value_has_data( record_value, error ); if( result == -1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to determine if value: %d has data.", function, value_entry ); return( -1 ); } else if( result != 0 ) { if( libfvalue_value_copy_to_boolean( record_value, 0, value_boolean, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_COPY_FAILED, "%s: unable to copy value to boolean value.", function ); return( -1 ); } } return( result ); } /* Retrieves the 8-bit value of a specific entry * Returns 1 if successful, 0 if value is NULL or -1 on error */ int libesedb_record_get_value_8bit( libesedb_record_t *record, int value_entry, uint8_t *value_8bit, libcerror_error_t **error ) { libesedb_catalog_definition_t *column_catalog_definition = NULL; libesedb_internal_record_t *internal_record = NULL; libfvalue_value_t *record_value = NULL; static char *function = "libesedb_record_get_value_8bit"; uint32_t column_type = 0; int result = 0; if( record == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid record.", function ); return( -1 ); } internal_record = (libesedb_internal_record_t *) record; if( libesedb_record_get_column_catalog_definition( internal_record, value_entry, &column_catalog_definition, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve column catalog definition.", function ); return( -1 ); } if( libesedb_catalog_definition_get_column_type( column_catalog_definition, &column_type, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve catalog definition column type.", function ); return( -1 ); } if( column_type != LIBESEDB_COLUMN_TYPE_INTEGER_8BIT_UNSIGNED ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE, "%s: unsupported column type: %" PRIu32 ".", function, column_type ); return( -1 ); } if( libcdata_array_get_entry_by_index( internal_record->values_array, value_entry, (intptr_t **) &record_value, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve value: %d from values array.", function, value_entry ); return( -1 ); } result = libfvalue_value_has_data( record_value, error ); if( result == -1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to determine if value: %d has data.", function, value_entry ); return( -1 ); } else if( result != 0 ) { if( libfvalue_value_copy_to_8bit( record_value, 0, value_8bit, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_COPY_FAILED, "%s: unable to copy value to 8-bit value.", function ); return( -1 ); } } return( result ); } /* Retrieves the 16-bit value of a specific entry * Returns 1 if successful, 0 if value is NULL or -1 on error */ int libesedb_record_get_value_16bit( libesedb_record_t *record, int value_entry, uint16_t *value_16bit, libcerror_error_t **error ) { libesedb_catalog_definition_t *column_catalog_definition = NULL; libesedb_internal_record_t *internal_record = NULL; libfvalue_value_t *record_value = NULL; static char *function = "libesedb_record_get_value_16bit"; uint32_t column_type = 0; int result = 0; if( record == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid record.", function ); return( -1 ); } internal_record = (libesedb_internal_record_t *) record; if( libesedb_record_get_column_catalog_definition( internal_record, value_entry, &column_catalog_definition, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve column catalog definition.", function ); return( -1 ); } if( libesedb_catalog_definition_get_column_type( column_catalog_definition, &column_type, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve catalog definition column type.", function ); return( -1 ); } if( ( column_type != LIBESEDB_COLUMN_TYPE_INTEGER_16BIT_SIGNED ) && ( column_type != LIBESEDB_COLUMN_TYPE_INTEGER_16BIT_UNSIGNED ) ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE, "%s: unsupported column type: %" PRIu32 ".", function, column_type ); return( -1 ); } if( libcdata_array_get_entry_by_index( internal_record->values_array, value_entry, (intptr_t **) &record_value, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve value: %d from values array.", function, value_entry ); return( -1 ); } result = libfvalue_value_has_data( record_value, error ); if( result == -1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to determine if value: %d has data.", function, value_entry ); return( -1 ); } else if( result != 0 ) { if( libfvalue_value_copy_to_16bit( record_value, 0, value_16bit, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_COPY_FAILED, "%s: unable to copy value to 16-bit value.", function ); return( -1 ); } } return( result ); } /* Retrieves the 32-bit value of a specific entry * Returns 1 if successful, 0 if value is NULL or -1 on error */ int libesedb_record_get_value_32bit( libesedb_record_t *record, int value_entry, uint32_t *value_32bit, libcerror_error_t **error ) { libesedb_catalog_definition_t *column_catalog_definition = NULL; libesedb_internal_record_t *internal_record = NULL; libfvalue_value_t *record_value = NULL; static char *function = "libesedb_record_get_value_32bit"; uint32_t column_type = 0; int result = 0; if( record == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid record.", function ); return( -1 ); } internal_record = (libesedb_internal_record_t *) record; if( libesedb_record_get_column_catalog_definition( internal_record, value_entry, &column_catalog_definition, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve column catalog definition.", function ); return( -1 ); } if( libesedb_catalog_definition_get_column_type( column_catalog_definition, &column_type, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve catalog definition column type.", function ); return( -1 ); } if( ( column_type != LIBESEDB_COLUMN_TYPE_INTEGER_32BIT_SIGNED ) && ( column_type != LIBESEDB_COLUMN_TYPE_INTEGER_32BIT_UNSIGNED ) ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE, "%s: unsupported column type: %" PRIu32 ".", function, column_type ); return( -1 ); } if( libcdata_array_get_entry_by_index( internal_record->values_array, value_entry, (intptr_t **) &record_value, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve value: %d from values array.", function, value_entry ); return( -1 ); } result = libfvalue_value_has_data( record_value, error ); if( result == -1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to determine if value: %d has data.", function, value_entry ); return( -1 ); } else if( result != 0 ) { if( libfvalue_value_copy_to_32bit( record_value, 0, value_32bit, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_COPY_FAILED, "%s: unable to copy value to 32-bit value.", function ); return( -1 ); } } return( result ); } /* Retrieves the 64-bit value of a specific entry * Returns 1 if successful, 0 if value is NULL or -1 on error */ int libesedb_record_get_value_64bit( libesedb_record_t *record, int value_entry, uint64_t *value_64bit, libcerror_error_t **error ) { libesedb_catalog_definition_t *column_catalog_definition = NULL; libesedb_internal_record_t *internal_record = NULL; libfvalue_value_t *record_value = NULL; static char *function = "libesedb_record_get_value_64bit"; uint32_t column_type = 0; int result = 0; if( record == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid record.", function ); return( -1 ); } internal_record = (libesedb_internal_record_t *) record; if( libesedb_record_get_column_catalog_definition( internal_record, value_entry, &column_catalog_definition, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve column catalog definition.", function ); return( -1 ); } if( libesedb_catalog_definition_get_column_type( column_catalog_definition, &column_type, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve catalog definition column type.", function ); return( -1 ); } if( ( column_type != LIBESEDB_COLUMN_TYPE_CURRENCY ) && ( column_type != LIBESEDB_COLUMN_TYPE_DATE_TIME ) && ( column_type != LIBESEDB_COLUMN_TYPE_INTEGER_64BIT_SIGNED ) ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE, "%s: unsupported column type: %" PRIu32 ".", function, column_type ); return( -1 ); } if( libcdata_array_get_entry_by_index( internal_record->values_array, value_entry, (intptr_t **) &record_value, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve value: %d from values array.", function, value_entry ); return( -1 ); } result = libfvalue_value_has_data( record_value, error ); if( result == -1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to determine if value: %d has data.", function, value_entry ); return( -1 ); } else if( result != 0 ) { if( libfvalue_value_copy_to_64bit( record_value, 0, value_64bit, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_COPY_FAILED, "%s: unable to copy value to 64-bit value.", function ); return( -1 ); } } return( result ); } /* Retrieves the 64-bit filetime value of a specific entry * Returns 1 if successful, 0 if value is NULL or -1 on error */ int libesedb_record_get_value_filetime( libesedb_record_t *record, int value_entry, uint64_t *value_filetime, libcerror_error_t **error ) { libesedb_catalog_definition_t *column_catalog_definition = NULL; libesedb_internal_record_t *internal_record = NULL; libfvalue_value_t *record_value = NULL; static char *function = "libesedb_record_get_value_filetime"; uint32_t column_type = 0; int result = 0; if( record == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid record.", function ); return( -1 ); } internal_record = (libesedb_internal_record_t *) record; if( libesedb_record_get_column_catalog_definition( internal_record, value_entry, &column_catalog_definition, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve column catalog definition.", function ); return( -1 ); } if( libesedb_catalog_definition_get_column_type( column_catalog_definition, &column_type, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve catalog definition column type.", function ); return( -1 ); } if( column_type != LIBESEDB_COLUMN_TYPE_DATE_TIME ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE, "%s: unsupported column type: %" PRIu32 ".", function, column_type ); return( -1 ); } if( libcdata_array_get_entry_by_index( internal_record->values_array, value_entry, (intptr_t **) &record_value, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve value: %d from values array.", function, value_entry ); return( -1 ); } result = libfvalue_value_has_data( record_value, error ); if( result == -1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to determine if value: %d has data.", function, value_entry ); return( -1 ); } else if( result != 0 ) { /* Copy the filetime to a 64-bit value */ if( libfvalue_value_copy_to_64bit( record_value, 0, value_filetime, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_COPY_FAILED, "%s: unable to copy value to 64-bit value.", function ); return( -1 ); } } return( result ); } /* Retrieves the single precision floating point value of a specific entry * Returns 1 if successful, 0 if value is NULL or -1 on error */ int libesedb_record_get_value_floating_point_32bit( libesedb_record_t *record, int value_entry, float *value_floating_point_32bit, libcerror_error_t **error ) { libesedb_catalog_definition_t *column_catalog_definition = NULL; libesedb_internal_record_t *internal_record = NULL; libfvalue_value_t *record_value = NULL; static char *function = "libesedb_record_get_value_floating_point_32bit"; uint32_t column_type = 0; int result = 0; if( record == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid record.", function ); return( -1 ); } internal_record = (libesedb_internal_record_t *) record; if( libesedb_record_get_column_catalog_definition( internal_record, value_entry, &column_catalog_definition, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve column catalog definition.", function ); return( -1 ); } if( libesedb_catalog_definition_get_column_type( column_catalog_definition, &column_type, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve catalog definition column type.", function ); return( -1 ); } if( column_type != LIBESEDB_COLUMN_TYPE_FLOAT_32BIT ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE, "%s: unsupported column type: %" PRIu32 ".", function, column_type ); return( -1 ); } if( libcdata_array_get_entry_by_index( internal_record->values_array, value_entry, (intptr_t **) &record_value, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve value: %d from values array.", function, value_entry ); return( -1 ); } result = libfvalue_value_has_data( record_value, error ); if( result == -1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to determine if value: %d has data.", function, value_entry ); return( -1 ); } else if( result != 0 ) { if( libfvalue_value_copy_to_float( record_value, 0, value_floating_point_32bit, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_COPY_FAILED, "%s: unable to copy value to single precision floating point value.", function ); return( -1 ); } } return( result ); } /* Retrieves the double precision floating point value of a specific entry * Returns 1 if successful, 0 if value is NULL or -1 on error */ int libesedb_record_get_value_floating_point_64bit( libesedb_record_t *record, int value_entry, double *value_floating_point_64bit, libcerror_error_t **error ) { libesedb_catalog_definition_t *column_catalog_definition = NULL; libesedb_internal_record_t *internal_record = NULL; libfvalue_value_t *record_value = NULL; static char *function = "libesedb_record_get_value_floating_point_64bit"; uint32_t column_type = 0; int result = 0; if( record == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid record.", function ); return( -1 ); } internal_record = (libesedb_internal_record_t *) record; if( libesedb_record_get_column_catalog_definition( internal_record, value_entry, &column_catalog_definition, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve column catalog definition.", function ); return( -1 ); } if( libesedb_catalog_definition_get_column_type( column_catalog_definition, &column_type, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve catalog definition column type.", function ); return( -1 ); } if( column_type != LIBESEDB_COLUMN_TYPE_DOUBLE_64BIT ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE, "%s: unsupported column type: %" PRIu32 ".", function, column_type ); return( -1 ); } if( libcdata_array_get_entry_by_index( internal_record->values_array, value_entry, (intptr_t **) &record_value, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve value: %d from values array.", function, value_entry ); return( -1 ); } result = libfvalue_value_has_data( record_value, error ); if( result == -1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to determine if value: %d has data.", function, value_entry ); return( -1 ); } else if( result != 0 ) { if( libfvalue_value_copy_to_double( record_value, 0, value_floating_point_64bit, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_COPY_FAILED, "%s: unable to copy value to double precision floating point value.", function ); return( -1 ); } } return( result ); } /* Retrieves the size of an UTF-8 string a specific entry * The returned size includes the end of string character * Returns 1 if successful, 0 if value is NULL or -1 on error */ int libesedb_record_get_value_utf8_string_size( libesedb_record_t *record, int value_entry, size_t *utf8_string_size, libcerror_error_t **error ) { libesedb_catalog_definition_t *column_catalog_definition = NULL; libesedb_internal_record_t *internal_record = NULL; libfvalue_value_t *record_value = NULL; static char *function = "libesedb_record_get_value_utf8_string_size"; uint32_t column_type = 0; int result = 0; if( record == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid record.", function ); return( -1 ); } internal_record = (libesedb_internal_record_t *) record; if( libesedb_record_get_column_catalog_definition( internal_record, value_entry, &column_catalog_definition, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve column catalog definition.", function ); return( -1 ); } if( libesedb_catalog_definition_get_column_type( column_catalog_definition, &column_type, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve catalog definition column type.", function ); return( -1 ); } if( ( column_type != LIBESEDB_COLUMN_TYPE_TEXT ) && ( column_type != LIBESEDB_COLUMN_TYPE_LARGE_TEXT ) ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE, "%s: unsupported column type: %" PRIu32 ".", function, column_type ); return( -1 ); } if( libcdata_array_get_entry_by_index( internal_record->values_array, value_entry, (intptr_t **) &record_value, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve value: %d from values array.", function, value_entry ); return( -1 ); } result = libesedb_record_value_get_utf8_string_size( record_value, utf8_string_size, error ); if( result == -1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve UTF-8 string size from value: %d.", function, value_entry ); return( -1 ); } return( result ); } /* Retrieves the UTF-8 encoded string of a specific entry * The function uses the codepage in the column definition if necessary * The size should include the end of string character * Returns 1 if successful, 0 if value is NULL or -1 on error */ int libesedb_record_get_value_utf8_string( libesedb_record_t *record, int value_entry, uint8_t *utf8_string, size_t utf8_string_size, libcerror_error_t **error ) { libesedb_catalog_definition_t *column_catalog_definition = NULL; libesedb_internal_record_t *internal_record = NULL; libfvalue_value_t *record_value = NULL; static char *function = "libesedb_record_get_value_utf8_string"; uint32_t column_type = 0; int result = 0; if( record == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid record.", function ); return( -1 ); } internal_record = (libesedb_internal_record_t *) record; if( libesedb_record_get_column_catalog_definition( internal_record, value_entry, &column_catalog_definition, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve column catalog definition.", function ); return( -1 ); } if( libesedb_catalog_definition_get_column_type( column_catalog_definition, &column_type, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve catalog definition column type.", function ); return( -1 ); } if( ( column_type != LIBESEDB_COLUMN_TYPE_TEXT ) && ( column_type != LIBESEDB_COLUMN_TYPE_LARGE_TEXT ) ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE, "%s: unsupported column type: %" PRIu32 ".", function, column_type ); return( -1 ); } if( libcdata_array_get_entry_by_index( internal_record->values_array, value_entry, (intptr_t **) &record_value, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve value: %d from values array.", function, value_entry ); return( -1 ); } result = libesedb_record_value_get_utf8_string( record_value, utf8_string, utf8_string_size, error ); if( result == -1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve UTF-8 string from value: %d.", function, value_entry ); return( -1 ); } return( result ); } /* Retrieves the size of an UTF-16 string a specific entry * The returned size includes the end of string character * Returns 1 if successful, 0 if value is NULL or -1 on error */ int libesedb_record_get_value_utf16_string_size( libesedb_record_t *record, int value_entry, size_t *utf16_string_size, libcerror_error_t **error ) { libesedb_catalog_definition_t *column_catalog_definition = NULL; libesedb_internal_record_t *internal_record = NULL; libfvalue_value_t *record_value = NULL; static char *function = "libesedb_record_get_value_utf16_string_size"; uint32_t column_type = 0; int result = 0; if( record == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid record.", function ); return( -1 ); } internal_record = (libesedb_internal_record_t *) record; if( libesedb_record_get_column_catalog_definition( internal_record, value_entry, &column_catalog_definition, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve column catalog definition.", function ); return( -1 ); } if( libesedb_catalog_definition_get_column_type( column_catalog_definition, &column_type, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve catalog definition column type.", function ); return( -1 ); } if( ( column_type != LIBESEDB_COLUMN_TYPE_TEXT ) && ( column_type != LIBESEDB_COLUMN_TYPE_LARGE_TEXT ) ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE, "%s: unsupported column type: %" PRIu32 ".", function, column_type ); return( -1 ); } if( libcdata_array_get_entry_by_index( internal_record->values_array, value_entry, (intptr_t **) &record_value, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve value: %d from values array.", function, value_entry ); return( -1 ); } result = libesedb_record_value_get_utf16_string_size( record_value, utf16_string_size, error ); if( result == -1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve UTF-16 string size from value: %d.", function, value_entry ); return( -1 ); } return( result ); } /* Retrieves the UTF-16 encoded string value of a specific entry * The function uses the codepage in the column definition if necessary * The size should include the end of string character * Returns 1 if successful, 0 if value is NULL or -1 on error */ int libesedb_record_get_value_utf16_string( libesedb_record_t *record, int value_entry, uint16_t *utf16_string, size_t utf16_string_size, libcerror_error_t **error ) { libesedb_catalog_definition_t *column_catalog_definition = NULL; libesedb_internal_record_t *internal_record = NULL; libfvalue_value_t *record_value = NULL; static char *function = "libesedb_record_get_value_utf16_string"; uint32_t column_type = 0; int result = 0; if( record == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid record.", function ); return( -1 ); } internal_record = (libesedb_internal_record_t *) record; if( libesedb_record_get_column_catalog_definition( internal_record, value_entry, &column_catalog_definition, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve column catalog definition.", function ); return( -1 ); } if( libesedb_catalog_definition_get_column_type( column_catalog_definition, &column_type, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve catalog definition column type.", function ); return( -1 ); } if( ( column_type != LIBESEDB_COLUMN_TYPE_TEXT ) && ( column_type != LIBESEDB_COLUMN_TYPE_LARGE_TEXT ) ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE, "%s: unsupported column type: %" PRIu32 ".", function, column_type ); return( -1 ); } if( libcdata_array_get_entry_by_index( internal_record->values_array, value_entry, (intptr_t **) &record_value, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve value: %d from values array.", function, value_entry ); return( -1 ); } result = libesedb_record_value_get_utf16_string( record_value, utf16_string, utf16_string_size, error ); if( result == -1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve UTF-16 string from value: %d.", function, value_entry ); return( -1 ); } return( result ); } /* Retrieves the binary data size of a specific entry * Returns 1 if successful, 0 if value is NULL or -1 on error */ int libesedb_record_get_value_binary_data_size( libesedb_record_t *record, int value_entry, size_t *binary_data_size, libcerror_error_t **error ) { libesedb_catalog_definition_t *column_catalog_definition = NULL; libesedb_internal_record_t *internal_record = NULL; libfvalue_value_t *record_value = NULL; uint8_t *entry_data = NULL; uint8_t *value_data = NULL; static char *function = "libesedb_record_get_value_binary_data_size"; size_t entry_data_size = 0; uint32_t column_type = 0; uint32_t data_flags = 0; int encoding = 0; int result = 0; if( record == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid record.", function ); return( -1 ); } internal_record = (libesedb_internal_record_t *) record; if( libesedb_record_get_column_catalog_definition( internal_record, value_entry, &column_catalog_definition, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve column catalog definition.", function ); return( -1 ); } if( libesedb_catalog_definition_get_column_type( column_catalog_definition, &column_type, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve catalog definition column type.", function ); return( -1 ); } if( ( column_type != LIBESEDB_COLUMN_TYPE_BINARY_DATA ) && ( column_type != LIBESEDB_COLUMN_TYPE_LARGE_BINARY_DATA ) ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE, "%s: unsupported column type: %" PRIu32 ".", function, column_type ); return( -1 ); } if( libcdata_array_get_entry_by_index( internal_record->values_array, value_entry, (intptr_t **) &record_value, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve value: %d from values array.", function, value_entry ); return( -1 ); } result = libfvalue_value_has_data( record_value, error ); if( result == -1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to determine if value: %d has data.", function, value_entry ); return( -1 ); } else if( result != 0 ) { if( libfvalue_value_get_data_flags( record_value, &data_flags, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve value: %d data flags.", function, value_entry ); return( -1 ); } if( ( data_flags & LIBESEDB_VALUE_FLAG_COMPRESSED ) != 0 ) { if( libfvalue_value_get_entry_data( record_value, 0, &entry_data, &entry_data_size, &encoding, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve record value entry data.", function ); return( -1 ); } result = libesedb_compression_decompress_get_size( entry_data, entry_data_size, binary_data_size, error ); } else { result = libfvalue_value_get_data( record_value, &value_data, binary_data_size, &encoding, error ); } if( result != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable retrieve value data.", function ); return( -1 ); } } return( result ); } /* Retrieves the binary data value of a specific entry * Returns 1 if successful, 0 if value is NULL or -1 on error */ int libesedb_record_get_value_binary_data( libesedb_record_t *record, int value_entry, uint8_t *binary_data, size_t binary_data_size, libcerror_error_t **error ) { libesedb_catalog_definition_t *column_catalog_definition = NULL; libesedb_internal_record_t *internal_record = NULL; libfvalue_value_t *record_value = NULL; uint8_t *entry_data = NULL; static char *function = "libesedb_record_get_value_binary_data"; size_t entry_data_size = 0; uint32_t column_type = 0; uint32_t data_flags = 0; int encoding = 0; int result = 0; if( record == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid record.", function ); return( -1 ); } internal_record = (libesedb_internal_record_t *) record; if( libesedb_record_get_column_catalog_definition( internal_record, value_entry, &column_catalog_definition, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve column catalog definition.", function ); return( -1 ); } if( libesedb_catalog_definition_get_column_type( column_catalog_definition, &column_type, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve catalog definition column type.", function ); return( -1 ); } if( ( column_type != LIBESEDB_COLUMN_TYPE_BINARY_DATA ) && ( column_type != LIBESEDB_COLUMN_TYPE_LARGE_BINARY_DATA ) ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE, "%s: unsupported column type: %" PRIu32 ".", function, column_type ); return( -1 ); } if( libcdata_array_get_entry_by_index( internal_record->values_array, value_entry, (intptr_t **) &record_value, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve value: %d from values array.", function, value_entry ); return( -1 ); } result = libfvalue_value_has_data( record_value, error ); if( result == -1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to determine if value: %d has data.", function, value_entry ); return( -1 ); } else if( result != 0 ) { if( libfvalue_value_get_data_flags( record_value, &data_flags, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve value: %d data flags.", function, value_entry ); return( -1 ); } if( ( data_flags & LIBESEDB_VALUE_FLAG_COMPRESSED ) != 0 ) { if( libfvalue_value_get_entry_data( record_value, 0, &entry_data, &entry_data_size, &encoding, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve record value entry data.", function ); return( -1 ); } result = libesedb_compression_decompress( entry_data, entry_data_size, binary_data, binary_data_size, error ); } else { result = libfvalue_value_copy_data( record_value, binary_data, binary_data_size, error ); } if( result != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_COPY_FAILED, "%s: unable copy value data.", function ); return( -1 ); } } return( result ); } /* Determines if a specific entry is a long value * Returns 1 if true, 0 if not or -1 on error */ int libesedb_record_is_long_value( libesedb_record_t *record, int value_entry, libcerror_error_t **error ) { libesedb_internal_record_t *internal_record = NULL; static char *function = "libesedb_record_is_long_value"; libfvalue_value_t *record_value = NULL; uint32_t data_flags = 0; if( record == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid record.", function ); return( -1 ); } internal_record = (libesedb_internal_record_t *) record; if( libcdata_array_get_entry_by_index( internal_record->values_array, value_entry, (intptr_t **) &record_value, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve value: %d from values array.", function, value_entry ); return( -1 ); } if( libfvalue_value_get_data_flags( record_value, &data_flags, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve value: %d data flags.", function, value_entry ); return( -1 ); } return( ( data_flags & LIBESEDB_VALUE_FLAG_LONG_VALUE ) != 0 ); } /* Determines if a specific entry is a multi value * Returns 1 if true, 0 if not or -1 on error */ int libesedb_record_is_multi_value( libesedb_record_t *record, int value_entry, libcerror_error_t **error ) { libesedb_internal_record_t *internal_record = NULL; static char *function = "libesedb_record_is_multi_value"; libfvalue_value_t *record_value = NULL; uint32_t data_flags = 0; if( record == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid record.", function ); return( -1 ); } internal_record = (libesedb_internal_record_t *) record; if( libcdata_array_get_entry_by_index( internal_record->values_array, value_entry, (intptr_t **) &record_value, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve value: %d from values array.", function, value_entry ); return( -1 ); } if( libfvalue_value_get_data_flags( record_value, &data_flags, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve value: %d data flags.", function, value_entry ); return( -1 ); } return( ( data_flags & LIBESEDB_VALUE_FLAG_MULTI_VALUE ) != 0 ); } /* Retrieves the long value data segments list of a specific entry * Creates a new data segments list * Returns 1 if successful, 0 if the item does not contain such value or -1 on error */ int libesedb_record_get_long_value_data_segments_list( libesedb_internal_record_t *internal_record, const uint8_t *long_value_key, size_t long_value_key_size, libfdata_list_t **data_segments_list, libcerror_error_t **error ) { uint8_t long_value_segment_key[ 8 ]; libesedb_data_definition_t *data_definition = NULL; libesedb_page_tree_key_t *key = NULL; static char *function = "libesedb_record_get_long_value_data_segments_list"; uint32_t long_value_segment_offset = 0; int result = 0; if( internal_record == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid record.", function ); return( -1 ); } if( long_value_key == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid long value key.", function ); return( -1 ); } if( long_value_key_size != 4 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE, "%s: unsupport long value key size: %" PRIzd ".", function, long_value_key_size ); return( -1 ); } if( data_segments_list == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid data segments list.", function ); return( -1 ); } if( libesedb_page_tree_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( libesedb_page_tree_key_set_data( key, long_value_key, long_value_key_size, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_SET_FAILED, "%s: unable to set long value key data in key.", function ); goto on_error; } key->type = LIBESEDB_KEY_TYPE_LONG_VALUE; result = libesedb_page_tree_get_leaf_value_by_key( internal_record->long_values_page_tree, internal_record->file_io_handle, key, &data_definition, error ); if( result == -1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve leaf value by key.", function ); goto on_error; } if( libesedb_page_tree_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; } if( result == 0 ) { return( 0 ); } if( libfdata_list_initialize( data_segments_list, NULL, NULL, NULL, (int (*)(intptr_t *, intptr_t *, libfdata_list_element_t *, libfdata_cache_t *, int, off64_t, size64_t, uint32_t, uint8_t, libcerror_error_t **)) &libesedb_data_segment_read_element_data, NULL, 0, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, "%s: unable to create data segments list.", function ); goto on_error; } if( libesedb_data_definition_read_long_value( data_definition, internal_record->file_io_handle, internal_record->long_values_pages_vector, internal_record->long_values_pages_cache, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_IO, LIBCERROR_IO_ERROR_READ_FAILED, "%s: unable to read data definition long value.", function ); goto on_error; } if( libesedb_data_definition_free( &data_definition, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED, "%s: unable to free data definition.", function ); goto on_error; } /* Reverse the reversed long value key */ long_value_segment_key[ 0 ] = long_value_key[ 3 ]; long_value_segment_key[ 1 ] = long_value_key[ 2 ]; long_value_segment_key[ 2 ] = long_value_key[ 1 ]; long_value_segment_key[ 3 ] = long_value_key[ 0 ]; do { byte_stream_copy_from_uint32_big_endian( &( long_value_segment_key[ 4 ] ), long_value_segment_offset ); if( libesedb_page_tree_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( libesedb_page_tree_key_set_data( key, long_value_segment_key, 8, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_SET_FAILED, "%s: unable to set long value segment key data in key.", function ); goto on_error; } key->type = LIBESEDB_KEY_TYPE_LONG_VALUE_SEGMENT; result = libesedb_page_tree_get_leaf_value_by_key( internal_record->long_values_page_tree, internal_record->file_io_handle, key, &data_definition, error ); if( result == -1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve leaf value by key.", function ); goto on_error; } else if( result != 0 ) { if( libesedb_data_definition_read_long_value_segment( data_definition, internal_record->file_io_handle, internal_record->io_handle, internal_record->long_values_pages_vector, internal_record->long_values_pages_cache, long_value_segment_offset, *data_segments_list, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_IO, LIBCERROR_IO_ERROR_READ_FAILED, "%s: unable to read data definition long value segment.", function ); goto on_error; } long_value_segment_offset += data_definition->data_size; if( libesedb_data_definition_free( &data_definition, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED, "%s: unable to free data definition.", function ); goto on_error; } } if( libesedb_page_tree_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; } } while( result == 1 ); return( 1 ); on_error: if( *data_segments_list != NULL ) { libfdata_list_free( data_segments_list, NULL ); } if( data_definition != NULL ) { libesedb_data_definition_free( &data_definition, NULL ); } if( key != NULL ) { libesedb_page_tree_key_free( &key, NULL ); } return( -1 ); } /* Retrieves the long value of a specific entry * Creates a new long value * Returns 1 if successful, 0 if the item does not contain such value or -1 on error */ int libesedb_record_get_long_value( libesedb_record_t *record, int value_entry, libesedb_long_value_t **long_value, libcerror_error_t **error ) { libesedb_catalog_definition_t *column_catalog_definition = NULL; libesedb_internal_record_t *internal_record = NULL; libfdata_list_t *data_segments_list = NULL; libfvalue_value_t *record_value = NULL; uint8_t* value_data = NULL; static char *function = "libesedb_record_get_long_value"; size_t value_data_size = 0; uint32_t data_flags = 0; int encoding = 0; int result = 0; if( record == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid record.", function ); return( -1 ); } internal_record = (libesedb_internal_record_t *) record; if( long_value == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid long value.", function ); return( -1 ); } if( *long_value != NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET, "%s: long value already set.", function ); return( -1 ); } if( libesedb_record_get_column_catalog_definition( internal_record, value_entry, &column_catalog_definition, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve column catalog definition.", function ); goto on_error; } if( libcdata_array_get_entry_by_index( internal_record->values_array, value_entry, (intptr_t **) &record_value, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve value: %d from values array.", function, value_entry ); goto on_error; } if( libfvalue_value_get_data_flags( record_value, &data_flags, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve value: %d data flags.", function, value_entry ); goto on_error; } if( ( data_flags & LIBESEDB_VALUE_FLAG_LONG_VALUE ) == 0 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE, "%s: unsupported data flags: 0x%02" PRIx32 ".", function, data_flags ); goto on_error; } if( ( data_flags & LIBESEDB_VALUE_FLAG_MULTI_VALUE ) != 0 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE, "%s: unsupported data flags: 0x%02" PRIx32 ".", function, data_flags ); goto on_error; } result = libfvalue_value_has_data( record_value, error ); if( result == -1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to determine if value: %d has data.", function, value_entry ); goto on_error; } else if( result == 0 ) { return( 0 ); } if( libfvalue_value_get_data( record_value, &value_data, &value_data_size, &encoding, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable retrieve value data.", function ); goto on_error; } result = libesedb_record_get_long_value_data_segments_list( internal_record, value_data, value_data_size, &data_segments_list, error ); if( result == -1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable retrieve value data.", function ); goto on_error; } else if( result == 0 ) { return( 0 ); } if( libesedb_long_value_initialize( long_value, internal_record->file_io_handle, internal_record->io_handle, column_catalog_definition, data_segments_list, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, "%s: unable to create long value.", function ); goto on_error; } return( 1 ); on_error: if( data_segments_list != NULL ) { libfdata_list_free( &data_segments_list, NULL ); } return( -1 ); } /* Retrieves the multi value of a specific entry * Creates a new multi value * Returns 1 if successful, 0 if the item does not contain such value or -1 on error */ int libesedb_record_get_multi_value( libesedb_record_t *record, int value_entry, libesedb_multi_value_t **multi_value, libcerror_error_t **error ) { libesedb_catalog_definition_t *column_catalog_definition = NULL; libesedb_internal_record_t *internal_record = NULL; libfvalue_value_t *record_value = NULL; uint8_t *value_data = NULL; static char *function = "libesedb_record_get_multi_value"; size_t value_data_offset = 0; size_t value_data_size = 0; uint32_t data_flags = 0; uint16_t number_of_value_entries = 0; uint16_t value_16bit = 0; uint16_t value_entry_offset = 0; uint16_t value_entry_offset_index = 0; uint16_t value_entry_size = 0; int encoding = 0; int result = 0; int value_entry_index = 0; if( record == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid record.", function ); return( -1 ); } internal_record = (libesedb_internal_record_t *) record; if( multi_value == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid multi value.", function ); return( -1 ); } if( *multi_value != NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET, "%s: multi value already set.", function ); return( -1 ); } if( libesedb_record_get_column_catalog_definition( internal_record, value_entry, &column_catalog_definition, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve column catalog definition.", function ); return( -1 ); } if( column_catalog_definition == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_VALUE_MISSING, "%s: missing column catalog definition.", function ); return( -1 ); } if( libcdata_array_get_entry_by_index( internal_record->values_array, value_entry, (intptr_t **) &record_value, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve value: %d from values array.", function, value_entry ); return( -1 ); } if( libfvalue_value_get_data_flags( record_value, &data_flags, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve value: %d data flags.", function, value_entry ); return( -1 ); } if( ( data_flags & LIBESEDB_VALUE_FLAG_MULTI_VALUE ) == 0 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE, "%s: unsupported data flags: 0x%02" PRIx32 ".", function, data_flags ); return( -1 ); } if( ( ( data_flags & LIBESEDB_VALUE_FLAG_LONG_VALUE ) != 0 ) || ( ( data_flags & 0x10 ) != 0 ) ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE, "%s: unsupported data flags: 0x%02" PRIx32 ".", function, data_flags ); return( -1 ); } result = libfvalue_value_has_data( record_value, error ); if( result == -1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to determine if value: %d has data.", function, value_entry ); return( -1 ); } else if( result != 0 ) { if( libfvalue_value_get_data( record_value, &value_data, &value_data_size, &encoding, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable retrieve value data.", function ); return( -1 ); } if( value_data == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_VALUE_MISSING, "%s: missing value data.", function ); return( -1 ); } if( value_data_size > (size_t) UINT16_MAX ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS, "%s: invalid value data size value out of bounds.", function ); return( -1 ); } #if defined( HAVE_DEBUG_OUTPUT ) if( libcnotify_verbose != 0 ) { libcnotify_printf( "%s: multi value data:\n", function ); libcnotify_print_data( value_data, value_data_size, 0 ); } #endif /* The first 2 bytes contain the offset to the first value * there is an offset for every value * therefore first offset / 2 = the number of value entries */ byte_stream_copy_to_uint16_little_endian( value_data, value_16bit ); value_data_offset += 2; #if defined( HAVE_DEBUG_OUTPUT ) if( libcnotify_verbose != 0 ) { libcnotify_printf( "%s: multi value offset: %03" PRIu16 "\t\t: 0x%04" PRIx16 " (%" PRIu16 ")\n", function, value_entry_offset_index, value_16bit, value_16bit & 0x7fff ); } #endif value_entry_offset = value_16bit & 0x7fff; number_of_value_entries = value_entry_offset / 2; if( number_of_value_entries == 0 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_VALUE_MISSING, "%s: missing value entries.", function ); return( -1 ); } for( value_entry_offset_index = 1; value_entry_offset_index < number_of_value_entries; value_entry_offset_index++ ) { byte_stream_copy_to_uint16_little_endian( &( value_data[ value_data_offset ] ), value_16bit ); value_data_offset += 2; #if defined( HAVE_DEBUG_OUTPUT ) if( libcnotify_verbose != 0 ) { libcnotify_printf( "%s: multi value offset: %03" PRIu16 "\t\t: 0x%04" PRIx16 " (%" PRIu16 ")\n", function, value_entry_offset_index, value_16bit, value_16bit & 0x7fff ); } #endif value_16bit &= 0x7fff; if( value_16bit < value_entry_offset ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS, "%s: invalid value offset: %" PRIu16 " value is smaller than previous.", function, value_entry_offset_index ); return( -1 ); } value_entry_size = value_16bit - value_entry_offset; if( libfvalue_value_append_entry( record_value, &value_entry_index, (size_t) value_entry_offset, (size_t) value_entry_size, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_SET_FAILED, "%s: unable set value entry: %" PRIu16 ".", function, value_entry_offset_index - 1 ); return( -1 ); } value_entry_offset = value_16bit; } value_entry_size = (uint16_t) value_data_size - value_entry_offset; if( libfvalue_value_append_entry( record_value, &value_entry_index, (size_t) value_entry_offset, (size_t) value_entry_size, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_SET_FAILED, "%s: unable set value entry: %" PRIu16 ".", function, value_entry_offset_index - 1 ); return( -1 ); } #if defined( HAVE_DEBUG_OUTPUT ) if( libcnotify_verbose != 0 ) { libcnotify_printf( "\n" ); } #endif if( libesedb_multi_value_initialize( multi_value, column_catalog_definition, record_value, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, "%s: unable to create multi value.", function ); return( -1 ); } } return( result ); }