/* * Debug 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 "libesedb_debug.h" #include "libesedb_definitions.h" #include "libesedb_libbfio.h" #include "libesedb_libcerror.h" #include "libesedb_libcnotify.h" #if defined( HAVE_DEBUG_OUTPUT ) /* Prints the file type */ void libesedb_debug_print_file_type( uint32_t file_type ) { switch( file_type ) { case LIBESEDB_FILE_TYPE_DATABASE: libcnotify_printf( "Database" ); break; case LIBESEDB_FILE_TYPE_STREAMING_FILE: libcnotify_printf( "Streaming file" ); break; default: libcnotify_printf( "(Unknown)" ); } } /* Prints the database state */ void libesedb_debug_print_database_state( uint32_t database_state ) { switch( database_state ) { case 1: libcnotify_printf( "Just created (JET_dbstateJustCreated)" ); break; case 2: libcnotify_printf( "Dirty Shutdown (JET_dbstateDirtyShutdown)" ); break; case 3: libcnotify_printf( "Clean Shutdown (JET_dbstateCleanShutdown)" ); break; case 4: libcnotify_printf( "Being converted (JET_dbstateBeingConverted)" ); break; case 5: libcnotify_printf( "Force Detach (JET_dbstateForceDetach)" ); break; default: libcnotify_printf( "(Unknown)" ); break; } } /* Prints the page flags */ void libesedb_debug_print_page_flags( uint32_t page_flags ) { if( ( page_flags & LIBESEDB_PAGE_FLAG_IS_ROOT ) != 0 ) { libcnotify_printf( "\tIs root\n" ); } if( ( page_flags & LIBESEDB_PAGE_FLAG_IS_LEAF ) != 0 ) { libcnotify_printf( "\tIs leaf\n" ); } if( ( page_flags & LIBESEDB_PAGE_FLAG_IS_PARENT ) != 0 ) { libcnotify_printf( "\tIs parent\n" ); } if( ( page_flags & LIBESEDB_PAGE_FLAG_IS_EMPTY ) != 0 ) { libcnotify_printf( "\tIs empty\n" ); } if( ( page_flags & LIBESEDB_PAGE_FLAG_IS_SPACE_TREE ) != 0 ) { libcnotify_printf( "\tIs space tree\n" ); } if( ( page_flags & LIBESEDB_PAGE_FLAG_IS_INDEX ) != 0 ) { libcnotify_printf( "\tIs index\n" ); } if( ( page_flags & LIBESEDB_PAGE_FLAG_IS_LONG_VALUE ) != 0 ) { libcnotify_printf( "\tIs long value\n" ); } if( ( page_flags & LIBESEDB_PAGE_FLAG_0x0400 ) != 0 ) { libcnotify_printf( "\t0x0400\n" ); } if( ( page_flags & LIBESEDB_PAGE_FLAG_0x0800 ) != 0 ) { libcnotify_printf( "\t0x0800 (primary?)\n" ); } if( ( page_flags & LIBESEDB_PAGE_FLAG_IS_NEW_RECORD_FORMAT ) != 0 ) { libcnotify_printf( "\tIs new record format\n" ); } if( ( page_flags & LIBESEDB_PAGE_FLAG_IS_SCRUBBED ) != 0 ) { libcnotify_printf( "\tIs scrubbed\n" ); } if( ( page_flags & LIBESEDB_PAGE_FLAG_0x8000 ) != 0 ) { libcnotify_printf( "\t0x8000\n" ); } } /* Prints the page tag flags */ void libesedb_debug_print_page_tag_flags( uint8_t page_tag_flags ) { if( page_tag_flags > 0 ) { libcnotify_printf( " (" ); if( ( page_tag_flags & 0x04 ) != 0 ) { libcnotify_printf( "c" ); } if( ( page_tag_flags & 0x02 ) != 0 ) { libcnotify_printf( "d" ); } if( ( page_tag_flags & 0x01 ) != 0 ) { libcnotify_printf( "v" ); } libcnotify_printf( ")" ); } } /* Prints the tagged data type flags */ void libesedb_debug_print_tagged_data_type_flags( uint8_t tagged_data_type_flags ) { if( ( tagged_data_type_flags & LIBESEDB_VALUE_FLAG_VARIABLE_SIZE ) != 0 ) { libcnotify_printf( "\tIs variable size\n" ); } if( ( tagged_data_type_flags & LIBESEDB_VALUE_FLAG_COMPRESSED ) != 0 ) { libcnotify_printf( "\tIs compressed\n" ); } if( ( tagged_data_type_flags & LIBESEDB_VALUE_FLAG_LONG_VALUE ) != 0 ) { libcnotify_printf( "\tIs long value\n" ); } if( ( tagged_data_type_flags & LIBESEDB_VALUE_FLAG_MULTI_VALUE ) != 0 ) { libcnotify_printf( "\tIs multi value\n" ); } } /* Prints the data definition type */ void libesedb_debug_print_page_value_definition_type( uint16_t page_value_definition_type ) { switch( page_value_definition_type ) { case 1: libcnotify_printf( "(Table)" ); break; case 2: libcnotify_printf( "(Column)" ); break; case 3: libcnotify_printf( "(Index)" ); break; case 4: libcnotify_printf( "(Long Value)" ); break; case 5: libcnotify_printf( "(Callback)" ); break; default: libcnotify_printf( "(Unknown)" ); break; } } /* Prints the table group of bits */ void libesedb_debug_print_table_group_of_bits( uint32_t table_group_of_bits ) { if( ( table_group_of_bits & 0x00000001 ) != 0 ) { libcnotify_printf( "\t(JET_bitTableCreateFixedDDL)\n" ); } if( ( table_group_of_bits & 0x00000002 ) != 0 ) { libcnotify_printf( "\t(JET_bitTableCreateTemplateTable)\n" ); } if( ( table_group_of_bits & 0x00000004 ) != 0 ) { libcnotify_printf( "\t(JET_bitTableCreateNoFixedVarColumnsInDerivedTables)\n" ); } } /* Prints the column group of bits */ void libesedb_debug_print_column_group_of_bits( uint32_t column_group_of_bits ) { if( ( column_group_of_bits & 0x00000001 ) != 0 ) { libcnotify_printf( "\tIs fixed size (JET_bitColumnFixed)\n" ); } if( ( column_group_of_bits & 0x00000002 ) != 0 ) { libcnotify_printf( "\tIs tagged (JET_bitColumnTagged)\n" ); } if( ( column_group_of_bits & 0x00000004 ) != 0 ) { libcnotify_printf( "\tNot empty (JET_bitColumnNotNULL)\n" ); } if( ( column_group_of_bits & 0x00000008 ) != 0 ) { libcnotify_printf( "\tIs version column (JET_bitColumnVersion)\n" ); } if( ( column_group_of_bits & 0x00000010 ) != 0 ) { libcnotify_printf( "\t(JET_bitColumnAutoincrement)\n" ); } if( ( column_group_of_bits & 0x00000020 ) != 0 ) { libcnotify_printf( "\t(JET_bitColumnUpdatable)\n" ); } if( ( column_group_of_bits & 0x00000040 ) != 0 ) { libcnotify_printf( "\t(JET_bitColumnTTKey)\n" ); } if( ( column_group_of_bits & 0x00000080 ) != 0 ) { libcnotify_printf( "\t(JET_bitColumnTTDescending)\n" ); } if( ( column_group_of_bits & 0x00000400 ) != 0 ) { libcnotify_printf( "\t(JET_bitColumnMultiValued)\n" ); } if( ( column_group_of_bits & 0x00000800 ) != 0 ) { libcnotify_printf( "\t(JET_bitColumnEscrowUpdate)\n" ); } if( ( column_group_of_bits & 0x00001000 ) != 0 ) { libcnotify_printf( "\t(JET_bitColumnUnversioned)\n" ); } if( ( column_group_of_bits & 0x00002000 ) != 0 ) { libcnotify_printf( "\t(JET_bitColumnDeleteOnZero or JET_bitColumnMaybeNull)\n" ); } if( ( column_group_of_bits & 0x00004000 ) != 0 ) { libcnotify_printf( "\t(JET_bitColumnFinalize)\n" ); } if( ( column_group_of_bits & 0x00008000 ) != 0 ) { libcnotify_printf( "\t(JET_bitColumnUserDefinedDefault)\n" ); } } /* Prints the index group of bits */ void libesedb_debug_print_index_group_of_bits( uint32_t index_group_of_bits ) { if( ( index_group_of_bits & 0x00000001 ) != 0 ) { libcnotify_printf( "\t(JET_bitIndexUnique)\n" ); } if( ( index_group_of_bits & 0x00000002 ) != 0 ) { libcnotify_printf( "\t(JET_bitIndexPrimary)\n" ); } if( ( index_group_of_bits & 0x00000004 ) != 0 ) { libcnotify_printf( "\t(JET_bitIndexDisallowNull)\n" ); } if( ( index_group_of_bits & 0x00000008 ) != 0 ) { libcnotify_printf( "\t(JET_bitIndexIgnoreNull)\n" ); } if( ( index_group_of_bits & 0x00000010 ) != 0 ) { libcnotify_printf( "\t(0x00000010)\n" ); } if( ( index_group_of_bits & 0x00000020 ) != 0 ) { libcnotify_printf( "\t(JET_bitIndexIgnoreAnyNull)\n" ); } if( ( index_group_of_bits & 0x00000040 ) != 0 ) { libcnotify_printf( "\t(JET_bitIndexIgnoreFirstNull)\n" ); } if( ( index_group_of_bits & 0x00000080 ) != 0 ) { libcnotify_printf( "\t(JET_bitIndexLazyFlush)\n" ); } if( ( index_group_of_bits & 0x00000100 ) != 0 ) { libcnotify_printf( "\t(JET_bitIndexEmpty)\n" ); } if( ( index_group_of_bits & 0x00000200 ) != 0 ) { libcnotify_printf( "\t(JET_bitIndexUnversioned)\n" ); } if( ( index_group_of_bits & 0x00000400 ) != 0 ) { libcnotify_printf( "\t(JET_bitIndexSortNullsHigh)\n" ); } if( ( index_group_of_bits & 0x00000800 ) != 0 ) { libcnotify_printf( "\t(JET_bitIndexUnicode)\n" ); } if( ( index_group_of_bits & 0x00001000 ) != 0 ) { libcnotify_printf( "\t(JET_bitIndexTuples)\n" ); } if( ( index_group_of_bits & 0x00002000 ) != 0 ) { libcnotify_printf( "\t(JET_bitIndexTupleLimits)\n" ); } if( ( index_group_of_bits & 0x00004000 ) != 0 ) { libcnotify_printf( "\t(JET_bitIndexCrossProduct)\n" ); } if( ( index_group_of_bits & 0x00008000 ) != 0 ) { libcnotify_printf( "\t(JET_bitIndexKeyMost)\n" ); } if( ( index_group_of_bits & 0x00010000 ) != 0 ) { libcnotify_printf( "\t(JET_bitIndexDisallowTruncation)\n" ); } } /* Prints the file attribute flags * Returns 1 if successful or -1 on error */ void libesedb_debug_print_file_attribute_flags( uint32_t file_attribute_flags ) { if( ( file_attribute_flags & LIBESEDB_FILE_ATTRIBUTE_FLAG_READ_ONLY ) != 0 ) { libcnotify_printf( "\tIs read-only (FILE_ATTRIBUTE_READ_ONLY)\n" ); } if( ( file_attribute_flags & LIBESEDB_FILE_ATTRIBUTE_FLAG_HIDDEN ) != 0 ) { libcnotify_printf( "\tIs hidden (FILE_ATTRIBUTE_HIDDEN)\n" ); } if( ( file_attribute_flags & LIBESEDB_FILE_ATTRIBUTE_FLAG_SYSTEM ) != 0 ) { libcnotify_printf( "\tIs system (FILE_ATTRIBUTE_SYSTEM)\n" ); } if( ( file_attribute_flags & LIBESEDB_FILE_ATTRIBUTE_FLAG_DIRECTORY ) != 0 ) { libcnotify_printf( "\tIs directory (FILE_ATTRIBUTE_DIRECTORY)\n" ); } if( ( file_attribute_flags & LIBESEDB_FILE_ATTRIBUTE_FLAG_ARCHIVE ) != 0 ) { libcnotify_printf( "\tShould be archived (FILE_ATTRIBUTE_ARCHIVE)\n" ); } if( ( file_attribute_flags & LIBESEDB_FILE_ATTRIBUTE_FLAG_DEVICE ) != 0 ) { libcnotify_printf( "\tIs device (FILE_ATTRIBUTE_DEVICE)\n" ); } if( ( file_attribute_flags & LIBESEDB_FILE_ATTRIBUTE_FLAG_NORMAL ) != 0 ) { libcnotify_printf( "\tIs normal (FILE_ATTRIBUTE_NORMAL)\n" ); } if( ( file_attribute_flags & LIBESEDB_FILE_ATTRIBUTE_FLAG_TEMPORARY ) != 0 ) { libcnotify_printf( "\tIs temporary (FILE_ATTRIBUTE_TEMPORARY)\n" ); } if( ( file_attribute_flags & LIBESEDB_FILE_ATTRIBUTE_FLAG_SPARSE_FILE ) != 0 ) { libcnotify_printf( "\tIs a sparse file (FILE_ATTRIBUTE_SPARSE_FILE)\n" ); } if( ( file_attribute_flags & LIBESEDB_FILE_ATTRIBUTE_FLAG_REPARSE_POINT ) != 0 ) { libcnotify_printf( "\tIs a reparse point or symbolic link (FILE_ATTRIBUTE_FLAG_REPARSE_POINT)\n" ); } if( ( file_attribute_flags & LIBESEDB_FILE_ATTRIBUTE_FLAG_COMPRESSED ) != 0 ) { libcnotify_printf( "\tIs compressed (FILE_ATTRIBUTE_COMPRESSED)\n" ); } if( ( file_attribute_flags & LIBESEDB_FILE_ATTRIBUTE_FLAG_OFFLINE ) != 0 ) { libcnotify_printf( "\tIs offline (FILE_ATTRIBUTE_OFFLINE)\n" ); } if( ( file_attribute_flags & LIBESEDB_FILE_ATTRIBUTE_FLAG_NOT_CONTENT_INDEXED ) != 0 ) { libcnotify_printf( "\tContent should not be indexed (FILE_ATTRIBUTE_NOT_CONTENT_INDEXED)\n" ); } if( ( file_attribute_flags & LIBESEDB_FILE_ATTRIBUTE_FLAG_ENCRYPTED ) != 0 ) { libcnotify_printf( "\tIs encrypted (FILE_ATTRIBUTE_ENCRYPTED)\n" ); } if( ( file_attribute_flags & LIBESEDB_FILE_ATTRIBUTE_FLAG_VIRTUAL ) != 0 ) { libcnotify_printf( "\tIs virtual (FILE_ATTRIBUTE_VIRTUAL)\n" ); } } /* Prints the LCMAP flags * Returns 1 if successful or -1 on error */ void libesedb_debug_print_lcmap_flags( uint32_t lcmap_flags ) { if( ( lcmap_flags & 0x00000300 ) != 0 ) { libcnotify_printf( "\t(LCMAP_TITLECASE)\n" ); } else if( ( lcmap_flags & 0x00000100 ) != 0 ) { libcnotify_printf( "\t(LCMAP_LOWERCASE)\n" ); } else if( ( lcmap_flags & 0x00000200 ) != 0 ) { libcnotify_printf( "\t(LCMAP_UPPERCASE)\n" ); } if( ( lcmap_flags & 0x00000400 ) != 0 ) { libcnotify_printf( "\t(LCMAP_SORTKEY)\n" ); } if( ( lcmap_flags & 0x00000800 ) != 0 ) { libcnotify_printf( "\t(LCMAP_BYTEREV)\n" ); } if( ( lcmap_flags & 0x00100000 ) != 0 ) { libcnotify_printf( "\t(LCMAP_HIRAGANA)\n" ); } if( ( lcmap_flags & 0x00200000 ) != 0 ) { libcnotify_printf( "\t(LCMAP_KATAKANA)\n" ); } if( ( lcmap_flags & 0x00400000 ) != 0 ) { libcnotify_printf( "\t(LCMAP_HALFWIDTH)\n" ); } if( ( lcmap_flags & 0x00800000 ) != 0 ) { libcnotify_printf( "\t(LCMAP_FULLWIDTH)\n" ); } if( ( lcmap_flags & 0x01000000 ) != 0 ) { libcnotify_printf( "\t(LCMAP_LINGUISTIC_CASING)\n" ); } if( ( lcmap_flags & 0x02000000 ) != 0 ) { libcnotify_printf( "\t(LCMAP_SIMPLIFIED_CHINESE)\n" ); } if( ( lcmap_flags & 0x04000000 ) != 0 ) { libcnotify_printf( "\t(LCMAP_TRADITIONAL_CHINESE)\n" ); } } /* Prints a log structure * Returns 1 if successful or -1 on error */ int libesedb_debug_print_log_time( uint8_t *log_time, size_t log_time_size, const char *description, const char *indentation, libcerror_error_t **error ) { static char *function = "libesedb_debug_print_log_time"; if( log_time == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid log time.", function ); return( -1 ); } if( log_time_size < 8 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL, "%s: log time too small.", function ); return( -1 ); } if( log_time_size > (size_t) SSIZE_MAX ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM, "%s: invalid log time size value exceeds maximum.", function ); return( -1 ); } if( description == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid description.", function ); return( -1 ); } if( indentation == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid indentation.", function ); return( -1 ); } libcnotify_printf( "%s: %s%s: %04d-%02d-%02d %02d:%02d:%02d (0x%02x 0x%02x)\n", function, description, indentation, 1900 + log_time[ 5 ], log_time[ 4 ], log_time[ 3 ], log_time[ 2 ], log_time[ 1 ], log_time[ 0 ], log_time[ 6 ], log_time[ 7 ] ); return( 1 ); } /* Prints the read offsets * Returns 1 if successful or -1 on error */ int libesedb_debug_print_read_offsets( libbfio_handle_t *file_io_handle, libcerror_error_t **error ) { static char *function = "libesedb_debug_print_read_offsets"; off64_t offset = 0; size64_t size = 0; int number_of_offsets = 0; int offset_iterator = 0; 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( libbfio_handle_get_number_of_offsets_read( file_io_handle, &number_of_offsets, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve number of offsets read.", function ); return( -1 ); } libcnotify_printf( "Offsets read:\n" ); for( offset_iterator = 0; offset_iterator < number_of_offsets; offset_iterator++ ) { if( libbfio_handle_get_offset_read( file_io_handle, offset_iterator, &offset, &size, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve offset: %d.", function, offset_iterator ); return( -1 ); } libcnotify_printf( "%08" PRIi64 " ( 0x%08" PRIx64 " ) - %08" PRIi64 " ( 0x%08" PRIx64 " ) size: %" PRIi64 "\n", offset, offset, offset + (off64_t) size, offset + (off64_t) size, size ); } libcnotify_printf( "\n" ); return( 1 ); } #endif /* defined( HAVE_DEBUG_OUTPUT ) */