Add support for negative sector addresses in read/write functions

This commit is contained in:
2025-10-02 17:07:17 +01:00
parent 5c7610c1c0
commit a8f39093bb
10 changed files with 114 additions and 85 deletions

View File

@@ -79,13 +79,13 @@ AARU_EXPORT void AARU_CALL aaruf_crc64_free(crc64_ctx *ctx);
AARU_EXPORT void AARU_CALL aaruf_crc64_slicing(uint64_t *previous_crc, const uint8_t *data, uint32_t len);
AARU_EXPORT uint64_t AARU_CALL aaruf_crc64_data(const uint8_t *data, uint32_t len);
AARU_EXPORT int32_t AARU_CALL aaruf_read_sector(void *context, uint64_t sector_address, uint8_t *data,
uint32_t *length);
AARU_EXPORT int32_t AARU_CALL aaruf_read_sector_long(void *context, uint64_t sector_address, uint8_t *data,
AARU_EXPORT int32_t AARU_CALL aaruf_read_sector(void *context, uint64_t sector_address, bool negative, uint8_t *data,
uint32_t *length);
AARU_EXPORT int32_t AARU_CALL aaruf_read_sector_long(void *context, uint64_t sector_address, bool negative,
uint8_t *data, uint32_t *length);
AARU_EXPORT int32_t AARU_CALL aaruf_write_sector(void *context, uint64_t sector_address, const uint8_t *data,
uint8_t sector_status, uint32_t length);
AARU_EXPORT int32_t AARU_CALL aaruf_write_sector(void *context, uint64_t sector_address, bool negative,
const uint8_t *data, uint8_t sector_status, uint32_t length);
AARU_EXPORT int32_t AARU_CALL aaruf_verify_image(void *context);

View File

@@ -39,14 +39,14 @@ void process_checksum_block(aaruformatContext *ctx, const IndexEntry *entry
void add_subindex_entries(aaruformatContext *ctx, UT_array *index_entries, IndexEntry *subindex_entry);
int32_t decode_ddt_entry_v1(aaruformatContext *ctx, uint64_t sector_address, uint64_t *offset, uint64_t *block_offset,
uint8_t *sector_status);
int32_t decode_ddt_entry_v2(aaruformatContext *ctx, uint64_t sector_address, uint64_t *offset, uint64_t *block_offset,
uint8_t *sector_status);
int32_t decode_ddt_single_level_v2(aaruformatContext *ctx, uint64_t sector_address, uint64_t *offset,
int32_t decode_ddt_entry_v2(aaruformatContext *ctx, uint64_t sector_address, bool negative, uint64_t *offset,
uint64_t *block_offset, uint8_t *sector_status);
int32_t decode_ddt_multi_level_v2(aaruformatContext *ctx, uint64_t sector_address, uint64_t *offset,
int32_t decode_ddt_single_level_v2(aaruformatContext *ctx, uint64_t sector_address, bool negative, uint64_t *offset,
uint64_t *block_offset, uint8_t *sector_status);
bool set_ddt_entry_v2(aaruformatContext *ctx, uint64_t sector_address, uint64_t offset, uint64_t block_offset,
uint8_t sector_status, uint64_t *ddt_entry);
int32_t decode_ddt_multi_level_v2(aaruformatContext *ctx, uint64_t sector_address, bool negative, uint64_t *offset,
uint64_t *block_offset, uint8_t *sector_status);
bool set_ddt_entry_v2(aaruformatContext *ctx, uint64_t sector_address, bool negative, uint64_t offset,
uint64_t block_offset, uint8_t sector_status, uint64_t *ddt_entry);
bool set_ddt_single_level_v2(aaruformatContext *ctx, uint64_t sector_address, bool negative, uint64_t offset,
uint64_t block_offset, uint8_t sector_status, uint64_t *ddt_entry);
bool set_ddt_multi_level_v2(aaruformatContext *ctx, uint64_t sector_address, bool negative, uint64_t offset,

View File

@@ -484,6 +484,7 @@ int32_t process_ddt_v2(aaruformatContext *ctx, IndexEntry *entry, bool *found_us
*
* @param ctx Pointer to the aaruformat context containing the loaded DDT structures.
* @param sector_address Logical sector address to decode (will be adjusted for negative sectors).
* @param negative Indicates if the sector address is negative.
* @param offset Pointer to store the resulting sector offset within the block.
* @param block_offset Pointer to store the resulting block offset in the image.
* @param sector_status Pointer to store the sector status (dumped, not dumped, etc.).
@@ -517,11 +518,11 @@ int32_t process_ddt_v2(aaruformatContext *ctx, IndexEntry *entry, bool *found_us
* @warning All output parameters must be valid pointers. No bounds checking is performed
* on the sector_address parameter at this level.
*/
int32_t decode_ddt_entry_v2(aaruformatContext *ctx, const uint64_t sector_address, uint64_t *offset,
int32_t decode_ddt_entry_v2(aaruformatContext *ctx, const uint64_t sector_address, bool negative, uint64_t *offset,
uint64_t *block_offset, uint8_t *sector_status)
{
TRACE("Entering decode_ddt_entry_v2(%p, %" PRIu64 ", %llu, %llu, %d)", ctx, sector_address, *offset, *block_offset,
*sector_status);
TRACE("Entering decode_ddt_entry_v2(%p, %" PRIu64 ", %d, %llu, %llu, %d)", ctx, sector_address, negative, *offset,
*block_offset, *sector_status);
// Check if the context and image stream are valid
if(ctx == NULL || ctx->imageStream == NULL)
{
@@ -532,9 +533,9 @@ int32_t decode_ddt_entry_v2(aaruformatContext *ctx, const uint64_t sector_addres
}
if(ctx->userDataDdtHeader.tableShift > 0)
return decode_ddt_multi_level_v2(ctx, sector_address, offset, block_offset, sector_status);
return decode_ddt_multi_level_v2(ctx, sector_address, negative, offset, block_offset, sector_status);
return decode_ddt_single_level_v2(ctx, sector_address, offset, block_offset, sector_status);
return decode_ddt_single_level_v2(ctx, sector_address, negative, offset, block_offset, sector_status);
}
/**
@@ -547,6 +548,7 @@ int32_t decode_ddt_entry_v2(aaruformatContext *ctx, const uint64_t sector_addres
*
* @param ctx Pointer to the aaruformat context containing the loaded DDT table.
* @param sector_address Logical sector address to decode (adjusted for negative sectors).
* @param negative Indicates if the sector address is negative.
* @param offset Pointer to store the resulting sector offset within the block.
* @param block_offset Pointer to store the resulting block offset in the image.
* @param sector_status Pointer to store the sector status (dumped, not dumped, etc.).
@@ -596,11 +598,11 @@ int32_t decode_ddt_entry_v2(aaruformatContext *ctx, const uint64_t sector_addres
* @warning This function should only be called when tableShift is 0. Calling it with
* tableShift > 0 will result in AARUF_ERROR_CANNOT_READ_BLOCK.
*/
int32_t decode_ddt_single_level_v2(aaruformatContext *ctx, uint64_t sector_address, uint64_t *offset,
int32_t decode_ddt_single_level_v2(aaruformatContext *ctx, uint64_t sector_address, bool negative, uint64_t *offset,
uint64_t *block_offset, uint8_t *sector_status)
{
TRACE("Entering decode_ddt_single_level_v2(%p, %" PRIu64 ", %llu, %llu, %d)", ctx, sector_address, *offset,
*block_offset, *sector_status);
TRACE("Entering decode_ddt_single_level_v2(%p, %" PRIu64 ", %d, %llu, %llu, %d)", ctx, sector_address, negative,
*offset, *block_offset, *sector_status);
uint64_t ddt_entry = 0;
@@ -621,7 +623,10 @@ int32_t decode_ddt_single_level_v2(aaruformatContext *ctx, uint64_t sector_addre
return AARUF_ERROR_CANNOT_READ_BLOCK;
}
// TODO: Take into account the negative and overflow blocks, library-wide
// Calculate positive or negative sector
if(negative)
sector_address -= ctx->userDataDdtHeader.negative;
else
sector_address += ctx->userDataDdtHeader.negative;
if(ctx->userDataDdtHeader.sizeType == SmallDdtSizeType)
@@ -660,8 +665,8 @@ int32_t decode_ddt_single_level_v2(aaruformatContext *ctx, uint64_t sector_addre
*offset = ddt_entry & offset_mask;
*block_offset = (ddt_entry >> ctx->userDataDdtHeader.dataShift) * (1 << ctx->userDataDdtHeader.blockAlignmentShift);
TRACE("Exiting decode_ddt_single_level_v2(%p, %" PRIu64 ", %llu, %llu, %d) = AARUF_STATUS_OK", ctx, sector_address,
*offset, *block_offset, *sector_status);
TRACE("Exiting decode_ddt_single_level_v2(%p, %" PRIu64 ", %d, %llu, %llu, %d) = AARUF_STATUS_OK", ctx,
sector_address, negative, *offset, *block_offset, *sector_status);
return AARUF_STATUS_OK;
}
@@ -676,6 +681,7 @@ int32_t decode_ddt_single_level_v2(aaruformatContext *ctx, uint64_t sector_addre
*
* @param ctx Pointer to the aaruformat context containing the loaded primary DDT table.
* @param sector_address Logical sector address to decode (adjusted for negative sectors).
* @param negative Indicates if the sector address is negative.
* @param offset Pointer to store the resulting sector offset within the block.
* @param block_offset Pointer to store the resulting block offset in the image.
* @param sector_status Pointer to store the sector status (dumped, not dumped, etc.).
@@ -752,11 +758,11 @@ int32_t decode_ddt_single_level_v2(aaruformatContext *ctx, uint64_t sector_addre
* @warning No bounds checking is performed on sector_address or calculated DDT positions.
* Accessing beyond table boundaries will result in undefined behavior.
*/
int32_t decode_ddt_multi_level_v2(aaruformatContext *ctx, uint64_t sector_address, uint64_t *offset,
int32_t decode_ddt_multi_level_v2(aaruformatContext *ctx, uint64_t sector_address, bool negative, uint64_t *offset,
uint64_t *block_offset, uint8_t *sector_status)
{
TRACE("Entering decode_ddt_multi_level_v2(%p, %" PRIu64 ", %llu, %llu, %d)", ctx, sector_address, *offset,
*block_offset, *sector_status);
TRACE("Entering decode_ddt_multi_level_v2(%p, %" PRIu64 ", %d, %llu, %llu, %d)", ctx, sector_address, negative,
*offset, *block_offset, *sector_status);
uint64_t ddt_entry = 0;
uint8_t lzma_properties[LZMA_PROPERTIES_LENGTH];
@@ -786,7 +792,10 @@ int32_t decode_ddt_multi_level_v2(aaruformatContext *ctx, uint64_t sector_addres
return AARUF_ERROR_CANNOT_READ_BLOCK;
}
// TODO: Take into account the negative and overflow blocks, library-wide
// Calculate positive or negative sector
if(negative)
sector_address -= ctx->userDataDdtHeader.negative;
else
sector_address += ctx->userDataDdtHeader.negative;
items_per_ddt_entry = 1 << ctx->userDataDdtHeader.tableShift;
@@ -1011,8 +1020,8 @@ int32_t decode_ddt_multi_level_v2(aaruformatContext *ctx, uint64_t sector_addres
*offset = ddt_entry & offset_mask;
*block_offset = (ddt_entry >> ctx->userDataDdtHeader.dataShift) * (1 << ctx->userDataDdtHeader.blockAlignmentShift);
TRACE("Exiting decode_ddt_multi_level_v2(%p, %" PRIu64 ", %llu, %llu, %d) = AARUF_STATUS_OK", ctx, sector_address,
*offset, *block_offset, *sector_status);
TRACE("Exiting decode_ddt_multi_level_v2(%p, %" PRIu64 ", %d, %llu, %llu, %d) = AARUF_STATUS_OK", ctx,
sector_address, negative, *offset, *block_offset, *sector_status);
return AARUF_STATUS_OK;
}
@@ -1023,6 +1032,7 @@ int32_t decode_ddt_multi_level_v2(aaruformatContext *ctx, uint64_t sector_addres
*
* @param ctx Pointer to the aaruformat context.
* @param sector_address Logical sector address to set.
* @param negative Indicates if the sector address is negative.
* @param offset Offset to set for the sector.
* @param block_offset Block offset to set for the sector.
* @param sector_status Status to set for the sector.
@@ -1031,11 +1041,11 @@ int32_t decode_ddt_multi_level_v2(aaruformatContext *ctx, uint64_t sector_addres
* @return Returns one of the following status codes:
* @retval true if the entry was set successfully, false otherwise.
*/
bool set_ddt_entry_v2(aaruformatContext *ctx, const uint64_t sector_address, const uint64_t offset,
bool set_ddt_entry_v2(aaruformatContext *ctx, const uint64_t sector_address, bool negative, const uint64_t offset,
const uint64_t block_offset, const uint8_t sector_status, uint64_t *ddt_entry)
{
TRACE("Entering set_ddt_entry_v2(%p, %" PRIu64 ", %llu, %llu, %d)", ctx, sector_address, offset, block_offset,
sector_status);
TRACE("Entering set_ddt_entry_v2(%p, %" PRIu64 ", %d, %llu, %llu, %d)", ctx, sector_address, negative, offset,
block_offset, sector_status);
// Check if the context and image stream are valid
if(ctx == NULL || ctx->imageStream == NULL)
@@ -1070,8 +1080,8 @@ bool set_ddt_single_level_v2(aaruformatContext *ctx, uint64_t sector_address, co
const uint64_t offset, const uint64_t block_offset, const uint8_t sector_status,
uint64_t *ddt_entry)
{
TRACE("Entering set_ddt_single_level_v2(%p, %" PRIu64 ", %llu, %llu, %d)", ctx, sector_address, offset,
block_offset, sector_status);
TRACE("Entering set_ddt_single_level_v2(%p, %" PRIu64 ", %d, %llu, %llu, %d)", ctx, sector_address, negative,
offset, block_offset, sector_status);
// Check if the context and image stream are valid
if(ctx == NULL || ctx->imageStream == NULL)

View File

@@ -145,6 +145,7 @@ int32_t aaruf_read_media_tag(void *context, uint8_t *data, const int32_t tag, ui
*
* @param context Pointer to the aaruformat context.
* @param sector_address The logical sector address to read from.
* @param negative Indicates if the sector address is negative.
* @param data Pointer to buffer where sector data will be stored. Can be NULL to query length.
* @param length Pointer to variable containing buffer size on input, actual data length on output.
*
@@ -237,9 +238,9 @@ int32_t aaruf_read_media_tag(void *context, uint8_t *data, const int32_t tag, ui
* @warning Sector addresses are zero-based. The maximum valid address is
* ctx->imageInfo.Sectors - 1.
*/
int32_t aaruf_read_sector(void *context, const uint64_t sector_address, uint8_t *data, uint32_t *length)
int32_t aaruf_read_sector(void *context, const uint64_t sector_address, bool negative, uint8_t *data, uint32_t *length)
{
TRACE("Entering aaruf_read_sector(%p, %" PRIu64 ", %p, %u)", context, sector_address, data, *length);
TRACE("Entering aaruf_read_sector(%p, %" PRIu64 ", %d, %p, %u)", context, sector_address, negative, data, *length);
aaruformatContext *ctx = NULL;
uint64_t offset = 0;
@@ -281,9 +282,17 @@ int32_t aaruf_read_sector(void *context, const uint64_t sector_address, uint8_t
}
if(ctx->ddtVersion == 1)
{
if(negative)
{
FATAL("Negative sector addresses not supported in this image");
return AARUF_ERROR_SECTOR_OUT_OF_BOUNDS;
}
error_no = decode_ddt_entry_v1(ctx, sector_address, &offset, &block_offset, &sector_status);
}
else if(ctx->ddtVersion == 2)
error_no = decode_ddt_entry_v2(ctx, sector_address, &offset, &block_offset, &sector_status);
error_no = decode_ddt_entry_v2(ctx, sector_address, negative, &offset, &block_offset, &sector_status);
if(error_no != AARUF_STATUS_OK)
{
@@ -635,7 +644,7 @@ int32_t aaruf_read_track_sector(void *context, uint8_t *data, const uint64_t sec
for(int i = 0; i < ctx->numberOfDataTracks; i++)
if(ctx->dataTracks[i].sequence == track)
return aaruf_read_sector(context, ctx->dataTracks[i].start + sector_address, data, length);
return aaruf_read_sector(context, ctx->dataTracks[i].start + sector_address, false, data, length);
TRACE("Track %d not found", track);
TRACE("Exiting aaruf_read_track_sector() = AARUF_ERROR_TRACK_NOT_FOUND");
@@ -654,6 +663,7 @@ int32_t aaruf_read_track_sector(void *context, uint8_t *data, const uint64_t sec
*
* @param context Pointer to the aaruformat context.
* @param sector_address The logical sector address to read from.
* @param negative Indicates if the sector address is negative.
* @param data Pointer to buffer where complete sector data will be stored. Can be NULL to query length.
* @param length Pointer to variable containing buffer size on input, actual data length on output.
*
@@ -741,9 +751,9 @@ int32_t aaruf_read_track_sector(void *context, uint8_t *data, const uint64_t sec
* @warning Not all AaruFormat images contain the metadata necessary for long sector
* reading. Some images may only support basic sector reading via aaruf_read_sector().
*/
int32_t aaruf_read_sector_long(void *context, const uint64_t sector_address, uint8_t *data, uint32_t *length)
int32_t aaruf_read_sector_long(void *context, const uint64_t sector_address, bool negative, uint8_t *data, uint32_t *length)
{
TRACE("Entering aaruf_read_sector_long(%p, %" PRIu64 ", %p, %u)", context, sector_address, data, *length);
TRACE("Entering aaruf_read_sector_long(%p, %" PRIu64 ", %d, %p, %u)", context, sector_address, data, *length);
const aaruformatContext *ctx = NULL;
uint32_t bare_length = 0;
@@ -773,6 +783,14 @@ int32_t aaruf_read_sector_long(void *context, const uint64_t sector_address, uin
return AARUF_ERROR_NOT_AARUFORMAT;
}
uint64_t corrected_sector_address = sector_address;
// Calculate positive or negative sector
if(negative)
corrected_sector_address -= ctx->userDataDdtHeader.negative;
else
corrected_sector_address += ctx->userDataDdtHeader.negative;
switch(ctx->imageInfo.XmlMediaType)
{
case OpticalDisc:
@@ -786,10 +804,10 @@ int32_t aaruf_read_sector_long(void *context, const uint64_t sector_address, uin
}
if((ctx->sectorSuffix == NULL || ctx->sectorPrefix == NULL) &&
(ctx->sectorSuffixCorrected == NULL || ctx->sectorPrefixCorrected == NULL))
return aaruf_read_sector(context, sector_address, data, length);
return aaruf_read_sector(context, sector_address, negative, data, length);
bare_length = 0;
aaruf_read_sector(context, sector_address, NULL, &bare_length);
aaruf_read_sector(context, sector_address, negative, NULL, &bare_length);
TRACE("Allocating memory for bare data");
bare_data = (uint8_t *)malloc(bare_length);
@@ -802,7 +820,7 @@ int32_t aaruf_read_sector_long(void *context, const uint64_t sector_address, uin
return AARUF_ERROR_NOT_ENOUGH_MEMORY;
}
res = aaruf_read_sector(context, sector_address, bare_data, &bare_length);
res = aaruf_read_sector(context, sector_address, negative, bare_data, &bare_length);
if(res < AARUF_STATUS_OK)
{
@@ -840,20 +858,20 @@ int32_t aaruf_read_sector_long(void *context, const uint64_t sector_address, uin
memcpy(data + 16, bare_data, 2048);
if(ctx->sectorPrefix != NULL)
memcpy(data, ctx->sectorPrefix + sector_address * 16, 16);
memcpy(data, ctx->sectorPrefix + corrected_sector_address * 16, 16);
else if(ctx->sectorPrefixDdt != NULL)
{
if((ctx->sectorPrefixDdt[sector_address] & CD_XFIX_MASK) == Correct)
if((ctx->sectorPrefixDdt[corrected_sector_address] & CD_XFIX_MASK) == Correct)
{
aaruf_ecc_cd_reconstruct_prefix(data, trk.type, sector_address);
res = AARUF_STATUS_OK;
}
else if((ctx->sectorPrefixDdt[sector_address] & CD_XFIX_MASK) == NotDumped)
else if((ctx->sectorPrefixDdt[corrected_sector_address] & CD_XFIX_MASK) == NotDumped)
res = AARUF_STATUS_SECTOR_NOT_DUMPED;
else
memcpy(data,
ctx->sectorPrefixCorrected +
((ctx->sectorPrefixDdt[sector_address] & CD_DFIX_MASK) - 1) * 16,
((ctx->sectorPrefixDdt[corrected_sector_address] & CD_DFIX_MASK) - 1) * 16,
16);
}
else
@@ -865,20 +883,20 @@ int32_t aaruf_read_sector_long(void *context, const uint64_t sector_address, uin
if(res != AARUF_STATUS_OK) return res;
if(ctx->sectorSuffix != NULL)
memcpy(data + 2064, ctx->sectorSuffix + sector_address * 288, 288);
memcpy(data + 2064, ctx->sectorSuffix + corrected_sector_address * 288, 288);
else if(ctx->sectorSuffixDdt != NULL)
{
if((ctx->sectorSuffixDdt[sector_address] & CD_XFIX_MASK) == Correct)
if((ctx->sectorSuffixDdt[corrected_sector_address] & CD_XFIX_MASK) == Correct)
{
aaruf_ecc_cd_reconstruct(ctx->eccCdContext, data, trk.type);
res = AARUF_STATUS_OK;
}
else if((ctx->sectorSuffixDdt[sector_address] & CD_XFIX_MASK) == NotDumped)
else if((ctx->sectorSuffixDdt[corrected_sector_address] & CD_XFIX_MASK) == NotDumped)
res = AARUF_STATUS_SECTOR_NOT_DUMPED;
else
memcpy(data + 2064,
ctx->sectorSuffixCorrected +
((ctx->sectorSuffixDdt[sector_address] & CD_DFIX_MASK) - 1) * 288,
((ctx->sectorSuffixDdt[corrected_sector_address] & CD_DFIX_MASK) - 1) * 288,
288);
}
else
@@ -892,20 +910,20 @@ int32_t aaruf_read_sector_long(void *context, const uint64_t sector_address, uin
case CdMode2Form1:
case CdMode2Form2:
if(ctx->sectorPrefix != NULL)
memcpy(data, ctx->sectorPrefix + sector_address * 16, 16);
memcpy(data, ctx->sectorPrefix + corrected_sector_address * 16, 16);
else if(ctx->sectorPrefixDdt != NULL)
{
if((ctx->sectorPrefixDdt[sector_address] & CD_XFIX_MASK) == Correct)
if((ctx->sectorPrefixDdt[corrected_sector_address] & CD_XFIX_MASK) == Correct)
{
aaruf_ecc_cd_reconstruct_prefix(data, trk.type, sector_address);
res = AARUF_STATUS_OK;
}
else if((ctx->sectorPrefixDdt[sector_address] & CD_XFIX_MASK) == NotDumped)
else if((ctx->sectorPrefixDdt[corrected_sector_address] & CD_XFIX_MASK) == NotDumped)
res = AARUF_STATUS_SECTOR_NOT_DUMPED;
else
memcpy(data,
ctx->sectorPrefixCorrected +
((ctx->sectorPrefixDdt[sector_address] & CD_DFIX_MASK) - 1) * 16,
((ctx->sectorPrefixDdt[corrected_sector_address] & CD_DFIX_MASK) - 1) * 16,
16);
}
else
@@ -918,21 +936,21 @@ int32_t aaruf_read_sector_long(void *context, const uint64_t sector_address, uin
if(ctx->mode2Subheaders != NULL && ctx->sectorSuffixDdt != NULL)
{
memcpy(data + 16, ctx->mode2Subheaders + sector_address * 8, 8);
memcpy(data + 16, ctx->mode2Subheaders + corrected_sector_address * 8, 8);
if((ctx->sectorSuffixDdt[sector_address] & CD_XFIX_MASK) == Mode2Form1Ok)
if((ctx->sectorSuffixDdt[corrected_sector_address] & CD_XFIX_MASK) == Mode2Form1Ok)
{
memcpy(data + 24, bare_data, 2048);
aaruf_ecc_cd_reconstruct(ctx->eccCdContext, data, CdMode2Form1);
}
else if((ctx->sectorSuffixDdt[sector_address] & CD_XFIX_MASK) == Mode2Form2Ok ||
(ctx->sectorSuffixDdt[sector_address] & CD_XFIX_MASK) == Mode2Form2NoCrc)
else if((ctx->sectorSuffixDdt[corrected_sector_address] & CD_XFIX_MASK) == Mode2Form2Ok ||
(ctx->sectorSuffixDdt[corrected_sector_address] & CD_XFIX_MASK) == Mode2Form2NoCrc)
{
memcpy(data + 24, bare_data, 2324);
if((ctx->sectorSuffixDdt[sector_address] & CD_XFIX_MASK) == Mode2Form2Ok)
if((ctx->sectorSuffixDdt[corrected_sector_address] & CD_XFIX_MASK) == Mode2Form2Ok)
aaruf_ecc_cd_reconstruct(ctx->eccCdContext, data, CdMode2Form2);
}
else if((ctx->sectorSuffixDdt[sector_address] & CD_XFIX_MASK) == NotDumped)
else if((ctx->sectorSuffixDdt[corrected_sector_address] & CD_XFIX_MASK) == NotDumped)
res = AARUF_STATUS_SECTOR_NOT_DUMPED;
else
// Mode 2 where ECC failed
@@ -940,7 +958,7 @@ int32_t aaruf_read_sector_long(void *context, const uint64_t sector_address, uin
}
else if(ctx->mode2Subheaders != NULL)
{
memcpy(data + 16, ctx->mode2Subheaders + sector_address * 8, 8);
memcpy(data + 16, ctx->mode2Subheaders + corrected_sector_address * 8, 8);
memcpy(data + 24, bare_data, 2328);
}
else
@@ -963,7 +981,7 @@ int32_t aaruf_read_sector_long(void *context, const uint64_t sector_address, uin
case AppleSonyDS:
case AppleWidget:
case PriamDataTower:
if(ctx->sectorSubchannel == NULL) return aaruf_read_sector(context, sector_address, data, length);
if(ctx->sectorSubchannel == NULL) return aaruf_read_sector(context, sector_address, negative, data, length);
switch(ctx->imageInfo.MediaType)
{
@@ -1008,7 +1026,7 @@ int32_t aaruf_read_sector_long(void *context, const uint64_t sector_address, uin
return AARUF_ERROR_NOT_ENOUGH_MEMORY;
}
res = aaruf_read_sector(context, sector_address, bare_data, &bare_length);
res = aaruf_read_sector(context, sector_address, negative, bare_data, &bare_length);
if(bare_length != 512)
{
@@ -1019,7 +1037,7 @@ int32_t aaruf_read_sector_long(void *context, const uint64_t sector_address, uin
return res;
}
memcpy(data, ctx->sectorSubchannel + sector_address * tag_length, tag_length);
memcpy(data, ctx->sectorSubchannel + corrected_sector_address * tag_length, tag_length);
memcpy(data, bare_data, 512);
free(bare_data);

View File

@@ -36,6 +36,7 @@
*
* @param context Pointer to the aaruformat context.
* @param sector_address Logical sector address to write.
* @param negative Indicates if the sector address is negative.
* @param data Pointer to the data buffer to write.
* @param sector_status Status of the sector to write.
* @param length Length of the data buffer.
@@ -96,11 +97,11 @@
* @warning No bounds checking is performed on sector_address. Writing beyond media limits
* may result in undefined behavior (TODO: implement bounds checking).
*/
int32_t aaruf_write_sector(void *context, uint64_t sector_address, const uint8_t *data, uint8_t sector_status,
uint32_t length)
int32_t aaruf_write_sector(void *context, uint64_t sector_address, bool negative, const uint8_t *data,
uint8_t sector_status, uint32_t length)
{
TRACE("Entering aaruf_write_sector(%p, %" PRIu64 ", %p, %u, %u)", context, sector_address, data, sector_status,
length);
TRACE("Entering aaruf_write_sector(%p, %" PRIu64 ", %d, %p, %u, %u)", context, sector_address, negative, data,
sector_status, length);
// Check context is correct AaruFormat context
if(context == NULL)
@@ -169,8 +170,8 @@ int32_t aaruf_write_sector(void *context, uint64_t sector_address, const uint8_t
bool existing = lookup_map(ctx->sectorHashMap, hash, &ddt_entry);
TRACE("Block does %s exist in deduplication map", existing ? "already" : "not yet");
ddt_ok = set_ddt_entry_v2(ctx, sector_address, ctx->currentBlockOffset, ctx->nextBlockPosition, sector_status,
&ddt_entry);
ddt_ok = set_ddt_entry_v2(ctx, sector_address, negative, ctx->currentBlockOffset, ctx->nextBlockPosition,
sector_status, &ddt_entry);
if(!ddt_ok)
{
TRACE("Exiting aaruf_write_sector() = AARUF_ERROR_CANNOT_SET_DDT_ENTRY");
@@ -188,8 +189,8 @@ int32_t aaruf_write_sector(void *context, uint64_t sector_address, const uint8_t
insert_map(ctx->sectorHashMap, hash, ddt_entry);
}
else
ddt_ok = set_ddt_entry_v2(ctx, sector_address, ctx->currentBlockOffset, ctx->nextBlockPosition, sector_status,
&ddt_entry);
ddt_ok = set_ddt_entry_v2(ctx, sector_address, negative, ctx->currentBlockOffset, ctx->nextBlockPosition,
sector_status, &ddt_entry);
if(!ddt_ok)
{

View File

@@ -106,8 +106,8 @@ int cli_compare(const char *path1, const char *path2)
buffer1_length = ctx1->imageInfo.SectorSize;
buffer2_length = ctx2->imageInfo.SectorSize;
read_result1 = aaruf_read_sector(ctx1, sector, buffer1, &buffer1_length);
read_result2 = aaruf_read_sector(ctx2, sector, buffer2, &buffer2_length);
read_result1 = aaruf_read_sector(ctx1, sector, false, buffer1, &buffer1_length);
read_result2 = aaruf_read_sector(ctx2, sector, false, buffer2, &buffer2_length);
// Handle read errors or missing sectors
const bool sector1_available = read_result1 == AARUF_STATUS_OK;

View File

@@ -489,7 +489,7 @@ int compare(const char *path1, const char *path2)
tb_printf(2, height - 5, TB_WHITE | TB_BOLD, TB_BLUE, "Comparing sector %llu of %llu", i + 1, sectors);
draw_progress_bar(height - 4, i * 100 / sectors);
errno = aaruf_read_sector(ctx1, i, buffer1, &sectorSize);
errno = aaruf_read_sector(ctx1, i, false, buffer1, &sectorSize);
if(errno != AARUF_STATUS_OK && errno != AARUF_STATUS_SECTOR_NOT_DUMPED)
{
tb_printf(2, lr++, TB_RED | TB_BOLD, TB_BLUE, "Error reading sector %llu: %s", i, errno);
@@ -497,7 +497,7 @@ int compare(const char *path1, const char *path2)
continue;
}
errno = aaruf_read_sector(ctx2, i, buffer2, &sectorSize);
errno = aaruf_read_sector(ctx2, i, false, buffer2, &sectorSize);
if(errno != AARUF_STATUS_OK && errno != AARUF_STATUS_SECTOR_NOT_DUMPED)
{
tb_printf(2, rr++, TB_RED | TB_BOLD, TB_BLUE, "Error reading sector %llu: %s", i, errno);

View File

@@ -93,7 +93,7 @@ int convert(const char *input_path, const char *output_path)
}
// Read sector from input
res = aaruf_read_sector(input_ctx, sector, sector_data, &read_length);
res = aaruf_read_sector(input_ctx, sector, false, sector_data, &read_length);
if(res != AARUF_STATUS_OK)
{
printf("\nError %d when reading sector %llu from input image.\n", res, (unsigned long long)sector);
@@ -101,7 +101,7 @@ int convert(const char *input_path, const char *output_path)
}
// Write sector to output
res = aaruf_write_sector(output_ctx, sector, sector_data, SectorStatusDumped, read_length);
res = aaruf_write_sector(output_ctx, sector, false, sector_data, SectorStatusDumped, read_length);
if(res != AARUF_STATUS_OK)
{
printf("\nError %d when writing sector %llu to output image.\n", res, (unsigned long long)sector);

View File

@@ -39,7 +39,7 @@ int read(const unsigned long long sector_no, const char *path)
return errno;
}
res = aaruf_read_sector(ctx, sector_no, NULL, &length);
res = aaruf_read_sector(ctx, sector_no, false, NULL, &length);
if(res != AARUF_STATUS_OK && res != AARUF_ERROR_BUFFER_TOO_SMALL)
{
@@ -58,7 +58,7 @@ int read(const unsigned long long sector_no, const char *path)
return AARUF_ERROR_NOT_ENOUGH_MEMORY;
}
res = aaruf_read_sector(ctx, sector_no, data, &length);
res = aaruf_read_sector(ctx, sector_no, false, data, &length);
if(res != AARUF_STATUS_OK)
{
@@ -91,7 +91,7 @@ int read_long(const unsigned long long sector_no, const char *path)
return errno;
}
res = aaruf_read_sector_long(ctx, sector_no, NULL, &length);
res = aaruf_read_sector_long(ctx, sector_no, false, NULL, &length);
if(res != AARUF_STATUS_OK && res != AARUF_ERROR_BUFFER_TOO_SMALL)
{
@@ -110,7 +110,7 @@ int read_long(const unsigned long long sector_no, const char *path)
return AARUF_ERROR_NOT_ENOUGH_MEMORY;
}
res = aaruf_read_sector_long(ctx, sector_no, data, &length);
res = aaruf_read_sector_long(ctx, sector_no, false, data, &length);
if(res != AARUF_STATUS_OK)
{

View File

@@ -83,7 +83,7 @@ int verify_sectors(const char *path)
for(uint64_t s = 0; s < ctx->imageInfo.Sectors; s++)
{
printf("\rVerifying sector %llu...", s);
res = aaruf_read_sector_long(ctx, s, buffer, &buffer_len);
res = aaruf_read_sector_long(ctx, s, buffer, false, &buffer_len);
if(res != AARUF_STATUS_OK)
{