/* Closes the info handle * Returns the 0 if succesful or -1 on error */ int info_handle_close( info_handle_t *info_handle, libcerror_error_t **error ) { static char *function = "info_handle_close"; if( info_handle == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid info handle.", function ); return( -1 ); } if( libvshadow_volume_close( info_handle->input_volume, error ) != 0 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_IO, LIBCERROR_IO_ERROR_CLOSE_FAILED, "%s: unable to close input volume.", function ); return( -1 ); } return( 0 ); }
/* Tests single open and close of a volume * Returns 1 if successful, 0 if not or -1 on error */ int vshadow_test_single_open_close_volume( libcstring_system_character_t *filename, int access_flags, int expected_result ) { libcerror_error_t *error = NULL; libvshadow_volume_t *volume = NULL; static char *function = "vshadow_test_single_open_close_volume"; int result = 0; if( libvshadow_volume_initialize( &volume, &error ) != 1 ) { libcerror_error_set( &error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, "%s: unable to create volume.", function ); return( -1 ); } #if defined( LIBCSTRING_HAVE_WIDE_SYSTEM_CHARACTER ) result = libvshadow_volume_open_wide( volume, filename, access_flags, &error ); #else result = libvshadow_volume_open( volume, filename, access_flags, &error ); #endif if( result == 1 ) { if( libvshadow_volume_close( volume, &error ) != 0 ) { libcerror_error_set( &error, LIBCERROR_ERROR_DOMAIN_IO, LIBCERROR_IO_ERROR_CLOSE_FAILED, "%s: unable to close volume.", function ); result = -1; } } if( libvshadow_volume_free( &volume, &error ) != 1 ) { libcerror_error_set( &error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED, "%s: unable to free volume.", function ); result = -1; } result = ( expected_result == result ); if( result == 1 ) { fprintf( stdout, "(PASS)" ); } else { fprintf( stdout, "(FAIL)" ); } fprintf( stdout, "\n" ); if( error != NULL ) { if( result != 1 ) { libcerror_error_backtrace_fprint( error, stderr ); } libcerror_error_free( &error ); } return( result ); }
int main( int argc, char * const argv[] ) #endif { libvshadow_error_t *error = NULL; libvshadow_store_t *store = NULL; libvshadow_volume_t *volume = NULL; size64_t volume_size = 0; int number_of_stores = 0; if( argc < 2 ) { fprintf( stderr, "Missing filename.\n" ); return( EXIT_FAILURE ); } #if defined( HAVE_DEBUG_OUTPUT ) && defined( VSHADOW_TEST_SEEK_VERBOSE ) libvshadow_notify_set_verbose( 1 ); libvshadow_notify_set_stream( stderr, NULL ); #endif /* Initialization */ if( libvshadow_volume_initialize( &volume, &error ) != 1 ) { fprintf( stderr, "Unable to create volume.\n" ); goto on_error; } #if defined( LIBCSTRING_HAVE_WIDE_SYSTEM_CHARACTER ) if( libvshadow_volume_open_wide( volume, argv[ 1 ], LIBVSHADOW_OPEN_READ, &error ) != 1 ) #else if( libvshadow_volume_open( volume, argv[ 1 ], LIBVSHADOW_OPEN_READ, &error ) != 1 ) #endif { fprintf( stderr, "Unable to open volume.\n" ); goto on_error; } if( libvshadow_volume_get_number_of_stores( volume, &number_of_stores, &error ) != 1 ) { fprintf( stderr, "Unable to retrieve number of stores.\n" ); goto on_error; } if( libvshadow_volume_get_store( volume, number_of_stores - 1, &store, &error ) != 1 ) { fprintf( stderr, "Unable to retrieve store: %d.\n", number_of_stores - 1 ); goto on_error; } if( libvshadow_volume_get_size( volume, &volume_size, &error ) != 1 ) { fprintf( stderr, "Unable to retrieve volume size.\n" ); goto on_error; } if( volume_size > (size64_t) INT64_MAX ) { fprintf( stderr, "Volume size exceeds maximum.\n" ); goto on_error; } /* Test: SEEK_SET offset: 0 * Expected result: 0 */ if( vshadow_test_seek_offset( store, 0, SEEK_SET, 0 ) != 1 ) { fprintf( stderr, "Unable to test seek offset.\n" ); goto on_error; } /* Test: SEEK_SET offset: <volume_size> * Expected result: <volume_size> */ if( vshadow_test_seek_offset( store, (off64_t) volume_size, SEEK_SET, (off64_t) volume_size ) != 1 ) { fprintf( stderr, "Unable to test seek offset.\n" ); goto on_error; } /* Test: SEEK_SET offset: <volume_size / 5> * Expected result: <volume_size / 5> */ if( vshadow_test_seek_offset( store, (off64_t) ( volume_size / 5 ), SEEK_SET, (off64_t) ( volume_size / 5 ) ) != 1 ) { fprintf( stderr, "Unable to test seek offset.\n" ); goto on_error; } /* Test: SEEK_SET offset: <volume_size + 987> * Expected result: <volume_size + 987> */ if( vshadow_test_seek_offset( store, (off64_t) ( volume_size + 987 ), SEEK_SET, (off64_t) ( volume_size + 987 ) ) != 1 ) { fprintf( stderr, "Unable to test seek offset.\n" ); goto on_error; } /* Test: SEEK_SET offset: -987 * Expected result: -1 */ if( vshadow_test_seek_offset( store, -987, SEEK_SET, -1 ) != 1 ) { fprintf( stderr, "Unable to test seek offset.\n" ); goto on_error; } /* Test: SEEK_CUR offset: 0 * Expected result: <volume_size + 987> */ if( vshadow_test_seek_offset( store, 0, SEEK_CUR, (off64_t) ( volume_size + 987 ) ) != 1 ) { fprintf( stderr, "Unable to test seek offset.\n" ); goto on_error; } /* Test: SEEK_CUR offset: <-1 * (volume_size + 987)> * Expected result: 0 */ if( vshadow_test_seek_offset( store, -1 * (off64_t) ( volume_size + 987 ), SEEK_CUR, 0 ) != 1 ) { fprintf( stderr, "Unable to test seek offset.\n" ); goto on_error; } /* Test: SEEK_CUR offset: <volume_size / 3> * Expected result: <volume_size / 3> */ if( vshadow_test_seek_offset( store, (off64_t) ( volume_size / 3 ), SEEK_CUR, (off64_t) ( volume_size / 3 ) ) != 1 ) { fprintf( stderr, "Unable to test seek offset.\n" ); goto on_error; } if( volume_size == 0 ) { /* Test: SEEK_CUR offset: <-2 * (volume_size / 3)> * Expected result: 0 */ if( vshadow_test_seek_offset( store, -2 * (off64_t) ( volume_size / 3 ), SEEK_CUR, 0 ) != 1 ) { fprintf( stderr, "Unable to test seek offset.\n" ); goto on_error; } } else { /* Test: SEEK_CUR offset: <-2 * (volume_size / 3)> * Expected result: -1 */ if( vshadow_test_seek_offset( store, -2 * (off64_t) ( volume_size / 3 ), SEEK_CUR, -1 ) != 1 ) { fprintf( stderr, "Unable to test seek offset.\n" ); goto on_error; } } /* Test: SEEK_END offset: 0 * Expected result: <volume_size> */ if( vshadow_test_seek_offset( store, 0, SEEK_END, (off64_t) volume_size ) != 1 ) { fprintf( stderr, "Unable to test seek offset.\n" ); goto on_error; } /* Test: SEEK_END offset: <-1 * volume_size> * Expected result: 0 */ if( vshadow_test_seek_offset( store, -1 * (off64_t) volume_size, SEEK_END, 0 ) != 1 ) { fprintf( stderr, "Unable to test seek offset.\n" ); goto on_error; } /* Test: SEEK_END offset: <-1 * (volume_size / 4)> * Expected result: <volume_size - (volume_size / 4)> */ if( vshadow_test_seek_offset( store, -1 * (off64_t) ( volume_size / 4 ), SEEK_END, (off64_t) volume_size - (off64_t) ( volume_size / 4 ) ) != 1 ) { fprintf( stderr, "Unable to test seek offset.\n" ); goto on_error; } /* Test: SEEK_END offset: 542 * Expected result: <volume_size + 542> */ if( vshadow_test_seek_offset( store, 542, SEEK_END, (off64_t) ( volume_size + 542 ) ) != 1 ) { fprintf( stderr, "Unable to test seek offset.\n" ); goto on_error; } /* Test: SEEK_END offset: <-1 * (volume_size + 542)> * Expected result: -1 */ if( vshadow_test_seek_offset( store, -1 * (off64_t) ( volume_size + 542 ), SEEK_END, -1 ) != 1 ) { fprintf( stderr, "Unable to test seek offset.\n" ); goto on_error; } /* Test: UNKNOWN (88) offset: 0 * Expected result: -1 */ if( vshadow_test_seek_offset( store, 0, 88, -1 ) != 1 ) { fprintf( stderr, "Unable to test seek offset.\n" ); goto on_error; } /* Clean up */ if( libvshadow_store_free( &store, &error ) != 1 ) { fprintf( stderr, "Unable to free store.\n" ); goto on_error; } if( libvshadow_volume_close( volume, &error ) != 0 ) { fprintf( stderr, "Unable to close volume.\n" ); goto on_error; } if( libvshadow_volume_free( &volume, &error ) != 1 ) { fprintf( stderr, "Unable to free volume.\n" ); goto on_error; } return( EXIT_SUCCESS ); on_error: if( error != NULL ) { libvshadow_error_backtrace_fprint( error, stderr ); libvshadow_error_free( &error ); } if( store != NULL ) { libvshadow_store_free( &store, NULL ); } if( volume != NULL ) { libvshadow_volume_close( volume, NULL ); libvshadow_volume_free( &volume, NULL ); } return( EXIT_FAILURE ); }
/* Frees a volume * Returns 1 if successful or -1 on error */ int libvshadow_volume_free( libvshadow_volume_t **volume, libcerror_error_t **error ) { libvshadow_internal_volume_t *internal_volume = NULL; static char *function = "libvshadow_volume_free"; int result = 1; if( volume == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid volume.", function ); return( -1 ); } if( *volume != NULL ) { internal_volume = (libvshadow_internal_volume_t *) *volume; if( internal_volume->file_io_handle != NULL ) { if( libvshadow_volume_close( *volume, error ) != 0 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_IO, LIBCERROR_IO_ERROR_CLOSE_FAILED, "%s: unable to close volume.", function ); result = -1; } } *volume = NULL; #if defined( HAVE_LIBVSHADOW_MULTI_THREAD_SUPPORT ) if( libcthreads_read_write_lock_free( &( internal_volume->read_write_lock ), error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED, "%s: unable to free read/write lock.", function ); result = -1; } #endif if( libcdata_array_free( &( internal_volume->store_descriptors_array ), (int (*)(intptr_t **, libcerror_error_t **)) &libvshadow_store_descriptor_free, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED, "%s: unable to free store descriptors array.", function ); result = -1; } if( libvshadow_io_handle_free( &( internal_volume->io_handle ), error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED, "%s: unable to free IO handle.", function ); result = -1; } memory_free( internal_volume ); } return( result ); }