28#define VERIFY_SIZE 1048576
33 uint64_t processed = 0;
35 while(processed < total_length)
37 size_t chunk = buffer_size;
38 uint64_t remaining = total_length - processed;
40 if(remaining < chunk) chunk = (size_t)remaining;
44 size_t read_bytes = fread(buffer, 1, chunk, stream);
45 if(read_bytes != chunk)
47 FATAL(
"Could not read %s chunk (expected %zu bytes, got %zu)", label, chunk, read_bytes);
52 processed += read_bytes;
132 TRACE(
"Entering aaruf_verify_image(%p)", context);
136 size_t read_bytes = 0;
143 uint32_t signature = 0;
144 UT_array *index_entries = NULL;
149 FATAL(
"Invalid context");
158 FATAL(
"Invalid context");
165 FATAL(
"Image stream is not available");
178 read_bytes = fread(&signature, 1,
sizeof(signature), ctx->
imageStream);
179 if(read_bytes !=
sizeof(signature))
181 FATAL(
"Could not read index signature");
188 FATAL(
"Incorrect index signature %4.4s", (
char *)&signature);
202 FATAL(
"Index verification failed with error code %d", status);
213 if(index_entries == NULL)
215 FATAL(
"Could not process index");
223 FATAL(
"Cannot allocate memory for verification buffer");
229 const unsigned int entry_count = utarray_len(index_entries);
230 bool has_ddt_block =
false;
231 bool has_flux_block =
false;
233 for(
unsigned int i = 0; i < entry_count; i++)
235 IndexEntry *entry = utarray_eltptr(index_entries, i);
236 TRACE(
"Checking block with type %4.4s at position %" PRIu64, (
char *)&entry->
blockType, entry->
offset);
243 FATAL(
"Could not seek to block at offset %" PRIu64, entry->
offset);
254 FATAL(
"Could not read block header");
260 if(crc64_context == NULL)
262 FATAL(
"Could not initialize CRC64 context");
278 FATAL(
"Could not read LZMA properties");
291 FATAL(
"Could not finalize CRC64 for data block");
300 FATAL(
"Expected block CRC 0x%16llX but got 0x%16llX", block_header.
cmpCrc64, crc64);
306 crc64_context = NULL;
312 FATAL(
"Could not read DDT header");
318 if(crc64_context == NULL)
320 FATAL(
"Could not initialize CRC64 context");
336 FATAL(
"Could not read LZMA properties");
349 FATAL(
"Could not finalize CRC64 for DDT block");
358 FATAL(
"Expected DDT CRC 0x%16llX but got 0x%16llX", ddt_header.
cmpCrc64, crc64);
364 crc64_context = NULL;
370 FATAL(
"Could not read DDT2 header");
376 if(crc64_context == NULL)
378 FATAL(
"Could not initialize CRC64 context");
392 FATAL(
"Could not read LZMA properties");
405 FATAL(
"Could not finalize CRC64 for DDT2 block");
412 FATAL(
"Expected DDT2 CRC 0x%16llX but got 0x%16llX", ddt2_header.
cmpCrc64, crc64);
418 crc64_context = NULL;
425 FATAL(
"Could not read tracks header");
430 const uint64_t tracks_bytes = (uint64_t)tracks_header.
entries *
sizeof(
TrackEntry);
433 FATAL(
"Tracks header length overflow (entries=%u)", tracks_header.
entries);
439 if(crc64_context == NULL)
441 FATAL(
"Could not initialize CRC64 context");
452 FATAL(
"Could not finalize CRC64 for tracks block");
459 if(crc64 != tracks_header.
crc64)
461 FATAL(
"Expected tracks CRC 0x%16llX but got 0x%16llX", tracks_header.
crc64, crc64);
467 crc64_context = NULL;
476 FATAL(
"Could not read DPM header");
483 FATAL(
"DPM header length %" PRIu64
" does not match its contents", dpm_header.
length);
489 if(crc64_context == NULL)
491 FATAL(
"Could not initialize CRC64 context");
497 crc64_context,
"DPM block");
502 FATAL(
"Could not finalize CRC64 for DPM block");
507 if(crc64 != dpm_header.
crc64)
509 FATAL(
"Expected DPM CRC 0x%16llX but got 0x%16llX", dpm_header.
crc64, crc64);
515 crc64_context = NULL;
526 if(!has_ddt_block && !has_flux_block)
528 FATAL(
"Image contains neither a user-data DDT nor a flux data block");
536 if(crc64_context != NULL)
539 crc64_context = NULL;
548 if(index_entries != NULL)
550 utarray_free(index_entries);
551 index_entries = NULL;
554 TRACE(
"Exiting aaruf_verify_image() = %d", status);
#define LZMA_PROPERTIES_LENGTH
Size in bytes of the fixed LZMA properties header (lc/lp/pb + dictionary size).
#define AARU_MAGIC
Magic identifier for AaruFormat container (ASCII "AARUFRMT").
#define AARUF_VERSION_V1
First on‑disk version (C# implementation).
int aaruf_crc64_update(crc64_ctx *ctx, const uint8_t *data, uint32_t len)
Updates the CRC64 context with new data.
void aaruf_crc64_free(crc64_ctx *ctx)
Frees a CRC64 context.
int32_t aaruf_verify_image(void *context)
Verifies the integrity of an AaruFormat image file.
int aaruf_crc64_final(crc64_ctx *ctx, uint64_t *crc)
Computes the final CRC64 value from the context.
crc64_ctx * aaruf_crc64_init(void)
Initializes a CRC64 context.
@ IndexBlock3
Block containing the index v3.
@ DataBlock
Block containing data.
@ IndexBlock2
Block containing the index v2.
@ IndexBlock
Block containing the index (v1).
@ DeDuplicationTable2
Block containing a deduplication table v2.
@ DeDuplicationTable
Block containing a deduplication table (v1).
@ DataPositionMeasurementBlock
Block containing data position measurements (reserved / TODO).
@ TracksBlock
Block containing optical disc tracks.
@ FluxDataBlock
Block containing flux data metadata.
@ kCompressionLzmaCst
LZMA applied to Claunia Subchannel Transform processed data.
@ kCompressionLzma
LZMA compression.
#define AARUF_STATUS_OK
Sector present and read without uncorrectable errors.
#define AARUF_ERROR_CANNOT_READ_HEADER
Failed to read container header.
#define AARUF_ERROR_NOT_ENOUGH_MEMORY
Memory allocation failure (critical).
#define AARUF_ERROR_CANNOT_READ_BLOCK
Generic block read failure (seek/read error).
#define AARUF_ERROR_INVALID_BLOCK_CRC
CRC64 mismatch indicating corruption.
#define AARUF_ERROR_CANNOT_READ_INDEX
Index block unreadable / truncated / bad identifier.
#define AARUF_ERROR_NOT_AARUFORMAT
Input file/stream failed magic or structural validation.
UT_array * process_index_v2(aaruformat_context *ctx)
Processes an index block (version 2) from the image stream.
uint64_t dpm_payload_length(const DpmHeader *header)
Computes the payload length a Data Position Measurement header describes.
UT_array * process_index_v1(aaruformat_context *ctx)
Processes an index block (version 1) from the image stream.
static int aaruf_fseek(FILE *stream, aaru_off_t offset, int origin)
int32_t verify_index_v1(aaruformat_context *ctx)
Verifies the integrity of an index block (version 1) in the image stream.
int32_t verify_index_v3(aaruformat_context *ctx)
Verifies the integrity of an index block (version 3) in the image stream.
int32_t verify_index_v2(aaruformat_context *ctx)
Verifies the integrity of an index block (version 2) in the image stream.
UT_array * process_index_v3(aaruformat_context *ctx)
Processes an index block (version 3) from the image stream.
Single index entry describing a block's type, (optional) data classification, and file offset.
uint32_t blockType
Block identifier of the referenced block (value from BlockType).
uint64_t offset
Absolute byte offset in the image where the referenced block header begins.
Single optical disc track descriptor (sequence, type, LBAs, session, ISRC, flags).
Master context representing an open or in‑creation Aaru image.
AaruHeaderV2 header
Parsed container header (v2).
uint64_t magic
File magic (AARU_MAGIC) post-open.
FILE * imageStream
Underlying FILE* stream (binary mode).
Minimal ECMA-182 CRC64 incremental state container (running value only).
static int32_t update_crc64_from_stream(FILE *stream, const uint64_t total_length, void *buffer, size_t buffer_size, crc64_ctx *crc_ctx, const char *label)