/* Creates a cluster block vector * Make sure the value cluster_block_vector is referencing, is set to NULL * Returns 1 if successful or -1 on error */ int libfsntfs_cluster_block_vector_initialize( libfdata_vector_t **cluster_block_vector, libfsntfs_io_handle_t *io_handle, libfsntfs_attribute_t *attribute, libcerror_error_t **error ) { libfsntfs_data_run_t *data_run = NULL; static char *function = "libfsntfs_cluster_block_vector_initialize"; int attribute_index = 0; int entry_index = 0; int number_of_entries = 0; int segment_index = 0; uint16_t attribute_data_flags = 0; if( cluster_block_vector == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid cluster block vector.", function ); return( -1 ); } if( io_handle == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid IO handle.", function ); return( -1 ); } if( attribute == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid attribute.", function ); return( -1 ); } if( libfsntfs_attribute_get_data_flags( attribute, &attribute_data_flags, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve attribute data flags.", function ); goto on_error; } if( ( attribute_data_flags & LIBFSNTFS_ATTRIBUTE_FLAG_COMPRESSION_MASK ) != 0 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE, "%s: unsupported compressed attribute data.", function ); goto on_error; } if( libfdata_vector_initialize( cluster_block_vector, (size64_t) io_handle->cluster_block_size, (intptr_t *) io_handle, NULL, NULL, (int (*)(intptr_t *, intptr_t *, libfdata_vector_t *, libfcache_cache_t *, int, int, off64_t, size64_t, uint32_t, uint8_t, libcerror_error_t **)) &libfsntfs_cluster_block_read_element_data, NULL, LIBFDATA_DATA_HANDLE_FLAG_NON_MANAGED, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, "%s: unable to create cluster block vector.", function ); goto on_error; } while( attribute != NULL ) { /* TODO check VCN of previous attribute? */ if( libfsntfs_attribute_get_number_of_data_runs( attribute, &number_of_entries, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve attribute: %d number of data runs.", function, attribute_index ); goto on_error; } for( entry_index = 0; entry_index < number_of_entries; entry_index++ ) { if( libfsntfs_attribute_get_data_run_by_index( attribute, entry_index, &data_run, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve attribute: %d data runs array entry: %d.", function, attribute_index, entry_index ); goto on_error; } if( data_run == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_VALUE_MISSING, "%s: missing attribute: %d data run: %d.", function, attribute_index, entry_index ); goto on_error; } if( libfdata_vector_append_segment( *cluster_block_vector, &segment_index, 0, data_run->start_offset, data_run->size, data_run->range_flags, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_APPEND_FAILED, "%s: unable to append attribute: %d data run: %d vector segment.", function, attribute_index, entry_index ); goto on_error; } } attribute_index++; if( libfsntfs_attribute_get_chained_attribute( attribute, &attribute, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve chained attribute: %d.", function, attribute_index ); goto on_error; } } return( 1 ); on_error: if( *cluster_block_vector != NULL ) { libfdata_vector_free( cluster_block_vector, NULL ); } return( -1 ); }
/* Creates a data stream * Make sure the value data_stream is referencing, is set to NULL * Returns 1 if successful or -1 on error */ int libfsntfs_data_stream_initialize( libfsntfs_data_stream_t **data_stream, libbfio_handle_t *file_io_handle, libfsntfs_io_handle_t *io_handle, libfsntfs_attribute_t *data_attribute, libcerror_error_t **error ) { libfsntfs_internal_data_stream_t *internal_data_stream = NULL; static char *function = "libfsntfs_data_stream_initialize"; int number_of_data_runs = 0; if( data_stream == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid data stream.", function ); return( -1 ); } if( *data_stream != NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET, "%s: invalid data stream value already set.", function ); return( -1 ); } if( data_attribute == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid data attribute.", function ); return( -1 ); } internal_data_stream = memory_allocate_structure( libfsntfs_internal_data_stream_t ); if( internal_data_stream == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, "%s: unable to create data stream.", function ); return( -1 ); } if( memory_set( internal_data_stream, 0, sizeof( libfsntfs_internal_data_stream_t ) ) == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_MEMORY, LIBCERROR_MEMORY_ERROR_SET_FAILED, "%s: unable to clear data stream.", function ); memory_free( internal_data_stream ); return( -1 ); } if( libfsntfs_attribute_get_number_of_data_runs( data_attribute, &number_of_data_runs, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve number of data runs.", function ); goto on_error; } if( libfsntfs_cluster_block_stream_initialize( &( internal_data_stream->data_cluster_block_stream ), io_handle, data_attribute, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, "%s: unable to create data cluster block stream.", function ); goto on_error; } if( libfsntfs_attribute_get_data_size( data_attribute, &( internal_data_stream->data_size ), error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve data attribute data size.", function ); return( -1 ); } internal_data_stream->file_io_handle = file_io_handle; internal_data_stream->data_attribute = data_attribute; *data_stream = (libfsntfs_data_stream_t *) internal_data_stream; return( 1 ); on_error: if( internal_data_stream != NULL ) { memory_free( internal_data_stream ); } return( -1 ); }