/* Exports the item * Returns 1 if successful or -1 on error */ int export_handle_export_item( export_handle_t *export_handle, libolecf_item_t *item, int item_index, int number_of_items, const system_character_t *export_path, size_t export_path_length, log_handle_t *log_handle, libcerror_error_t **error ) { libcfile_file_t *stream_data_file = NULL; system_character_t *item_name = NULL; system_character_t *item_path = NULL; system_character_t *sanitized_name = NULL; system_character_t *target_path = NULL; uint8_t *buffer = NULL; static char *function = "export_handle_export_item"; size_t buffer_size = EXPORT_HANDLE_BUFFER_SIZE; size_t item_name_size = 0; size_t item_path_size = 0; size_t minimum_item_name_size = 0; size_t read_size = 0; size_t sanitized_name_size = 0; size_t target_path_size = 0; ssize_t read_count = 0; ssize_t write_count = 0; uint32_t stream_data_size = 0; int print_count = 0; int result = 0; if( export_handle == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid export handle.", function ); return( -1 ); } if( item == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid item.", function ); return( -1 ); } if( export_path == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid export path.", function ); return( -1 ); } log_handle_printf( log_handle, "Processing item: %05d in path: %" PRIs_SYSTEM "%c\n", item_index, export_path, LIBCPATH_SEPARATOR ); /* Create the storage or stream directory */ #if defined( HAVE_WIDE_SYSTEM_CHARACTER ) result = libolecf_item_get_utf16_name_size( item, &item_name_size, error ); #else result = libolecf_item_get_utf8_name_size( item, &item_name_size, error ); #endif if( result != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve item name size.", function ); goto on_error; } minimum_item_name_size = item_name_size; if( minimum_item_name_size < 10 ) { minimum_item_name_size = 10; } item_name = system_string_allocate( minimum_item_name_size ); if( item_name == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_MEMORY, LIBCERROR_MEMORY_ERROR_INSUFFICIENT, "%s: unable to create the item name.", function ); goto on_error; } #if defined( HAVE_WIDE_SYSTEM_CHARACTER ) result = libolecf_item_get_utf16_name( item, (uint16_t *) item_name, item_name_size, error ); #else result = libolecf_item_get_utf8_name( item, (uint8_t *) item_name, item_name_size, error ); #endif if( result != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve item name.", function ); goto on_error; } #if defined( HAVE_WIDE_SYSTEM_CHARACTER ) if( libcpath_path_get_sanitized_filename_wide( item_name, item_name_size - 1, &sanitized_name, &sanitized_name_size, error ) != 1 ) #else if( libcpath_path_get_sanitized_filename( item_name, item_name_size - 1, &sanitized_name, &sanitized_name_size, error ) != 1 ) #endif { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_SET_FAILED, "%s: unable to sanitize item name.", function ); goto on_error; } memory_free( item_name ); item_name = sanitized_name; item_name_size = sanitized_name_size; sanitized_name = NULL; sanitized_name_size = 0; #if defined( HAVE_WIDE_SYSTEM_CHARACTER ) result = libcpath_path_join_wide( &item_path, &item_path_size, export_path, export_path_length, item_name, item_name_size - 1, error ); #else result = libcpath_path_join( &item_path, &item_path_size, export_path, export_path_length, item_name, item_name_size - 1, error ); #endif if( result != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, "%s: unable to create item path.", function ); goto on_error; } if( item_path == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid item path.", function ); goto on_error; } #if defined( HAVE_WIDE_SYSTEM_CHARACTER ) result = libcfile_file_exists_wide( item_path, error ); #else result = libcfile_file_exists( item_path, error ); #endif if( result == -1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_IO, LIBCERROR_IO_ERROR_GENERIC, "%s: unable to determine if %" PRIs_SYSTEM " exists.", function, item_path ); goto on_error; } else if( result == 1 ) { memory_free( item_path ); item_path = NULL; print_count = system_string_sprintf( item_name, 10, _SYSTEM_STRING( "Item%05d" ), item_index + 1 ); if( ( print_count < 0 ) || ( print_count > 12 ) ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_SET_FAILED, "%s: unable to set item name.", function ); goto on_error; } item_name[ 9 ] = 0; item_name_size = 10; log_handle_printf( log_handle, "Item already exists defaulting to: %" PRIs_SYSTEM "\n", item_name ); #if defined( HAVE_WIDE_SYSTEM_CHARACTER ) result = libcpath_path_join_wide( &item_path, &item_path_size, export_path, export_path_length, item_name, item_name_size - 1, error ); #else result = libcpath_path_join( &item_path, &item_path_size, export_path, export_path_length, item_name, item_name_size - 1, error ); #endif if( result != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, "%s: unable to create item path.", function ); goto on_error; } if( item_path == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid item path.", function ); goto on_error; } } memory_free( item_name ); item_name = NULL; #if defined( HAVE_WIDE_SYSTEM_CHARACTER ) result = libcpath_path_make_directory_wide( item_path, error ); #else result = libcpath_path_make_directory( item_path, error ); #endif if( result != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_IO, LIBCERROR_IO_ERROR_WRITE_FAILED, "%s: unable to make directory: %" PRIs_SYSTEM ".", function, item_path ); goto on_error; } log_handle_printf( log_handle, "Created directory: %" PRIs_SYSTEM ".\n", item_path ); /* Create the item file */ #if defined( HAVE_WIDE_SYSTEM_CHARACTER ) result = libcpath_path_join_wide( &target_path, &target_path_size, item_path, item_path_size - 1, L"StreamData.bin", 14, error ); #else result = libcpath_path_join( &target_path, &target_path_size, item_path, item_path_size - 1, "StreamData.bin", 14, error ); #endif if( result != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, "%s: unable to create target path.", function ); goto on_error; } if( target_path == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid target path.", function ); goto on_error; } #if defined( HAVE_WIDE_SYSTEM_CHARACTER ) result = libcfile_file_exists_wide( target_path, error ); #else result = libcfile_file_exists( target_path, error ); #endif if( result == -1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_IO, LIBCERROR_IO_ERROR_GENERIC, "%s: unable to determine if %" PRIs_SYSTEM " exists.", function, target_path ); goto on_error; } else if( result != 0 ) { log_handle_printf( log_handle, "Skipping item: %" PRIs_SYSTEM " it already exists.\n", target_path ); memory_free( target_path ); memory_free( item_path ); return( 1 ); } if( libolecf_item_get_size( item, &stream_data_size, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve item stream data size.", function ); goto on_error; } if( libcfile_file_initialize( &stream_data_file, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, "%s: unable to create stream data file.", function ); goto on_error; } #if defined( HAVE_WIDE_SYSTEM_CHARACTER ) result = libcfile_file_open_wide( stream_data_file, target_path, LIBCFILE_OPEN_WRITE, error ); #else result = libcfile_file_open( stream_data_file, target_path, LIBCFILE_OPEN_WRITE, error ); #endif if( result != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_IO, LIBCERROR_IO_ERROR_OPEN_FAILED, "%s: unable to open: %" PRIs_SYSTEM ".", function, target_path ); goto on_error; } memory_free( target_path ); target_path = NULL; if( stream_data_size > 0 ) { buffer = (uint8_t *) memory_allocate( sizeof( uint8_t ) * buffer_size ); if( buffer == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_MEMORY, LIBCERROR_MEMORY_ERROR_INSUFFICIENT, "%s: unable to create the buffer.", function ); goto on_error; } while( stream_data_size > 0 ) { read_size = buffer_size; if( read_size > stream_data_size ) { read_size = stream_data_size; } read_count = libolecf_stream_read_buffer( item, buffer, read_size, error ); if( read_count != (ssize_t) read_size ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_IO, LIBCERROR_IO_ERROR_READ_FAILED, "%s: unable to read stream data from item.", function ); goto on_error; } stream_data_size -= read_size; write_count = libcfile_file_write_buffer( stream_data_file, buffer, read_size, error ); if( write_count != (ssize_t) read_size ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_IO, LIBCERROR_IO_ERROR_WRITE_FAILED, "%s: unable to write stream data to file.", function ); goto on_error; } } memory_free( buffer ); buffer = NULL; } if( libcfile_file_close( stream_data_file, error ) != 0 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_IO, LIBCERROR_IO_ERROR_CLOSE_FAILED, "%s: unable to stream data file.", function ); goto on_error; } if( libcfile_file_free( &stream_data_file, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED, "%s: unable to free stream data file.", function ); goto on_error; } /* Export the sub items */ if( export_handle_export_sub_items( export_handle, item, item_path, item_path_size - 1, log_handle, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_OUTPUT, LIBCERROR_OUTPUT_ERROR_GENERIC, "%s: unable to export sub items.", function ); goto on_error; } memory_free( item_path ); item_path = NULL; return( 1 ); on_error: if( buffer != NULL ) { memory_free( buffer ); } if( stream_data_file != NULL ) { libcfile_file_free( &stream_data_file, NULL ); } if( target_path != NULL ) { memory_free( target_path ); } if( item_path != NULL ) { memory_free( item_path ); } if( sanitized_name != NULL ) { memory_free( sanitized_name ); } if( item_name != NULL ) { memory_free( item_name ); } return( -1 ); }
/* Prints an item to a stream * Returns 1 if successful or -1 on error */ int info_handle_item_fprint( info_handle_t *info_handle, libolecf_item_t *item, int indentation_level, libcerror_error_t **error ) { libcstring_system_character_t *name = NULL; libolecf_item_t *sub_item = NULL; static char *function = "info_handle_item_fprint"; size_t name_index = 0; size_t name_size = 0; uint32_t size = 0; int number_of_sub_items = 0; int indentation_iterator = 0; int result = 0; int sub_item_index = 0; if( info_handle == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid info handle.", function ); return( -1 ); } if( item == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid item.", function ); return( -1 ); } #if defined( LIBCSTRING_HAVE_WIDE_SYSTEM_CHARACTER ) result = libolecf_item_get_utf16_name_size( item, &name_size, error ); #else result = libolecf_item_get_utf8_name_size( item, &name_size, error ); #endif if( result != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve item name size.", function ); goto on_error; } name = libcstring_system_string_allocate( name_size ); if( name == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_MEMORY, LIBCERROR_MEMORY_ERROR_INSUFFICIENT, "%s: unable to create name.", function ); goto on_error; } #if defined( LIBCSTRING_HAVE_WIDE_SYSTEM_CHARACTER ) result = libolecf_item_get_utf16_name( item, (uint16_t *) name, name_size, error ); #else result = libolecf_item_get_utf8_name( item, (uint8_t *) name, name_size, error ); #endif if( result != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve item name.", function ); goto on_error; } if( libolecf_item_get_size( item, &size, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve item size.", function ); goto on_error; } for( indentation_iterator = 0; indentation_iterator < indentation_level; indentation_iterator++ ) { fprintf( info_handle->notify_stream, " " ); } for( name_index = 0; name_index < ( name_size - 1 ); name_index++ ) { /* Print control characters as hexadecimal values */ if( ( name[ name_index ] < 0x20 ) || ( name[ name_index ] == 0x7f ) ) { fprintf( info_handle->notify_stream, "\\x%02" PRIx8 "", (uint8_t) name[ name_index ] ); } else { fprintf( info_handle->notify_stream, "%" PRIc_LIBCSTRING_SYSTEM "", name[ name_index ] ); } } fprintf( info_handle->notify_stream, " (%" PRIu32 " bytes)\n", size ); memory_free( name ); name = NULL; if( libolecf_item_get_number_of_sub_items( item, &number_of_sub_items, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve number of sub items.", function ); goto on_error; } for( sub_item_index = 0; sub_item_index < number_of_sub_items; sub_item_index++ ) { if( libolecf_item_get_sub_item( item, sub_item_index, &sub_item, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve sub item: %d.", function, sub_item_index ); goto on_error; } if( info_handle_item_fprint( info_handle, sub_item, indentation_level + 1, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_PRINT_FAILED, "%s: unable to print sub item: %d.", function, sub_item_index ); libolecf_item_free( &sub_item, NULL ); goto on_error; } if( libolecf_item_free( &sub_item, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED, "%s: unable to free sub item: %d.", function, sub_item_index ); goto on_error; } } return( 1 ); on_error: if( name != NULL ) { memory_free( name ); } return( -1 ); }