string_t stream_read_line(stream_t* stream, char delimiter) { char buffer[128]; char* outbuffer = 0; size_t outsize = 0; size_t cursize = 0; size_t read, i; size_t want_read = 128; if (!(stream->mode & STREAM_IN)) return (string_t) { 0, 0 }; //Need to read one byte at a time since we can't scan back if overreading if (stream_is_sequential(stream)) want_read = 1; while (!stream_eos(stream)) { read = stream->vtable->read(stream, buffer, want_read); if (!read) break; for (i = 0; i < read; ++i) { if (buffer[i] == delimiter) break; } if (cursize + i > outsize) { size_t nextsize; if (!outbuffer) { nextsize = (i >= 32 ? i + 1 : (i > 1 ? i + 1 : 32)); outbuffer = memory_allocate(0, nextsize, 0, MEMORY_PERSISTENT); } else { nextsize = (outsize < 511 ? 512 : outsize + 513); //Always aligns to 512 multiples FOUNDATION_ASSERT(!(nextsize % 512)); outbuffer = memory_reallocate(outbuffer, nextsize, 0, outsize + 1); } outsize = nextsize - 1; } if (i) { memcpy(outbuffer + cursize, buffer, i); //lint !e613 cursize += i; } if (i < read) { if ((i + 1) < read) { //Sequential should never end up here reading one byte at a time FOUNDATION_ASSERT(!stream_is_sequential(stream)); stream_seek(stream, (ssize_t)(1 + i) - (ssize_t)read, STREAM_SEEK_CURRENT); } break; } } if (outbuffer) outbuffer[cursize] = 0; return (string_t) { outbuffer, cursize }; }
/* Resizes a buffer * Returns 1 if successful or -1 on error */ int storage_media_buffer_resize( storage_media_buffer_t *buffer, size_t size, libcerror_error_t **error ) { void *reallocation = NULL; static char *function = "storage_media_buffer_resize"; if( buffer == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid buffer.", function ); return( -1 ); } if( size > buffer->raw_buffer_size ) { reallocation = memory_reallocate( buffer->raw_buffer, sizeof( uint8_t ) * size ); if( reallocation == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_MEMORY, LIBCERROR_MEMORY_ERROR_INSUFFICIENT, "%s: unable to reallocate read buffer.", function ); return( -1 ); } buffer->raw_buffer = (uint8_t *) reallocation; buffer->raw_buffer_size = size; buffer->raw_buffer_data_size = 0; /* The compression buffer is cleared */ if( buffer->compression_buffer != NULL ) { memory_free( buffer->compression_buffer ); buffer->compression_buffer = NULL; buffer->compression_buffer_size = 0; buffer->compression_buffer_data_size = 0; } } return( 1 ); }
char* stream_read_line( stream_t* stream, char delimiter ) { char buffer[128]; char* outbuffer; int outsize = 32; int cursize = 0; int read, i; int want_read = 128; FOUNDATION_ASSERT( stream ); if( !( stream->mode & STREAM_IN ) ) return 0; FOUNDATION_ASSERT( stream->vtable->read ); if( stream_is_sequential( stream ) ) //Need to read one byte at a time since we can't scan back if overreading want_read = 1; outbuffer = memory_allocate( outsize + 1, 0, MEMORY_PERSISTENT ); while( !stream_eos( stream ) ) { read = (int)stream->vtable->read( stream, buffer, want_read ); if( !read ) break; for( i = 0; i < read; ++i ) { if( buffer[i] == delimiter ) break; } if( cursize + i > outsize ) { outsize += 512; outbuffer = memory_reallocate( outbuffer, outsize + 1, 0, cursize ); } memcpy( outbuffer + cursize, buffer, i ); cursize += i; if( i < read ) { if( ( i + 1 ) < read ) { FOUNDATION_ASSERT( !stream_is_sequential( stream ) ); //Sequential should never end up here reading one byte at a time stream_seek( stream, 1 + i - read, STREAM_SEEK_CURRENT ); } break; } } outbuffer[cursize] = 0; return outbuffer; }
static FOUNDATION_NOINLINE void* lua_allocator(void* env, void* block, size_t osize, size_t nsize) { if (!nsize && osize) { memory_deallocate(block); } else if (nsize) { if (!block) block = memory_allocate(HASH_LUA, nsize, 0, MEMORY_PERSISTENT | MEMORY_32BIT_ADDRESS); else block = memory_reallocate(block, nsize, 0, osize); if (block == 0 && env && ((lua_t*)env)->state) log_panicf(HASH_LUA, ERROR_OUT_OF_MEMORY, STRING_CONST("Unable to allocate Lua memory (%u bytes)"), nsize); } return block; }
int hashify_generate_preamble(stream_t* output_file, string_t output_filename) { //Read and preserve everything before #pragma once in case it contains header comments to be preserved char line_buffer[HASHIFY_LINEBUFFER_LENGTH]; size_t capacity = 1024; string_t preamble = string_allocate(0, capacity); stream_t* prev_file = stream_open(STRING_ARGS(output_filename), STREAM_IN); memset(line_buffer, 0, sizeof(line_buffer)); while (prev_file && !stream_eos(prev_file)) { string_t line; string_const_t stripped_line; line = stream_read_line_buffer(prev_file, line_buffer, sizeof(line_buffer), '\n'); stripped_line = string_strip(STRING_ARGS(line), STRING_CONST("\n\r")); if ((string_find_string(STRING_ARGS(stripped_line), STRING_CONST("pragma"), 0) != STRING_NPOS) && (string_find_string(STRING_ARGS(stripped_line), STRING_CONST("once"), 0) != STRING_NPOS)) break; if (preamble.length + stripped_line.length + 1 >= capacity) { size_t newcapacity = capacity + 1024 + stripped_line.length; preamble.str = memory_reallocate(preamble.str, newcapacity, 0, capacity); capacity = newcapacity; } preamble = string_append(STRING_ARGS(preamble), capacity, STRING_ARGS(stripped_line)); if (line.length < sizeof(line_buffer)) preamble = string_append(STRING_ARGS(preamble), capacity, STRING_CONST(STRING_NEWLINE)); } stream_deallocate(prev_file); stream_seek(output_file, 0, STREAM_SEEK_BEGIN); if (preamble.length) stream_write_string(output_file, STRING_ARGS(preamble)); stream_write_string(output_file, STRING_CONST( "#pragma once\n\n" "#include <foundation/hash.h>\n\n" "/* ****** AUTOMATICALLY GENERATED, DO NOT EDIT ******\n" " Edit corresponding definitions file and rerun\n" " the foundation hashify tool to update this file */\n\n" )); string_deallocate(preamble.str); return 0; }
static FOUNDATION_NOINLINE int lua_import_dump_writer(lua_State* state, const void* buffer, size_t size, void* user_data) { luaimport_dump_t* dump = user_data; FOUNDATION_UNUSED(state); if (size <= 0) return 0; dump->bytecode = (dump->bytecode ? memory_reallocate(dump->bytecode, dump->bytecode_size + size, 0, dump->bytecode_size) : memory_allocate(HASH_LUA, size, 0, MEMORY_PERSISTENT)); memcpy(dump->bytecode + dump->bytecode_size, buffer, size); dump->bytecode_size += size; return 0; }
static void _buffer_stream_truncate(stream_t* stream, size_t size) { stream_buffer_t* buffer_stream = (stream_buffer_t*)stream; if (buffer_stream->capacity >= size) { buffer_stream->size = size; } else if (buffer_stream->grow) { buffer_stream->capacity = size; buffer_stream->buffer = memory_reallocate(buffer_stream->buffer, buffer_stream->capacity, 0, buffer_stream->current); buffer_stream->size = buffer_stream->capacity; } else { buffer_stream->size = buffer_stream->capacity; } if (buffer_stream->current > buffer_stream->size) buffer_stream->current = buffer_stream->size; buffer_stream->lastmod = time_current(); }
void _array_growfn( void* arr, int increment, int factor, int itemsize ) { void** parr = (void**)arr; int capacity = *parr ? ( factor * _array_rawcapacity(*parr) + increment ) : increment; int storage_size = itemsize * capacity; uint64_t header_size = 4ULL * _array_header_size; uint64_t buffer_size = (unsigned int)storage_size + header_size; int* buffer = *parr ? memory_reallocate( _array_raw( *parr ), buffer_size, 0 ) : memory_allocate( buffer_size, 16, MEMORY_PERSISTENT ); FOUNDATION_ASSERT_MSG( buffer, "Failed to reallocate array storage" ); if( buffer ) { buffer[0] = capacity; if( !*parr ) { buffer[1] = 0; buffer[2] = _array_watermark; } *parr = buffer + _array_header_size; } }
static size_t _buffer_stream_write(stream_t* stream, const void* source, size_t num) { size_t available, want, num_write; stream_buffer_t* buffer_stream = (stream_buffer_t*)stream; FOUNDATION_ASSERT(buffer_stream->size >= buffer_stream->current); available = buffer_stream->size - buffer_stream->current; want = num; if (want > available) { if (buffer_stream->capacity >= (buffer_stream->current + want)) { available = want; buffer_stream->size = buffer_stream->current + want; } else if (buffer_stream->grow) { size_t prev_capacity = buffer_stream->capacity; available = want; buffer_stream->size = buffer_stream->current + want; buffer_stream->capacity = (buffer_stream->size < 1024) ? 1024 : buffer_stream->size + 1024; //tail segment from current to size will be overwritten buffer_stream->buffer = memory_reallocate(buffer_stream->buffer, buffer_stream->capacity, 0, prev_capacity); } else { available = buffer_stream->capacity - buffer_stream->current; buffer_stream->size = buffer_stream->capacity; } } buffer_stream->lastmod = time_current(); num_write = (want < available) ? want : available; if (num_write > 0) { memcpy(pointer_offset(buffer_stream->buffer, buffer_stream->current), source, num_write); buffer_stream->current += num_write; return num_write; } return 0; }
static uint64_t _buffer_stream_write( stream_t* stream, const void* source, uint64_t num ) { stream_buffer_t* buffer_stream = (stream_buffer_t*)stream; uint64_t available = buffer_stream->size - buffer_stream->current; uint64_t want = num; uint64_t num_write; if( want > available ) { if( buffer_stream->capacity >= ( buffer_stream->current + want ) ) { available = want; buffer_stream->size = buffer_stream->current + want; } else if( buffer_stream->grow ) { available = want; buffer_stream->size = buffer_stream->current + want; buffer_stream->capacity = ( buffer_stream->size < 1024 ) ? 1024 : buffer_stream->size + 1024; buffer_stream->buffer = memory_reallocate( buffer_stream->buffer, buffer_stream->capacity, 0, buffer_stream->current ); //tail segment from current to size will be overwritten } else { available = buffer_stream->capacity - buffer_stream->current; buffer_stream->size = buffer_stream->capacity; } } num_write = ( want < available ) ? want : available; if( num_write > 0 ) { memcpy( pointer_offset( buffer_stream->buffer, buffer_stream->current ), source, (size_t)num_write ); buffer_stream->current += num_write; return num_write; } return 0; }
/* Resizes an allocation_table * Returns 1 if successful or -1 on error */ int libolecf_allocation_table_resize( libolecf_allocation_table_t *allocation_table, int number_of_sector_identifiers, libcerror_error_t **error ) { void *reallocation = NULL; static char *function = "libolecf_allocation_table_resize"; size_t sector_identifiers_size = 0; if( allocation_table == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid allocation_table.", function ); return( -1 ); } if( number_of_sector_identifiers < 0 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_VALUE_LESS_THAN_ZERO, "%s: invalid number of sector identifiers value less than zero.", function ); return( -1 ); } if( allocation_table->number_of_sector_identifiers < number_of_sector_identifiers ) { sector_identifiers_size = sizeof( uint32_t ) * number_of_sector_identifiers; if( sector_identifiers_size > (size_t) SSIZE_MAX ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_VALUE_EXCEEDS_MAXIMUM, "%s: invalid sector identifiers size value exceeds maximum.", function ); return( -1 ); } reallocation = memory_reallocate( allocation_table->sector_identifier, sector_identifiers_size ); if( reallocation == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_MEMORY, LIBCERROR_MEMORY_ERROR_INSUFFICIENT, "%s: unable to resize sector identifiers.", function ); return( -1 ); } allocation_table->sector_identifier = (uint32_t *) reallocation; allocation_table->number_of_sector_identifiers = number_of_sector_identifiers; if( memory_set( allocation_table->sector_identifier, 0, sizeof( uint32_t ) * ( number_of_sector_identifiers - allocation_table->number_of_sector_identifiers ) ) == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_MEMORY, LIBCERROR_MEMORY_ERROR_SET_FAILED, "%s: unable to clear sector identifiers.", function ); return( -1 ); } } return( 1 ); }
/* Globs the segment files according to the EWF naming schema * if format is known the filename should contain the base of the filename * otherwise the function will try to determine the format based on the extension * Returns 1 if successful or -1 on error */ int libewf_glob_wide( const wchar_t *filename, size_t filename_length, uint8_t format, wchar_t **filenames[], int *number_of_filenames, libcerror_error_t **error ) { libbfio_handle_t *file_io_handle = NULL; wchar_t *segment_filename = NULL; void *reallocation = NULL; static char *function = "libewf_glob_wide"; size_t additional_length = 4; size_t segment_filename_length = 0; int result = 0; uint8_t segment_file_type = 0; uint8_t ewf_format = 0; if( filename == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid filename.", function ); return( -1 ); } if( ( filename_length == 0 ) || ( filename_length > (size_t) SSIZE_MAX ) ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS, "%s: invalid filename length.", function ); return( -1 ); } if( ( format != LIBEWF_FORMAT_UNKNOWN ) && ( format != LIBEWF_FORMAT_ENCASE1 ) && ( format != LIBEWF_FORMAT_ENCASE2 ) && ( format != LIBEWF_FORMAT_ENCASE3 ) && ( format != LIBEWF_FORMAT_ENCASE4 ) && ( format != LIBEWF_FORMAT_ENCASE5 ) && ( format != LIBEWF_FORMAT_ENCASE6 ) && ( format != LIBEWF_FORMAT_LINEN5 ) && ( format != LIBEWF_FORMAT_LINEN6 ) && ( format != LIBEWF_FORMAT_SMART ) && ( format != LIBEWF_FORMAT_FTK ) && ( format != LIBEWF_FORMAT_LVF ) && ( format != LIBEWF_FORMAT_EWF ) && ( format != LIBEWF_FORMAT_EWFX ) ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE, "%s: unsupported format.", function ); return( -1 ); } if( filenames == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid filenames.", function ); return( -1 ); } if( number_of_filenames == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid number of filenames.", function ); return( -1 ); } if( format == LIBEWF_FORMAT_UNKNOWN ) { if( filename[ filename_length - 4 ] != (wchar_t) '.' ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE, "%s: invalid filename - missing extension.", function ); return( -1 ); } additional_length = 0; if( filename[ filename_length - 3 ] == (wchar_t) 'E' ) { format = LIBEWF_FORMAT_ENCASE5; } else if( filename[ filename_length - 3 ] == (wchar_t) 'e' ) { format = LIBEWF_FORMAT_EWF; } else if( filename[ filename_length - 3 ] == (wchar_t) 'L' ) { format = LIBEWF_FORMAT_LVF; } else if( filename[ filename_length - 3 ] == (wchar_t) 's' ) { format = LIBEWF_FORMAT_SMART; } else { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE, "%s: invalid filename - unsupported extension: %s.", function, &( filename[ filename_length - 4 ] ) ); return( -1 ); } } if( format == LIBEWF_FORMAT_LVF ) { segment_file_type = LIBEWF_SEGMENT_FILE_TYPE_LWF; ewf_format = EWF_FORMAT_L01; } else if( format == LIBEWF_FORMAT_SMART ) { segment_file_type = LIBEWF_SEGMENT_FILE_TYPE_EWF; ewf_format = EWF_FORMAT_S01; } else { segment_file_type = LIBEWF_SEGMENT_FILE_TYPE_EWF; ewf_format = EWF_FORMAT_E01; } if( libbfio_file_initialize( &file_io_handle, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, "%s: unable to create file IO handle.", function ); goto on_error; } *number_of_filenames = 0; while( *number_of_filenames < (int) UINT16_MAX ) { segment_filename_length = filename_length + additional_length; segment_filename = (wchar_t *) memory_allocate( sizeof( wchar_t ) * ( segment_filename_length + 1 ) ); if( segment_filename == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_MEMORY, LIBCERROR_MEMORY_ERROR_INSUFFICIENT, "%s: unable to create segment filename.", function ); goto on_error; } if( libcstring_wide_string_copy( segment_filename, filename, filename_length ) == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_MEMORY, LIBCERROR_MEMORY_ERROR_COPY_FAILED, "%s: unable to copy filename.", function ); goto on_error; } if( additional_length > 0 ) { segment_filename[ filename_length ] = (wchar_t) '.'; } if( libewf_filename_set_extension_wide( &( segment_filename[ segment_filename_length - 3 ] ), (uint16_t) ( *number_of_filenames + 1 ), UINT16_MAX, segment_file_type, format, ewf_format, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_SET_FAILED, "%s: unable to set extension.", function ); goto on_error; } segment_filename[ segment_filename_length ] = 0; if( libbfio_file_set_name_wide( file_io_handle, segment_filename, segment_filename_length, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_SET_FAILED, "%s: unable to set name in file IO handle.", function ); goto on_error; } result = libbfio_handle_exists( file_io_handle, error ); if( result == -1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_IO, LIBCERROR_IO_ERROR_GENERIC, "%s: unable to test if file exists.", function ); goto on_error; } else if( result == 0 ) { memory_free( segment_filename ); break; } *number_of_filenames += 1; reallocation = memory_reallocate( *filenames, sizeof( wchar_t * ) * *number_of_filenames ); if( reallocation == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_MEMORY, LIBCERROR_MEMORY_ERROR_INSUFFICIENT, "%s: unable to resize filenames.", function ); goto on_error; } *filenames = (wchar_t **) reallocation; ( *filenames )[ *number_of_filenames - 1 ] = segment_filename; } if( libbfio_handle_free( &file_io_handle, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED, "%s: unable to free file IO handle.", function ); goto on_error; } return( 1 ); on_error: if( segment_filename != NULL ) { memory_free( segment_filename ); } if( file_io_handle != NULL ) { libbfio_handle_free( &file_io_handle, NULL ); } return( -1 ); }
/* Resizes the glob * Returns 1 if successful or -1 on error */ int libsystem_glob_resize( libsystem_glob_t *glob, int new_number_of_results, liberror_error_t **error ) { void *reallocation = NULL; static char *function = "libsystem_glob_resize"; size_t previous_size = 0; size_t new_size = 0; if( glob == NULL ) { liberror_error_set( error, LIBERROR_ERROR_DOMAIN_ARGUMENTS, LIBERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid glob.", function ); return( -1 ); } if( glob->number_of_results >= new_number_of_results ) { liberror_error_set( error, LIBERROR_ERROR_DOMAIN_RUNTIME, LIBERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS, "%s: new number of results less equal than current.", function ); return( -1 ); } previous_size = sizeof( libcstring_system_character_t * ) * glob->number_of_results; new_size = sizeof( libcstring_system_character_t * ) * new_number_of_results; if( ( previous_size > (size_t) SSIZE_MAX ) || ( new_size > (size_t) SSIZE_MAX ) ) { liberror_error_set( error, LIBERROR_ERROR_DOMAIN_RUNTIME, LIBERROR_RUNTIME_ERROR_VALUE_EXCEEDS_MAXIMUM, "%s: invalid size value exceeds maximum.", function ); return( -1 ); } reallocation = memory_reallocate( glob->result, new_size ); if( reallocation == NULL ) { liberror_error_set( error, LIBERROR_ERROR_DOMAIN_MEMORY, LIBERROR_MEMORY_ERROR_INSUFFICIENT, "%s: unable to reallocate glob results.", function ); return( -1 ); } glob->result = (libcstring_system_character_t **) reallocation; if( memory_set( &( glob->result[ glob->number_of_results ] ), 0, new_size - previous_size ) == NULL ) { liberror_error_set( error, LIBERROR_ERROR_DOMAIN_MEMORY, LIBERROR_MEMORY_ERROR_SET_FAILED, "%s: unable to clear glob.", function ); return( -1 ); } glob->number_of_results = new_number_of_results; return( 1 ); }
/* Resizes the chunk cache * Returns 1 if successful or -1 on error */ int libewf_chunk_cache_resize( libewf_chunk_cache_t *chunk_cache, size_t size, liberror_error_t **error ) { static char *function = "libewf_chunk_cache_resize"; void *reallocation = NULL; if( chunk_cache == NULL ) { liberror_error_set( error, LIBERROR_ERROR_DOMAIN_ARGUMENTS, LIBERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid chunk cache.", function ); return( -1 ); } if( size > (size_t) SSIZE_MAX ) { liberror_error_set( error, LIBERROR_ERROR_DOMAIN_ARGUMENTS, LIBERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM, "%s: invalid size value exceeds maximum.", function ); return( -1 ); } if( size > chunk_cache->allocated_size ) { reallocation = memory_reallocate( chunk_cache->compressed, sizeof( uint8_t ) * size ); if( reallocation == NULL ) { liberror_error_set( error, LIBERROR_ERROR_DOMAIN_MEMORY, LIBERROR_MEMORY_ERROR_INSUFFICIENT, "%s: unable to resize chunk cache compressed.", function ); return( -1 ); } chunk_cache->compressed = (uint8_t *) reallocation; reallocation = memory_reallocate( chunk_cache->data, sizeof( uint8_t ) * size ); if( reallocation == NULL ) { liberror_error_set( error, LIBERROR_ERROR_DOMAIN_MEMORY, LIBERROR_MEMORY_ERROR_INSUFFICIENT, "%s: unable to resize chunk cache data.", function ); return( -1 ); } chunk_cache->data = (uint8_t *) reallocation; chunk_cache->allocated_size = size; chunk_cache->chunk = 0; chunk_cache->amount = 0; chunk_cache->offset = 0; chunk_cache->cached = 0; } return( 1 ); }
/* Packs the chunk data * This function either adds the checksum or compresses the chunk data * Returns 1 if successful or -1 on error */ int libewf_chunk_data_pack( libewf_chunk_data_t *chunk_data, int8_t compression_level, uint8_t compression_flags, uint8_t ewf_format, size32_t chunk_size, const uint8_t *compressed_zero_byte_empty_block, size_t compressed_zero_byte_empty_block_size, liberror_error_t **error ) { static char *function = "libewf_chunk_data_pack"; void *reallocation = NULL; uint32_t calculated_checksum = 0; int is_empty_zero_block = 0; int result = 0; if( chunk_data == NULL ) { liberror_error_set( error, LIBERROR_ERROR_DOMAIN_ARGUMENTS, LIBERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid chunk data.", function ); return( -1 ); } if( chunk_data->data == NULL ) { liberror_error_set( error, LIBERROR_ERROR_DOMAIN_RUNTIME, LIBERROR_RUNTIME_ERROR_VALUE_MISSING, "%s: invalid chunk data - missing data.", function ); return( -1 ); } if( chunk_data->is_packed != 0 ) { return( 1 ); } chunk_data->is_compressed = 0; if( ( ewf_format != EWF_FORMAT_S01 ) && ( compression_flags & LIBEWF_FLAG_COMPRESS_EMPTY_BLOCK ) != 0 ) { result = libewf_empty_block_test( chunk_data->data, chunk_data->data_size, error ); if( result == -1 ) { liberror_error_set( error, LIBERROR_ERROR_DOMAIN_RUNTIME, LIBERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to determine if chunk data is empty an empty block.", function ); return( -1 ); } else if( result == 1 ) { if( compression_level == EWF_COMPRESSION_NONE ) { compression_level = EWF_COMPRESSION_DEFAULT; } if( ( chunk_data->data )[ 0 ] == 0 ) { is_empty_zero_block = 1; } } else { compression_level = EWF_COMPRESSION_NONE; } } if( ( ewf_format == EWF_FORMAT_S01 ) || ( compression_level != EWF_COMPRESSION_NONE ) ) { chunk_data->compressed_data_size = 2 * chunk_data->data_size; chunk_data->compressed_data = (uint8_t *) memory_allocate( sizeof( uint8_t ) * chunk_data->compressed_data_size ); if( chunk_data->compressed_data == NULL ) { liberror_error_set( error, LIBERROR_ERROR_DOMAIN_MEMORY, LIBERROR_MEMORY_ERROR_INSUFFICIENT, "%s: unable to create compressed data.", function ); return( -1 ); } if( ( is_empty_zero_block != 0 ) && ( chunk_data->data_size == (size_t) chunk_size ) && ( compressed_zero_byte_empty_block != NULL ) ) { if( memory_copy( chunk_data->compressed_data, compressed_zero_byte_empty_block, compressed_zero_byte_empty_block_size ) == NULL ) { liberror_error_set( error, LIBERROR_ERROR_DOMAIN_MEMORY, LIBERROR_MEMORY_ERROR_COPY_FAILED, "%s: unable to copy compressed zero byte empty block to compressed chunk buffer.", function ); return( -1 ); } chunk_data->compressed_data_size = compressed_zero_byte_empty_block_size; } else { result = libewf_compress( chunk_data->compressed_data, &( chunk_data->compressed_data_size ), chunk_data->data, chunk_data->data_size, compression_level, error ); /* Check if the compressed buffer was too small * and a new compressed data size buffer was passed back */ if( ( result == -1 ) && ( chunk_data->compressed_data_size > 0 ) ) { liberror_error_free( error ); reallocation = memory_reallocate( chunk_data->compressed_data, sizeof( uint8_t ) * chunk_data->compressed_data_size ); if( reallocation == NULL ) { liberror_error_set( error, LIBERROR_ERROR_DOMAIN_MEMORY, LIBERROR_MEMORY_ERROR_INSUFFICIENT, "%s: unable to resize compressed data.", function ); return( -1 ); } chunk_data->compressed_data = (uint8_t *) reallocation; result = libewf_compress( chunk_data->compressed_data, &( chunk_data->compressed_data_size ), chunk_data->data, chunk_data->data_size, compression_level, error ); } if( result != 1 ) { liberror_error_set( error, LIBERROR_ERROR_DOMAIN_COMPRESSION, LIBERROR_COMPRESSION_ERROR_COMPRESS_FAILED, "%s: unable to compress chunk data.", function ); return( -1 ); } } if( ( ewf_format == EWF_FORMAT_S01 ) || ( chunk_data->compressed_data_size < chunk_data->data_size ) ) { memory_free( chunk_data->data ); chunk_data->data = chunk_data->compressed_data; chunk_data->data_size = chunk_data->compressed_data_size; chunk_data->compressed_data = NULL; chunk_data->compressed_data_size = 0; chunk_data->is_compressed = 1; } } if( chunk_data->is_compressed == 0 ) { if( ( chunk_data->data_size + sizeof( uint32_t ) ) > chunk_data->allocated_data_size ) { liberror_error_set( error, LIBERROR_ERROR_DOMAIN_RUNTIME, LIBERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS, "%s: chunk data size value out of bounds.", function ); return( -1 ); } calculated_checksum = ewf_checksum_calculate( chunk_data->data, chunk_data->data_size, 1 ); byte_stream_copy_from_uint32_little_endian( &( ( chunk_data->data )[ chunk_data->data_size ] ), calculated_checksum ); chunk_data->data_size += sizeof( uint32_t ); } chunk_data->is_packed = 1; return( 1 ); }
char* stream_read_string( stream_t* stream ) { char buffer[128]; char* outbuffer; int outsize = 128; int cursize = 0; int read, i; bool binary = stream_is_binary( stream ); FOUNDATION_ASSERT( stream ); if( !( stream->mode & STREAM_IN ) ) return 0; FOUNDATION_ASSERT( stream->vtable->read ); outbuffer = memory_allocate( outsize, 0, MEMORY_PERSISTENT ); if( stream_is_sequential( stream ) ) { //Single byte reading since we can't seek backwards (and don't want to block on network sockets) char c; if( !binary ) { //Consume whitespace while( !stream_eos( stream ) ) { read = (int)stream->vtable->read( stream, &c, 1 ); if( !read ) break; if( ( c != ' ' ) && ( c != '\n' ) && ( c != '\r' ) && ( c != '\t' ) ) { outbuffer[cursize++] = c; break; } } } while( !stream_eos( stream ) ) { read = (int)stream->vtable->read( stream, &c, 1 ); if( !read ) break; if( !c ) break; if( !binary && ( ( c == ' ' ) || ( c == '\n' ) || ( c == '\r' ) || ( c == '\t' ) ) ) break; if( cursize + 1 > outsize ) { outsize += 512; outbuffer = memory_reallocate( outbuffer, outsize, 0, cursize ); } outbuffer[cursize++] = c; } outbuffer[cursize] = 0; } else { if( !binary ) { //Consume whitespace while( !stream_eos( stream ) ) { read = (int)stream->vtable->read( stream, buffer, 16 ); if( !read ) break; for( i = 0; i < read; ++i ) { char c = buffer[i]; if( ( c != ' ' ) && ( c != '\n' ) && ( c != '\r' ) && ( c != '\t' ) ) break; } if( i < read ) { stream_seek( stream, i - read, STREAM_SEEK_CURRENT ); break; } } } while( !stream_eos( stream ) ) { read = (int)stream->vtable->read( stream, buffer, 128 ); if( !read ) break; for( i = 0; i < read; ++i ) { char c = buffer[i]; if( !c ) break; if( !binary && ( ( c == ' ' ) || ( c == '\n' ) || ( c == '\r' ) || ( c == '\t' ) ) ) break; } if( i ) { if( cursize + i > outsize ) { outsize += 512; outbuffer = memory_reallocate( outbuffer, outsize, 0, cursize ); } memcpy( outbuffer + cursize, buffer, i ); cursize += i; } if( i < 128 ) { if( ( i + 1 ) < read ) stream_seek( stream, 1 + i - read, STREAM_SEEK_CURRENT ); break; } } outbuffer[cursize] = 0; } return outbuffer; }
/* Resizes the values table * Returns 1 if successful or -1 on error */ int libewf_values_table_resize( libewf_values_table_t *values_table, int amount_of_values, liberror_error_t **error ) { static char *function = "libewf_values_table_resize"; void *reallocation = NULL; size_t values_table_size = 0; size_t values_table_string_size = 0; if( values_table == NULL ) { liberror_error_set( error, LIBERROR_ERROR_DOMAIN_ARGUMENTS, LIBERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid values table.", function ); return( -1 ); } if( amount_of_values < 0 ) { liberror_error_set( error, LIBERROR_ERROR_DOMAIN_ARGUMENTS, LIBERROR_ARGUMENT_ERROR_VALUE_LESS_THAN_ZERO, "%s: invalid amount of values less than zero.", function ); return( -1 ); } if( values_table->amount_of_values < amount_of_values ) { values_table_string_size = amount_of_values * sizeof( uint8_t * ); if( values_table_string_size > (ssize_t) SSIZE_MAX ) { liberror_error_set( error, LIBERROR_ERROR_DOMAIN_RUNTIME, LIBERROR_RUNTIME_ERROR_VALUE_EXCEEDS_MAXIMUM, "%s: invalid values table string size value exceeds maximum.", function ); return( -1 ); } values_table_size = amount_of_values * sizeof( size_t ); if( values_table_size > (ssize_t) SSIZE_MAX ) { liberror_error_set( error, LIBERROR_ERROR_DOMAIN_RUNTIME, LIBERROR_RUNTIME_ERROR_VALUE_EXCEEDS_MAXIMUM, "%s: invalid values table size value exceeds maximum.", function ); return( -1 ); } reallocation = memory_reallocate( values_table->identifier, values_table_string_size ); if( reallocation == NULL ) { liberror_error_set( error, LIBERROR_ERROR_DOMAIN_MEMORY, LIBERROR_MEMORY_ERROR_INSUFFICIENT, "%s: unable to resize identifiers.", function ); return( -1 ); } values_table->identifier = (uint8_t **) reallocation; if( memory_set( &( values_table->identifier[ values_table->amount_of_values ] ), 0, sizeof( uint8_t * ) * ( amount_of_values - values_table->amount_of_values ) ) == NULL ) { liberror_error_set( error, LIBERROR_ERROR_DOMAIN_MEMORY, LIBERROR_MEMORY_ERROR_SET_FAILED, "%s: unable to clear identifiers.", function ); return( -1 ); } reallocation = memory_reallocate( values_table->identifier_length, values_table_size ); if( reallocation == NULL ) { liberror_error_set( error, LIBERROR_ERROR_DOMAIN_MEMORY, LIBERROR_MEMORY_ERROR_INSUFFICIENT, "%s: unable to resize identifier lengths.", function ); return( -1 ); } values_table->identifier_length = (size_t *) reallocation; if( memory_set( &( values_table->identifier_length[ values_table->amount_of_values ] ), 0, sizeof( size_t ) * ( amount_of_values - values_table->amount_of_values ) ) == NULL ) { liberror_error_set( error, LIBERROR_ERROR_DOMAIN_MEMORY, LIBERROR_MEMORY_ERROR_SET_FAILED, "%s: unable to clear identifier lengths.", function ); return( -1 ); } reallocation = memory_reallocate( values_table->value, values_table_string_size ); if( reallocation == NULL ) { liberror_error_set( error, LIBERROR_ERROR_DOMAIN_MEMORY, LIBERROR_MEMORY_ERROR_INSUFFICIENT, "%s: unable to resize values.", function ); return( -1 ); } values_table->value = (uint8_t **) reallocation; if( memory_set( &( values_table->value[ values_table->amount_of_values ] ), 0, sizeof( uint8_t * ) * ( amount_of_values - values_table->amount_of_values ) ) == NULL ) { liberror_error_set( error, LIBERROR_ERROR_DOMAIN_MEMORY, LIBERROR_MEMORY_ERROR_SET_FAILED, "%s: unable to clear values.", function ); return( -1 ); } reallocation = memory_reallocate( values_table->value_length, values_table_size ); if( reallocation == NULL ) { liberror_error_set( error, LIBERROR_ERROR_DOMAIN_MEMORY, LIBERROR_MEMORY_ERROR_INSUFFICIENT, "%s: unable to resize value lengths.", function ); return( -1 ); } values_table->value_length = (size_t *) reallocation; if( memory_set( &( values_table->value_length[ values_table->amount_of_values ] ), 0, sizeof( size_t ) * ( amount_of_values - values_table->amount_of_values ) ) == NULL ) { liberror_error_set( error, LIBERROR_ERROR_DOMAIN_MEMORY, LIBERROR_MEMORY_ERROR_SET_FAILED, "%s: unable to clear value sizes.", function ); return( -1 ); } values_table->amount_of_values = amount_of_values; } return( 1 ); }
string_t stream_read_string(stream_t* stream) { char buffer[128]; char* outbuffer = buffer; size_t outsize = sizeof(buffer); size_t cursize = 0; size_t read, i; bool binary = stream_is_binary(stream); if (!(stream->mode & STREAM_IN)) return (string_t) { 0, 0 }; if (stream_is_sequential(stream)) { //Single byte reading since we can't seek backwards (and don't want to block on network sockets) char c; if (!binary) { //Consume whitespace while (!stream_eos(stream)) { read = stream->vtable->read(stream, &c, 1); if (!read) break; if ((c != ' ') && (c != '\n') && (c != '\r') && (c != '\t')) { buffer[cursize++] = c; break; } } } if (cursize > 0) { while (!stream_eos(stream)) { read = stream->vtable->read(stream, &c, 1); if (!read) break; if (!c) break; if (!binary && ((c == ' ') || (c == '\n') || (c == '\r') || (c == '\t'))) break; if (cursize + 1 >= outsize) { outsize += 512; if (outbuffer != buffer) { outbuffer = memory_reallocate(outbuffer, outsize, 0, cursize); } else { outbuffer = memory_allocate(0, outsize, 0, MEMORY_PERSISTENT); memcpy(outbuffer, buffer, sizeof(buffer)); } } outbuffer[cursize++] = c; } outbuffer[cursize] = 0; //lint !e661 } } else { if (!binary) { //Consume whitespace while (!stream_eos(stream)) { read = stream->vtable->read(stream, buffer, 16); if (!read) break; for (i = 0; i < read; ++i) { char c = buffer[i]; if ((c != ' ') && (c != '\n') && (c != '\r') && (c != '\t')) break; } if (i < read) { stream_seek(stream, (ssize_t)i - (ssize_t)read, STREAM_SEEK_CURRENT); break; } } } while (!stream_eos(stream)) { if (outbuffer != buffer) read = stream->vtable->read(stream, buffer, sizeof(buffer)); else read = stream->vtable->read(stream, buffer + cursize, sizeof(buffer) - cursize); if (!read) break; for (i = 0; i < read; ++i) { char c = buffer[i]; if (!c) break; if (!binary && ((c == ' ') || (c == '\n') || (c == '\r') || (c == '\t'))) break; } if (i) { if (cursize + i >= outsize) { outsize += 512; if (outbuffer != buffer) { outbuffer = memory_reallocate(outbuffer, outsize, 0, cursize); } else { FOUNDATION_ASSERT(cursize == 0); //Or internal assumptions about code flow is incorrect outbuffer = memory_allocate(0, outsize, 0, MEMORY_PERSISTENT); memcpy(outbuffer, buffer, i); } } else if (outbuffer != buffer) memcpy(outbuffer + cursize, buffer, i); cursize += i; } if (i < sizeof(buffer)) { if ((i + 1) < read) stream_seek(stream, (ssize_t)(1 + i) - (ssize_t)read, STREAM_SEEK_CURRENT); break; } } outbuffer[cursize] = 0; } if (outbuffer == buffer) { if (cursize == 0) return (string_t) { 0, 0 }; outbuffer = memory_allocate(0, cursize + 1, 0, MEMORY_PERSISTENT); memcpy(outbuffer, buffer, cursize); outbuffer[cursize] = 0; } return (string_t) { outbuffer, cursize }; }
/* Resizes an array * Returns 1 if successful or -1 on error */ int libodraw_array_resize( libodraw_array_t *array, int number_of_entries, int (*entry_free_function)( intptr_t **entry, libcerror_error_t **error ), libcerror_error_t **error ) { void *reallocation = NULL; static char *function = "libodraw_array_resize"; size_t entries_size = 0; int entry_iterator = 0; int result = 1; if( array == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid array.", function ); return( -1 ); } if( number_of_entries < 0 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid number of entries.", function ); return( -1 ); } if( number_of_entries > array->number_of_allocated_entries ) { entries_size = sizeof( intptr_t * ) * number_of_entries; if( entries_size > (size_t) SSIZE_MAX ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_VALUE_EXCEEDS_MAXIMUM, "%s: invalid entries size value exceeds maximum.", function ); return( -1 ); } reallocation = memory_reallocate( array->entries, entries_size ); if( reallocation == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_MEMORY, LIBCERROR_MEMORY_ERROR_INSUFFICIENT, "%s: unable to resize array entries.", function ); return( -1 ); } array->entries = (intptr_t **) reallocation; if( memory_set( &( array->entries[ array->number_of_allocated_entries ] ), 0, sizeof( intptr_t * ) * ( number_of_entries - array->number_of_allocated_entries ) ) == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_MEMORY, LIBCERROR_MEMORY_ERROR_SET_FAILED, "%s: unable to clear array entries.", function ); result = -1; } array->number_of_allocated_entries = number_of_entries; array->number_of_entries = number_of_entries; } else if( number_of_entries > array->number_of_entries ) { array->number_of_entries = number_of_entries; } else if( array->entries != NULL ) { if( entry_free_function == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid entry free function.", function ); return( -1 ); } for( entry_iterator = number_of_entries; entry_iterator < array->number_of_entries; entry_iterator++ ) { if( array->entries[ entry_iterator ] != NULL ) { if( entry_free_function != NULL ) { if( entry_free_function( &( array->entries[ entry_iterator ] ), error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED, "%s: unable to free array entry: %d.", function, entry_iterator ); result = -1; } } array->entries[ entry_iterator ] = NULL; } } array->number_of_entries = number_of_entries; } return( result ); }
/* Appends a value entry * Returns if successful or -1 on error */ int libfvalue_data_handle_append_value_entry( libfvalue_data_handle_t *data_handle, int *value_entry_index, const uint8_t *value_entry_data, size_t value_entry_data_size, int encoding, libcerror_error_t **error ) { libfvalue_internal_data_handle_t *internal_data_handle = NULL; libfvalue_value_entry_t *value_entry = NULL; void *reallocation = NULL; static char *function = "libfvalue_data_handle_append_value_entry"; if( data_handle == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid data handle.", function ); return( -1 ); } internal_data_handle = (libfvalue_internal_data_handle_t *) data_handle; if( value_entry_index == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid value entry index.", function ); return( -1 ); } if( value_entry_data == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid value entry data.", function ); return( -1 ); } if( value_entry_data_size > (size_t) SSIZE_MAX ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM, "%s: invalid value entry data size value exceeds maximum.", function ); return( -1 ); } if( internal_data_handle->data == NULL ) { if( libfvalue_data_handle_set_data( data_handle, value_entry_data, value_entry_data_size, encoding, LIBFVALUE_VALUE_DATA_FLAG_MANAGED, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_SET_FAILED, "%s: unable to set data in data handle.", function ); goto on_error; } internal_data_handle->encoding = encoding; } else { if( encoding != internal_data_handle->encoding ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS, "%s: invalid encoding value out of bounds.", function ); return( -1 ); } if( ( internal_data_handle->data_size + value_entry_data_size ) > (size_t) SSIZE_MAX ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM, "%s: invalid value entry data size value exceeds maximum.", function ); return( -1 ); } if( internal_data_handle->value_entries == NULL ) { if( libcdata_array_initialize( &( internal_data_handle->value_entries ), 1, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, "%s: unable to create value entries array.", function ); goto on_error; } if( libfvalue_value_entry_initialize( &value_entry, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, "%s: unable to create value entry.", function ); goto on_error; } value_entry->offset = 0; value_entry->size = internal_data_handle->data_size; if( libcdata_array_set_entry_by_index( internal_data_handle->value_entries, 0, (intptr_t *) value_entry, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_SET_FAILED, "%s: unable to set entry: 0 in values entries array.", function ); goto on_error; } value_entry = NULL; } if( libfvalue_value_entry_initialize( &value_entry, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, "%s: unable to create value entry.", function ); goto on_error; } value_entry->offset = internal_data_handle->data_size; value_entry->size = value_entry_data_size; reallocation = memory_reallocate( internal_data_handle->data, internal_data_handle->data_size + value_entry_data_size ); if( reallocation == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_MEMORY, LIBCERROR_MEMORY_ERROR_INSUFFICIENT, "%s: unable to resize array entries.", function ); goto on_error; } internal_data_handle->data = (uint8_t *) reallocation; internal_data_handle->data_size += value_entry_data_size; if( memory_copy( &( ( internal_data_handle->data )[ value_entry->offset ] ), value_entry_data, value_entry->size ) == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_MEMORY, LIBCERROR_MEMORY_ERROR_COPY_FAILED, "%s: unable to copy value entry data.", function ); goto on_error; } if( libcdata_array_append_entry( internal_data_handle->value_entries, value_entry_index, (intptr_t *) value_entry, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_APPEND_FAILED, "%s: unable to append entry to values entries array.", function ); goto on_error; } value_entry = NULL; } return( 1 ); on_error: if( value_entry != NULL ) { libfvalue_value_entry_free( &value_entry, NULL ); } return( -1 ); }
/* Append the data * Returns 1 if successful or -1 on error */ int libesedb_key_append_data( libesedb_key_t *key, const uint8_t *data, size_t data_size, libcerror_error_t **error ) { void *reallocation = NULL; static char *function = "libesedb_key_append_data"; if( key == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid key.", function ); return( -1 ); } if( data == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid data.", function ); return( -1 ); } if( data_size > (size_t) SSIZE_MAX ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_VALUE_EXCEEDS_MAXIMUM, "%s: invalid data size value exceeds maximum.", function ); return( -1 ); } if( data_size > 0 ) { reallocation = memory_reallocate( key->data, sizeof( uint8_t ) * ( key->data_size + data_size ) ); if( reallocation == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_MEMORY, LIBCERROR_MEMORY_ERROR_INSUFFICIENT, "%s: unable to resize data.", function ); return( -1 ); } key->data = (uint8_t *) reallocation; if( memory_copy( &( key->data[ key->data_size ] ), data, sizeof( uint8_t ) * data_size ) == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_MEMORY, LIBCERROR_MEMORY_ERROR_COPY_FAILED, "%s: unable to copy data.", function ); return( -1 ); } key->data_size += data_size; } return( 1 ); }
/* Retrieves the table of contents from the optical disk using the SCSI READ TOC command * Returns 1 if successful, 0 if not or -1 on error */ int libsmdev_optical_disc_get_table_of_contents_scsi( libcfile_file_t *device_file, libsmdev_internal_handle_t *internal_handle, libcerror_error_t **error ) { uint8_t track_info_data[ 64 ]; uint8_t *toc_data = NULL; uint8_t *toc_entries = NULL; static char *function = "libsmdev_optical_disc_get_table_of_contents_scsi"; void *reallocation = NULL; size_t toc_data_offset = 0; size_t toc_data_size = 0; ssize_t read_count = 0; uint32_t lead_out_size = 0; uint32_t lead_out_offset = 0; uint32_t last_track_offset = 0; uint32_t track_offset = 0; uint32_t session_size = 0; uint32_t session_offset = 0; uint32_t next_session_offset = 0; uint16_t entry_index = 0; uint8_t first_track_number = 0; uint8_t last_track_number = 0; uint8_t lead_out_index = 0; uint8_t number_of_sessions = 0; uint8_t session_index = 0; uint8_t track_index = 0; uint8_t track_number = 0; uint8_t track_type = 0; int result = 0; toc_data_size = 1024; toc_data = (uint8_t *) memory_allocate( sizeof( uint8_t ) * toc_data_size ); if( toc_data == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_MEMORY, LIBCERROR_MEMORY_ERROR_INSUFFICIENT, "%s: unable to create TOC data.", function ); goto on_error; } if( memory_set( toc_data, 0, sizeof( uint8_t ) * toc_data_size ) == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_MEMORY, LIBCERROR_MEMORY_ERROR_SET_FAILED, "%s: unable to clear TOC data.", function ); goto on_error; } read_count = libsmdev_scsi_read_toc( device_file, LIBSMDEV_SCSI_TOC_CDB_FORMAT_RAW_TOC, toc_data, toc_data_size, error ); if( read_count == -1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve TOC.", function ); #if defined( HAVE_DEBUG_OUTPUT ) if( libcnotify_verbose != 0 ) { if( ( error != NULL ) && ( *error != NULL ) ) { libcnotify_print_error_backtrace( *error ); } } #endif libcerror_error_free( error ); byte_stream_copy_to_uint16_big_endian( toc_data, toc_data_size ); if( toc_data_size > 1024 ) { reallocation = memory_reallocate( toc_data, sizeof( uint8_t ) * toc_data_size ); if( reallocation == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_MEMORY, LIBCERROR_MEMORY_ERROR_INSUFFICIENT, "%s: unable to resize TOC data.", function ); goto on_error; } toc_data = (uint8_t *) reallocation; read_count = libsmdev_scsi_read_toc( device_file, LIBSMDEV_SCSI_TOC_CDB_FORMAT_RAW_TOC, toc_data, toc_data_size, error ); if( read_count == -1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve TOC.", function ); #if defined( HAVE_DEBUG_OUTPUT ) if( libcnotify_verbose != 0 ) { if( ( error != NULL ) && ( *error != NULL ) ) { libcnotify_print_error_backtrace( *error ); } } #endif libcerror_error_free( error ); } } } toc_data_size = (size_t) read_count; if( toc_data_size > 4 ) { #if defined( HAVE_DEBUG_OUTPUT ) if( libcnotify_verbose != 0 ) { libcnotify_printf( "%s: header:\n", function ); libcnotify_print_data( toc_data, 4, 0 ); } #endif number_of_sessions = (uint16_t) toc_data[ 3 ]; #if defined( HAVE_DEBUG_OUTPUT ) if( libcnotify_verbose != 0 ) { libcnotify_printf( "%s: number of sessions\t\t\t: %" PRIu8 "\n", function, number_of_sessions ); libcnotify_printf( "\n" ); } #endif toc_entries = &( toc_data[ 4 ] ); toc_data_offset = 4; while( toc_data_offset < (size_t) toc_data_size ) { #if defined( HAVE_DEBUG_OUTPUT ) if( libcnotify_verbose != 0 ) { libcnotify_printf( "%s: entry: %02" PRIu16 ":\n", function, entry_index ); libcnotify_print_data( toc_entries, 11, 0 ); } #endif if( toc_entries[ 3 ] <= 0x63 ) { libsmdev_optical_disc_copy_msf_to_lba( toc_entries[ 8 ], toc_entries[ 9 ], toc_entries[ 10 ], track_offset ); } else if( toc_entries[ 3 ] == 0xa0 ) { first_track_number = toc_entries[ 8 ]; } else if( toc_entries[ 3 ] == 0xa1 ) { last_track_number = toc_entries[ 8 ]; } else if( toc_entries[ 3 ] == 0xa2 ) { libsmdev_optical_disc_copy_msf_to_lba( toc_entries[ 8 ], toc_entries[ 9 ], toc_entries[ 10 ], lead_out_offset ); } else if( toc_entries[ 3 ] == 0xb0 ) { libsmdev_optical_disc_copy_absolute_msf_to_lba( toc_entries[ 4 ], toc_entries[ 5 ], toc_entries[ 6 ], next_session_offset ); } #if defined( HAVE_DEBUG_OUTPUT ) if( libcnotify_verbose != 0 ) { if( toc_entries[ 3 ] <= 0x63 ) { libcnotify_printf( "%s: session: %02" PRIu16 " track: %02" PRIu8 "\t\t\t: %02" PRIu8 ":%02" PRIu8 ".%02" PRIu8 " (offset: %" PRIu32 ")\n", function, toc_entries[ 0 ], toc_entries[ 3 ], toc_entries[ 4 ], toc_entries[ 5 ], toc_entries[ 6 ], track_offset ); } else if( toc_entries[ 3 ] == 0xa0 ) { libcnotify_printf( "%s: session: %02" PRIu8 " first track number\t: %" PRIu8 "\n", function, toc_entries[ 0 ], first_track_number ); } else if( toc_entries[ 3 ] == 0xa1 ) { libcnotify_printf( "%s: session: %02" PRIu8 " last track number\t\t: %" PRIu8 "\n", function, toc_entries[ 0 ], last_track_number ); } else if( toc_entries[ 3 ] == 0xa2 ) { libcnotify_printf( "%s: session: %02" PRIu8 " lead out\t\t\t: %02" PRIu8 ":%02" PRIu8 ".%02" PRIu8 " (offset: %" PRIu32 ")\n", function, toc_entries[ 0 ], toc_entries[ 8 ], toc_entries[ 9 ], toc_entries[ 10 ], lead_out_offset ); } else if( toc_entries[ 3 ] == 0xb0 ) { libcnotify_printf( "%s: session: %02" PRIu16 " end\t\t\t: %02" PRIu8 ":%02" PRIu8 ".%02" PRIu8 " (offset: %" PRIu32 ")\n", function, toc_entries[ 0 ], toc_entries[ 4 ], toc_entries[ 5 ], toc_entries[ 6 ], next_session_offset ); } libcnotify_printf( "\n" ); } #endif if( ( toc_entries[ 3 ] <= 0x63 ) || ( toc_entries[ 3 ] == 0xb0 ) ) { if( track_number >= first_track_number ) { if( toc_entries[ 3 ] == 0xb0 ) { track_offset = lead_out_offset; } if( track_offset < last_track_offset ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS, "%s: invalid track offset value out of bounds.", function ); goto on_error; } if( ( track_index + 1 ) != track_number ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS, "%s: invalid track number value out of bounds.", function ); goto on_error; } if( toc_entries[ 3 ] == 0xa2 ) { if( track_number != last_track_number ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS, "%s: invalid track number value out of bounds.", function ); goto on_error; } } if( memory_set( track_info_data, 0, 64 ) == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_MEMORY, LIBCERROR_MEMORY_ERROR_SET_FAILED, "%s: unable to clear track info data.", function ); goto on_error; } read_count = libsmdev_scsi_read_track_information( device_file, last_track_offset, track_info_data, 64, error ); if( read_count == -1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve track info data: %d.", function, track_index ); #if defined( HAVE_DEBUG_OUTPUT ) if( libcnotify_verbose != 0 ) { if( ( error != NULL ) && ( *error != NULL ) ) { libcnotify_print_error_backtrace( *error ); } } #endif libcerror_error_free( error ); break; } #if defined( HAVE_DEBUG_OUTPUT ) if( libcnotify_verbose != 0 ) { libcnotify_printf( "%s: track information data: %d:\n", function, track_index ); libcnotify_print_data( track_info_data, (size_t) read_count, 0 ); } #endif if( track_info_data[ 2 ] != toc_entries[ 0 ] ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS, "%s: invalid track information data - session number value out of bounds.", function ); goto on_error; } if( track_info_data[ 3 ] != track_number ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS, "%s: invalid track information data - track number value out of bounds.", function ); goto on_error; } track_type = LIBSMDEV_TRACK_TYPE_UNKNOWN; if( ( track_info_data[ 5 ] & 0x04 ) != 0 ) { if( ( track_info_data[ 5 ] & 0x08 ) == 0 ) { if( ( track_info_data[ 6 ] & 0x0f ) == 1 ) { track_type = LIBSMDEV_TRACK_TYPE_MODE1_2048; } else if( ( track_info_data[ 6 ] & 0x0f ) == 2 ) { track_type = LIBSMDEV_TRACK_TYPE_MODE2_2048; } } } else { track_type = LIBSMDEV_TRACK_TYPE_AUDIO; } if( libsmdev_handle_append_track( internal_handle, last_track_offset, track_offset - last_track_offset, track_type, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_APPEND_FAILED, "%s: unable to append track: %d.", function, track_index ); goto on_error; } track_index++; } last_track_offset = track_offset; if( toc_entries[ 3 ] != 0xb0 ) { track_number = toc_entries[ 3 ]; } } if( toc_entries[ 3 ] == 0xb0 ) { if( session_offset >= next_session_offset ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS, "%s: invalid session offset value out of bounds.", function ); goto on_error; } if( ( session_index + 1 ) != toc_entries[ 0 ] ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS, "%s: invalid session number value out of bounds.", function ); goto on_error; } lead_out_size = 0; if( ( lead_out_offset >= session_offset ) && ( lead_out_offset < next_session_offset ) ) { lead_out_size = next_session_offset - lead_out_offset; if( libsmdev_handle_append_lead_out( internal_handle, lead_out_offset, lead_out_size, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_APPEND_FAILED, "%s: unable to append lead_out: %d.", function, lead_out_index ); goto on_error; } lead_out_index++; } session_size = next_session_offset - session_offset; if( ( session_index + 1 ) == number_of_sessions ) { session_size -= lead_out_size; } if( libsmdev_handle_append_session( internal_handle, session_offset, session_size, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_APPEND_FAILED, "%s: unable to append session: %d.", function, session_index ); goto on_error; } session_offset = next_session_offset; session_index++; } toc_entries += 11; toc_data_offset += 11; entry_index++; } if( ( track_index + 1 ) == track_number ) { if( track_offset < last_track_offset ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS, "%s: invalid track offset value out of bounds.", function ); goto on_error; } if( memory_set( track_info_data, 0, 64 ) == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_MEMORY, LIBCERROR_MEMORY_ERROR_SET_FAILED, "%s: unable to clear track info data.", function ); goto on_error; } read_count = libsmdev_scsi_read_track_information( device_file, last_track_offset, track_info_data, 64, error ); if( read_count == -1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve track info data: %d.", function, track_index ); #if defined( HAVE_DEBUG_OUTPUT ) if( libcnotify_verbose != 0 ) { if( ( error != NULL ) && ( *error != NULL ) ) { libcnotify_print_error_backtrace( *error ); } } #endif libcerror_error_free( error ); } else { #if defined( HAVE_DEBUG_OUTPUT ) if( libcnotify_verbose != 0 ) { libcnotify_printf( "%s: track information data: %d:\n", function, track_index ); libcnotify_print_data( track_info_data, (size_t) read_count, 0 ); } #endif if( track_info_data[ 2 ] != toc_entries[ 0 ] ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS, "%s: invalid track information data - session number value out of bounds.", function ); goto on_error; } if( track_info_data[ 3 ] != toc_entries[ 3 ] ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS, "%s: invalid track information data - track number value out of bounds.", function ); goto on_error; } track_type = LIBSMDEV_TRACK_TYPE_UNKNOWN; if( ( track_info_data[ 5 ] & 0x04 ) != 0 ) { if( ( track_info_data[ 5 ] & 0x08 ) == 0 ) { if( ( track_info_data[ 6 ] & 0x0f ) == 1 ) { track_type = LIBSMDEV_TRACK_TYPE_MODE1_2048; } else if( ( track_info_data[ 6 ] & 0x0f ) == 2 ) { track_type = LIBSMDEV_TRACK_TYPE_MODE2_2048; } } } else { track_type = LIBSMDEV_TRACK_TYPE_AUDIO; } if( libsmdev_handle_append_track( internal_handle, last_track_offset, track_offset - last_track_offset, track_type, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_APPEND_FAILED, "%s: unable to append last track: %d.", function, track_index ); goto on_error; } } if( session_index != number_of_sessions ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS, "%s: invalid session index value out of bounds.", function ); goto on_error; } result = 1; } } if( result == 0 ) { if( libcdata_array_empty( internal_handle->tracks_array, (int (*)(intptr_t **, libcerror_error_t **)) &libsmdev_track_value_free, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED, "%s: unable to empty tracks array.", function ); goto on_error; } if( libcdata_array_empty( internal_handle->lead_outs_array, (int (*)(intptr_t **, libcerror_error_t **)) &libsmdev_sector_range_free, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED, "%s: unable to empty lead outs array.", function ); goto on_error; } if( libcdata_array_empty( internal_handle->sessions_array, (int (*)(intptr_t **, libcerror_error_t **)) &libsmdev_sector_range_free, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED, "%s: unable to empty sessions array.", function ); goto on_error; } } memory_free( toc_data ); toc_data = NULL; return( result ); on_error: if( toc_data != NULL ) { memory_free( toc_data ); } libcdata_array_empty( internal_handle->tracks_array, (int (*)(intptr_t **, libcerror_error_t **)) &libsmdev_track_value_free, NULL ); libcdata_array_empty( internal_handle->lead_outs_array, (int (*)(intptr_t **, libcerror_error_t **)) &libsmdev_sector_range_free, NULL ); libcdata_array_empty( internal_handle->sessions_array, (int (*)(intptr_t **, libcerror_error_t **)) &libsmdev_sector_range_free, NULL ); return( -1 ); }
/* Globs the segment files according to the EWF naming schema * Make sure the value filenames is referencing, is set to NULL * * If the format is known the filename should contain the base of the filename * otherwise the function will try to determine the format based on the extension * Returns 1 if successful or -1 on error */ int libewf_glob( const char *filename, size_t filename_length, uint8_t format, char **filenames[], int *number_of_filenames, libcerror_error_t **error ) { libbfio_handle_t *file_io_handle = NULL; char *segment_filename = NULL; void *reallocation = NULL; static char *function = "libewf_glob"; size_t additional_length = 0; size_t segment_extention_length = 0; size_t segment_filename_index = 0; size_t segment_filename_length = 0; uint8_t segment_file_type = 0; int result = 0; if( filename == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid filename.", function ); return( -1 ); } if( ( filename_length == 0 ) || ( filename_length > (size_t) SSIZE_MAX ) ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS, "%s: invalid filename length value out of bounds.", function ); return( -1 ); } if( ( format != LIBEWF_FORMAT_UNKNOWN ) && ( format != LIBEWF_FORMAT_ENCASE1 ) && ( format != LIBEWF_FORMAT_ENCASE2 ) && ( format != LIBEWF_FORMAT_ENCASE3 ) && ( format != LIBEWF_FORMAT_ENCASE4 ) && ( format != LIBEWF_FORMAT_ENCASE5 ) && ( format != LIBEWF_FORMAT_ENCASE6 ) && ( format != LIBEWF_FORMAT_LINEN5 ) && ( format != LIBEWF_FORMAT_LINEN6 ) && ( format != LIBEWF_FORMAT_SMART ) && ( format != LIBEWF_FORMAT_FTK_IMAGER ) && ( format != LIBEWF_FORMAT_LOGICAL_ENCASE5 ) && ( format != LIBEWF_FORMAT_LOGICAL_ENCASE6 ) && ( format != LIBEWF_FORMAT_LOGICAL_ENCASE7 ) && ( format != LIBEWF_FORMAT_V2_ENCASE7 ) && ( format != LIBEWF_FORMAT_V2_LOGICAL_ENCASE7 ) && ( format != LIBEWF_FORMAT_EWF ) && ( format != LIBEWF_FORMAT_EWFX ) ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE, "%s: unsupported format.", function ); return( -1 ); } if( filenames == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid filenames.", function ); return( -1 ); } if( *filenames != NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET, "%s: invalid filenames value already set.", function ); return( -1 ); } if( number_of_filenames == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid number of filenames.", function ); return( -1 ); } if( format == LIBEWF_FORMAT_UNKNOWN ) { if( ( filename_length > 4 ) && ( filename[ filename_length - 4 ] == '.' ) ) { if( filename[ filename_length - 3 ] == 'E' ) { format = LIBEWF_FORMAT_ENCASE5; } else if( filename[ filename_length - 3 ] == 'e' ) { format = LIBEWF_FORMAT_EWF; } else if( filename[ filename_length - 3 ] == 'L' ) { format = LIBEWF_FORMAT_LOGICAL_ENCASE5; } else if( filename[ filename_length - 3 ] == 's' ) { format = LIBEWF_FORMAT_SMART; } else { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE, "%s: invalid filename - unsupported extension: %s.", function, &( filename[ filename_length - 4 ] ) ); return( -1 ); } segment_extention_length = 4; } else if( ( filename_length > 5 ) && ( filename[ filename_length - 5 ] == '.' ) ) { if( filename[ filename_length - 4 ] == 'E' ) { format = LIBEWF_FORMAT_V2_ENCASE7; } else if( filename[ filename_length - 4 ] == 'L' ) { format = LIBEWF_FORMAT_V2_LOGICAL_ENCASE7; } else { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE, "%s: invalid filename - unsupported extension: %s.", function, &( filename[ filename_length - 5 ] ) ); return( -1 ); } if( filename[ filename_length - 3 ] != 'x' ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE, "%s: invalid filename - unsupported extension: %s.", function, &( filename[ filename_length - 5 ] ) ); return( -1 ); } segment_extention_length = 5; } else { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE, "%s: invalid filename - missing extension.", function ); return( -1 ); } } else { additional_length = 4; } if( segment_file_type == 0 ) { if( ( format == LIBEWF_FORMAT_LOGICAL_ENCASE5 ) || ( format == LIBEWF_FORMAT_LOGICAL_ENCASE6 ) || ( format == LIBEWF_FORMAT_LOGICAL_ENCASE7 ) ) { segment_file_type = LIBEWF_SEGMENT_FILE_TYPE_EWF1_LOGICAL; } else if( format == LIBEWF_FORMAT_SMART ) { segment_file_type = LIBEWF_SEGMENT_FILE_TYPE_EWF1_SMART; } else if( format == LIBEWF_FORMAT_V2_ENCASE7 ) { segment_file_type = LIBEWF_SEGMENT_FILE_TYPE_EWF2; } else if( format == LIBEWF_FORMAT_V2_LOGICAL_ENCASE7 ) { segment_file_type = LIBEWF_SEGMENT_FILE_TYPE_EWF2_LOGICAL; } else { segment_file_type = LIBEWF_SEGMENT_FILE_TYPE_EWF1; } } if( libbfio_file_initialize( &file_io_handle, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, "%s: unable to create file IO handle.", function ); goto on_error; } *number_of_filenames = 0; while( *number_of_filenames < (int) UINT16_MAX ) { segment_filename_length = filename_length + additional_length; segment_filename = (char *) memory_allocate( sizeof( char ) * ( segment_filename_length + 1 ) ); if( segment_filename == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_MEMORY, LIBCERROR_MEMORY_ERROR_INSUFFICIENT, "%s: unable to create segment filename.", function ); goto on_error; } if( libcstring_narrow_string_copy( segment_filename, filename, filename_length ) == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_MEMORY, LIBCERROR_MEMORY_ERROR_COPY_FAILED, "%s: unable to copy filename.", function ); goto on_error; } if( additional_length == 0 ) { segment_filename_index = segment_filename_length - segment_extention_length; } else { segment_filename_index = filename_length; } segment_filename[ segment_filename_index++ ] = '.'; if( libewf_filename_set_extension( segment_filename, segment_filename_length + 1, &segment_filename_index, (uint32_t) ( *number_of_filenames + 1 ), (uint32_t) UINT16_MAX, segment_file_type, format, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_SET_FAILED, "%s: unable to set extension.", function ); goto on_error; } /* The libewf_filename_set_extension also adds the end-of-string character */ if( libbfio_file_set_name( file_io_handle, segment_filename, segment_filename_length, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_SET_FAILED, "%s: unable to set name in file IO handle.", function ); goto on_error; } result = libbfio_handle_exists( file_io_handle, error ); if( result == -1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_IO, LIBCERROR_IO_ERROR_GENERIC, "%s: unable to test if file exists.", function ); goto on_error; } else if( result == 0 ) { memory_free( segment_filename ); break; } *number_of_filenames += 1; reallocation = memory_reallocate( *filenames, sizeof( char * ) * *number_of_filenames ); if( reallocation == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_MEMORY, LIBCERROR_MEMORY_ERROR_INSUFFICIENT, "%s: unable to resize filenames.", function ); goto on_error; } *filenames = (char **) reallocation; ( *filenames )[ *number_of_filenames - 1 ] = segment_filename; } if( libbfio_handle_free( &file_io_handle, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED, "%s: unable to free file IO handle.", function ); goto on_error; } return( 1 ); on_error: if( segment_filename != NULL ) { memory_free( segment_filename ); } if( file_io_handle != NULL ) { libbfio_handle_free( &file_io_handle, NULL ); } return( -1 ); }
char* path_clean( char* path, bool absolute ) { //Since this function is used a lot we want to perform as much operations //in place instead of splicing up into a string array and remerge char* replace; char* inpath; char* next; unsigned int inlength, length, remain, protocollen, up, last_up, prev_up, driveofs; if( !path ) return string_allocate( 0 ); inpath = path; inlength = string_length( path ); protocollen = string_find_string( path, "://", 0 ); if( ( protocollen != STRING_NPOS ) && ( protocollen > 1 ) ) { absolute = true; protocollen += 3; //Also skip the "://" separator inlength -= protocollen; path += protocollen; } else { protocollen = 0; } length = inlength; driveofs = 0; replace = path; while( ( replace = strchr( replace, '\\' ) ) != 0 ) *replace++ = '/'; remain = length; replace = path; while( ( next = strstr( replace, "/./" ) ) != 0 ) { remain -= (unsigned int)( next - replace ) + 2; length -= 2; memmove( next + 1, next + 3, remain ); //Include terminating zero to avoid looping when string ends in "/./" replace = next; } remain = length; replace = path; while( ( next = strstr( replace, "//" ) ) != 0 ) { remain -= (unsigned int)( next - replace ) + 1; --length; memmove( next + 1, next + 2, remain ); //Include terminating zero to avoid looping when string ends in "//" replace = next; } path[length] = 0; if( string_equal( path, "." ) ) { length = 0; path[0] = 0; } else if( length > 1 ) { if( ( path[ length - 2 ] == '/' ) && ( path[ length - 1 ] == '.' ) ) { path[ length - 2 ] = 0; length -= 2; } if( string_equal( path, "." ) ) { length = 0; path[0] = 0; } else if( string_equal( path, "./" ) ) { length = 1; path[0] = '/'; path[1] = 0; } else if( ( length > 1 ) && ( path[0] == '.' ) && ( path[1] == '/' ) ) { --length; memmove( path, path + 1, length ); path[length] = 0; } } if( absolute ) { if( !length ) { if( !inlength ) { inlength = 2; inpath = memory_reallocate( inpath, inlength + protocollen + 1, 0, protocollen + 1 ); path = inpath + protocollen; } path[0] = '/'; path[1] = 0; ++length; } else if( ( length >= 2 ) && ( path[1] == ':' ) ) { driveofs = 2; //Make sure first character is upper case if( ( path[0] >= 'a' ) && ( path[0] <= 'z' ) ) path[0] = ( path[0] - (char)( (int)'a' - (int)'A' ) ); if( length == 2 ) { if( inlength <= 2 ) { inpath = memory_reallocate( inpath, inlength + 2 + protocollen + 1, 0, inlength + protocollen + 1 ); inlength += 2; path = inpath + protocollen; } path[2] = '/'; ++length; } else if( path[2] != '/' ) { //splice in slash in weird-format paths (C:foo/bar/...) if( inlength < ( length + 1 ) ) { //Need more space inpath = memory_reallocate( inpath, length + protocollen + 2, 0, inlength + protocollen + 1 ); inlength = length + 1; path = inpath + protocollen; } memmove( path + 3, path + 2, length + 1 - 2 ); path[2] = '/'; ++length; } } else if( !protocollen && ( path[0] != '/' ) ) { //make sure capacity is enough to hold additional character if( inlength < ( length + 1 ) ) { //Need more space inpath = memory_reallocate( inpath, length + protocollen + 2, 0, inlength + protocollen + 1 ); inlength = length + 1; path = inpath + protocollen; } memmove( path + 1, path, length + 1 ); path[0] = '/'; ++length; } } else //relative { if( length && ( path[0] == '/' ) ) { memmove( path, path + 1, length - 1 ); --length; } } //Deal with .. references last_up = driveofs; while( ( up = string_find_string( path, "/../", last_up ) ) != STRING_NPOS ) { if( up >= length ) break; if( up == driveofs ) { if( absolute ) { memmove( path + driveofs + 1, path + driveofs + 4, length - ( driveofs + 3 ) ); length -= 3; } else { last_up = driveofs + 3; } continue; } prev_up = string_rfind( path, '/', up - 1 ); if( prev_up == STRING_NPOS ) { if( absolute ) { memmove( path, path + up + 3, length - up - 2 ); length -= ( up + 3 ); } else { memmove( path, path + up + 4, length - up - 3 ); length -= ( up + 4 ); } } else if( prev_up >= last_up ) { memmove( path + prev_up, path + up + 3, length - up - 2 ); length -= ( up - prev_up + 3 ); } else { last_up = up + 1; } } if( length > 1 ) { if( path[ length - 1 ] == '/' ) { path[ length - 1 ] = 0; --length; } } if( protocollen ) { if( path[0] == '/' ) { if( length == 1 ) length = 0; else { memmove( path, path + 1, length ); --length; } } length += protocollen; path = inpath; } path[length] = 0; return path; }
int BootFromFlash( void ) { long int HexFile_p = 0; /* datafile descriptor */ long int HexFileSize = 0; /* size in bytes of the file */ int ErrorCount = 0; ST_ErrorCode_t ReturnError = ST_NO_ERROR; char Filename[] = "flash.hex"; U8 Block; U32 BlockStart; STFLASH_Print(( "\n" )); STFLASH_Print(( "============================================================\n" )); STFLASH_Print(( "Commencing Boot From Flash Test ..\n" )); STFLASH_Print(( "============================================================\n" )); /* Init Bank 0, Vpp 0 */ InitParams_s.DeviceType = DEVICE_TYPE; InitParams_s.BaseAddress = (U32*)STFLASH_BANK_0_BASE; InitParams_s.VppAddress = (U32*)STFLASH_VPP_0_ENABLE; InitParams_s.MinAccessWidth = MIN_ACCESS_WIDTH; InitParams_s.MaxAccessWidth = MAX_ACCESS_WIDTH; InitParams_s.NumberOfBlocks = NUM_BLOCKS; InitParams_s.Blocks = BlockData_s; #ifdef ST_OS21 InitParams_s.DriverPartition = system_partition; #else InitParams_s.DriverPartition = TEST_PARTITION_1; #endif STFLASH_Print(( "FLASH_BANK_0_BASE = %x\n", STFLASH_BANK_0_BASE )); STFLASH_Print(( "Calling STFLASH_Init() Bank0 ..........\n" )); ReturnError = STFLASH_Init( "Bank0", &InitParams_s ); ErrorReport( &ErrorCount, ReturnError, ST_NO_ERROR ); /* Open Bank 0 */ STFLASH_Print(( "Calling STFLASH_Open() Bank0 ..........\n" )); ReturnError = STFLASH_Open( "Bank0", &OpenParams_s, &FLASHHndl[0] ); ErrorReport( &ErrorCount, ReturnError, ST_NO_ERROR ); /* GetParams for Bank 0 */ GetParams_s.InitParams.Blocks = GetBlkDat_s; STFLASH_Print(( "Calling STFLASH_GetParams() Bank 0 ....\n" )); ReturnError = STFLASH_GetParams( FLASHHndl[0], &GetParams_s ); ErrorReport( &ErrorCount, ReturnError, ST_NO_ERROR ); ParamsReport( &GetParams_s ); BlockStart = BaseAddress[BANK0] = (U32) InitParams_s.BaseAddress; for ( Block = 0; Block < InitParams_s.NumberOfBlocks; Block ++) { BlockInfo[Block].Bank = 0; BlockInfo[Block].Address = BlockStart; BlockInfo[Block].Length = InitParams_s.Blocks[Block].Length; BlockStart += InitParams_s.Blocks[Block].Length; } /* Open and Read file into memory */ HexFile_p = debugopen(Filename, "rb"); STFLASH_Print(("HexFile_p = 0x%8x\n",HexFile_p)); if (HexFile_p < 0) { STFLASH_Print(("Error opening file \'%s\'\n", Filename )); return (0); } else { HexFileSize = debugfilesize(HexFile_p); STFLASH_Print(("HexFileSize = 0x%8x\n",HexFileSize)); /* allocate File data buffer */ FlashData_p = (char*) memory_allocate( system_partition, (U32) HexFileSize ); if ( FlashData_p != NULL ) { STFLASH_Print(("Loading \'%s\' into memory, wait .. ", Filename )); debugread(HexFile_p, FlashData_p, (size_t) HexFileSize); STFLASH_Print(("%d bytes\n", HexFileSize )); } else { STFLASH_Print(("Not enough memory for HEX file (%d bytes)\n", HexFileSize)); HexFileSize = 0; } debugclose(HexFile_p); } if ( HexFileSize > 0 ) { /* convert buffer to binary and resize memory */ STFLASH_Print(("Converting file in memory, wait .. ")); FlashSize = ConvertMemory( HexFileSize ); if ( FlashSize > 0 ) { STFLASH_Print(("%d bytes\n", FlashSize )); FlashData_p = (char*) memory_reallocate( system_partition, FlashData_p, FlashSize ); } else { STFLASH_Print(("Invalid file\n")); } } if ( EraseFlash(FALSE) == FALSE ) { if ( ProgramFlash() == FALSE ) { VerifyFlash(); } } /* Close Bank 0 */ STFLASH_Print(( "Calling STFLASH_Close() Bank 0 ........\n" )); ReturnError = STFLASH_Close( FLASHHndl[0] ); ErrorReport( &ErrorCount, ReturnError, ST_NO_ERROR ); /* Term Bank 0 */ TermParams_s.ForceTerminate = FALSE; STFLASH_Print(( "Calling STFLASH_Term() Bank 0 .........\n" )); ReturnError = STFLASH_Term( "Bank0", &TermParams_s ); ErrorReport( &ErrorCount, ReturnError, ST_NO_ERROR ); return( ErrorCount ); }
/* Resizes the pool * Returns 1 if successful or -1 on error */ int libbfio_pool_resize( libbfio_pool_t *pool, int amount_of_handles, liberror_error_t **error ) { libbfio_internal_pool_t *internal_pool = NULL; void *reallocation = NULL; static char *function = "libbfio_pool_resize"; size_t handles_size = 0; if( pool == NULL ) { liberror_error_set( error, LIBERROR_ERROR_DOMAIN_ARGUMENTS, LIBERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid pool.", function ); return( -1 ); } internal_pool = (libbfio_internal_pool_t *) pool; if( amount_of_handles <= 0 ) { liberror_error_set( error, LIBERROR_ERROR_DOMAIN_ARGUMENTS, LIBERROR_ARGUMENT_ERROR_VALUE_ZERO_OR_LESS, "%s: invalid amount of handles value zero or less.", function ); return( -1 ); } if( internal_pool->amount_of_handles < amount_of_handles ) { handles_size = sizeof( libbfio_handle_t * ) * amount_of_handles; if( handles_size > (size_t) SSIZE_MAX ) { liberror_error_set( error, LIBERROR_ERROR_DOMAIN_RUNTIME, LIBERROR_RUNTIME_ERROR_VALUE_EXCEEDS_MAXIMUM, "%s: invalid handles size value exceeds maximum.", function ); return( -1 ); } reallocation = memory_reallocate( internal_pool->handles, handles_size ); if( reallocation == NULL ) { liberror_error_set( error, LIBERROR_ERROR_DOMAIN_MEMORY, LIBERROR_MEMORY_ERROR_INSUFFICIENT, "%s: unable to resize handles.", function ); return( -1 ); } internal_pool->handles = (libbfio_handle_t **) reallocation; if( memory_set( &( internal_pool->handles[ internal_pool->amount_of_handles ] ), 0, sizeof( libbfio_handle_t * ) * ( amount_of_handles - internal_pool->amount_of_handles ) ) == NULL ) { liberror_error_set( error, LIBERROR_ERROR_DOMAIN_MEMORY, LIBERROR_MEMORY_ERROR_SET_FAILED, "%s: unable to clear handles.", function ); return( -1 ); } internal_pool->amount_of_handles = amount_of_handles; } return( 1 ); }
static void * cacheRealloc(void *state, void *ptr, size_t size) { return ((void **) memory_reallocate(NULL, ((void **) ptr) - 1, size+sizeof(void *))) + 1; }
/* Sets an error and adds a system specific error string if possible * Creates the error if necessary * The error domain and code are set only the first time and the error message is appended for back tracing */ void VARARGS( libcerror_system_set_error, libcerror_error_t **error, int error_domain, int error_code, uint32_t system_error_code, const char *, format_string ) { va_list argument_list; libcerror_internal_error_t *internal_error = NULL; system_character_t *error_string = NULL; system_character_t *system_format_string = NULL; void *reallocation = NULL; size_t error_string_size = 0; size_t format_string_length = 0; size_t message_size = 0; size_t next_message_size = LIBCERROR_MESSAGE_INCREMENT_SIZE; size_t string_index = 0; int message_index = 0; int print_count = 0; if( error == NULL ) { return; } if( format_string == NULL ) { return; } format_string_length = narrow_string_length( format_string ); #if defined( HAVE_WIDE_SYSTEM_CHARACTER ) libcerror_error_get_system_format_string( format_string, format_string_length, &system_format_string ); if( system_format_string == NULL ) { return; } #else system_format_string = (system_character_t *) format_string; #endif if( *error == NULL ) { if( libcerror_error_initialize( error, error_domain, error_code ) != 1 ) { goto on_error; } } internal_error = (libcerror_internal_error_t *) *error; if( libcerror_error_resize( internal_error ) != 1 ) { goto on_error; } if( format_string_length > next_message_size ) { next_message_size = ( ( format_string_length / LIBCERROR_MESSAGE_INCREMENT_SIZE ) + 1 ) * LIBCERROR_MESSAGE_INCREMENT_SIZE; } message_index = internal_error->number_of_messages - 1; error_string = internal_error->messages[ message_index ]; do { if( next_message_size >= LIBCERROR_MESSAGE_MAXIMUM_SIZE ) { next_message_size = LIBCERROR_MESSAGE_MAXIMUM_SIZE; } reallocation = memory_reallocate( error_string, sizeof( system_character_t ) * next_message_size ); if( reallocation == NULL ) { memory_free( error_string ); goto on_error; } error_string = (system_character_t *) reallocation; message_size = next_message_size; /* argument_list cannot be reused in successive calls to vsnprintf */ VASTART( argument_list, const char *, format_string ); print_count = system_string_vsnprintf( error_string, message_size, system_format_string, argument_list ); VAEND( argument_list ); if( print_count <= -1 ) { next_message_size += LIBCERROR_MESSAGE_INCREMENT_SIZE; } else if( ( (size_t) print_count >= message_size ) || ( error_string[ print_count ] != (system_character_t) 0 ) ) { next_message_size = (size_t) ( print_count + 1 ); print_count = -1; } else { error_string_size = (size_t) print_count + 1; } if( message_size >= LIBCERROR_MESSAGE_MAXIMUM_SIZE ) { break; } } while( print_count <= -1 ); if( message_size >= LIBCERROR_MESSAGE_MAXIMUM_SIZE ) { error_string[ LIBCERROR_MESSAGE_MAXIMUM_SIZE - 4 ] = (system_character_t) '.'; error_string[ LIBCERROR_MESSAGE_MAXIMUM_SIZE - 3 ] = (system_character_t) '.'; error_string[ LIBCERROR_MESSAGE_MAXIMUM_SIZE - 2 ] = (system_character_t) '.'; error_string[ LIBCERROR_MESSAGE_MAXIMUM_SIZE - 1 ] = 0; error_string_size = (size_t) LIBCERROR_MESSAGE_MAXIMUM_SIZE; } internal_error->messages[ message_index ] = error_string; internal_error->sizes[ message_index ] = error_string_size; #if defined( HAVE_WIDE_SYSTEM_CHARACTER ) memory_free( system_format_string ); system_format_string = NULL; #endif message_size = internal_error->sizes[ message_index ]; if( message_size < LIBCERROR_MESSAGE_MAXIMUM_SIZE ) { /* TODO move to separate helper function */ string_index = internal_error->sizes[ message_index ] - 1; if( ( internal_error->messages[ message_index ] != NULL ) && ( ( internal_error->messages[ message_index ] )[ string_index - 1 ] == (system_character_t) '.' ) ) { string_index -= 1; } reallocation = memory_reallocate( internal_error->messages[ message_index ], sizeof( system_character_t ) * ( message_size + 13 + 512 ) ); if( reallocation == NULL ) { memory_free( internal_error->messages[ message_index ] ); internal_error->messages[ message_index ] = NULL; goto on_error; } internal_error->messages[ message_index ] = (system_character_t *) reallocation; if( system_string_copy( &( ( internal_error->messages[ message_index ] )[ string_index ] ), _SYSTEM_STRING( " with error: " ), 13 ) == NULL ) { memory_free( internal_error->messages[ message_index ] ); internal_error->messages[ message_index ] = NULL; goto on_error; } internal_error->sizes[ message_index ] += 13; string_index += 13; print_count = libcerror_system_copy_string_from_error_number( &( ( internal_error->messages[ message_index ] )[ string_index ] ), 512, system_error_code ); if( print_count == -1 ) { goto on_error; } message_size += (size_t) print_count; internal_error->sizes[ message_index ] += print_count; } if( internal_error->sizes[ message_index ] >= LIBCERROR_MESSAGE_MAXIMUM_SIZE ) { internal_error->messages[ message_index ][ LIBCERROR_MESSAGE_MAXIMUM_SIZE - 4 ] = (system_character_t) '.'; internal_error->messages[ message_index ][ LIBCERROR_MESSAGE_MAXIMUM_SIZE - 3 ] = (system_character_t) '.'; internal_error->messages[ message_index ][ LIBCERROR_MESSAGE_MAXIMUM_SIZE - 2 ] = (system_character_t) '.'; internal_error->messages[ message_index ][ LIBCERROR_MESSAGE_MAXIMUM_SIZE - 1 ] = 0; internal_error->sizes[ message_index ] = (size_t) LIBCERROR_MESSAGE_MAXIMUM_SIZE; } return; on_error: #if defined( HAVE_WIDE_SYSTEM_CHARACTER ) if( system_format_string != NULL ) { memory_free( system_format_string ); } #endif return; }
/* Resizes an array * This function is not multi-thread safe acquire write lock before call * Returns 1 if successful or -1 on error */ int libcdata_internal_array_resize( libcdata_internal_array_t *internal_array, int number_of_entries, int (*entry_free_function)( intptr_t **entry, libcerror_error_t **error ), libcerror_error_t **error ) { void *reallocation = NULL; static char *function = "libcdata_internal_array_resize"; size_t entries_size = 0; int entry_iterator = 0; int number_of_allocated_entries = 0; int result = 1; if( internal_array == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid array.", function ); return( -1 ); } if( number_of_entries < 0 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_VALUE_LESS_THAN_ZERO, "%s: invalid number of entries value less than zero.", function ); return( -1 ); } if( number_of_entries > internal_array->number_of_allocated_entries ) { /* Pre-allocate in blocks of 16 entries */ number_of_allocated_entries = ( number_of_entries & ~( 15 ) ) + 16; #if SIZEOF_INT <= SIZEOF_SIZE_T if( (size_t) number_of_allocated_entries > (size_t) ( SSIZE_MAX / sizeof( intptr_t * ) ) ) #else if( number_of_allocated_entries > (int) ( SSIZE_MAX / sizeof( intptr_t * ) ) ) #endif { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_VALUE_EXCEEDS_MAXIMUM, "%s: invalid number of allocated entries value exceeds maximum.", function ); return( -1 ); } entries_size = sizeof( intptr_t * ) * number_of_allocated_entries; if( entries_size > (size_t) SSIZE_MAX ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_VALUE_EXCEEDS_MAXIMUM, "%s: invalid entries size value exceeds maximum.", function ); return( -1 ); } reallocation = memory_reallocate( internal_array->entries, entries_size ); if( reallocation == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_MEMORY, LIBCERROR_MEMORY_ERROR_INSUFFICIENT, "%s: unable to resize array entries.", function ); return( -1 ); } internal_array->entries = (intptr_t **) reallocation; if( memory_set( &( internal_array->entries[ internal_array->number_of_allocated_entries ] ), 0, sizeof( intptr_t * ) * ( number_of_allocated_entries - internal_array->number_of_allocated_entries ) ) == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_MEMORY, LIBCERROR_MEMORY_ERROR_SET_FAILED, "%s: unable to clear array entries.", function ); result = -1; } internal_array->number_of_allocated_entries = number_of_allocated_entries; internal_array->number_of_entries = number_of_entries; } else if( number_of_entries > internal_array->number_of_entries ) { internal_array->number_of_entries = number_of_entries; } else if( internal_array->entries != NULL ) { if( entry_free_function == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid entry free function.", function ); return( -1 ); } for( entry_iterator = number_of_entries; entry_iterator < internal_array->number_of_entries; entry_iterator++ ) { if( internal_array->entries[ entry_iterator ] != NULL ) { if( entry_free_function != NULL ) { if( entry_free_function( &( internal_array->entries[ entry_iterator ] ), error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED, "%s: unable to free array entry: %d.", function, entry_iterator ); result = -1; } } internal_array->entries[ entry_iterator ] = NULL; } } internal_array->number_of_entries = number_of_entries; } return( result ); }
/* Sets an error and adds a system specific error string if possible * Creates the error if necessary * The error domain and code are set only the first time and the error message is appended for back tracing */ void VARARGS( libcerror_system_set_error, libcerror_error_t **error, int error_domain, int error_code, uint32_t system_error_code, const char *, format_string ) { va_list argument_list; libcerror_internal_error_t *internal_error = NULL; libcstring_system_character_t *system_format_string = NULL; void *reallocation = NULL; size_t format_string_length = 0; size_t message_size = LIBCERROR_MESSAGE_INCREMENT_SIZE; size_t string_index = 0; int message_index = 0; int print_count = 0; if( error == NULL ) { return; } if( format_string == NULL ) { return; } format_string_length = libcstring_narrow_string_length( format_string ); if( format_string_length > message_size ) { message_size = ( ( format_string_length / LIBCERROR_MESSAGE_INCREMENT_SIZE ) + 1 ) * LIBCERROR_MESSAGE_INCREMENT_SIZE; } #if defined( LIBCSTRING_HAVE_WIDE_SYSTEM_CHARACTER ) do { reallocation = memory_reallocate( system_format_string, sizeof( libcstring_system_character_t ) * ( format_string_length + 1 ) ); if( reallocation == NULL ) { goto on_error; } system_format_string = (libcstring_system_character_t *) reallocation; #if defined( __BORLANDC__ ) || defined( _MSC_VER ) print_count = libcstring_wide_string_snwprintf( system_format_string, format_string_length + 1, L"%S", format_string ); #else print_count = libcstring_wide_string_snwprintf( system_format_string, format_string_length + 1, L"%s", format_string ); #endif if( print_count <= -1 ) { format_string_length += LIBCERROR_MESSAGE_INCREMENT_SIZE; } else if( ( (size_t) print_count > format_string_length ) || ( system_format_string[ print_count ] != 0 ) ) { format_string_length = (size_t) print_count; print_count = -1; } if( format_string_length >= LIBCERROR_MESSAGE_MAXIMUM_SIZE ) { goto on_error; } } while( print_count <= -1 ); #else system_format_string = (libcstring_system_character_t *) format_string; #endif #if defined( __BORLANDC__ ) || defined( _MSC_VER ) /* Rewrite %s to %S */ string_index = 0; while( string_index < format_string_length ) { if( system_format_string[ string_index ] == 0 ) { break; } else if( system_format_string[ string_index ] == (libcstring_system_character_t) '%' ) { string_index++; if( system_format_string[ string_index ] == (libcstring_system_character_t) 's' ) { system_format_string[ string_index ] = (libcstring_system_character_t) 'S'; } } string_index++; } #endif if( *error == NULL ) { internal_error = memory_allocate_structure( libcerror_internal_error_t ); if( internal_error == NULL ) { goto on_error; } internal_error->domain = error_domain; internal_error->code = error_code; internal_error->number_of_messages = 0; internal_error->messages = NULL; internal_error->sizes = NULL; *error = (libcerror_error_t *) internal_error; } else { internal_error = (libcerror_internal_error_t *) *error; } reallocation = memory_reallocate( internal_error->messages, sizeof( libcstring_system_character_t * ) * ( internal_error->number_of_messages + 1 ) ); if( reallocation == NULL ) { goto on_error; } internal_error->messages = (libcstring_system_character_t **) reallocation; reallocation = memory_reallocate( internal_error->sizes, sizeof( size_t ) * ( internal_error->number_of_messages + 1 ) ); if( reallocation == NULL ) { goto on_error; } internal_error->sizes = (size_t *) reallocation; message_index = internal_error->number_of_messages; internal_error->messages[ message_index ] = NULL; internal_error->sizes[ message_index ] = 0; internal_error->number_of_messages += 1; do { reallocation = memory_reallocate( internal_error->messages[ message_index ], sizeof( libcstring_system_character_t ) * message_size ); if( reallocation == NULL ) { memory_free( internal_error->messages[ message_index ] ); internal_error->messages[ message_index ] = NULL; break; } internal_error->messages[ message_index ] = (libcstring_system_character_t *) reallocation; VASTART( argument_list, const char *, format_string ); print_count = libcstring_system_string_vsprintf( internal_error->messages[ message_index ], message_size, system_format_string, argument_list ); VAEND( argument_list ); if( print_count <= -1 ) { message_size += LIBCERROR_MESSAGE_INCREMENT_SIZE; } else if( ( (size_t) print_count > message_size ) || ( ( internal_error->messages[ message_index ] )[ print_count ] != 0 ) ) { message_size = (size_t) ( print_count + 1 ); print_count = -1; } if( message_size >= LIBCERROR_MESSAGE_MAXIMUM_SIZE ) { memory_free( internal_error->messages[ message_index ] ); internal_error->messages[ message_index ] = NULL; internal_error->sizes[ message_index ] = 0; break; } internal_error->sizes[ message_index ] = (size_t) print_count + 1; } while( print_count <= -1 ); #if defined( LIBCSTRING_HAVE_WIDE_SYSTEM_CHARACTER ) memory_free( system_format_string ); system_format_string = NULL; #endif string_index = internal_error->sizes[ message_index ] - 1; if( ( internal_error->messages[ message_index ] != NULL ) && ( ( internal_error->messages[ message_index ] )[ string_index - 1 ] == (libcstring_system_character_t) '.' ) ) { string_index -= 1; } reallocation = memory_reallocate( internal_error->messages[ message_index ], sizeof( libcstring_system_character_t ) * ( message_size + 13 + 512 ) ); if( reallocation == NULL ) { memory_free( internal_error->messages[ message_index ] ); internal_error->messages[ message_index ] = NULL; goto on_error; } internal_error->messages[ message_index ] = (libcstring_system_character_t *) reallocation; if( libcstring_system_string_copy( &( ( internal_error->messages[ message_index ] )[ string_index ] ), _LIBCSTRING_SYSTEM_STRING( " with error: " ), 13 ) == NULL ) { memory_free( internal_error->messages[ message_index ] ); internal_error->messages[ message_index ] = NULL; goto on_error; } internal_error->sizes[ message_index ] += 13; string_index += 13; print_count = libcerror_system_copy_string_from_error_number( &( ( internal_error->messages[ message_index ] )[ string_index ] ), 512, system_error_code ); if( print_count == -1 ) { goto on_error; } message_size += (size_t) print_count; if( message_size >= LIBCERROR_MESSAGE_MAXIMUM_SIZE ) { memory_free( internal_error->messages[ message_index ] ); internal_error->messages[ message_index ] = NULL; internal_error->sizes[ message_index ] = 0; goto on_error; } internal_error->sizes[ message_index ] += print_count; return; on_error: #if defined( LIBCSTRING_HAVE_WIDE_SYSTEM_CHARACTER ) if( system_format_string != NULL ) { memory_free( system_format_string ); } #endif if( ( *error == NULL ) && ( internal_error != NULL ) ) { memory_free( internal_error ); } return; }