mirror of
https://github.com/aaru-dps/libaaruformat.git
synced 2025-12-16 19:24:40 +00:00
Add support for resuming images.
This commit is contained in:
@@ -67,7 +67,7 @@ AARU_EXPORT int AARU_CALL aaruf_identify(const char *filename);
|
|||||||
|
|
||||||
AARU_EXPORT int AARU_CALL aaruf_identify_stream(FILE *image_stream);
|
AARU_EXPORT int AARU_CALL aaruf_identify_stream(FILE *image_stream);
|
||||||
|
|
||||||
AARU_EXPORT void *AARU_CALL aaruf_open(const char *filepath);
|
AARU_EXPORT void *AARU_CALL aaruf_open(const char *filepath, bool resume_mode, char *options);
|
||||||
|
|
||||||
AARU_EXPORT void *AARU_CALL aaruf_create(const char *filepath, uint32_t media_type, uint32_t sector_size,
|
AARU_EXPORT void *AARU_CALL aaruf_create(const char *filepath, uint32_t media_type, uint32_t sector_size,
|
||||||
uint64_t user_sectors, uint64_t negative_sectors, uint64_t overflow_sectors,
|
uint64_t user_sectors, uint64_t negative_sectors, uint64_t overflow_sectors,
|
||||||
|
|||||||
51
src/open.c
51
src/open.c
@@ -122,7 +122,8 @@ static void cleanup_open_failure(aaruformat_context *ctx)
|
|||||||
* @warning Some memory allocations (version strings) are optional and failure doesn't
|
* @warning Some memory allocations (version strings) are optional and failure doesn't
|
||||||
* prevent opening, but may affect functionality that depends on version information.
|
* prevent opening, but may affect functionality that depends on version information.
|
||||||
*/
|
*/
|
||||||
AARU_EXPORT void AARU_CALL *aaruf_open(const char *filepath) // NOLINT(readability-function-size)
|
AARU_EXPORT void AARU_CALL *aaruf_open(const char *filepath, const bool resume_mode,
|
||||||
|
const char *options) // NOLINT(readability-function-size)
|
||||||
{
|
{
|
||||||
aaruformat_context *ctx = NULL;
|
aaruformat_context *ctx = NULL;
|
||||||
int error_no = 0;
|
int error_no = 0;
|
||||||
@@ -157,6 +158,9 @@ AARU_EXPORT void AARU_CALL *aaruf_open(const char *filepath) // NOLINT(readabil
|
|||||||
memset(ctx, 0, sizeof(aaruformat_context));
|
memset(ctx, 0, sizeof(aaruformat_context));
|
||||||
|
|
||||||
TRACE("Opening file %s", filepath);
|
TRACE("Opening file %s", filepath);
|
||||||
|
if(resume_mode)
|
||||||
|
ctx->imageStream = fopen(filepath, "a+b");
|
||||||
|
else
|
||||||
ctx->imageStream = fopen(filepath, "rb");
|
ctx->imageStream = fopen(filepath, "rb");
|
||||||
|
|
||||||
if(ctx->imageStream == NULL)
|
if(ctx->imageStream == NULL)
|
||||||
@@ -488,6 +492,51 @@ AARU_EXPORT void AARU_CALL *aaruf_open(const char *filepath) // NOLINT(readabil
|
|||||||
ctx->library_major_version = LIBAARUFORMAT_MAJOR_VERSION;
|
ctx->library_major_version = LIBAARUFORMAT_MAJOR_VERSION;
|
||||||
ctx->library_minor_version = LIBAARUFORMAT_MINOR_VERSION;
|
ctx->library_minor_version = LIBAARUFORMAT_MINOR_VERSION;
|
||||||
|
|
||||||
|
if(!resume_mode)
|
||||||
|
{
|
||||||
TRACE("Exiting aaruf_open() = %p", ctx);
|
TRACE("Exiting aaruf_open() = %p", ctx);
|
||||||
return ctx;
|
return ctx;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse the options
|
||||||
|
TRACE("Parsing options");
|
||||||
|
const aaru_options parsed_options = parse_options(options);
|
||||||
|
|
||||||
|
ctx->header.lastWrittenTime = get_filetime_uint64();
|
||||||
|
ctx->image_info.LastModificationTime = ctx->header.lastWrittenTime;
|
||||||
|
|
||||||
|
// Calculate aligned next block position
|
||||||
|
fseek(ctx->imageStream, 0, SEEK_END);
|
||||||
|
const uint64_t alignment_mask = (1ULL << ctx->user_data_ddt_header.blockAlignmentShift) - 1;
|
||||||
|
ctx->next_block_position = ftell(ctx->imageStream); // Start just after the header
|
||||||
|
ctx->next_block_position = ctx->next_block_position + alignment_mask & ~alignment_mask;
|
||||||
|
|
||||||
|
TRACE("Data blocks will start at position %" PRIu64, ctx->next_block_position);
|
||||||
|
|
||||||
|
// Position file pointer at the data start position
|
||||||
|
if(fseek(ctx->imageStream, ctx->next_block_position, SEEK_SET) != 0)
|
||||||
|
{
|
||||||
|
FATAL("Could not seek to data start position");
|
||||||
|
errno = AARUF_ERROR_CANNOT_CREATE_FILE;
|
||||||
|
TRACE("Exiting aaruf_open() = NULL");
|
||||||
|
cleanup_open_failure(ctx);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply applicable options (we cannot change table or alignment options resuming)
|
||||||
|
ctx->compression_enabled = parsed_options.compress;
|
||||||
|
ctx->lzma_dict_size = parsed_options.dictionary;
|
||||||
|
ctx->deduplicate = parsed_options.deduplicate;
|
||||||
|
if(ctx->deduplicate)
|
||||||
|
ctx->sector_hash_map = create_map(ctx->user_data_ddt_header.blocks * 25 / 100); // 25% of total sectors
|
||||||
|
|
||||||
|
// Cannot checksum a resumed file
|
||||||
|
ctx->rewinded = true;
|
||||||
|
|
||||||
|
// Is writing
|
||||||
|
ctx->is_writing = true;
|
||||||
|
|
||||||
|
TRACE("Exiting aaruf_open() = %p", ctx);
|
||||||
|
// Return context
|
||||||
|
return ctx;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user