From dde81f67730915d10c15e3efff56d35b4f26789c Mon Sep 17 00:00:00 2001 From: Natalia Portillo Date: Sat, 11 Oct 2025 12:42:32 +0100 Subject: [PATCH] Add sector status parameter to read sector functions --- include/aaruformat/decls.h | 10 ++++---- src/read.c | 50 +++++++++++++++++++++++--------------- tool/cli_compare.c | 15 +++++++++--- tool/compare.c | 6 +++-- tool/convert.c | 13 +++++----- tool/read.c | 26 +++++++++++--------- tool/verify.c | 6 +++-- 7 files changed, 75 insertions(+), 51 deletions(-) diff --git a/include/aaruformat/decls.h b/include/aaruformat/decls.h index 369a579..4743ec9 100644 --- a/include/aaruformat/decls.h +++ b/include/aaruformat/decls.h @@ -90,9 +90,9 @@ AARU_EXPORT int32_t AARU_CALL aaruf_get_tracks(const void *context, uint8_t *buf AARU_EXPORT int32_t AARU_CALL aaruf_set_tracks(void *context, TrackEntry *tracks, const int count); AARU_EXPORT int32_t AARU_CALL aaruf_read_sector(void *context, uint64_t sector_address, bool negative, uint8_t *data, - uint32_t *length); + uint32_t *length, uint8_t *sector_status); AARU_EXPORT int32_t AARU_CALL aaruf_read_sector_long(void *context, uint64_t sector_address, bool negative, - uint8_t *data, uint32_t *length); + uint8_t *data, uint32_t *length, uint8_t *sector_status); 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); @@ -137,9 +137,9 @@ AARU_EXPORT void AARU_CALL aaruf_ecc_cd_reconstruct(void *context, uint8_t *sect AARU_EXPORT uint32_t AARU_CALL aaruf_edc_cd_compute(void *context, uint32_t edc, const uint8_t *src, int size, int pos); AARU_EXPORT int32_t AARU_CALL aaruf_read_track_sector(void *context, uint8_t *data, uint64_t sector_address, - uint32_t *length, uint8_t track); -AARU_EXPORT int32_t AARU_CALL aaruf_read_sector_tag(const void *context, uint64_t sector_address, bool negative, uint8_t *buffer, - uint32_t *length, int32_t tag); + uint32_t *length, uint8_t track, uint8_t *sector_status); +AARU_EXPORT int32_t AARU_CALL aaruf_read_sector_tag(const void *context, uint64_t sector_address, bool negative, + uint8_t *buffer, uint32_t *length, int32_t tag); AARU_LOCAL int32_t AARU_CALL aaruf_get_media_tag_type_for_datatype(int32_t type); AARU_LOCAL int32_t AARU_CALL aaruf_get_datatype_for_media_tag_type(int32_t tag_type); diff --git a/src/read.c b/src/read.c index 6049d4e..6159504 100644 --- a/src/read.c +++ b/src/read.c @@ -157,6 +157,9 @@ AARU_EXPORT int32_t AARU_CALL aaruf_read_media_tag(void *context, uint8_t *data, * @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. + * @param sector_status Pointer to variable that will receive the sector status flags. Must not be NULL. + * The status indicates the condition of the sector data, such as whether it contains + * errors, was not dumped, or has other quality indicators from the imaging process. * * @return Returns one of the following status codes: * @retval AARUF_STATUS_OK (0) Successfully read the sector data. This is returned when: @@ -248,7 +251,7 @@ AARU_EXPORT int32_t AARU_CALL aaruf_read_media_tag(void *context, uint8_t *data, * ctx->imageInfo.Sectors - 1. */ AARU_EXPORT int32_t AARU_CALL aaruf_read_sector(void *context, const uint64_t sector_address, bool negative, - uint8_t *data, uint32_t *length) + uint8_t *data, uint32_t *length, uint8_t *sector_status) { const uint32_t initial_length = length == NULL ? 0U : *length; @@ -262,10 +265,10 @@ AARU_EXPORT int32_t AARU_CALL aaruf_read_sector(void *context, const uint64_t se uint8_t *block = NULL; size_t read_bytes = 0; uint8_t lzma_properties[LZMA_PROPERTIES_LENGTH]; - size_t lzma_size = 0; - uint8_t *cmp_data = NULL; - int error_no = 0; - uint8_t sector_status = 0; + size_t lzma_size = 0; + uint8_t *cmp_data = NULL; + int error_no = 0; + *sector_status = SectorStatusNotDumped; if(context == NULL) { @@ -318,10 +321,10 @@ AARU_EXPORT int32_t AARU_CALL aaruf_read_sector(void *context, const uint64_t se return AARUF_ERROR_SECTOR_OUT_OF_BOUNDS; } - error_no = decode_ddt_entry_v1(ctx, sector_address, &offset, &block_offset, §or_status); + error_no = decode_ddt_entry_v1(ctx, sector_address, &offset, &block_offset, sector_status); } else if(ctx->ddt_version == 2) - error_no = decode_ddt_entry_v2(ctx, sector_address, negative, &offset, &block_offset, §or_status); + error_no = decode_ddt_entry_v2(ctx, sector_address, negative, &offset, &block_offset, sector_status); if(error_no != AARUF_STATUS_OK) { @@ -332,7 +335,7 @@ AARU_EXPORT int32_t AARU_CALL aaruf_read_sector(void *context, const uint64_t se } // Partially written image... as we can't know the real sector size just assume it's common :/ - if(sector_status == SectorStatusNotDumped) + if(*sector_status == SectorStatusNotDumped) { *length = ctx->image_info.SectorSize; @@ -606,6 +609,9 @@ AARU_EXPORT int32_t AARU_CALL aaruf_read_sector(void *context, const uint64_t se * @param sector_address The sector address relative to the track start. * @param length Pointer to variable containing buffer size on input, actual data length on output. * @param track The track sequence number to read from. + * @param sector_status Pointer to variable that will receive the sector status flags. Must not be NULL. + * The status indicates the condition of the sector data, such as whether it contains + * errors, was not dumped, or has other quality indicators from the imaging process. * * @return Returns one of the following status codes: * @retval AARUF_STATUS_OK (0) Successfully read the sector data from the specified track. This is returned when: @@ -662,7 +668,7 @@ AARU_EXPORT int32_t AARU_CALL aaruf_read_sector(void *context, const uint64_t se * existence before assuming a track number is valid. */ AARU_EXPORT int32_t AARU_CALL aaruf_read_track_sector(void *context, uint8_t *data, const uint64_t sector_address, - uint32_t *length, const uint8_t track) + uint32_t *length, const uint8_t track, uint8_t *sector_status) { const uint32_t initial_length = length == NULL ? 0U : *length; @@ -706,7 +712,8 @@ AARU_EXPORT int32_t AARU_CALL aaruf_read_track_sector(void *context, uint8_t *da for(int i = 0; i < ctx->number_of_data_tracks; i++) if(ctx->data_tracks[i].sequence == track) - return aaruf_read_sector(context, ctx->data_tracks[i].start + sector_address, false, data, length); + return aaruf_read_sector(context, ctx->data_tracks[i].start + sector_address, false, data, length, + sector_status); TRACE("Track %d not found", track); TRACE("Exiting aaruf_read_track_sector() = AARUF_ERROR_TRACK_NOT_FOUND"); @@ -728,6 +735,9 @@ AARU_EXPORT int32_t AARU_CALL aaruf_read_track_sector(void *context, uint8_t *da * @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. + * @param sector_status Pointer to variable that will receive the sector status flags. Must not be NULL. + * The status indicates the condition of the sector data, such as whether it contains + * errors, was not dumped, or has other quality indicators from the imaging process. * * @return Returns one of the following status codes: * @retval AARUF_STATUS_OK (0) Successfully read the complete sector with metadata. This is returned when: @@ -814,7 +824,7 @@ AARU_EXPORT int32_t AARU_CALL aaruf_read_track_sector(void *context, uint8_t *da * reading. Some images may only support basic sector reading via aaruf_read_sector(). */ AARU_EXPORT int32_t AARU_CALL aaruf_read_sector_long(void *context, const uint64_t sector_address, bool negative, - uint8_t *data, uint32_t *length) + uint8_t *data, uint32_t *length, uint8_t *sector_status) { const uint32_t initial_length = length == NULL ? 0U : *length; @@ -896,7 +906,7 @@ AARU_EXPORT int32_t AARU_CALL aaruf_read_sector_long(void *context, const uint64 { if(ctx->sector_id == NULL || ctx->sector_ied == NULL || ctx->sector_cpr_mai == NULL || ctx->sector_edc == NULL) - return aaruf_read_sector(context, sector_address, negative, data, length); + return aaruf_read_sector(context, sector_address, negative, data, length, sector_status); if(*length < 2064 || data == NULL) { @@ -908,7 +918,7 @@ AARU_EXPORT int32_t AARU_CALL aaruf_read_sector_long(void *context, const uint64 } bare_length = 0; - query_status = aaruf_read_sector(context, sector_address, negative, NULL, &bare_length); + query_status = aaruf_read_sector(context, sector_address, negative, NULL, &bare_length, sector_status); if(query_status != AARUF_ERROR_BUFFER_TOO_SMALL && query_status != AARUF_STATUS_OK) { @@ -935,7 +945,7 @@ AARU_EXPORT int32_t AARU_CALL aaruf_read_sector_long(void *context, const uint64 return AARUF_ERROR_NOT_ENOUGH_MEMORY; } - res = aaruf_read_sector(context, sector_address, negative, bare_data, &bare_length); + res = aaruf_read_sector(context, sector_address, negative, bare_data, &bare_length, sector_status); if(res != AARUF_STATUS_OK) { @@ -970,10 +980,10 @@ AARU_EXPORT int32_t AARU_CALL aaruf_read_sector_long(void *context, const uint64 if((ctx->sector_suffix == NULL || ctx->sector_prefix == NULL) && (ctx->sector_suffix_ddt == NULL || ctx->sector_prefix_ddt == NULL) && (ctx->sector_suffix_ddt2 == NULL || ctx->sector_prefix_ddt2 == NULL)) - return aaruf_read_sector(context, sector_address, negative, data, length); + return aaruf_read_sector(context, sector_address, negative, data, length, sector_status); bare_length = 0; - query_status = aaruf_read_sector(context, sector_address, negative, NULL, &bare_length); + query_status = aaruf_read_sector(context, sector_address, negative, NULL, &bare_length, sector_status); if(query_status != AARUF_ERROR_BUFFER_TOO_SMALL && query_status != AARUF_STATUS_OK) { @@ -1000,7 +1010,7 @@ AARU_EXPORT int32_t AARU_CALL aaruf_read_sector_long(void *context, const uint64 return AARUF_ERROR_NOT_ENOUGH_MEMORY; } - res = aaruf_read_sector(context, sector_address, negative, bare_data, &bare_length); + res = aaruf_read_sector(context, sector_address, negative, bare_data, &bare_length, sector_status); if(res != AARUF_STATUS_OK) { @@ -1255,7 +1265,7 @@ AARU_EXPORT int32_t AARU_CALL aaruf_read_sector_long(void *context, const uint64 case AppleWidget: case PriamDataTower: if(ctx->sector_subchannel == NULL) - return aaruf_read_sector(context, sector_address, negative, data, length); + return aaruf_read_sector(context, sector_address, negative, data, length, sector_status); switch(ctx->image_info.MediaType) { @@ -1300,7 +1310,7 @@ AARU_EXPORT int32_t AARU_CALL aaruf_read_sector_long(void *context, const uint64 return AARUF_ERROR_NOT_ENOUGH_MEMORY; } - res = aaruf_read_sector(context, sector_address, negative, bare_data, &bare_length); + res = aaruf_read_sector(context, sector_address, negative, bare_data, &bare_length, sector_status); if(res != AARUF_STATUS_OK) { @@ -1841,4 +1851,4 @@ AARU_EXPORT int32_t AARU_CALL aaruf_read_sector_tag(const void *context, const u TRACE("Do not know how to read sector tag %d", tag); return AARUF_ERROR_INVALID_TAG; } -} \ No newline at end of file +} diff --git a/tool/cli_compare.c b/tool/cli_compare.c index 346226f..7d97dd9 100644 --- a/tool/cli_compare.c +++ b/tool/cli_compare.c @@ -40,6 +40,8 @@ int cli_compare(const char *path1, const char *path2, bool use_long) int result = 0; int32_t read_result1 = 0; int32_t read_result2 = 0; + uint8_t sector_status1 = 0; + uint8_t sector_status2 = 0; printf("Opening first image: %s\n", path1); ctx1 = aaruf_open(path1); @@ -115,13 +117,13 @@ int cli_compare(const char *path1, const char *path2, bool use_long) if(use_long) { - read_result1 = aaruf_read_sector_long(ctx1, sector, false, buffer1, &buffer1_length); - read_result2 = aaruf_read_sector_long(ctx2, sector, false, buffer2, &buffer2_length); + read_result1 = aaruf_read_sector_long(ctx1, sector, false, buffer1, &buffer1_length, §or_status1); + read_result2 = aaruf_read_sector_long(ctx2, sector, false, buffer2, &buffer2_length, §or_status2); } else { - read_result1 = aaruf_read_sector(ctx1, sector, false, buffer1, &buffer1_length); - read_result2 = aaruf_read_sector(ctx2, sector, false, buffer2, &buffer2_length); + read_result1 = aaruf_read_sector(ctx1, sector, false, buffer1, &buffer1_length, §or_status1); + read_result2 = aaruf_read_sector(ctx2, sector, false, buffer2, &buffer2_length, §or_status2); } // Handle read errors or missing sectors @@ -139,6 +141,11 @@ int cli_compare(const char *path1, const char *path2, bool use_long) // One sector is available, the other is not - they're different sectors_different = true; } + else if(sector_status1 != sector_status2) + { + // Both sectors are available but have different status codes + sectors_different = true; + } else if(sector1_available && sector2_available && (buffer1_length != buffer2_length || memcmp(buffer1, buffer2, buffer1_length) != 0)) { diff --git a/tool/compare.c b/tool/compare.c index edd73ed..8984e29 100644 --- a/tool/compare.c +++ b/tool/compare.c @@ -62,6 +62,8 @@ int compare(const char *path1, const char *path2) uintattr_t sectorsColor = TB_WHITE; uintattr_t sectorSizeColor = TB_WHITE; uintattr_t versionColor = TB_WHITE; + uint8_t sector_status1 = 0; + uint8_t sector_status2 = 0; // Initialize termbox2 if(tb_init() != 0) return 1; @@ -489,7 +491,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, false, buffer1, §orSize); + errno = aaruf_read_sector(ctx1, i, false, buffer1, §orSize, §or_status1); 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 +499,7 @@ int compare(const char *path1, const char *path2) continue; } - errno = aaruf_read_sector(ctx2, i, false, buffer2, §orSize); + errno = aaruf_read_sector(ctx2, i, false, buffer2, §orSize, §or_status2); 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); diff --git a/tool/convert.c b/tool/convert.c index 56db13b..132e9e4 100644 --- a/tool/convert.c +++ b/tool/convert.c @@ -36,6 +36,7 @@ int convert(const char *input_path, const char *output_path, bool use_long) uint32_t sector_size = 0; uint64_t total_sectors = 0; uint8_t *sector_data = NULL; + uint8_t sector_status = 0; printf("Converting image from %s to %s%s...\n", input_path, output_path, use_long ? " (long mode)" : ""); @@ -182,9 +183,9 @@ int convert(const char *input_path, const char *output_path, bool use_long) // Check sector size if(use_long) - res = aaruf_read_sector_long(input_ctx, sector, false, sector_data, &read_length); + res = aaruf_read_sector_long(input_ctx, sector, false, sector_data, &read_length, §or_status); else - res = aaruf_read_sector(input_ctx, sector, false, sector_data, &read_length); + res = aaruf_read_sector(input_ctx, sector, false, sector_data, &read_length, §or_status); if(res != AARUF_ERROR_BUFFER_TOO_SMALL) { @@ -208,9 +209,9 @@ int convert(const char *input_path, const char *output_path, bool use_long) // Read sector from input if(use_long) - res = aaruf_read_sector_long(input_ctx, sector, false, sector_data, &read_length); + res = aaruf_read_sector_long(input_ctx, sector, false, sector_data, &read_length, §or_status); else - res = aaruf_read_sector(input_ctx, sector, false, sector_data, &read_length); + res = aaruf_read_sector(input_ctx, sector, false, sector_data, &read_length, §or_status); if(res != AARUF_STATUS_OK) { @@ -220,9 +221,9 @@ int convert(const char *input_path, const char *output_path, bool use_long) // Write sector to output if(use_long) - res = aaruf_write_sector_long(output_ctx, sector, false, sector_data, SectorStatusDumped, read_length); + res = aaruf_write_sector_long(output_ctx, sector, false, sector_data, sector_status, read_length); else - res = aaruf_write_sector(output_ctx, sector, false, sector_data, SectorStatusDumped, read_length); + res = aaruf_write_sector(output_ctx, sector, false, sector_data, sector_status, read_length); if(res != AARUF_STATUS_OK) { diff --git a/tool/read.c b/tool/read.c index 7303a5f..dd5b05a 100644 --- a/tool/read.c +++ b/tool/read.c @@ -26,10 +26,11 @@ int read(const unsigned long long sector_no, const char *path) { - aaruformat_context *ctx = NULL; - int32_t res = 0; - uint32_t length = 0; - uint8_t *data = NULL; + aaruformat_context *ctx = NULL; + int32_t res = 0; + uint32_t length = 0; + uint8_t *data = NULL; + uint8_t sector_status = 0; ctx = aaruf_open(path); @@ -39,7 +40,7 @@ int read(const unsigned long long sector_no, const char *path) return errno; } - res = aaruf_read_sector(ctx, sector_no, false, NULL, &length); + res = aaruf_read_sector(ctx, sector_no, false, NULL, &length, §or_status); if(res != AARUF_STATUS_OK && res != AARUF_ERROR_BUFFER_TOO_SMALL) { @@ -58,7 +59,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, false, data, &length); + res = aaruf_read_sector(ctx, sector_no, false, data, &length, §or_status); if(res != AARUF_STATUS_OK) { @@ -78,10 +79,11 @@ int read(const unsigned long long sector_no, const char *path) int read_long(const unsigned long long sector_no, const char *path) { - aaruformat_context *ctx = NULL; - int32_t res = 0; - uint32_t length = 0; - uint8_t *data = NULL; + aaruformat_context *ctx = NULL; + int32_t res = 0; + uint32_t length = 0; + uint8_t *data = NULL; + uint8_t sector_status = 0; ctx = aaruf_open(path); @@ -91,7 +93,7 @@ int read_long(const unsigned long long sector_no, const char *path) return errno; } - res = aaruf_read_sector_long(ctx, sector_no, false, NULL, &length); + res = aaruf_read_sector_long(ctx, sector_no, false, NULL, &length, §or_status); if(res != AARUF_STATUS_OK && res != AARUF_ERROR_BUFFER_TOO_SMALL) { @@ -110,7 +112,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, false, data, &length); + res = aaruf_read_sector_long(ctx, sector_no, false, data, &length, §or_status); if(res != AARUF_STATUS_OK) { diff --git a/tool/verify.c b/tool/verify.c index cbf191b..3ac61bb 100644 --- a/tool/verify.c +++ b/tool/verify.c @@ -20,6 +20,7 @@ #include #include +#include #include "aaruformattool.h" @@ -61,7 +62,8 @@ int verify_sectors(const char *path) bool edc_correct = false; bool unknown = false; uint64_t errors = 0, unknowns = 0; - bool any_error = false; + bool any_error = false; + uint8_t sector_status = 0; if(ctx == NULL) { @@ -83,7 +85,7 @@ int verify_sectors(const char *path) for(uint64_t s = 0; s < ctx->image_info.Sectors; s++) { printf("\rVerifying sector %llu...", s); - res = aaruf_read_sector_long(ctx, s, buffer, false, &buffer_len); + res = aaruf_read_sector_long(ctx, s, buffer, false, &buffer_len, §or_status); if(res != AARUF_STATUS_OK) {