?? ewfcommon.c
字號:
} fprintf( ewfcommon_process_status_stream, " completion" ); ewfcommon_timestamp_fprint( ewfcommon_process_status_stream, (time_t) seconds_remaining ); ewfcommon_bytes_per_second_fprint( ewfcommon_process_status_stream, bytes_total, seconds_total ); fprintf( ewfcommon_process_status_stream, ".\n" ); } fprintf( ewfcommon_process_status_stream, "\n" ); }}/* Prints status information of the stream process */void ewfcommon_stream_process_status_fprint( uint64_t bytes_read, uint64_t bytes_total ){ time_t timestamp_current = 0; uint64_t seconds_current = 0; if( ewfcommon_process_status_stream == NULL ) { return; } if( ewfcommon_process_status_string == NULL ) { return; } timestamp_current = time( NULL ); if( timestamp_current > ewfcommon_process_status_timestamp_last ) { /* Update state * - if no status was printed before * - or input has grown > 10 Mb * - or the last update was 30 seconds ago */ if( ( ewfcommon_process_status_last_bytes_total == 0 ) || ( bytes_read > ( ewfcommon_process_status_last_bytes_total + ( 10 * 1024 * 1024 ) ) ) || ( ( timestamp_current - ewfcommon_process_status_timestamp_last ) > 30 ) ) { ewfcommon_process_status_timestamp_last = timestamp_current; ewfcommon_process_status_last_bytes_total = bytes_read; fprintf( ewfcommon_process_status_stream, "Status: %" PRIs_EWF "", ewfcommon_process_status_string ); ewfcommon_bytes_fprint( ewfcommon_process_status_stream, bytes_read ); fprintf( ewfcommon_process_status_stream, "\n" ); seconds_current = (uint64_t) difftime( timestamp_current, ewfcommon_process_status_timestamp_start ); fprintf( ewfcommon_process_status_stream, " " ); ewfcommon_timestamp_fprint( ewfcommon_process_status_stream, (time_t) seconds_current ); ewfcommon_bytes_per_second_fprint( ewfcommon_process_status_stream, bytes_read, seconds_current ); fprintf( ewfcommon_process_status_stream, ".\n\n" ); } }}/* Prints summary information of the process */void ewfcommon_process_summary_fprint( FILE *stream, LIBEWF_CHAR *string, int64_t byte_count, time_t timestamp_start, time_t timestamp_end ){ time_t timestamp_acquiry = 0; uint64_t seconds_acquiry = 0; if( stream == NULL ) { return; } if( string == NULL ) { return; } timestamp_acquiry = timestamp_end - timestamp_start; seconds_acquiry = (uint64_t) difftime( timestamp_end, timestamp_start ); fprintf( stream, "%" PRIs_EWF ":", string ); ewfcommon_bytes_fprint( stream, byte_count ); ewfcommon_timestamp_fprint( stream, timestamp_acquiry ); ewfcommon_bytes_per_second_fprint( stream, byte_count, seconds_acquiry ); fprintf( stream, ".\n" );}/* Reads data from a file descriptor into the chunk cache * Returns the amount of bytes read, 0 if at end of input, or -1 on error */int32_t ewfcommon_read_input( LIBEWF_HANDLE *handle, int file_descriptor, EWF_CHUNK *buffer, uint64_t size, int64_t total_read_count, uint64_t total_input_size, uint8_t read_error_retry, uint32_t sector_error_granularity, uint8_t wipe_block_on_read_error, uint8_t seek_on_error ){#if defined(HAVE_STRERROR_R) || defined(HAVE_STRERROR) CHAR_T *error_string = NULL;#endif ssize_t read_count = 0; size_t read_size = 0; size_t bytes_to_read = 0; size_t read_remaining_bytes = 0; size_t error_remaining_bytes = 0; int64_t current_read_offset = 0; int64_t current_calculated_offset = 0; int64_t chunk_amount = 0; int64_t buffer_offset = 0; uint64_t error2_sector = 0; int32_t read_amount_of_errors = 0; uint32_t chunk_size = 0; uint32_t bytes_per_sector = 0; uint32_t read_error_offset = 0; uint32_t error_skip_bytes = 0; uint32_t error_granularity_offset = 0; uint32_t error2_amount_of_sectors = 0; uint32_t byte_error_granularity = 0; if( handle == NULL ) { LIBEWF_WARNING_PRINT( "ewfcommon_read_input: invalid handle.\n" ); return( -1 ); } if( buffer == NULL ) { LIBEWF_WARNING_PRINT( "ewfcommon_read_input: invalid read buffer.\n" ); return( -1 ); } chunk_size = libewf_get_chunk_size( handle ); if( chunk_size == 0 ) { LIBEWF_WARNING_PRINT( "ewfcommon_read_input: unable to determine chunk media.\n" ); return( -1 ); } if( size > (uint64_t) INT64_MAX ) { LIBEWF_WARNING_PRINT( "ewfcommon_read_input: invalid size - size larger than 2^63 not supported.\n" ); return( -1 ); } if( file_descriptor == -1 ) { LIBEWF_WARNING_PRINT( "ewfcommon_read_input: invalid file descriptor.\n" ); return( -1 ); } if( total_read_count <= -1 ) { LIBEWF_WARNING_PRINT( "ewfcommon_read_input: invalid total read count.\n" ); return( -1 ); } bytes_per_sector = libewf_get_bytes_per_sector( handle ); if( bytes_per_sector == 0 ) { LIBEWF_WARNING_PRINT( "ewfcommon_read_input: invalid amount of bytes per sector.\n" ); return( -1 ); } chunk_amount = libewf_get_write_amount_of_chunks( handle ); if( ( chunk_amount <= -1 ) || ( chunk_amount > (int64_t) UINT32_MAX ) ) { LIBEWF_WARNING_PRINT( "ewfcommon_read_input: invalid amount of chunks written.\n" ); return( -1 ); } while( size > 0 ) { /* Determine the amount of bytes to read from the input * Read as much as possible in chunk sizes */ if( size < (uint64_t) chunk_size ) { read_size = (uint32_t) size; } else { read_size = chunk_size; } bytes_to_read = read_size; while( read_amount_of_errors <= read_error_retry ) { read_count = libewf_common_read( file_descriptor, &buffer[ buffer_offset + read_error_offset ], bytes_to_read ); LIBEWF_VERBOSE_PRINT( "ewfcommon_read_input: read chunk: %" PRIi64 " with size: %zi.\n", ( chunk_amount + 1 ), read_count ); current_calculated_offset = (off_t) ( total_read_count + buffer_offset + read_error_offset ); if( read_count <= -1 ) {#if defined(HAVE_STRERROR_R) || defined(HAVE_STRERROR) if( ( errno == ESPIPE ) || ( errno == EPERM ) || ( errno == ENXIO ) || ( errno == ENODEV ) ) { error_string = libewf_common_strerror( errno ); if( error_string != NULL ) { LIBEWF_WARNING_PRINT( "ewfcommon_read_input: error reading data: %s.\n", error_string ); libewf_common_free( error_string ); } return( -1 ); }#else if( errno == ESPIPE ) { LIBEWF_WARNING_PRINT( "ewfcommon_read_input: error reading data: Invalid seek.\n" ); return( -1 ); } else if( errno == EPERM ) { LIBEWF_WARNING_PRINT( "ewfcommon_read_input: error reading data: Operation not permitted.\n" ); return( -1 ); } else if( errno == ENXIO ) { LIBEWF_WARNING_PRINT( "ewfcommon_read_input: error reading data: No such device or address.\n" ); return( -1 ); } else if( errno == ENODEV ) { LIBEWF_WARNING_PRINT( "ewfcommon_read_input: error reading data: No such device.\n" ); return( -1 ); }#endif if( seek_on_error == 1 ) { current_read_offset = libewf_common_lseek( file_descriptor, 0, SEEK_CUR ); if( current_read_offset != current_calculated_offset ) { LIBEWF_VERBOSE_PRINT( "ewfcommon_read_input: correcting offset drift current: %jd, calculated: %jd.\n", current_read_offset, current_calculated_offset ); if( current_read_offset < current_calculated_offset ) { LIBEWF_WARNING_PRINT( "ewfcommon_read_input: unable to correct offset drift.\n" ); return( -1 ); } read_count = (ssize_t) ( current_read_offset - current_calculated_offset ); read_error_offset += read_count; bytes_to_read -= read_count; } } } else { /* The last read is OK, correct read_count */ if( read_count == (int32_t) bytes_to_read ) { read_count = read_error_offset + bytes_to_read; } /* The entire read is OK */ if( read_count == (int32_t) read_size ) { break; } /* If no end of input can be determined */ if( total_input_size == 0 ) { /* If some bytes were read it is possible that the end of the input reached */ if( read_count > 0 ) { return( (int32_t) ( buffer_offset + read_count ) ); } } else { /* Check if the end of the input was reached */ if( ( total_read_count + buffer_offset + read_count ) >= (int64_t) total_input_size ) { break; } } /* No bytes were read */ if( read_count == 0 ) { return( 0 ); } LIBEWF_VERBOSE_PRINT( "ewfcommon_read_input: read error at offset %jd after reading %zi bytes.\n", current_calculated_offset, read_count ); /* There was a read error at a certain offset */ read_error_offset += read_count; bytes_to_read -= read_count; } read_amount_of_errors++; if( read_amount_of_errors > read_error_retry ) { if( seek_on_error == 0 ) { LIBEWF_VERBOSE_PRINT( "ewfcommon_read_input: unable to handle more input.\n" ); return( 0 ); } current_calculated_offset = total_read_count + buffer_offset; /* Check if last chunk is smaller than the chunk size and take corrective measures */ if( ( total_input_size != 0 ) && ( ( current_calculated_offset + chunk_size ) > (int64_t) total_input_size ) ) { read_remaining_bytes = (size_t) ( total_input_size - current_calculated_offset ); } else { read_remaining_bytes = (size_t) chunk_size; } if( read_remaining_bytes > (size_t) SSIZE_MAX ) { LIBEWF_VERBOSE_PRINT( "ewfcommon_read_input: invalid remaining bytes value exceeds maximum.\n" ); return( -1 ); } byte_error_granularity = sector_error_granularity * bytes_per_sector; error_remaining_bytes = read_remaining_bytes - read_error_offset; error2_sector = current_calculated_offset; error_granularity_offset = ( read_error_offset / byte_error_granularity ) * byte_error_granularity; error_skip_bytes = ( error_granularity_offset + byte_error_granularity ) - read_error_offset; if( wipe_block_on_read_error == 1 ) { LIBEWF_VERBOSE_PRINT( "ewfcommon_read_input: wiping block of %" PRIu32 " bytes at offset %" PRIu32 ".\n", byte_error_granularity, error_granularity_offset ); if( libewf_common_memset( &buffer[ error_granularity_offset ], 0, byte_error_granularity ) == NULL ) { LIBEWF_WARNING_PRINT( "ewfcommon_read_input: unable to wipe data in chunk on error.\n" ); return( -1 ); } error2_sector += error_granularity_offset; error2_amount_of_sectors = byte_error_granularity; } else { error2_sector += read_error_offset; error2_amount_of_sectors = error_skip_bytes; } error2_sector /= bytes_per_sector; error2_amount_of_sectors /= bytes_per_sector; if( libewf_add_acquiry_error( handle, error2_sector, error2_amount_of_sectors ) != 1 ) { LIBEWF_WARNING_PRINT( "ewfcommon_read_input: unable to add acquiry read errror sectors.\n" ); return( -1 ); } LIBEWF_VERBOSE_PRINT( "ewfcommon_read_input: adding error2: %" PRIu32 " sector: %" PRIu64 ", count: %" PRIu32 ".\n", ( (LIBEWF_INTERNAL_HANDLE *) handle )->acquiry_amount_of_errors, error2_sector, error2_amount_of_sectors ); LIBEWF_VERBOSE_PRINT( "ewfcommon_read_input: skipping %" PRIu32 " bytes.\n", error_skip_bytes ); /* At the end of the input */ if( ( total_input_size != 0 ) && ( ( current_calculated_offset + read_remaining_bytes ) >= (int64_t) total_input_size ) ) { LIBEWF_VERBOSE_PRINT( "ewfcommon_read_input: at end of input no remaining bytes to read from chunk.\n" ); read_count = (ssize_t) read_remaining_bytes; break; } if( libewf_common_lseek( file_descriptor, error_skip_bytes, SEEK_CUR ) == -1 ) {#if defined(HAVE_STRERROR_R) || defined(HAVE_STRERROR) error_string = libewf_common_strerror( errno ); if( error_string != NULL ) { LIBEWF_WARNING_PRINT( "ewfcommon_read_input: unable skip %" PRIu32 " bytes after sector with error - %s.\n", error_skip_bytes, error_string ); libewf_common_free( error_string ); }#else LIBEWF_WARNING_PRINT( "ewfcommon_read_input: unable skip %" PRIu32 " bytes after sector with error.\n", error_skip_bytes );#endif return( -1 ); } /* If error granularity skip is still within the chunk */ if( error_remaining_bytes > byte_error_granularity ) { bytes_to_read = error_remaining_bytes - error_skip_bytes; read_error_offset += error_skip_bytes; read_amount_of_errors = 0; LIBEWF_VERBOSE_PRINT( "ewfcommon_read_input: remaining to read from chunk %" PRIu32 " bytes.\n", bytes_to_read ); } else { read_count = (ssize_t) read_remaining_bytes; LIBEWF_VERBOSE_PRINT( "ewfcommon_read_input: no remaining bytes to read from chunk.\n" ); break; } } } size -= read_count; buffer_offset += read_count; /* At the end of the input */ if( ( total_input_size != 0 ) && ( ( total_read_count + buffer_offset ) >= (int64_t) total_input_size ) ) { break; } } return( (int32_t) buffer_offset );}/* Reads the data (to nowhere) * This processes the entire file for the MD5 calculation with status information * Returns a -1 on error, the amount of bytes read on success */int64_t ewfcommon_read( LIBEWF_HANDLE *handle, uint8_t calculate_sha1, void (*callback)( uint64_t bytes_read, uint64_t bytes_total ) ){ EWFSHA1_CONTEXT sha1_context; LIBEWF_CHAR *sha1_hash_string = NULL;#ifndef HAVE_CHUNK_CACHE_PASSTHROUGH uint8_t *data = NULL;#endif off_t read_offset = 0; ssize_t read_count = 0; size_t size = 0; size_t buffer_size = 0; int64_t total_read_count = 0; uint64_t media_size = 0; uint32_t chunk_size = 0; if( handle == NULL ) { LIBEWF_WARNING_PRINT( "ewfcommon_read: invalid handle.\n" );
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -