diff --git a/src/close.c b/src/close.c index 961819a..c352e6a 100644 --- a/src/close.c +++ b/src/close.c @@ -448,7 +448,16 @@ static int32_t write_single_level_ddt(aaruformatContext *ctx) } // Write the DDT header first - fseek(ctx->imageStream, ctx->primaryDdtOffset, SEEK_SET); + fseek(ctx->imageStream, 0, SEEK_END); + long ddt_position = ftell(ctx->imageStream); + // Align index position to block boundary if needed + const uint64_t alignment_mask = (1ULL << ctx->userDataDdtHeader.blockAlignmentShift) - 1; + if(ddt_position & alignment_mask) + { + const uint64_t aligned_position = ddt_position + alignment_mask & ~alignment_mask; + fseek(ctx->imageStream, aligned_position, SEEK_SET); + ddt_position = aligned_position; + } size_t header_written = fwrite(&ctx->userDataDdtHeader, sizeof(DdtHeader2), 1, ctx->imageStream); if(header_written != 1) @@ -479,10 +488,10 @@ static int32_t write_single_level_ddt(aaruformatContext *ctx) IndexEntry single_ddt_entry; single_ddt_entry.blockType = DeDuplicationTable2; single_ddt_entry.dataType = UserData; - single_ddt_entry.offset = ctx->primaryDdtOffset; + single_ddt_entry.offset = ddt_position; utarray_push_back(ctx->indexEntries, &single_ddt_entry); - TRACE("Added single-level DDT index entry at offset %" PRIu64, ctx->primaryDdtOffset); + TRACE("Added single-level DDT index entry at offset %" PRIu64, ddt_position); } else TRACE("Failed to write single-level DDT table data to file"); diff --git a/src/create.c b/src/create.c index d21ead4..5a31dbe 100644 --- a/src/create.c +++ b/src/create.c @@ -269,8 +269,13 @@ void *aaruf_create(const char *filepath, const uint32_t media_type, const uint32 : ctx->userDataDdtHeader.entries * sizeof(uint32_t); // Calculate where data blocks can start (after primary DDT + header) - const uint64_t dataStartPosition = ctx->primaryDdtOffset + sizeof(DdtHeader2) + primaryTableSize; - ctx->nextBlockPosition = dataStartPosition + alignmentMask & ~alignmentMask; + if(ctx->userDataDdtHeader.tableShift > 0) + { + const uint64_t dataStartPosition = ctx->primaryDdtOffset + sizeof(DdtHeader2) + primaryTableSize; + ctx->nextBlockPosition = dataStartPosition + alignmentMask & ~alignmentMask; + } + else + ctx->nextBlockPosition = ctx->primaryDdtOffset; // Single-level DDT can start anywhere TRACE("Data blocks will start at position %" PRIu64, ctx->nextBlockPosition);