mirror of
https://github.com/aaru-dps/libaaruformat.git
synced 2025-12-16 19:24:40 +00:00
Remove concept of 16-bit DDTs.
This commit is contained in:
@@ -188,8 +188,10 @@ typedef struct aaruformatContext
|
||||
bool inMemoryDdt; ///< True if primary (and possibly secondary) DDT loaded.
|
||||
uint64_t *userDataDdt; ///< Legacy flat DDT pointer (NULL when using v2 mini/big arrays).
|
||||
size_t mappedMemoryDdtSize; ///< Length of mmapped DDT if userDataDdt is mmapped.
|
||||
uint32_t *sectorPrefixDdt; ///< Legacy CD sector prefix DDT (deprecated by *_Mini/Big).
|
||||
uint32_t *sectorPrefixDdt; ///< Legacy CD sector prefix DDT (deprecated by *2).
|
||||
uint32_t *sectorSuffixDdt; ///< Legacy CD sector suffix DDT.
|
||||
uint32_t *sectorPrefixDdt2; ///< CD sector prefix DDT V2.
|
||||
uint32_t *sectorSuffixDdt2; ///< CD sector suffix DDT V2.
|
||||
|
||||
GeometryBlockHeader geometryBlock; ///< Logical geometry block (if present).
|
||||
MetadataBlockHeader metadataBlockHeader; ///< Metadata block header.
|
||||
@@ -215,15 +217,11 @@ typedef struct aaruformatContext
|
||||
|
||||
DdtHeader2 userDataDdtHeader; ///< Active user data DDT v2 header (primary table meta).
|
||||
int ddtVersion; ///< DDT version in use (1=legacy, 2=v2 hierarchical).
|
||||
uint16_t *userDataDdtMini; ///< DDT entries (small variant) primary/secondary current.
|
||||
uint32_t *userDataDdtBig; ///< DDT entries (big variant) primary/secondary current.
|
||||
uint16_t *sectorPrefixDdtMini; ///< CD sector prefix corrected DDT (small) if present.
|
||||
uint16_t *sectorSuffixDdtMini; ///< CD sector suffix corrected DDT (small) if present.
|
||||
|
||||
uint64_t cachedDdtOffset; ///< File offset of currently cached secondary DDT (0=none).
|
||||
uint64_t cachedDdtPosition; ///< Position index of cached secondary DDT.
|
||||
uint64_t primaryDdtOffset; ///< File offset of the primary DDT v2 table.
|
||||
uint16_t *cachedSecondaryDdtSmall; ///< Cached secondary table (small entries) or NULL.
|
||||
uint32_t *cachedSecondaryDdtBig; ///< Cached secondary table (big entries) or NULL.
|
||||
|
||||
bool isWriting; ///< True if context opened/created for writing.
|
||||
|
||||
@@ -226,7 +226,6 @@ typedef enum
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
SmallDdtSizeType = 0, ///< Small sized DDT entries.
|
||||
BigDdtSizeType = 1 ///< Large sized DDT entries.
|
||||
} DdtSizeType;
|
||||
|
||||
|
||||
128
src/close.c
128
src/close.c
@@ -79,8 +79,7 @@ static int32_t write_cached_secondary_ddt(aaruformatContext *ctx)
|
||||
// Write cached secondary table to file end and update primary table entry with its position
|
||||
// Check if we have a cached table that needs to be written (either it has an offset or exists in memory)
|
||||
bool has_cached_secondary_ddt =
|
||||
ctx->userDataDdtHeader.tableShift > 0 &&
|
||||
(ctx->cachedDdtOffset != 0 || ctx->cachedSecondaryDdtSmall != NULL || ctx->cachedSecondaryDdtBig != NULL);
|
||||
ctx->userDataDdtHeader.tableShift > 0 && (ctx->cachedDdtOffset != 0 || ctx->cachedSecondaryDdtBig != NULL);
|
||||
|
||||
if(!has_cached_secondary_ddt) return AARUF_STATUS_OK;
|
||||
|
||||
@@ -126,18 +125,12 @@ static int32_t write_cached_secondary_ddt(aaruformatContext *ctx)
|
||||
ddt_header.start = ctx->cachedDdtPosition * items_per_ddt_entry;
|
||||
|
||||
// Calculate data size
|
||||
if(ctx->userDataDdtHeader.sizeType == SmallDdtSizeType)
|
||||
ddt_header.length = items_per_ddt_entry * sizeof(uint16_t);
|
||||
else
|
||||
ddt_header.length = items_per_ddt_entry * sizeof(uint32_t);
|
||||
|
||||
// Calculate CRC64 of the data
|
||||
crc64_ctx *crc64_context = aaruf_crc64_init();
|
||||
if(crc64_context != NULL)
|
||||
{
|
||||
if(ctx->userDataDdtHeader.sizeType == SmallDdtSizeType)
|
||||
aaruf_crc64_update(crc64_context, (uint8_t *)ctx->cachedSecondaryDdtSmall, (uint32_t)ddt_header.length);
|
||||
else
|
||||
aaruf_crc64_update(crc64_context, (uint8_t *)ctx->cachedSecondaryDdtBig, (uint32_t)ddt_header.length);
|
||||
|
||||
uint64_t crc64;
|
||||
@@ -150,9 +143,6 @@ static int32_t write_cached_secondary_ddt(aaruformatContext *ctx)
|
||||
|
||||
if(ddt_header.compression == None)
|
||||
{
|
||||
if(ctx->userDataDdtHeader.sizeType == SmallDdtSizeType)
|
||||
buffer = (uint8_t *)ctx->cachedSecondaryDdtSmall;
|
||||
else
|
||||
buffer = (uint8_t *)ctx->cachedSecondaryDdtBig;
|
||||
ddt_header.cmpCrc64 = ddt_header.crc64;
|
||||
}
|
||||
@@ -167,11 +157,10 @@ static int32_t write_cached_secondary_ddt(aaruformatContext *ctx)
|
||||
|
||||
size_t dst_size = (size_t)ddt_header.length * 2 * 2;
|
||||
size_t props_size = LZMA_PROPERTIES_LENGTH;
|
||||
aaruf_lzma_encode_buffer(
|
||||
buffer, &dst_size,
|
||||
ctx->userDataDdtHeader.sizeType == SmallDdtSizeType ? (uint8_t *)ctx->cachedSecondaryDdtSmall
|
||||
: (uint8_t *)ctx->cachedSecondaryDdtBig,
|
||||
ddt_header.length, lzma_properties, &props_size, 9, ctx->lzma_dict_size, 4, 0, 2, 273, 8);
|
||||
aaruf_lzma_encode_buffer(buffer, &dst_size,
|
||||
|
||||
(uint8_t *)ctx->cachedSecondaryDdtBig, ddt_header.length, lzma_properties, &props_size,
|
||||
9, ctx->lzma_dict_size, 4, 0, 2, 273, 8);
|
||||
|
||||
ddt_header.cmpLength = (uint32_t)dst_size;
|
||||
|
||||
@@ -179,9 +168,6 @@ static int32_t write_cached_secondary_ddt(aaruformatContext *ctx)
|
||||
{
|
||||
ddt_header.compression = None;
|
||||
free(buffer);
|
||||
if(ctx->userDataDdtHeader.sizeType == SmallDdtSizeType)
|
||||
buffer = (uint8_t *)ctx->cachedSecondaryDdtSmall;
|
||||
else
|
||||
buffer = (uint8_t *)ctx->cachedSecondaryDdtBig;
|
||||
}
|
||||
}
|
||||
@@ -207,9 +193,6 @@ static int32_t write_cached_secondary_ddt(aaruformatContext *ctx)
|
||||
// Update primary table entry to point to new location
|
||||
const uint64_t new_secondary_table_block_offset = end_of_file >> ctx->userDataDdtHeader.blockAlignmentShift;
|
||||
|
||||
if(ctx->userDataDdtHeader.sizeType == SmallDdtSizeType)
|
||||
ctx->userDataDdtMini[ctx->cachedDdtPosition] = (uint16_t)new_secondary_table_block_offset;
|
||||
else
|
||||
ctx->userDataDdtBig[ctx->cachedDdtPosition] = (uint32_t)new_secondary_table_block_offset;
|
||||
|
||||
// Update index: remove old entry for cached DDT and add new one
|
||||
@@ -247,14 +230,9 @@ static int32_t write_cached_secondary_ddt(aaruformatContext *ctx)
|
||||
long saved_pos = ftell(ctx->imageStream);
|
||||
fseek(ctx->imageStream, ctx->primaryDdtOffset + sizeof(DdtHeader2), SEEK_SET);
|
||||
|
||||
size_t primary_table_size = ctx->userDataDdtHeader.sizeType == SmallDdtSizeType
|
||||
? ctx->userDataDdtHeader.entries * sizeof(uint16_t)
|
||||
: ctx->userDataDdtHeader.entries * sizeof(uint32_t);
|
||||
size_t primary_table_size = ctx->userDataDdtHeader.entries * sizeof(uint32_t);
|
||||
|
||||
size_t primary_written_bytes = 0;
|
||||
if(ctx->userDataDdtHeader.sizeType == SmallDdtSizeType)
|
||||
primary_written_bytes = fwrite(ctx->userDataDdtMini, primary_table_size, 1, ctx->imageStream);
|
||||
else
|
||||
primary_written_bytes = fwrite(ctx->userDataDdtBig, primary_table_size, 1, ctx->imageStream);
|
||||
|
||||
if(primary_written_bytes != 1)
|
||||
@@ -272,16 +250,8 @@ static int32_t write_cached_secondary_ddt(aaruformatContext *ctx)
|
||||
TRACE("Failed to write cached secondary DDT header");
|
||||
|
||||
// Free the cached table
|
||||
if(ctx->cachedSecondaryDdtSmall != NULL)
|
||||
{
|
||||
free(ctx->cachedSecondaryDdtSmall);
|
||||
ctx->cachedSecondaryDdtSmall = NULL;
|
||||
}
|
||||
if(ctx->cachedSecondaryDdtBig != NULL)
|
||||
{
|
||||
free(ctx->cachedSecondaryDdtBig);
|
||||
ctx->cachedSecondaryDdtBig = NULL;
|
||||
}
|
||||
ctx->cachedDdtOffset = 0;
|
||||
|
||||
// Set position
|
||||
@@ -312,8 +282,7 @@ static int32_t write_cached_secondary_ddt(aaruformatContext *ctx)
|
||||
static int32_t write_primary_ddt(aaruformatContext *ctx)
|
||||
{
|
||||
// Write the cached primary DDT table back to its position in the file
|
||||
if(ctx->userDataDdtHeader.tableShift <= 0 || ctx->userDataDdtMini == NULL && ctx->userDataDdtBig == NULL)
|
||||
return AARUF_STATUS_OK;
|
||||
if(ctx->userDataDdtHeader.tableShift <= 0 || ctx->userDataDdtBig == NULL) return AARUF_STATUS_OK;
|
||||
|
||||
TRACE("Writing cached primary DDT table back to file");
|
||||
|
||||
@@ -321,13 +290,8 @@ static int32_t write_primary_ddt(aaruformatContext *ctx)
|
||||
crc64_ctx *crc64_context = aaruf_crc64_init();
|
||||
if(crc64_context != NULL)
|
||||
{
|
||||
size_t primary_table_size = ctx->userDataDdtHeader.sizeType == SmallDdtSizeType
|
||||
? ctx->userDataDdtHeader.entries * sizeof(uint16_t)
|
||||
: ctx->userDataDdtHeader.entries * sizeof(uint32_t);
|
||||
size_t primary_table_size = ctx->userDataDdtHeader.entries * sizeof(uint32_t);
|
||||
|
||||
if(ctx->userDataDdtHeader.sizeType == SmallDdtSizeType)
|
||||
aaruf_crc64_update(crc64_context, (uint8_t *)ctx->userDataDdtMini, primary_table_size);
|
||||
else
|
||||
aaruf_crc64_update(crc64_context, (uint8_t *)ctx->userDataDdtBig, primary_table_size);
|
||||
|
||||
uint64_t crc64;
|
||||
@@ -358,15 +322,10 @@ static int32_t write_primary_ddt(aaruformatContext *ctx)
|
||||
}
|
||||
|
||||
// Then write the table data (position is already after the header)
|
||||
size_t primary_table_size = ctx->userDataDdtHeader.sizeType == SmallDdtSizeType
|
||||
? ctx->userDataDdtHeader.entries * sizeof(uint16_t)
|
||||
: ctx->userDataDdtHeader.entries * sizeof(uint32_t);
|
||||
size_t primary_table_size = ctx->userDataDdtHeader.entries * sizeof(uint32_t);
|
||||
|
||||
// Write the primary table data
|
||||
size_t written_bytes = 0;
|
||||
if(ctx->userDataDdtHeader.sizeType == SmallDdtSizeType)
|
||||
written_bytes = fwrite(ctx->userDataDdtMini, primary_table_size, 1, ctx->imageStream);
|
||||
else
|
||||
written_bytes = fwrite(ctx->userDataDdtBig, primary_table_size, 1, ctx->imageStream);
|
||||
|
||||
if(written_bytes == 1)
|
||||
@@ -409,15 +368,12 @@ static int32_t write_primary_ddt(aaruformatContext *ctx)
|
||||
static int32_t write_single_level_ddt(aaruformatContext *ctx)
|
||||
{
|
||||
// Write the single level DDT table block aligned just after the header
|
||||
if(ctx->userDataDdtHeader.tableShift != 0 || ctx->userDataDdtMini == NULL && ctx->userDataDdtBig == NULL)
|
||||
return AARUF_STATUS_OK;
|
||||
if(ctx->userDataDdtHeader.tableShift != 0 || ctx->userDataDdtBig == NULL) return AARUF_STATUS_OK;
|
||||
|
||||
TRACE("Writing single-level DDT table to file");
|
||||
|
||||
// Calculate CRC64 of the primary DDT table data
|
||||
const size_t primary_table_size = ctx->userDataDdtHeader.sizeType == SmallDdtSizeType
|
||||
? ctx->userDataDdtHeader.entries * sizeof(uint16_t)
|
||||
: ctx->userDataDdtHeader.entries * sizeof(uint32_t);
|
||||
const size_t primary_table_size = ctx->userDataDdtHeader.entries * sizeof(uint32_t);
|
||||
|
||||
// Properly populate all header fields
|
||||
ctx->userDataDdtHeader.identifier = DeDuplicationTable2;
|
||||
@@ -431,9 +387,6 @@ static int32_t write_single_level_ddt(aaruformatContext *ctx)
|
||||
ctx->userDataDdtHeader.length = primary_table_size;
|
||||
ctx->userDataDdtHeader.cmpLength = primary_table_size;
|
||||
|
||||
if(ctx->userDataDdtHeader.sizeType == SmallDdtSizeType)
|
||||
ctx->userDataDdtHeader.crc64 = aaruf_crc64_data((uint8_t *)ctx->userDataDdtMini, primary_table_size);
|
||||
else
|
||||
ctx->userDataDdtHeader.crc64 = aaruf_crc64_data((uint8_t *)ctx->userDataDdtBig, primary_table_size);
|
||||
|
||||
TRACE("Calculated CRC64 for single-level DDT: 0x%16lX", ctx->userDataDdtHeader.crc64);
|
||||
@@ -443,9 +396,7 @@ static int32_t write_single_level_ddt(aaruformatContext *ctx)
|
||||
|
||||
if(ctx->userDataDdtHeader.compression == None)
|
||||
{
|
||||
if(ctx->userDataDdtHeader.sizeType == SmallDdtSizeType)
|
||||
cmp_buffer = (uint8_t *)ctx->userDataDdtMini;
|
||||
else
|
||||
|
||||
cmp_buffer = (uint8_t *)ctx->userDataDdtBig;
|
||||
ctx->userDataDdtHeader.cmpCrc64 = ctx->userDataDdtHeader.crc64;
|
||||
}
|
||||
@@ -460,11 +411,8 @@ static int32_t write_single_level_ddt(aaruformatContext *ctx)
|
||||
|
||||
size_t dst_size = (size_t)ctx->userDataDdtHeader.length * 2 * 2;
|
||||
size_t props_size = LZMA_PROPERTIES_LENGTH;
|
||||
aaruf_lzma_encode_buffer(cmp_buffer, &dst_size,
|
||||
ctx->userDataDdtHeader.sizeType == SmallDdtSizeType ? (uint8_t *)ctx->userDataDdtMini
|
||||
: (uint8_t *)ctx->userDataDdtBig,
|
||||
ctx->userDataDdtHeader.length, lzma_properties, &props_size, 9, ctx->lzma_dict_size, 4,
|
||||
0, 2, 273, 8);
|
||||
aaruf_lzma_encode_buffer(cmp_buffer, &dst_size, (uint8_t *)ctx->userDataDdtBig, ctx->userDataDdtHeader.length,
|
||||
lzma_properties, &props_size, 9, ctx->lzma_dict_size, 4, 0, 2, 273, 8);
|
||||
|
||||
ctx->userDataDdtHeader.cmpLength = (uint32_t)dst_size;
|
||||
|
||||
@@ -472,9 +420,7 @@ static int32_t write_single_level_ddt(aaruformatContext *ctx)
|
||||
{
|
||||
ctx->userDataDdtHeader.compression = None;
|
||||
free(cmp_buffer);
|
||||
if(ctx->userDataDdtHeader.sizeType == SmallDdtSizeType)
|
||||
cmp_buffer = (uint8_t *)ctx->userDataDdtMini;
|
||||
else
|
||||
|
||||
cmp_buffer = (uint8_t *)ctx->userDataDdtBig;
|
||||
}
|
||||
}
|
||||
@@ -1241,7 +1187,7 @@ static void write_sector_suffix(aaruformatContext *ctx)
|
||||
* Notes:
|
||||
* - Unlike DDT v1, there are no CD_XFIX_MASK / CD_DFIX_MASK macros used here. The bit layout is compact
|
||||
* and directly encoded when writing (status values are pre-shifted where needed in write.c).
|
||||
* - Only the 16-bit mini variant is currently produced (sectorPrefixDdtMini). A 32-bit form is reserved
|
||||
* - Only the 16-bit mini variant is currently produced (sectorPrefixDdt2). A 32-bit form is reserved
|
||||
* for future expansion (sectorPrefixDdt) but is not emitted unless populated.
|
||||
* - The table length equals (negative + Sectors + overflow) * entrySize.
|
||||
* - dataShift is set to 4 (2^4 = 16) expressing the granularity of referenced prefix units.
|
||||
@@ -1257,7 +1203,7 @@ static void write_sector_suffix(aaruformatContext *ctx)
|
||||
*/
|
||||
static void write_sector_prefix_ddt(aaruformatContext *ctx)
|
||||
{
|
||||
if(ctx->sectorPrefixDdtMini == NULL) return;
|
||||
if(ctx->sectorPrefixDdt2 == NULL) return;
|
||||
|
||||
fseek(ctx->imageStream, 0, SEEK_END);
|
||||
long prefix_ddt_position = ftell(ctx->imageStream);
|
||||
@@ -1282,20 +1228,20 @@ static void write_sector_prefix_ddt(aaruformatContext *ctx)
|
||||
ddt_header2.blockAlignmentShift = ctx->userDataDdtHeader.blockAlignmentShift;
|
||||
ddt_header2.dataShift = ctx->userDataDdtHeader.dataShift;
|
||||
ddt_header2.tableShift = 0; // Single-level DDT
|
||||
ddt_header2.sizeType = SmallDdtSizeType;
|
||||
ddt_header2.sizeType = BigDdtSizeType;
|
||||
ddt_header2.entries = ctx->imageInfo.Sectors + ctx->userDataDdtHeader.negative + ctx->userDataDdtHeader.overflow;
|
||||
ddt_header2.blocks = ctx->userDataDdtHeader.blocks;
|
||||
ddt_header2.start = 0;
|
||||
ddt_header2.length = ddt_header2.entries * sizeof(uint16_t);
|
||||
ddt_header2.length = ddt_header2.entries * sizeof(uint32_t);
|
||||
// Calculate CRC64
|
||||
ddt_header2.crc64 = aaruf_crc64_data((uint8_t *)ctx->sectorPrefixDdtMini, (uint32_t)ddt_header2.length);
|
||||
ddt_header2.crc64 = aaruf_crc64_data((uint8_t *)ctx->sectorPrefixDdt2, (uint32_t)ddt_header2.length);
|
||||
|
||||
uint8_t *buffer = NULL;
|
||||
uint8_t lzma_properties[LZMA_PROPERTIES_LENGTH] = {0};
|
||||
|
||||
if(ddt_header2.compression == None)
|
||||
{
|
||||
buffer = (uint8_t *)ctx->sectorPrefixDdtMini;
|
||||
buffer = (uint8_t *)ctx->sectorPrefixDdt2;
|
||||
ddt_header2.cmpCrc64 = ddt_header2.crc64;
|
||||
}
|
||||
else
|
||||
@@ -1309,7 +1255,7 @@ static void write_sector_prefix_ddt(aaruformatContext *ctx)
|
||||
|
||||
size_t dst_size = (size_t)ddt_header2.length * 2 * 2;
|
||||
size_t props_size = LZMA_PROPERTIES_LENGTH;
|
||||
aaruf_lzma_encode_buffer(buffer, &dst_size, (uint8_t *)ctx->sectorPrefixDdtMini, ddt_header2.length,
|
||||
aaruf_lzma_encode_buffer(buffer, &dst_size, (uint8_t *)ctx->sectorPrefixDdt2, ddt_header2.length,
|
||||
lzma_properties, &props_size, 9, ctx->lzma_dict_size, 4, 0, 2, 273, 8);
|
||||
|
||||
ddt_header2.cmpLength = (uint32_t)dst_size;
|
||||
@@ -1318,7 +1264,7 @@ static void write_sector_prefix_ddt(aaruformatContext *ctx)
|
||||
{
|
||||
ddt_header2.compression = None;
|
||||
free(buffer);
|
||||
buffer = (uint8_t *)ctx->sectorPrefixDdtMini;
|
||||
buffer = (uint8_t *)ctx->sectorPrefixDdt2;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1375,13 +1321,13 @@ static void write_sector_prefix_ddt(aaruformatContext *ctx)
|
||||
*
|
||||
* Characteristics & constraints:
|
||||
* - Only DDT v2 is supported here; no fallback or mixed-mode emission with v1 occurs.
|
||||
* - Only the compact "mini" (16-bit) table form is currently produced (sectorSuffixDdtMini filled during write).
|
||||
* - Only the compact "mini" (16-bit) table form is currently produced (sectorSuffixDdt2 filled during write).
|
||||
* - Table length = (negative + total Sectors + overflow) * sizeof(uint16_t).
|
||||
* - dataShift mirrors userDataDdtHeader.dataShift (expressing granularity for index referencing).
|
||||
* - Single-level table (levels = 1, tableLevel = 0, tableShift = 0).
|
||||
* - Compression is applied if enabled; CRC64 protects the table bytes.
|
||||
* - Alignment: The table is aligned to 2^(blockAlignmentShift) before writing to guarantee block boundary access.
|
||||
* - Idempotence: If sectorSuffixDdtMini is NULL the function is a no-op (indicating no suffix anomalies captured).
|
||||
* - Idempotence: If sectorSuffixDdt2 is NULL the function is a no-op (indicating no suffix anomalies captured).
|
||||
*
|
||||
* Index integration:
|
||||
* On success an IndexEntry (blockType = DeDuplicationTable2, dataType = CdSectorSuffix, offset = file position)
|
||||
@@ -1395,14 +1341,14 @@ static void write_sector_prefix_ddt(aaruformatContext *ctx)
|
||||
*
|
||||
* Preconditions:
|
||||
* - ctx must be a valid non-NULL pointer opened for writing.
|
||||
* - ctx->sectorSuffixDdtMini must point to a fully populated contiguous array of uint16_t entries.
|
||||
* - ctx->sectorSuffixDdt2 must point to a fully populated contiguous array of uint16_t entries.
|
||||
*
|
||||
* @param ctx Active aaruformatContext being finalized.
|
||||
* @internal
|
||||
*/
|
||||
static void write_sector_suffix_ddt(aaruformatContext *ctx)
|
||||
{
|
||||
if(ctx->sectorSuffixDdtMini == NULL) return;
|
||||
if(ctx->sectorSuffixDdt2 == NULL) return;
|
||||
|
||||
fseek(ctx->imageStream, 0, SEEK_END);
|
||||
long suffix_ddt_position = ftell(ctx->imageStream);
|
||||
@@ -1427,20 +1373,20 @@ static void write_sector_suffix_ddt(aaruformatContext *ctx)
|
||||
ddt_header2.blockAlignmentShift = ctx->userDataDdtHeader.blockAlignmentShift;
|
||||
ddt_header2.dataShift = ctx->userDataDdtHeader.dataShift;
|
||||
ddt_header2.tableShift = 0; // Single-level DDT
|
||||
ddt_header2.sizeType = SmallDdtSizeType;
|
||||
ddt_header2.sizeType = BigDdtSizeType;
|
||||
ddt_header2.entries = ctx->imageInfo.Sectors + ctx->userDataDdtHeader.negative + ctx->userDataDdtHeader.overflow;
|
||||
ddt_header2.blocks = ctx->userDataDdtHeader.blocks;
|
||||
ddt_header2.start = 0;
|
||||
ddt_header2.length = ddt_header2.entries * sizeof(uint16_t);
|
||||
ddt_header2.length = ddt_header2.entries * sizeof(uint32_t);
|
||||
// Calculate CRC64
|
||||
ddt_header2.crc64 = aaruf_crc64_data((uint8_t *)ctx->sectorSuffixDdtMini, (uint32_t)ddt_header2.length);
|
||||
ddt_header2.crc64 = aaruf_crc64_data((uint8_t *)ctx->sectorSuffixDdt2, (uint32_t)ddt_header2.length);
|
||||
|
||||
uint8_t *buffer = NULL;
|
||||
uint8_t lzma_properties[LZMA_PROPERTIES_LENGTH] = {0};
|
||||
|
||||
if(ddt_header2.compression == None)
|
||||
{
|
||||
buffer = (uint8_t *)ctx->sectorSuffixDdtMini;
|
||||
buffer = (uint8_t *)ctx->sectorSuffixDdt2;
|
||||
ddt_header2.cmpCrc64 = ddt_header2.crc64;
|
||||
}
|
||||
else
|
||||
@@ -1454,7 +1400,7 @@ static void write_sector_suffix_ddt(aaruformatContext *ctx)
|
||||
|
||||
size_t dst_size = (size_t)ddt_header2.length * 2 * 2;
|
||||
size_t props_size = LZMA_PROPERTIES_LENGTH;
|
||||
aaruf_lzma_encode_buffer(buffer, &dst_size, (uint8_t *)ctx->sectorSuffixDdtMini, ddt_header2.length,
|
||||
aaruf_lzma_encode_buffer(buffer, &dst_size, (uint8_t *)ctx->sectorSuffixDdt2, ddt_header2.length,
|
||||
lzma_properties, &props_size, 9, ctx->lzma_dict_size, 4, 0, 2, 273, 8);
|
||||
|
||||
ddt_header2.cmpLength = (uint32_t)dst_size;
|
||||
@@ -1463,7 +1409,7 @@ static void write_sector_suffix_ddt(aaruformatContext *ctx)
|
||||
{
|
||||
ddt_header2.compression = None;
|
||||
free(buffer);
|
||||
buffer = (uint8_t *)ctx->sectorSuffixDdtMini;
|
||||
buffer = (uint8_t *)ctx->sectorSuffixDdt2;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4226,12 +4172,12 @@ int aaruf_close(void *context)
|
||||
}
|
||||
#endif
|
||||
|
||||
free(ctx->sectorPrefixDdtMini);
|
||||
ctx->sectorPrefixDdtMini = NULL;
|
||||
free(ctx->sectorPrefixDdt2);
|
||||
ctx->sectorPrefixDdt2 = NULL;
|
||||
free(ctx->sectorPrefixDdt);
|
||||
ctx->sectorPrefixDdt = NULL;
|
||||
free(ctx->sectorSuffixDdtMini);
|
||||
ctx->sectorSuffixDdtMini = NULL;
|
||||
free(ctx->sectorSuffixDdt2);
|
||||
ctx->sectorSuffixDdt2 = NULL;
|
||||
free(ctx->sectorSuffixDdt);
|
||||
ctx->sectorSuffixDdt = NULL;
|
||||
|
||||
|
||||
25
src/create.c
25
src/create.c
@@ -43,12 +43,6 @@ static void cleanup_failed_create(aaruformatContext *ctx)
|
||||
ctx->indexEntries = NULL;
|
||||
}
|
||||
|
||||
if(ctx->userDataDdtMini != NULL)
|
||||
{
|
||||
free(ctx->userDataDdtMini);
|
||||
ctx->userDataDdtMini = NULL;
|
||||
}
|
||||
|
||||
if(ctx->userDataDdtBig != NULL)
|
||||
{
|
||||
free(ctx->userDataDdtBig);
|
||||
@@ -459,20 +453,7 @@ void *aaruf_create(const char *filepath, const uint32_t media_type, const uint32
|
||||
ctx->userDataDdtHeader.entries++;
|
||||
|
||||
TRACE("Initializing primary/single DDT");
|
||||
if(ctx->userDataDdtHeader.sizeType == SmallDdtSizeType)
|
||||
{
|
||||
ctx->userDataDdtMini =
|
||||
(uint16_t *)calloc(ctx->userDataDdtHeader.entries, sizeof(uint16_t)); // All entries to zero
|
||||
if(ctx->userDataDdtMini == NULL)
|
||||
{
|
||||
FATAL("Not enough memory to allocate primary DDT (mini)");
|
||||
errno = AARUF_ERROR_NOT_ENOUGH_MEMORY;
|
||||
TRACE("Exiting aaruf_create() = NULL");
|
||||
cleanup_failed_create(ctx);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
else if(ctx->userDataDdtHeader.sizeType == BigDdtSizeType)
|
||||
if(ctx->userDataDdtHeader.sizeType == BigDdtSizeType)
|
||||
{
|
||||
ctx->userDataDdtBig =
|
||||
(uint32_t *)calloc(ctx->userDataDdtHeader.entries, sizeof(uint32_t)); // All entries to zero
|
||||
@@ -494,9 +475,7 @@ void *aaruf_create(const char *filepath, const uint32_t media_type, const uint32
|
||||
TRACE("Primary DDT will be placed at offset %" PRIu64, ctx->primaryDdtOffset);
|
||||
|
||||
// Calculate size of primary DDT table
|
||||
const uint64_t primary_table_size = ctx->userDataDdtHeader.sizeType == SmallDdtSizeType
|
||||
? ctx->userDataDdtHeader.entries * sizeof(uint16_t)
|
||||
: ctx->userDataDdtHeader.entries * sizeof(uint32_t);
|
||||
const uint64_t primary_table_size = ctx->userDataDdtHeader.entries * sizeof(uint32_t);
|
||||
|
||||
// Calculate where data blocks can start (after primary DDT + header)
|
||||
if(ctx->userDataDdtHeader.tableShift > 0)
|
||||
|
||||
245
src/ddt/ddt_v2.c
245
src/ddt/ddt_v2.c
@@ -247,9 +247,6 @@ int32_t process_ddt_v2(aaruformatContext *ctx, IndexEntry *entry, bool *found_us
|
||||
return AARUF_ERROR_INVALID_BLOCK_CRC;
|
||||
}
|
||||
|
||||
if(ddt_header.sizeType == SmallDdtSizeType)
|
||||
ctx->userDataDdtMini = (uint16_t *)buffer;
|
||||
else if(ddt_header.sizeType == BigDdtSizeType)
|
||||
ctx->userDataDdtBig = (uint32_t *)buffer;
|
||||
|
||||
ctx->inMemoryDdt = true;
|
||||
@@ -296,9 +293,6 @@ int32_t process_ddt_v2(aaruformatContext *ctx, IndexEntry *entry, bool *found_us
|
||||
return AARUF_ERROR_INVALID_BLOCK_CRC;
|
||||
}
|
||||
|
||||
if(ddt_header.sizeType == SmallDdtSizeType)
|
||||
ctx->userDataDdtMini = (uint16_t *)buffer;
|
||||
else if(ddt_header.sizeType == BigDdtSizeType)
|
||||
ctx->userDataDdtBig = (uint32_t *)buffer;
|
||||
|
||||
ctx->inMemoryDdt = true;
|
||||
@@ -405,20 +399,8 @@ int32_t process_ddt_v2(aaruformatContext *ctx, IndexEntry *entry, bool *found_us
|
||||
return AARUF_ERROR_INVALID_BLOCK_CRC;
|
||||
}
|
||||
|
||||
if(entry->dataType == CdSectorPrefixCorrected)
|
||||
{
|
||||
if(ddt_header.sizeType == SmallDdtSizeType)
|
||||
ctx->sectorPrefixDdtMini = (uint16_t *)buffer;
|
||||
else if(ddt_header.sizeType == BigDdtSizeType)
|
||||
ctx->sectorPrefixDdt = (uint32_t *)buffer;
|
||||
}
|
||||
else if(entry->dataType == CdSectorSuffixCorrected)
|
||||
{
|
||||
if(ddt_header.sizeType == SmallDdtSizeType)
|
||||
ctx->sectorSuffixDdtMini = (uint16_t *)buffer;
|
||||
else if(ddt_header.sizeType == BigDdtSizeType)
|
||||
ctx->sectorSuffixDdt = (uint32_t *)buffer;
|
||||
}
|
||||
if(entry->dataType == CdSectorPrefixCorrected) { ctx->sectorPrefixDdt = (uint32_t *)buffer; }
|
||||
else if(entry->dataType == CdSectorSuffixCorrected) { ctx->sectorSuffixDdt = (uint32_t *)buffer; }
|
||||
else
|
||||
free(buffer);
|
||||
|
||||
@@ -463,20 +445,8 @@ int32_t process_ddt_v2(aaruformatContext *ctx, IndexEntry *entry, bool *found_us
|
||||
return AARUF_ERROR_INVALID_BLOCK_CRC;
|
||||
}
|
||||
|
||||
if(entry->dataType == CdSectorPrefixCorrected)
|
||||
{
|
||||
if(ddt_header.sizeType == SmallDdtSizeType)
|
||||
ctx->sectorPrefixDdtMini = (uint16_t *)buffer;
|
||||
else if(ddt_header.sizeType == BigDdtSizeType)
|
||||
ctx->sectorPrefixDdt = (uint32_t *)buffer;
|
||||
}
|
||||
else if(entry->dataType == CdSectorSuffixCorrected)
|
||||
{
|
||||
if(ddt_header.sizeType == SmallDdtSizeType)
|
||||
ctx->sectorSuffixDdtMini = (uint16_t *)buffer;
|
||||
else if(ddt_header.sizeType == BigDdtSizeType)
|
||||
ctx->sectorSuffixDdt = (uint32_t *)buffer;
|
||||
}
|
||||
if(entry->dataType == CdSectorPrefixCorrected) { ctx->sectorPrefixDdt = (uint32_t *)buffer; }
|
||||
else if(entry->dataType == CdSectorSuffixCorrected) { ctx->sectorSuffixDdt = (uint32_t *)buffer; }
|
||||
else
|
||||
free(buffer);
|
||||
|
||||
@@ -646,9 +616,7 @@ int32_t decode_ddt_single_level_v2(aaruformatContext *ctx, uint64_t sector_addre
|
||||
else
|
||||
sector_address += ctx->userDataDdtHeader.negative;
|
||||
|
||||
if(ctx->userDataDdtHeader.sizeType == SmallDdtSizeType)
|
||||
ddt_entry = ctx->userDataDdtMini[sector_address];
|
||||
else if(ctx->userDataDdtHeader.sizeType == BigDdtSizeType)
|
||||
if(ctx->userDataDdtHeader.sizeType == BigDdtSizeType)
|
||||
ddt_entry = ctx->userDataDdtBig[sector_address];
|
||||
else
|
||||
{
|
||||
@@ -667,16 +635,8 @@ int32_t decode_ddt_single_level_v2(aaruformatContext *ctx, uint64_t sector_addre
|
||||
return AARUF_STATUS_OK;
|
||||
}
|
||||
|
||||
if(ctx->userDataDdtHeader.sizeType == SmallDdtSizeType)
|
||||
{
|
||||
*sector_status = ddt_entry >> 12;
|
||||
ddt_entry &= 0xfff;
|
||||
}
|
||||
else if(ctx->userDataDdtHeader.sizeType == BigDdtSizeType)
|
||||
{
|
||||
*sector_status = ddt_entry >> 28;
|
||||
ddt_entry &= 0x0fffffff;
|
||||
}
|
||||
|
||||
const uint64_t offset_mask = (uint64_t)((1 << ctx->userDataDdtHeader.dataShift) - 1);
|
||||
*offset = ddt_entry & offset_mask;
|
||||
@@ -818,9 +778,7 @@ int32_t decode_ddt_multi_level_v2(aaruformatContext *ctx, uint64_t sector_addres
|
||||
items_per_ddt_entry = 1 << ctx->userDataDdtHeader.tableShift;
|
||||
ddt_position = sector_address / items_per_ddt_entry;
|
||||
|
||||
if(ctx->userDataDdtHeader.sizeType == SmallDdtSizeType)
|
||||
secondary_ddt_offset = ctx->userDataDdtMini[ddt_position];
|
||||
else if(ctx->userDataDdtHeader.sizeType == BigDdtSizeType)
|
||||
if(ctx->userDataDdtHeader.sizeType == BigDdtSizeType)
|
||||
secondary_ddt_offset = ctx->userDataDdtBig[ddt_position];
|
||||
else
|
||||
{
|
||||
@@ -949,9 +907,6 @@ int32_t decode_ddt_multi_level_v2(aaruformatContext *ctx, uint64_t sector_addres
|
||||
return AARUF_ERROR_INVALID_BLOCK_CRC;
|
||||
}
|
||||
|
||||
if(ddt_header.sizeType == SmallDdtSizeType)
|
||||
ctx->cachedSecondaryDdtSmall = (uint16_t *)buffer;
|
||||
else if(ddt_header.sizeType == BigDdtSizeType)
|
||||
ctx->cachedSecondaryDdtBig = (uint32_t *)buffer;
|
||||
|
||||
ctx->cachedDdtOffset = secondary_ddt_offset;
|
||||
@@ -998,9 +953,6 @@ int32_t decode_ddt_multi_level_v2(aaruformatContext *ctx, uint64_t sector_addres
|
||||
return AARUF_ERROR_INVALID_BLOCK_CRC;
|
||||
}
|
||||
|
||||
if(ddt_header.sizeType == SmallDdtSizeType)
|
||||
ctx->cachedSecondaryDdtSmall = (uint16_t *)buffer;
|
||||
else if(ddt_header.sizeType == BigDdtSizeType)
|
||||
ctx->cachedSecondaryDdtBig = (uint32_t *)buffer;
|
||||
|
||||
ctx->cachedDdtOffset = secondary_ddt_offset;
|
||||
@@ -1013,9 +965,6 @@ int32_t decode_ddt_multi_level_v2(aaruformatContext *ctx, uint64_t sector_addres
|
||||
}
|
||||
}
|
||||
|
||||
if(ctx->userDataDdtHeader.sizeType == SmallDdtSizeType)
|
||||
ddt_entry = ctx->cachedSecondaryDdtSmall[sector_address % items_per_ddt_entry];
|
||||
else if(ctx->userDataDdtHeader.sizeType == BigDdtSizeType)
|
||||
ddt_entry = ctx->cachedSecondaryDdtBig[sector_address % items_per_ddt_entry];
|
||||
|
||||
if(ddt_entry == 0)
|
||||
@@ -1029,16 +978,8 @@ int32_t decode_ddt_multi_level_v2(aaruformatContext *ctx, uint64_t sector_addres
|
||||
return AARUF_STATUS_OK;
|
||||
}
|
||||
|
||||
if(ctx->userDataDdtHeader.sizeType == SmallDdtSizeType)
|
||||
{
|
||||
*sector_status = ddt_entry >> 12;
|
||||
ddt_entry &= 0xfff;
|
||||
}
|
||||
else if(ctx->userDataDdtHeader.sizeType == BigDdtSizeType)
|
||||
{
|
||||
*sector_status = ddt_entry >> 28;
|
||||
ddt_entry &= 0x0fffffff;
|
||||
}
|
||||
|
||||
const uint64_t offset_mask = (uint64_t)((1 << ctx->userDataDdtHeader.dataShift) - 1);
|
||||
*offset = ddt_entry & offset_mask;
|
||||
@@ -1134,19 +1075,7 @@ bool set_ddt_single_level_v2(aaruformatContext *ctx, uint64_t sector_address, co
|
||||
const uint64_t block_index = block_offset >> ctx->userDataDdtHeader.blockAlignmentShift;
|
||||
*ddt_entry = offset & (1ULL << ctx->userDataDdtHeader.dataShift) - 1 | block_index
|
||||
<< ctx->userDataDdtHeader.dataShift;
|
||||
if(ctx->userDataDdtHeader.sizeType == SmallDdtSizeType)
|
||||
{ // Overflow detection for DDT entry
|
||||
if(*ddt_entry > 0xFFF)
|
||||
{
|
||||
FATAL("DDT overflow: media does not fit in small DDT");
|
||||
TRACE("Exiting set_ddt_single_level_v2() = false");
|
||||
return false;
|
||||
}
|
||||
|
||||
*ddt_entry |= (uint64_t)sector_status << 12;
|
||||
}
|
||||
else if(ctx->userDataDdtHeader.sizeType == BigDdtSizeType)
|
||||
{
|
||||
// Overflow detection for DDT entry
|
||||
if(*ddt_entry > 0xFFFFFFF)
|
||||
{
|
||||
@@ -1157,18 +1086,9 @@ bool set_ddt_single_level_v2(aaruformatContext *ctx, uint64_t sector_address, co
|
||||
|
||||
*ddt_entry |= (uint64_t)sector_status << 28;
|
||||
}
|
||||
}
|
||||
|
||||
if(ctx->userDataDdtHeader.sizeType == SmallDdtSizeType)
|
||||
{
|
||||
TRACE("Setting small single-level DDT entry %d to %u", sector_address, (uint16_t)*ddt_entry);
|
||||
ctx->userDataDdtMini[sector_address] = (uint16_t)*ddt_entry;
|
||||
}
|
||||
else if(ctx->userDataDdtHeader.sizeType == BigDdtSizeType)
|
||||
{
|
||||
TRACE("Setting big single-level DDT entry %d to %u", sector_address, (uint32_t)*ddt_entry);
|
||||
ctx->userDataDdtBig[sector_address] = (uint32_t)*ddt_entry;
|
||||
}
|
||||
|
||||
TRACE("Exiting set_ddt_single_level_v2() = true");
|
||||
return true;
|
||||
@@ -1234,9 +1154,7 @@ bool set_ddt_multi_level_v2(aaruformatContext *ctx, uint64_t sector_address, boo
|
||||
items_per_ddt_entry = 1 << ctx->userDataDdtHeader.tableShift;
|
||||
ddt_position = sector_address / items_per_ddt_entry;
|
||||
|
||||
if(ctx->userDataDdtHeader.sizeType == SmallDdtSizeType)
|
||||
secondary_ddt_offset = ctx->userDataDdtMini[ddt_position];
|
||||
else if(ctx->userDataDdtHeader.sizeType == BigDdtSizeType)
|
||||
if(ctx->userDataDdtHeader.sizeType == BigDdtSizeType)
|
||||
secondary_ddt_offset = ctx->userDataDdtBig[ddt_position];
|
||||
else
|
||||
{
|
||||
@@ -1258,20 +1176,6 @@ bool set_ddt_multi_level_v2(aaruformatContext *ctx, uint64_t sector_address, boo
|
||||
*ddt_entry = offset & (1ULL << ctx->userDataDdtHeader.dataShift) - 1 |
|
||||
block_index << ctx->userDataDdtHeader.dataShift;
|
||||
|
||||
if(ctx->userDataDdtHeader.sizeType == SmallDdtSizeType)
|
||||
{
|
||||
// Overflow detection for DDT entry
|
||||
if(*ddt_entry > 0xFFF)
|
||||
{
|
||||
FATAL("DDT overflow: media does not fit in small DDT");
|
||||
TRACE("Exiting set_ddt_multi_level_v2() = false");
|
||||
return false;
|
||||
}
|
||||
|
||||
*ddt_entry |= (uint64_t)sector_status << 12;
|
||||
}
|
||||
else if(ctx->userDataDdtHeader.sizeType == BigDdtSizeType)
|
||||
{
|
||||
// Overflow detection for DDT entry
|
||||
if(*ddt_entry > 0xFFFFFFF)
|
||||
{
|
||||
@@ -1282,20 +1186,9 @@ bool set_ddt_multi_level_v2(aaruformatContext *ctx, uint64_t sector_address, boo
|
||||
|
||||
*ddt_entry |= (uint64_t)sector_status << 28;
|
||||
}
|
||||
}
|
||||
|
||||
if(ctx->userDataDdtHeader.sizeType == SmallDdtSizeType)
|
||||
{
|
||||
TRACE("Setting small secondary DDT entry %d to %u", sector_address % items_per_ddt_entry,
|
||||
(uint16_t)*ddt_entry);
|
||||
ctx->cachedSecondaryDdtSmall[sector_address % items_per_ddt_entry] = (uint16_t)*ddt_entry;
|
||||
}
|
||||
else if(ctx->userDataDdtHeader.sizeType == BigDdtSizeType)
|
||||
{
|
||||
TRACE("Setting small secondary DDT entry %d to %u", sector_address % items_per_ddt_entry,
|
||||
(uint16_t)*ddt_entry);
|
||||
TRACE("Setting small secondary DDT entry %d to %u", sector_address % items_per_ddt_entry, (uint16_t)*ddt_entry);
|
||||
ctx->cachedSecondaryDdtBig[sector_address % items_per_ddt_entry] = (uint32_t)*ddt_entry;
|
||||
}
|
||||
|
||||
TRACE("Updated cached secondary DDT entry at position %" PRIu64, sector_address % items_per_ddt_entry);
|
||||
TRACE("Exiting set_ddt_multi_level_v2() = true");
|
||||
@@ -1304,7 +1197,7 @@ bool set_ddt_multi_level_v2(aaruformatContext *ctx, uint64_t sector_address, boo
|
||||
|
||||
// Step 2.5: Handle case where we have a cached secondary DDT that has never been written to disk
|
||||
// but does not contain the requested block
|
||||
if(ctx->cachedDdtOffset == 0 && (ctx->cachedSecondaryDdtSmall != NULL || ctx->cachedSecondaryDdtBig != NULL))
|
||||
if(ctx->cachedDdtOffset == 0 && (ctx->cachedSecondaryDdtBig != NULL))
|
||||
{
|
||||
// Only write the cached table to disk if the requested block belongs to a different DDT position
|
||||
if(ddt_position != ctx->cachedDdtPosition)
|
||||
@@ -1346,9 +1239,7 @@ bool set_ddt_multi_level_v2(aaruformatContext *ctx, uint64_t sector_address, boo
|
||||
ddt_header.entries = items_per_ddt_entry;
|
||||
|
||||
// Calculate data size
|
||||
if(ctx->userDataDdtHeader.sizeType == SmallDdtSizeType)
|
||||
ddt_header.length = items_per_ddt_entry * sizeof(uint16_t);
|
||||
else
|
||||
|
||||
ddt_header.length = items_per_ddt_entry * sizeof(uint32_t);
|
||||
|
||||
// Calculate CRC64 of the data
|
||||
@@ -1360,9 +1251,6 @@ bool set_ddt_multi_level_v2(aaruformatContext *ctx, uint64_t sector_address, boo
|
||||
return false;
|
||||
}
|
||||
|
||||
if(ctx->userDataDdtHeader.sizeType == SmallDdtSizeType)
|
||||
aaruf_crc64_update(crc64_context, (uint8_t *)ctx->cachedSecondaryDdtSmall, (uint32_t)ddt_header.length);
|
||||
else
|
||||
aaruf_crc64_update(crc64_context, (uint8_t *)ctx->cachedSecondaryDdtBig, (uint32_t)ddt_header.length);
|
||||
|
||||
aaruf_crc64_final(crc64_context, &crc64);
|
||||
@@ -1373,9 +1261,7 @@ bool set_ddt_multi_level_v2(aaruformatContext *ctx, uint64_t sector_address, boo
|
||||
|
||||
if(ddt_header.compression == None)
|
||||
{
|
||||
if(ctx->userDataDdtHeader.sizeType == SmallDdtSizeType)
|
||||
cmp_buffer = (uint8_t *)ctx->cachedSecondaryDdtSmall;
|
||||
else
|
||||
|
||||
cmp_buffer = (uint8_t *)ctx->cachedSecondaryDdtBig;
|
||||
ddt_header.cmpCrc64 = ddt_header.crc64;
|
||||
}
|
||||
@@ -1390,11 +1276,9 @@ bool set_ddt_multi_level_v2(aaruformatContext *ctx, uint64_t sector_address, boo
|
||||
|
||||
size_t dst_size = (size_t)ddt_header.length * 2 * 2;
|
||||
size_t props_size = LZMA_PROPERTIES_LENGTH;
|
||||
aaruf_lzma_encode_buffer(
|
||||
cmp_buffer, &dst_size,
|
||||
ctx->userDataDdtHeader.sizeType == SmallDdtSizeType ? (uint8_t *)ctx->cachedSecondaryDdtSmall
|
||||
: (uint8_t *)ctx->cachedSecondaryDdtBig,
|
||||
ddt_header.length, lzma_properties, &props_size, 9, ctx->lzma_dict_size, 4, 0, 2, 273, 8);
|
||||
aaruf_lzma_encode_buffer(cmp_buffer, &dst_size, (uint8_t *)ctx->cachedSecondaryDdtBig,
|
||||
ddt_header.length, lzma_properties, &props_size, 9, ctx->lzma_dict_size, 4, 0,
|
||||
2, 273, 8);
|
||||
|
||||
ddt_header.cmpLength = (uint32_t)dst_size;
|
||||
|
||||
@@ -1402,9 +1286,7 @@ bool set_ddt_multi_level_v2(aaruformatContext *ctx, uint64_t sector_address, boo
|
||||
{
|
||||
ddt_header.compression = None;
|
||||
free(cmp_buffer);
|
||||
if(ctx->userDataDdtHeader.sizeType == SmallDdtSizeType)
|
||||
cmp_buffer = (uint8_t *)ctx->cachedSecondaryDdtSmall;
|
||||
else
|
||||
|
||||
cmp_buffer = (uint8_t *)ctx->cachedSecondaryDdtBig;
|
||||
}
|
||||
}
|
||||
@@ -1452,22 +1334,14 @@ bool set_ddt_multi_level_v2(aaruformatContext *ctx, uint64_t sector_address, boo
|
||||
// Update the primary level table entry to point to the new location of the secondary table
|
||||
uint64_t new_secondary_table_block_offset = end_of_file >> ctx->userDataDdtHeader.blockAlignmentShift;
|
||||
|
||||
if(ctx->userDataDdtHeader.sizeType == SmallDdtSizeType)
|
||||
ctx->userDataDdtMini[ctx->cachedDdtPosition] = (uint16_t)new_secondary_table_block_offset;
|
||||
else
|
||||
ctx->userDataDdtBig[ctx->cachedDdtPosition] = (uint32_t)new_secondary_table_block_offset;
|
||||
|
||||
// Write the updated primary table back to its original position in the file
|
||||
long saved_pos = ftell(ctx->imageStream);
|
||||
fseek(ctx->imageStream, ctx->primaryDdtOffset + sizeof(DdtHeader2), SEEK_SET);
|
||||
|
||||
size_t primary_table_size = ctx->userDataDdtHeader.sizeType == SmallDdtSizeType
|
||||
? ctx->userDataDdtHeader.entries * sizeof(uint16_t)
|
||||
: ctx->userDataDdtHeader.entries * sizeof(uint32_t);
|
||||
size_t primary_table_size = ctx->userDataDdtHeader.entries * sizeof(uint32_t);
|
||||
|
||||
if(ctx->userDataDdtHeader.sizeType == SmallDdtSizeType)
|
||||
written_bytes = fwrite(ctx->userDataDdtMini, primary_table_size, 1, ctx->imageStream);
|
||||
else
|
||||
written_bytes = fwrite(ctx->userDataDdtBig, primary_table_size, 1, ctx->imageStream);
|
||||
|
||||
if(written_bytes != 1)
|
||||
@@ -1485,16 +1359,9 @@ bool set_ddt_multi_level_v2(aaruformatContext *ctx, uint64_t sector_address, boo
|
||||
TRACE("Updated nextBlockPosition after never-written DDT write to %" PRIu64, ctx->nextBlockPosition);
|
||||
|
||||
// Free the cached table
|
||||
if(ctx->userDataDdtHeader.sizeType == SmallDdtSizeType && ctx->cachedSecondaryDdtSmall)
|
||||
{
|
||||
free(ctx->cachedSecondaryDdtSmall);
|
||||
ctx->cachedSecondaryDdtSmall = NULL;
|
||||
}
|
||||
else if(ctx->userDataDdtHeader.sizeType == BigDdtSizeType && ctx->cachedSecondaryDdtBig)
|
||||
{
|
||||
|
||||
free(ctx->cachedSecondaryDdtBig);
|
||||
ctx->cachedSecondaryDdtBig = NULL;
|
||||
}
|
||||
|
||||
// Reset cached values since we've written and freed the table
|
||||
ctx->cachedDdtOffset = 0;
|
||||
@@ -1549,9 +1416,7 @@ bool set_ddt_multi_level_v2(aaruformatContext *ctx, uint64_t sector_address, boo
|
||||
ddt_header.entries = items_per_ddt_entry;
|
||||
|
||||
// Calculate data size
|
||||
if(ctx->userDataDdtHeader.sizeType == SmallDdtSizeType)
|
||||
ddt_header.length = items_per_ddt_entry * sizeof(uint16_t);
|
||||
else
|
||||
|
||||
ddt_header.length = items_per_ddt_entry * sizeof(uint32_t);
|
||||
|
||||
// Calculate CRC64 of the data
|
||||
@@ -1563,9 +1428,6 @@ bool set_ddt_multi_level_v2(aaruformatContext *ctx, uint64_t sector_address, boo
|
||||
return false;
|
||||
}
|
||||
|
||||
if(ctx->userDataDdtHeader.sizeType == SmallDdtSizeType)
|
||||
aaruf_crc64_update(crc64_context, (uint8_t *)ctx->cachedSecondaryDdtSmall, ddt_header.length);
|
||||
else
|
||||
aaruf_crc64_update(crc64_context, (uint8_t *)ctx->cachedSecondaryDdtBig, ddt_header.length);
|
||||
|
||||
aaruf_crc64_final(crc64_context, &crc64);
|
||||
@@ -1576,9 +1438,7 @@ bool set_ddt_multi_level_v2(aaruformatContext *ctx, uint64_t sector_address, boo
|
||||
|
||||
if(ddt_header.compression == None)
|
||||
{
|
||||
if(ctx->userDataDdtHeader.sizeType == SmallDdtSizeType)
|
||||
cmp_buffer = (uint8_t *)ctx->cachedSecondaryDdtSmall;
|
||||
else
|
||||
|
||||
cmp_buffer = (uint8_t *)ctx->cachedSecondaryDdtBig;
|
||||
ddt_header.cmpCrc64 = ddt_header.crc64;
|
||||
}
|
||||
@@ -1593,11 +1453,8 @@ bool set_ddt_multi_level_v2(aaruformatContext *ctx, uint64_t sector_address, boo
|
||||
|
||||
size_t dst_size = (size_t)ddt_header.length * 2 * 2;
|
||||
size_t props_size = LZMA_PROPERTIES_LENGTH;
|
||||
aaruf_lzma_encode_buffer(
|
||||
cmp_buffer, &dst_size,
|
||||
ctx->userDataDdtHeader.sizeType == SmallDdtSizeType ? (uint8_t *)ctx->cachedSecondaryDdtSmall
|
||||
: (uint8_t *)ctx->cachedSecondaryDdtBig,
|
||||
ddt_header.length, lzma_properties, &props_size, 9, ctx->lzma_dict_size, 4, 0, 2, 273, 8);
|
||||
aaruf_lzma_encode_buffer(cmp_buffer, &dst_size, (uint8_t *)ctx->cachedSecondaryDdtBig, ddt_header.length,
|
||||
lzma_properties, &props_size, 9, ctx->lzma_dict_size, 4, 0, 2, 273, 8);
|
||||
|
||||
ddt_header.cmpLength = (uint32_t)dst_size;
|
||||
|
||||
@@ -1605,9 +1462,7 @@ bool set_ddt_multi_level_v2(aaruformatContext *ctx, uint64_t sector_address, boo
|
||||
{
|
||||
ddt_header.compression = None;
|
||||
free(cmp_buffer);
|
||||
if(ctx->userDataDdtHeader.sizeType == SmallDdtSizeType)
|
||||
cmp_buffer = (uint8_t *)ctx->cachedSecondaryDdtSmall;
|
||||
else
|
||||
|
||||
cmp_buffer = (uint8_t *)ctx->cachedSecondaryDdtBig;
|
||||
}
|
||||
}
|
||||
@@ -1681,22 +1536,15 @@ bool set_ddt_multi_level_v2(aaruformatContext *ctx, uint64_t sector_address, boo
|
||||
|
||||
// Update the primary table entry to point to the new location of the secondary table
|
||||
// Use ddtPosition which was calculated from sectorAddress, not cachedDdtOffset
|
||||
if(ctx->userDataDdtHeader.sizeType == SmallDdtSizeType)
|
||||
ctx->userDataDdtMini[ddt_position] = (uint16_t)new_secondary_table_block_offset;
|
||||
else
|
||||
|
||||
ctx->userDataDdtBig[ddt_position] = (uint32_t)new_secondary_table_block_offset;
|
||||
|
||||
// Write the updated primary table back to its original position in the file
|
||||
long saved_pos = ftell(ctx->imageStream);
|
||||
fseek(ctx->imageStream, ctx->primaryDdtOffset + sizeof(DdtHeader2), SEEK_SET);
|
||||
|
||||
size_t primary_table_size = ctx->userDataDdtHeader.sizeType == SmallDdtSizeType
|
||||
? ctx->userDataDdtHeader.entries * sizeof(uint16_t)
|
||||
: ctx->userDataDdtHeader.entries * sizeof(uint32_t);
|
||||
size_t primary_table_size = ctx->userDataDdtHeader.entries * sizeof(uint32_t);
|
||||
|
||||
if(ctx->userDataDdtHeader.sizeType == SmallDdtSizeType)
|
||||
written_bytes = fwrite(ctx->userDataDdtMini, primary_table_size, 1, ctx->imageStream);
|
||||
else
|
||||
written_bytes = fwrite(ctx->userDataDdtBig, primary_table_size, 1, ctx->imageStream);
|
||||
|
||||
if(written_bytes != 1)
|
||||
@@ -1716,23 +1564,16 @@ bool set_ddt_multi_level_v2(aaruformatContext *ctx, uint64_t sector_address, boo
|
||||
fseek(ctx->imageStream, saved_pos, SEEK_SET);
|
||||
|
||||
// Free the cached table
|
||||
if(ctx->userDataDdtHeader.sizeType == SmallDdtSizeType && ctx->cachedSecondaryDdtSmall)
|
||||
{
|
||||
free(ctx->cachedSecondaryDdtSmall);
|
||||
ctx->cachedSecondaryDdtSmall = NULL;
|
||||
}
|
||||
else if(ctx->userDataDdtHeader.sizeType == BigDdtSizeType && ctx->cachedSecondaryDdtBig)
|
||||
{
|
||||
|
||||
free(ctx->cachedSecondaryDdtBig);
|
||||
ctx->cachedSecondaryDdtBig = NULL;
|
||||
}
|
||||
|
||||
// Restore file position
|
||||
fseek(ctx->imageStream, current_pos, SEEK_SET);
|
||||
}
|
||||
|
||||
// Step 5: Check if the specified block already has an existing secondary level table
|
||||
create_new_table = ctx->cachedSecondaryDdtSmall == NULL && ctx->cachedSecondaryDdtBig == NULL;
|
||||
create_new_table = ctx->cachedSecondaryDdtBig == NULL;
|
||||
|
||||
if(!create_new_table && secondary_ddt_offset != 0)
|
||||
{
|
||||
@@ -1788,9 +1629,7 @@ bool set_ddt_multi_level_v2(aaruformatContext *ctx, uint64_t sector_address, boo
|
||||
}
|
||||
|
||||
// Cache the loaded table
|
||||
if(ctx->userDataDdtHeader.sizeType == SmallDdtSizeType)
|
||||
ctx->cachedSecondaryDdtSmall = (uint16_t *)buffer;
|
||||
else
|
||||
|
||||
ctx->cachedSecondaryDdtBig = (uint32_t *)buffer;
|
||||
|
||||
ctx->cachedDdtOffset = secondary_ddt_offset;
|
||||
@@ -1799,9 +1638,7 @@ bool set_ddt_multi_level_v2(aaruformatContext *ctx, uint64_t sector_address, boo
|
||||
if(create_new_table)
|
||||
{
|
||||
// Create a new empty table
|
||||
size_t table_size = ctx->userDataDdtHeader.sizeType == SmallDdtSizeType
|
||||
? items_per_ddt_entry * sizeof(uint16_t)
|
||||
: items_per_ddt_entry * sizeof(uint32_t);
|
||||
size_t table_size = items_per_ddt_entry * sizeof(uint32_t);
|
||||
|
||||
buffer = calloc(1, table_size);
|
||||
if(buffer == NULL)
|
||||
@@ -1811,9 +1648,6 @@ bool set_ddt_multi_level_v2(aaruformatContext *ctx, uint64_t sector_address, boo
|
||||
return false;
|
||||
}
|
||||
|
||||
if(ctx->userDataDdtHeader.sizeType == SmallDdtSizeType)
|
||||
ctx->cachedSecondaryDdtSmall = (uint16_t *)buffer;
|
||||
else
|
||||
ctx->cachedSecondaryDdtBig = (uint32_t *)buffer;
|
||||
|
||||
ctx->cachedDdtOffset = 0; // Will be set when written to file
|
||||
@@ -1828,20 +1662,6 @@ bool set_ddt_multi_level_v2(aaruformatContext *ctx, uint64_t sector_address, boo
|
||||
*ddt_entry = offset & (1ULL << ctx->userDataDdtHeader.dataShift) - 1 | block_index
|
||||
<< ctx->userDataDdtHeader.dataShift;
|
||||
|
||||
if(ctx->userDataDdtHeader.sizeType == SmallDdtSizeType)
|
||||
{
|
||||
// Overflow detection for DDT entry
|
||||
if(*ddt_entry > 0xFFF)
|
||||
{
|
||||
FATAL("DDT overflow: media does not fit in small DDT");
|
||||
TRACE("Exiting set_ddt_multi_level_v2() = false");
|
||||
return false;
|
||||
}
|
||||
|
||||
*ddt_entry |= (uint64_t)sector_status << 12;
|
||||
}
|
||||
else if(ctx->userDataDdtHeader.sizeType == BigDdtSizeType)
|
||||
{
|
||||
// Overflow detection for DDT entry
|
||||
if(*ddt_entry > 0xFFFFFFF)
|
||||
{
|
||||
@@ -1852,18 +1672,9 @@ bool set_ddt_multi_level_v2(aaruformatContext *ctx, uint64_t sector_address, boo
|
||||
|
||||
*ddt_entry |= (uint64_t)sector_status << 28;
|
||||
}
|
||||
}
|
||||
|
||||
if(ctx->userDataDdtHeader.sizeType == SmallDdtSizeType)
|
||||
{
|
||||
TRACE("Setting small secondary DDT entry %d to %u", sector_address % items_per_ddt_entry, (uint16_t)*ddt_entry);
|
||||
ctx->cachedSecondaryDdtSmall[sector_address % items_per_ddt_entry] = (uint16_t)*ddt_entry;
|
||||
}
|
||||
else if(ctx->userDataDdtHeader.sizeType == BigDdtSizeType)
|
||||
{
|
||||
TRACE("Setting big secondary DDT entry %d to %u", sector_address % items_per_ddt_entry, (uint32_t)*ddt_entry);
|
||||
ctx->cachedSecondaryDdtBig[sector_address % items_per_ddt_entry] = (uint32_t)*ddt_entry;
|
||||
}
|
||||
|
||||
TRACE("Updated secondary DDT entry at position %" PRIu64, sector_address % items_per_ddt_entry);
|
||||
TRACE("Exiting set_ddt_multi_level_v2() = true");
|
||||
|
||||
84
src/write.c
84
src/write.c
@@ -371,8 +371,8 @@ int32_t aaruf_write_sector(void *context, uint64_t sector_address, bool negative
|
||||
*
|
||||
* **Memory Management Strategy:**
|
||||
* - **Mini-DDT Arrays**: Lazily allocated 16-bit arrays sized for total addressable space (negative + user + overflow)
|
||||
* * sectorPrefixDdtMini: Tracks prefix status and buffer offsets (high 4 bits = status, low 12 bits = offset/16)
|
||||
* * sectorSuffixDdtMini: Tracks suffix status and buffer offsets (high 4 bits = status, low 12 bits = offset/288)
|
||||
* * sectorPrefixDdt2: Tracks prefix status and buffer offsets (high 4 bits = status, low 12 bits = offset/16)
|
||||
* * sectorSuffixDdt2: Tracks suffix status and buffer offsets (high 4 bits = status, low 12 bits = offset/288)
|
||||
* - **Prefix Buffer**: Dynamically growing buffer storing non-standard 16-byte CD prefixes
|
||||
* - **Suffix Buffer**: Dynamically growing buffer storing non-standard CD suffixes (288 bytes for Mode 1, 4 bytes for
|
||||
* Mode 2 Form 2, 280 bytes for Mode 2 Form 1)
|
||||
@@ -468,7 +468,7 @@ int32_t aaruf_write_sector(void *context, uint64_t sector_address, bool negative
|
||||
* - length not in {512, 524, 532, 536} for supported block media types
|
||||
*
|
||||
* @retval AARUF_ERROR_NOT_ENOUGH_MEMORY (-9) Memory allocation failed. This occurs when:
|
||||
* - Failed to allocate mini-DDT arrays (sectorPrefixDdtMini, sectorSuffixDdtMini)
|
||||
* - Failed to allocate mini-DDT arrays (sectorPrefixDdt2, sectorSuffixDdt2)
|
||||
* - Failed to allocate or grow prefix buffer (sector_prefix)
|
||||
* - Failed to allocate or grow suffix buffer (sector_suffix)
|
||||
* - Failed to allocate subheader buffer (mode2_subheaders)
|
||||
@@ -686,13 +686,13 @@ int32_t aaruf_write_sector_long(void *context, uint64_t sector_address, bool neg
|
||||
case CdMode1:
|
||||
|
||||
// If we do not have a DDT V2 for sector prefix, create one
|
||||
if(ctx->sectorPrefixDdtMini == NULL)
|
||||
if(ctx->sectorPrefixDdt2 == NULL)
|
||||
{
|
||||
ctx->sectorPrefixDdtMini =
|
||||
calloc(1, sizeof(uint16_t) * (ctx->userDataDdtHeader.negative + ctx->imageInfo.Sectors +
|
||||
ctx->sectorPrefixDdt2 =
|
||||
calloc(1, sizeof(uint32_t) * (ctx->userDataDdtHeader.negative + ctx->imageInfo.Sectors +
|
||||
ctx->userDataDdtHeader.overflow));
|
||||
|
||||
if(ctx->sectorPrefixDdtMini == NULL)
|
||||
if(ctx->sectorPrefixDdt2 == NULL)
|
||||
{
|
||||
FATAL("Could not allocate memory for CD sector prefix DDT");
|
||||
|
||||
@@ -702,13 +702,13 @@ int32_t aaruf_write_sector_long(void *context, uint64_t sector_address, bool neg
|
||||
}
|
||||
|
||||
// If we do not have a DDT V2 for sector suffix, create one
|
||||
if(ctx->sectorSuffixDdtMini == NULL)
|
||||
if(ctx->sectorSuffixDdt2 == NULL)
|
||||
{
|
||||
ctx->sectorSuffixDdtMini =
|
||||
calloc(1, sizeof(uint16_t) * (ctx->userDataDdtHeader.negative + ctx->imageInfo.Sectors +
|
||||
ctx->sectorSuffixDdt2 =
|
||||
calloc(1, sizeof(uint32_t) * (ctx->userDataDdtHeader.negative + ctx->imageInfo.Sectors +
|
||||
ctx->userDataDdtHeader.overflow));
|
||||
|
||||
if(ctx->sectorSuffixDdtMini == NULL)
|
||||
if(ctx->sectorSuffixDdt2 == NULL)
|
||||
{
|
||||
FATAL("Could not allocate memory for CD sector prefix DDT");
|
||||
|
||||
@@ -758,8 +758,8 @@ int32_t aaruf_write_sector_long(void *context, uint64_t sector_address, bool neg
|
||||
|
||||
if(empty)
|
||||
{
|
||||
ctx->sectorPrefixDdtMini[corrected_sector_address] = SectorStatusNotDumped;
|
||||
ctx->sectorSuffixDdtMini[corrected_sector_address] = SectorStatusNotDumped;
|
||||
ctx->sectorPrefixDdt2[corrected_sector_address] = SectorStatusNotDumped;
|
||||
ctx->sectorSuffixDdt2[corrected_sector_address] = SectorStatusNotDumped;
|
||||
return aaruf_write_sector(context, sector_address, negative, data + 16, SectorStatusNotDumped,
|
||||
2048);
|
||||
}
|
||||
@@ -782,13 +782,13 @@ int32_t aaruf_write_sector_long(void *context, uint64_t sector_address, bool neg
|
||||
}
|
||||
|
||||
if(prefix_correct)
|
||||
ctx->sectorPrefixDdtMini[corrected_sector_address] = SectorStatusMode1Correct << 12;
|
||||
ctx->sectorPrefixDdt2[corrected_sector_address] = SectorStatusMode1Correct << 28;
|
||||
else
|
||||
{
|
||||
// Copy CD prefix from data buffer to prefix buffer
|
||||
memcpy(ctx->sector_prefix + ctx->sector_prefix_offset, data, 16);
|
||||
ctx->sectorPrefixDdtMini[corrected_sector_address] = (uint16_t)(ctx->sector_prefix_offset / 16);
|
||||
ctx->sectorPrefixDdtMini[corrected_sector_address] |= SectorStatusErrored << 12;
|
||||
ctx->sectorPrefixDdt2[corrected_sector_address] = (uint32_t)(ctx->sector_prefix_offset / 16);
|
||||
ctx->sectorPrefixDdt2[corrected_sector_address] |= SectorStatusErrored << 28;
|
||||
ctx->sector_prefix_offset += 16;
|
||||
|
||||
// Grow prefix buffer if needed
|
||||
@@ -810,14 +810,13 @@ int32_t aaruf_write_sector_long(void *context, uint64_t sector_address, bool neg
|
||||
const bool suffix_correct = aaruf_ecc_cd_is_suffix_correct(context, data);
|
||||
|
||||
if(suffix_correct)
|
||||
ctx->sectorSuffixDdtMini[corrected_sector_address] = SectorStatusMode1Correct << 12;
|
||||
ctx->sectorSuffixDdt2[corrected_sector_address] = SectorStatusMode1Correct << 28;
|
||||
else
|
||||
{
|
||||
// Copy CD suffix from data buffer to suffix buffer
|
||||
memcpy(ctx->sector_suffix + ctx->sector_suffix_offset, data + 2064, 288);
|
||||
ctx->sectorSuffixDdtMini[corrected_sector_address] =
|
||||
(uint16_t)(ctx->sector_suffix_offset / 288);
|
||||
ctx->sectorSuffixDdtMini[corrected_sector_address] |= SectorStatusErrored << 12;
|
||||
ctx->sectorSuffixDdt2[corrected_sector_address] = (uint32_t)(ctx->sector_suffix_offset / 288);
|
||||
ctx->sectorSuffixDdt2[corrected_sector_address] |= SectorStatusErrored << 28;
|
||||
ctx->sector_suffix_offset += 288;
|
||||
|
||||
// Grow suffix buffer if needed
|
||||
@@ -842,13 +841,13 @@ int32_t aaruf_write_sector_long(void *context, uint64_t sector_address, bool neg
|
||||
case CdMode2Form2:
|
||||
case CdMode2Formless:
|
||||
// If we do not have a DDT V2 for sector prefix, create one
|
||||
if(ctx->sectorPrefixDdtMini == NULL)
|
||||
if(ctx->sectorPrefixDdt2 == NULL)
|
||||
{
|
||||
ctx->sectorPrefixDdtMini =
|
||||
calloc(1, sizeof(uint16_t) * (ctx->userDataDdtHeader.negative + ctx->imageInfo.Sectors +
|
||||
ctx->sectorPrefixDdt2 =
|
||||
calloc(1, sizeof(uint32_t) * (ctx->userDataDdtHeader.negative + ctx->imageInfo.Sectors +
|
||||
ctx->userDataDdtHeader.overflow));
|
||||
|
||||
if(ctx->sectorPrefixDdtMini == NULL)
|
||||
if(ctx->sectorPrefixDdt2 == NULL)
|
||||
{
|
||||
FATAL("Could not allocate memory for CD sector prefix DDT");
|
||||
|
||||
@@ -858,13 +857,13 @@ int32_t aaruf_write_sector_long(void *context, uint64_t sector_address, bool neg
|
||||
}
|
||||
|
||||
// If we do not have a DDT V2 for sector suffix, create one
|
||||
if(ctx->sectorSuffixDdtMini == NULL)
|
||||
if(ctx->sectorSuffixDdt2 == NULL)
|
||||
{
|
||||
ctx->sectorSuffixDdtMini =
|
||||
calloc(1, sizeof(uint16_t) * (ctx->userDataDdtHeader.negative + ctx->imageInfo.Sectors +
|
||||
ctx->sectorSuffixDdt2 =
|
||||
calloc(1, sizeof(uint32_t) * (ctx->userDataDdtHeader.negative + ctx->imageInfo.Sectors +
|
||||
ctx->userDataDdtHeader.overflow));
|
||||
|
||||
if(ctx->sectorSuffixDdtMini == NULL)
|
||||
if(ctx->sectorSuffixDdt2 == NULL)
|
||||
{
|
||||
FATAL("Could not allocate memory for CD sector prefix DDT");
|
||||
|
||||
@@ -914,8 +913,8 @@ int32_t aaruf_write_sector_long(void *context, uint64_t sector_address, bool neg
|
||||
|
||||
if(empty)
|
||||
{
|
||||
ctx->sectorPrefixDdtMini[corrected_sector_address] = SectorStatusNotDumped;
|
||||
ctx->sectorSuffixDdtMini[corrected_sector_address] = SectorStatusNotDumped;
|
||||
ctx->sectorPrefixDdt2[corrected_sector_address] = SectorStatusNotDumped;
|
||||
ctx->sectorSuffixDdt2[corrected_sector_address] = SectorStatusNotDumped;
|
||||
return aaruf_write_sector(context, sector_address, negative, data + 16, SectorStatusNotDumped,
|
||||
2328);
|
||||
}
|
||||
@@ -940,14 +939,14 @@ int32_t aaruf_write_sector_long(void *context, uint64_t sector_address, bool neg
|
||||
}
|
||||
|
||||
if(prefix_correct)
|
||||
ctx->sectorPrefixDdtMini[corrected_sector_address] =
|
||||
(form2 ? SectorStatusMode2Form2Ok : SectorStatusMode2Form1Ok) << 12;
|
||||
ctx->sectorPrefixDdt2[corrected_sector_address] =
|
||||
(form2 ? SectorStatusMode2Form2Ok : SectorStatusMode2Form1Ok) << 28;
|
||||
else
|
||||
{
|
||||
// Copy CD prefix from data buffer to prefix buffer
|
||||
memcpy(ctx->sector_prefix + ctx->sector_prefix_offset, data, 16);
|
||||
ctx->sectorPrefixDdtMini[corrected_sector_address] = (uint16_t)(ctx->sector_prefix_offset / 16);
|
||||
ctx->sectorPrefixDdtMini[corrected_sector_address] |= SectorStatusErrored << 12;
|
||||
ctx->sectorPrefixDdt2[corrected_sector_address] = (uint32_t)(ctx->sector_prefix_offset / 16);
|
||||
ctx->sectorPrefixDdt2[corrected_sector_address] |= SectorStatusErrored << 28;
|
||||
ctx->sector_prefix_offset += 16;
|
||||
|
||||
// Grow prefix buffer if needed
|
||||
@@ -989,16 +988,16 @@ int32_t aaruf_write_sector_long(void *context, uint64_t sector_address, bool neg
|
||||
const bool correct_edc = computed_edc == edc;
|
||||
|
||||
if(correct_edc)
|
||||
ctx->sectorSuffixDdtMini[corrected_sector_address] = SectorStatusMode2Form2Ok << 12;
|
||||
ctx->sectorSuffixDdt2[corrected_sector_address] = SectorStatusMode2Form2Ok << 28;
|
||||
else if(edc == 0)
|
||||
ctx->sectorSuffixDdtMini[corrected_sector_address] = SectorStatusMode2Form2NoCrc << 12;
|
||||
ctx->sectorSuffixDdt2[corrected_sector_address] = SectorStatusMode2Form2NoCrc << 28;
|
||||
else
|
||||
{
|
||||
// Copy CD suffix from data buffer to suffix buffer
|
||||
memcpy(ctx->sector_suffix + ctx->sector_suffix_offset, data + 2348, 4);
|
||||
ctx->sectorSuffixDdtMini[corrected_sector_address] =
|
||||
(uint16_t)(ctx->sector_suffix_offset / 288);
|
||||
ctx->sectorSuffixDdtMini[corrected_sector_address] |= SectorStatusErrored << 12;
|
||||
ctx->sectorSuffixDdt2[corrected_sector_address] =
|
||||
(uint32_t)(ctx->sector_suffix_offset / 288);
|
||||
ctx->sectorSuffixDdt2[corrected_sector_address] |= SectorStatusErrored << 28;
|
||||
ctx->sector_suffix_offset += 288;
|
||||
|
||||
// Grow suffix buffer if needed
|
||||
@@ -1033,14 +1032,13 @@ int32_t aaruf_write_sector_long(void *context, uint64_t sector_address, bool neg
|
||||
const bool correct_edc = computed_edc == edc;
|
||||
|
||||
if(correct_ecc && correct_edc)
|
||||
ctx->sectorSuffixDdtMini[corrected_sector_address] = SectorStatusMode2Form1Ok << 12;
|
||||
ctx->sectorSuffixDdt2[corrected_sector_address] = SectorStatusMode2Form1Ok << 28;
|
||||
else
|
||||
{
|
||||
// Copy CD suffix from data buffer to suffix buffer
|
||||
memcpy(ctx->sector_suffix + ctx->sector_suffix_offset, data + 2072, 280);
|
||||
ctx->sectorSuffixDdtMini[corrected_sector_address] =
|
||||
(uint16_t)(ctx->sector_suffix_offset / 288);
|
||||
ctx->sectorSuffixDdtMini[corrected_sector_address] |= SectorStatusErrored << 12;
|
||||
ctx->sectorSuffixDdt2[corrected_sector_address] = (uint32_t)(ctx->sector_suffix_offset / 288);
|
||||
ctx->sectorSuffixDdt2[corrected_sector_address] |= SectorStatusErrored << 28;
|
||||
ctx->sector_suffix_offset += 288;
|
||||
|
||||
// Grow suffix buffer if needed
|
||||
|
||||
Reference in New Issue
Block a user