/* * Input/Output (IO) handle 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 #include "libesedb_checksum.h" #include "libesedb_codepage.h" #include "libesedb_debug.h" #include "libesedb_definitions.h" #include "libesedb_io_handle.h" #include "libesedb_libbfio.h" #include "libesedb_libcerror.h" #include "libesedb_libcnotify.h" #include "libesedb_libfdata.h" #include "libesedb_page.h" #include "libesedb_unused.h" const uint8_t esedb_file_signature[ 4 ] = { 0xef, 0xcd, 0xab, 0x89 }; /* Creates an IO handle * Make sure the value io_handle is referencing, is set to NULL * Returns 1 if successful or -1 on error */ int libesedb_io_handle_initialize( libesedb_io_handle_t **io_handle, libcerror_error_t **error ) { static char *function = "libesedb_io_handle_initialize"; if( io_handle == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid IO handle.", function ); return( -1 ); } if( *io_handle != NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET, "%s: invalid IO handle value already set.", function ); return( -1 ); } *io_handle = memory_allocate_structure( libesedb_io_handle_t ); if( *io_handle == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_MEMORY, LIBCERROR_MEMORY_ERROR_INSUFFICIENT, "%s: unable to create IO handle.", function ); goto on_error; } if( memory_set( *io_handle, 0, sizeof( libesedb_io_handle_t ) ) == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_MEMORY, LIBCERROR_MEMORY_ERROR_SET_FAILED, "%s: unable to clear IO handle.", function ); goto on_error; } ( *io_handle )->ascii_codepage = LIBESEDB_CODEPAGE_WINDOWS_1252; return( 1 ); on_error: if( *io_handle != NULL ) { memory_free( *io_handle ); *io_handle = NULL; } return( -1 ); } /* Frees an IO handle * Returns 1 if successful or -1 on error */ int libesedb_io_handle_free( libesedb_io_handle_t **io_handle, libcerror_error_t **error ) { static char *function = "libesedb_io_handle_free"; int result = 1; if( io_handle == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid IO handle.", function ); return( -1 ); } if( *io_handle != NULL ) { memory_free( *io_handle ); *io_handle = NULL; } return( result ); } /* Clears the IO handle * Returns 1 if successful or -1 on error */ int libesedb_io_handle_clear( libesedb_io_handle_t *io_handle, libcerror_error_t **error ) { static char *function = "libesedb_io_handle_clear"; if( io_handle == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid IO handle.", function ); return( -1 ); } if( memory_set( io_handle, 0, sizeof( libesedb_io_handle_t ) ) == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_MEMORY, LIBCERROR_MEMORY_ERROR_SET_FAILED, "%s: unable to clear IO handle.", function ); return( -1 ); } io_handle->ascii_codepage = LIBESEDB_CODEPAGE_WINDOWS_1252; return( 1 ); } /* Sets the pages data range * Returns 1 if successful or -1 on error */ int libesedb_io_handle_set_pages_data_range( libesedb_io_handle_t *io_handle, size64_t file_size, libcerror_error_t **error ) { static char *function = "libesedb_io_handle_set_pages_data_range"; if( io_handle == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid IO handle.", function ); return( -1 ); } if( io_handle->page_size == 0 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_VALUE_MISSING, "%s: invalid IO handle - missing page size.", function ); return( -1 ); } io_handle->file_size = file_size; io_handle->pages_data_offset = (off64_t) ( io_handle->page_size * 2 ); io_handle->pages_data_size = file_size - (size64_t) io_handle->pages_data_offset; io_handle->last_page_number = (uint32_t) ( io_handle->pages_data_size / io_handle->page_size ); return( 1 ); } /* Reads a page * Callback function for the page vector * Returns 1 if successful or -1 on error */ int libesedb_io_handle_read_page( libesedb_io_handle_t *io_handle, libbfio_handle_t *file_io_handle, libfdata_vector_t *vector, libfdata_cache_t *cache, int element_index, int element_file_index LIBESEDB_ATTRIBUTE_UNUSED, off64_t element_offset, size64_t element_size LIBESEDB_ATTRIBUTE_UNUSED, uint32_t element_flags LIBESEDB_ATTRIBUTE_UNUSED, uint8_t read_flags LIBESEDB_ATTRIBUTE_UNUSED, libcerror_error_t **error ) { libesedb_page_t *page = NULL; static char *function = "libesedb_io_handle_read_page"; LIBESEDB_UNREFERENCED_PARAMETER( element_file_index ); LIBESEDB_UNREFERENCED_PARAMETER( element_size ); LIBESEDB_UNREFERENCED_PARAMETER( element_flags ); LIBESEDB_UNREFERENCED_PARAMETER( read_flags ); if( libesedb_page_initialize( &page, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, "%s: unable to create page.", function ); goto on_error; } if( libesedb_page_read_file_io_handle( page, io_handle, file_io_handle, element_offset, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_IO, LIBCERROR_IO_ERROR_READ_FAILED, "%s: unable to read page.", function ); goto on_error; } if( libfdata_vector_set_element_value_by_index( vector, (intptr_t *) file_io_handle, cache, element_index, (intptr_t *) page, (int (*)(intptr_t **, libcerror_error_t **)) &libesedb_page_free, LIBFDATA_VECTOR_ELEMENT_VALUE_FLAG_MANAGED, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_SET_FAILED, "%s: unable to set page as element value.", function ); goto on_error; } return( 1 ); on_error: if( page != NULL ) { libesedb_page_free( &page, NULL ); } return( -1 ); }