libaaruformat 1.0
Aaru Data Preservation Suite - Format Library
Loading...
Searching...
No Matches
open.c
Go to the documentation of this file.
1/*
2 * This file is part of the Aaru Data Preservation Suite.
3 * Copyright (c) 2019-2026 Natalia Portillo.
4 *
5 * This library is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU Lesser General Public License as
7 * published by the Free Software Foundation; either version 2.1 of the
8 * License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
17 */
18
19#include <errno.h>
20#include <inttypes.h>
21#include <stdio.h>
22#include <stdlib.h>
23#include <string.h>
24
25#if defined(_WIN32) || defined(_WIN64)
26#include <windows.h>
27#endif
28
29#include <aaruformat.h>
30
31#include "erasure_internal.h"
32#include "internal.h"
33#include "log.h"
34#include "utarray.h"
35
36static inline void aaruf_set_open_error(const int error_code)
37{
38 errno = error_code;
39#if defined(_WIN32) || defined(_WIN64)
40 SetLastError((DWORD)error_code);
41#endif
42}
43
45{
46 if(ctx == NULL) return;
47
48 if(ctx->imageStream != NULL)
49 {
50 fclose(ctx->imageStream);
51 ctx->imageStream = NULL;
52 }
53
54 free(ctx->readableSectorTags);
55 ctx->readableSectorTags = NULL;
56
57 free(ctx);
58}
59
236AARU_EXPORT void *AARU_CALL aaruf_open(const char *filepath, const bool resume_mode,
237 const char *options) // NOLINT(readability-function-size)
238{
239 aaruformat_context *ctx = NULL;
240 int error_no = 0;
241 size_t read_bytes = 0;
242 aaru_off_t pos = 0;
243 int i = 0;
244 uint32_t signature = 0;
245 UT_array *index_entries = NULL;
246
247#ifdef USE_SLOG
248#include "slog.h"
249
250 slog_init("aaruformat.log", SLOG_FLAGS_ALL, 0);
251#endif
252
253 TRACE("Logging initialized");
254
255 TRACE("Entering aaruf_open(%s)", filepath);
257
258 TRACE("Allocating memory for context");
259 ctx = (aaruformat_context *)malloc(sizeof(aaruformat_context));
260
261 if(ctx == NULL)
262 {
263 FATAL("Not enough memory to create context");
265
266 TRACE("Exiting aaruf_open() = NULL");
267 return NULL;
268 }
269
270 memset(ctx, 0, sizeof(aaruformat_context));
271
272 TRACE("Opening file %s", filepath);
273 if(resume_mode)
274 ctx->imageStream = fopen(filepath, "r+b");
275 else
276 ctx->imageStream = fopen(filepath, "rb");
277
278 if(ctx->imageStream == NULL)
279 {
280 FATAL("Error %d opening file %s for reading", errno, filepath);
281 error_no = errno;
283 aaruf_set_open_error(error_no);
284
285 TRACE("Exiting aaruf_open() = NULL");
286 return NULL;
287 }
288
289 TRACE("Reading header at position 0");
290 aaruf_fseek(ctx->imageStream, 0, SEEK_SET);
291 read_bytes = fread(&ctx->header, 1, sizeof(AaruHeader), ctx->imageStream);
292
293 if(read_bytes != sizeof(AaruHeader))
294 {
295 FATAL("Could not read header");
298
299 TRACE("Exiting aaruf_open() = NULL");
300 return NULL;
301 }
302
304 {
305 /* Primary header corrupt — try recovery footer backup header */
306 TRACE("Primary header invalid, trying recovery footer backup header");
307
308 aaruf_fseek(ctx->imageStream, 0, SEEK_END);
309 int64_t file_size = aaruf_ftell(ctx->imageStream);
310
311 if(file_size >= (int64_t)sizeof(AaruRecoveryFooter))
312 {
314 (aaru_off_t)(file_size - (int64_t)sizeof(AaruRecoveryFooter)), SEEK_SET);
315 AaruRecoveryFooter recovery_footer;
316 if(fread(&recovery_footer, sizeof(AaruRecoveryFooter), 1, ctx->imageStream) == 1 &&
317 recovery_footer.footerMagic == AARU_RECOVERY_FOOTER_MAGIC)
318 {
319 /* Verify the backup header's CRC matches what was recorded */
320 uint64_t backup_crc = aaruf_crc64_data(
321 (const uint8_t *)&recovery_footer.backupHeader, sizeof(AaruHeaderV2));
322 if(backup_crc == recovery_footer.headerCrc64 &&
323 (recovery_footer.backupHeader.identifier == DIC_MAGIC ||
324 recovery_footer.backupHeader.identifier == AARU_MAGIC))
325 {
326 TRACE("Recovery footer backup header valid, using it");
327 memcpy(&ctx->header, &recovery_footer.backupHeader, sizeof(AaruHeaderV2));
328 /* Seek past the header for the next read */
329 aaruf_fseek(ctx->imageStream, (aaru_off_t)sizeof(AaruHeaderV2), SEEK_SET);
330 }
331 else
332 {
333 FATAL("Recovery footer backup header also invalid");
336 TRACE("Exiting aaruf_open() = NULL");
337 return NULL;
338 }
339 }
340 else
341 {
342 FATAL("No recovery footer found, cannot recover from corrupt header");
345 TRACE("Exiting aaruf_open() = NULL");
346 return NULL;
347 }
348 }
349 else
350 {
351 FATAL("Incorrect identifier for AaruFormat file: %8.8s", (char *)&ctx->header.identifier);
354 TRACE("Exiting aaruf_open() = NULL");
355 return NULL;
356 }
357 }
358
359 if(ctx->header.imageMajorVersion < AARUF_VERSION_V2 && resume_mode)
360 {
361 TRACE("Cannot write to old images");
364 TRACE("Exiting aaruf_open() = NULL");
365 return NULL;
366 }
367
368 // Read new header version
370 {
371 TRACE("Reading new header version at position 0");
372 aaruf_fseek(ctx->imageStream, 0, SEEK_SET);
373 read_bytes = fread(&ctx->header, 1, sizeof(AaruHeaderV2), ctx->imageStream);
374
375 if(read_bytes != sizeof(AaruHeaderV2))
376 {
379
380 return NULL;
381 }
382 }
383
385 {
386 FATAL("Incompatible AaruFormat version %d.%d found, maximum supported is %d.%d", ctx->header.imageMajorVersion,
390
391 TRACE("Exiting aaruf_open() = NULL");
392 return NULL;
393 }
394
395 // Check feature compatibility for V2+ images
397 {
398 uint64_t unknown_incompat = ctx->header.featureIncompatible & ~AARUF_KNOWN_INCOMPAT_FEATURES;
399
400 if(unknown_incompat != 0)
401 {
402 FATAL("Image requires unsupported incompatible features: 0x%016" PRIX64, unknown_incompat);
405
406 TRACE("Exiting aaruf_open() = NULL");
407 return NULL;
408 }
409
410 uint64_t unknown_rocompat = ctx->header.featureCompatibleRo & ~AARUF_KNOWN_ROCOMPAT_FEATURES;
411
412 if(unknown_rocompat != 0)
413 {
414 if(resume_mode)
415 {
416 FATAL("Image has unsupported read-only compatible features: 0x%016" PRIX64 ", cannot open for writing",
417 unknown_rocompat);
420
421 TRACE("Exiting aaruf_open() = NULL");
422 return NULL;
423 }
424
425 TRACE("Image has unsupported read-only compatible features: 0x%016" PRIX64 ", forcing read-only",
426 unknown_rocompat);
427 }
428 }
429
430 TRACE("Opening image version %d.%d", ctx->header.imageMajorVersion, ctx->header.imageMinorVersion);
431
432 TRACE("Allocating memory for readable sector tags bitmap");
433 ctx->readableSectorTags = (bool *)malloc(sizeof(bool) * MaxSectorTag);
434
435 if(ctx->readableSectorTags == NULL)
436 {
437 FATAL("Could not allocate memory for readable sector tags bitmap");
440
441 TRACE("Exiting aaruf_open() = NULL");
442 return NULL;
443 }
444
445 memset(ctx->readableSectorTags, 0, sizeof(bool) * MaxSectorTag);
446
447 TRACE("Setting up image info");
448
449 // Handle application name based on image version
450 memset(ctx->image_info.Application, 0, 64);
451
453 {
454 // Version 2+: application name is UTF-8, direct copy
455 TRACE("Converting application name (v2+): UTF-8 direct copy");
456 size_t copy_len = AARU_HEADER_APP_NAME_LEN < 63 ? AARU_HEADER_APP_NAME_LEN : 63;
457 memcpy(ctx->image_info.Application, ctx->header.application, copy_len);
458 ctx->image_info.Application[63] = '\0';
459 }
460 else
461 {
462 // Version 1: application name is UTF-16LE, convert by taking every other byte
463 TRACE("Converting application name (v1): UTF-16LE to ASCII");
464 int dest_idx = 0;
465 for(int j = 0; j < AARU_HEADER_APP_NAME_LEN && dest_idx < 63; j += 2)
466 // Take the low byte, skip the high byte (assuming it's 0x00 for ASCII)
467 if(ctx->header.application[j] != 0)
468 ctx->image_info.Application[dest_idx++] = ctx->header.application[j];
469 else
470 // Stop at null terminator
471 break;
472 ctx->image_info.Application[dest_idx] = '\0';
473 }
474
475 // Set application version string directly in the fixed-size array
476 memset(ctx->image_info.ApplicationVersion, 0, 32);
479
480 // Set image version string directly in the fixed-size array
481 memset(ctx->image_info.Version, 0, 32);
482 sprintf(ctx->image_info.Version, "%d.%d", ctx->header.imageMajorVersion, ctx->header.imageMinorVersion);
483
485
486 // Read the index header
487 TRACE("Reading index header at position %" PRIu64, ctx->header.indexOffset);
488 if(aaruf_fseek(ctx->imageStream, (aaru_off_t)ctx->header.indexOffset, SEEK_SET) != 0)
489 {
492
493 return NULL;
494 }
495
496 pos = aaruf_ftell(ctx->imageStream);
497 if(pos != ctx->header.indexOffset)
498 {
501
502 return NULL;
503 }
504
505 read_bytes = fread(&signature, 1, sizeof(uint32_t), ctx->imageStream);
506
507 if(read_bytes != sizeof(uint32_t) ||
508 (signature != IndexBlock && signature != IndexBlock2 && signature != IndexBlock3))
509 {
510 FATAL("Could not read index header or incorrect identifier %4.4s", (char *)&signature);
513
514 TRACE("Exiting aaruf_open() = NULL");
515 return NULL;
516 }
517
518 if(signature == IndexBlock)
519 index_entries = process_index_v1(ctx);
520 else if(signature == IndexBlock2)
521 index_entries = process_index_v2(ctx);
522 else if(signature == IndexBlock3)
523 index_entries = process_index_v3(ctx);
524
525 if(index_entries == NULL)
526 {
527 FATAL("Could not process index.");
528 utarray_free(index_entries);
531
532 TRACE("Exiting aaruf_open() = NULL");
533 return NULL;
534 }
535
536 TRACE("Index at %" PRIu64 " contains %d entries", ctx->header.indexOffset, utarray_len(index_entries));
537
538 for(i = 0; i < utarray_len(index_entries); i++)
539 {
540 IndexEntry *entry = utarray_eltptr(index_entries, i);
541 TRACE("Block type %4.4s with data type %d is indexed to be at %" PRIu64 "", (char *)&entry->blockType,
542 entry->dataType, entry->offset);
543 }
544
545 bool found_user_data_ddt = false;
546 ctx->image_info.ImageSize = 0;
547 for(i = 0; i < utarray_len(index_entries); i++)
548 {
549 IndexEntry *entry = utarray_eltptr(index_entries, i);
550
551 if(aaruf_fseek(ctx->imageStream, (aaru_off_t)entry->offset, SEEK_SET) != 0 ||
552 aaruf_ftell(ctx->imageStream) != (aaru_off_t)entry->offset)
553 {
554 TRACE("Could not seek to %" PRIu64 " as indicated by index entry %d, continuing...", entry->offset, i);
555
556 continue;
557 }
558
559 TRACE("Processing block type %4.4s with data type %d at position %" PRIu64 "", (char *)&entry->blockType,
560 entry->dataType, entry->offset);
561 switch(entry->blockType)
562 {
563 case DataBlock:
564 if(entry->dataType == kDataTypeUserData && ctx->header.biggestSectorSize > 0) break;
565
566 error_no = process_data_block(ctx, entry);
567
568 if(error_no != AARUF_STATUS_OK)
569 {
570 utarray_free(index_entries);
572 aaruf_set_open_error(error_no);
573
574 return NULL;
575 }
576
577 break;
578
580 error_no = process_ddt_v1(ctx, entry, &found_user_data_ddt);
581
582 if(error_no != AARUF_STATUS_OK)
583 {
584 utarray_free(index_entries);
586 aaruf_set_open_error(error_no);
587
588 return NULL;
589 }
590
591 break;
593 error_no = process_ddt_v2(ctx, entry, &found_user_data_ddt);
594
595 if(error_no != AARUF_STATUS_OK)
596 {
597 utarray_free(index_entries);
599 aaruf_set_open_error(error_no);
600
601 return NULL;
602 }
603
604 switch(entry->dataType)
605 {
610
611 break;
619 break;
620 default:
621 break;
622 }
623
624 break;
625 case GeometryBlock:
626 process_geometry_block(ctx, entry);
627
628 break;
629 case MetadataBlock:
630 process_metadata_block(ctx, entry);
631
632 break;
633 case TracksBlock:
634 process_tracks_block(ctx, entry);
635
636 break;
637 case CicmBlock:
638 process_cicm_block(ctx, entry);
639
640 break;
643
644 break;
645 // Dump hardware block
647 process_dumphw_block(ctx, entry);
648
649 break;
650 case ChecksumBlock:
651 process_checksum_block(ctx, entry);
652
653 break;
654 case TapeFileBlock:
655 process_tape_files_block(ctx, entry);
656
657 break;
660
661 break;
662 case FluxDataBlock:
663 // Store the FluxDataBlock offset for lazy loading
664 // Don't read flux entries during open - load them on-demand when actually needed
665 // This avoids unnecessary I/O if flux data is never accessed
666 break;
667 default:
668 TRACE("Unhandled block type %4.4s with data type %d is indexed to be at %" PRIu64 "",
669 (char *)&entry->blockType, entry->dataType, entry->offset);
670 break;
671 }
672 }
673
674 ctx->index_entries = index_entries;
675
676 if(!found_user_data_ddt)
677 {
678 FATAL("Could not find user data deduplication table, aborting...");
679 aaruf_close(ctx);
681
682 TRACE("Exiting aaruf_open() = NULL");
683 return NULL;
684 }
685
686 if(ctx->header.biggestSectorSize != 0)
687 {
688 TRACE("Setting sector size to %u bytes", ctx->header.biggestSectorSize);
690 }
691
695
697 {
698 ctx->cylinders = (uint32_t)(ctx->image_info.Sectors / 16 / 63);
699 ctx->heads = 16;
700 ctx->sectors_per_track = 63;
701 }
702
703 // Initialize caches
704 TRACE("Initializing caches");
705 ctx->block_header_cache.cache = NULL;
706 ctx->block_cache.cache = NULL;
707
708 // Set free functions for cached values (both cache malloc'd data)
709 ctx->block_header_cache.free_func = free;
710 ctx->block_cache.free_func = free;
711
712 const uint64_t cache_divisor = (uint64_t)ctx->image_info.SectorSize * (1ULL << ctx->shift);
713 if(cache_divisor == 0)
714 {
716 ctx->block_cache.max_items = 0;
717 }
718 else
719 {
720 ctx->block_header_cache.max_items = MAX_CACHE_SIZE / cache_divisor;
722 }
723
724 // TODO: Cache tracks and sessions?
725
726 // Initialize ECC for Compact Disc
727 TRACE("Initializing ECC for Compact Disc");
729
730 ctx->magic = AARU_MAGIC;
733
734 /* Try to load erasure coding recovery metadata from EOF footer */
735 ec_load_ecmb(ctx);
736
737 if(!resume_mode)
738 {
739 TRACE("Exiting aaruf_open() = %p", ctx);
740 return ctx;
741 }
742
743 // Parse the options
744 TRACE("Parsing options");
745 bool table_shift_found = false;
746 const aaru_options parsed_options = parse_options(options, &table_shift_found);
747
750
751 // Calculate aligned next block position
752 aaruf_fseek(ctx->imageStream, 0, SEEK_END);
753 const uint64_t alignment_mask = (1ULL << ctx->user_data_ddt_header.blockAlignmentShift) - 1;
754 ctx->next_block_position = (uint64_t)aaruf_ftell(ctx->imageStream); // Start just after the header
755 ctx->next_block_position = ctx->next_block_position + alignment_mask & ~alignment_mask;
756
757 TRACE("Data blocks will start at position %" PRIu64, ctx->next_block_position);
758
759 // Position file pointer at the data start position
760 if(aaruf_fseek(ctx->imageStream, (aaru_off_t)ctx->next_block_position, SEEK_SET) != 0)
761 {
762 FATAL("Could not seek to data start position");
763 TRACE("Exiting aaruf_open() = NULL");
766 return NULL;
767 }
768
769 // Apply applicable options (we cannot change table or alignment options resuming)
770 ctx->compression_enabled = parsed_options.compress;
771 ctx->lzma_dict_size = parsed_options.dictionary;
772 ctx->deduplicate = parsed_options.deduplicate;
773 if(ctx->deduplicate)
774 ctx->sector_hash_map = create_map(ctx->user_data_ddt_header.blocks * 25 / 100); // 25% of total sectors
775
776 // Cannot checksum a resumed file
777 ctx->rewinded = true;
778
779 // Is writing
780 ctx->is_writing = true;
782
783 TRACE("Exiting aaruf_open() = %p", ctx);
784 // Return context
785 return ctx;
786}
#define LIBAARUFORMAT_MAJOR_VERSION
Definition aaruformat.h:22
#define LIBAARUFORMAT_MINOR_VERSION
Definition aaruformat.h:23
#define DIC_MAGIC
Magic identifier for legacy DiscImageChef container (ASCII "DICMFRMT").
Definition consts.h:61
#define AARU_RECOVERY_FOOTER_MAGIC
Magic number at the end of the recovery footer: "AVRECMFR" in ASCII little-endian.
Definition consts.h:115
#define AARU_MAGIC
Magic identifier for AaruFormat container (ASCII "AARUFRMT").
Definition consts.h:64
#define MAX_CACHE_SIZE
Maximum read cache size (bytes).
Definition consts.h:79
#define AARUF_KNOWN_ROCOMPAT_FEATURES
Bitmask of all featureCompatibleRo bits understood by this library version.
Definition consts.h:107
#define AARUF_KNOWN_INCOMPAT_FEATURES
Bitmask of all featureIncompatible bits understood by this library version.
Definition consts.h:104
#define AARUF_VERSION_V2
Second on‑disk version (C implementation).
Definition consts.h:75
#define AARUF_VERSION
Current image format major version (incompatible changes bump this).
Definition consts.h:68
#define AARU_CALL
Definition decls.h:46
uint64_t aaruf_crc64_data(const uint8_t *data, uint32_t len)
Definition crc64.c:160
int aaruf_close(void *context)
Close an Aaru image context, flushing pending data structures and releasing resources.
Definition close.c:80
#define AARU_EXPORT
Definition decls.h:55
void * aaruf_ecc_cd_init()
Initializes a Compact Disc ECC context.
Definition ecc_cd.c:35
int32_t aaruf_get_xml_mediatype(int32_t type)
Definition helpers.c:399
@ IndexBlock3
Block containing the index v3.
Definition enums.h:171
@ ChecksumBlock
Block containing contents checksums.
Definition enums.h:176
@ DataBlock
Block containing data.
Definition enums.h:164
@ TapePartitionBlock
Block containing list of partitions for a tape image.
Definition enums.h:182
@ IndexBlock2
Block containing the index v2.
Definition enums.h:170
@ GeometryBlock
Block containing logical geometry.
Definition enums.h:172
@ AaruMetadataJsonBlock
Block containing JSON version of Aaru Metadata.
Definition enums.h:183
@ CicmBlock
Block containing CICM XML metadata.
Definition enums.h:175
@ IndexBlock
Block containing the index (v1).
Definition enums.h:169
@ DeDuplicationTable2
Block containing a deduplication table v2.
Definition enums.h:166
@ TapeFileBlock
Block containing list of files for a tape image.
Definition enums.h:181
@ DeDuplicationTable
Block containing a deduplication table (v1).
Definition enums.h:165
@ DumpHardwareBlock
Block containing an array of hardware used to create the image.
Definition enums.h:180
@ MetadataBlock
Block containing metadata.
Definition enums.h:173
@ TracksBlock
Block containing optical disc tracks.
Definition enums.h:174
@ FluxDataBlock
Block containing flux data metadata.
Definition enums.h:184
@ BlockMedia
Media that is physically block-based or abstracted like that.
Definition enums.h:247
@ kDataTypeCdSectorSuffix
Compact Disc sector suffix (EDC, ECC P, ECC Q).
Definition enums.h:117
@ kDataTypeCdSectorSuffixCorrected
Compact Disc sector suffix (EDC, ECC P, ECC Q) corrected-only stored.
Definition enums.h:124
@ kDataTypeUserData
User (main) data.
Definition enums.h:48
@ kDataTypeCdSectorPrefix
Compact Disc sector prefix (sync, header).
Definition enums.h:116
@ kDataTypeCdSectorPrefixCorrected
Compact Disc sector prefix (sync, header) corrected-only stored.
Definition enums.h:123
void ec_load_ecmb(aaruformat_context *ctx)
Try to load the ECMB from the recovery footer at EOF.
Definition erasure.c:941
#define AARUF_ERROR_CANNOT_CREATE_FILE
Output file could not be created / opened for write.
Definition errors.h:58
#define AARUF_STATUS_OK
Sector present and read without uncorrectable errors.
Definition errors.h:81
#define AARUF_ERROR_INCOMPATIBLE_FEATURES
Image requires features not supported by this library.
Definition errors.h:72
#define AARUF_ERROR_NOT_ENOUGH_MEMORY
Memory allocation failure (critical).
Definition errors.h:48
#define AARUF_ERROR_INCOMPATIBLE_VERSION
Image uses a newer incompatible on-disk version.
Definition errors.h:42
#define AARUF_ERROR_CANNOT_READ_INDEX
Index block unreadable / truncated / bad identifier.
Definition errors.h:43
#define AARUF_ERROR_NOT_AARUFORMAT
Input file/stream failed magic or structural validation.
Definition errors.h:40
#define AARUF_ERROR_FILE_TOO_SMALL
File size insufficient for mandatory header / structures.
Definition errors.h:41
@ kSectorTagCdHeader
4-byte CD header (minute, second, frame, mode)
Definition aaru.h:962
@ kSectorTagCdSync
12-byte CD sync pattern (00 FF*10 00)
Definition aaru.h:961
@ kSectorTagCdSubHeader
Mode 2 Form subheader (8 bytes: copy, submode, channel).
Definition aaru.h:963
@ MaxSectorTag
Definition aaru.h:983
@ kSectorTagCdEdc
32-bit CRC (EDC)
Definition aaru.h:964
@ kSectorTagCdEccP
172 bytes Reed-Solomon ECC (P)
Definition aaru.h:965
@ kSectorTagCdEccQ
104 bytes Reed-Solomon ECC (Q)
Definition aaru.h:966
@ kSectorTagCdEcc
Combined P+Q ECC (276 bytes).
Definition aaru.h:967
hash_map_t * create_map(size_t size)
Creates a new hash map with the specified initial size.
Definition hash_map.c:51
#define AARU_HEADER_APP_NAME_LEN
Size in bytes (UTF-16LE) of application name field (32 UTF-16 code units).
Definition header.h:59
void process_dumphw_block(aaruformat_context *ctx, const IndexEntry *entry)
Processes a dump hardware block from the image stream.
Definition dump.c:107
UT_array * process_index_v2(aaruformat_context *ctx)
Processes an index block (version 2) from the image stream.
Definition index_v2.c:82
int32_t process_ddt_v2(aaruformat_context *ctx, IndexEntry *entry, bool *found_user_data_ddt)
Processes a DDT v2 block from the image stream.
Definition ddt_v2.c:96
int32_t process_data_block(aaruformat_context *ctx, IndexEntry *entry)
Processes a data block from the image stream.
Definition data.c:72
uint64_t get_filetime_uint64()
Gets the current time as a 64-bit FILETIME value.
Definition time.c:45
void process_tracks_block(aaruformat_context *ctx, const IndexEntry *entry)
Parse and integrate a Tracks block from the image stream into the context.
Definition optical.c:112
void process_metadata_block(aaruformat_context *ctx, const IndexEntry *entry)
Processes a metadata block from the image stream.
Definition metadata.c:36
void process_checksum_block(aaruformat_context *ctx, const IndexEntry *entry)
Processes a checksum block from the image stream.
Definition checksum.c:40
UT_array * process_index_v1(aaruformat_context *ctx)
Processes an index block (version 1) from the image stream.
Definition index_v1.c:80
void process_cicm_block(aaruformat_context *ctx, const IndexEntry *entry)
Processes a CICM XML metadata block from the image stream.
Definition metadata.c:312
static int aaruf_fseek(FILE *stream, aaru_off_t offset, int origin)
Definition internal.h:46
static aaru_off_t aaruf_ftell(FILE *stream)
Definition internal.h:52
int32_t aaruf_finalize_write(aaruformat_context *ctx)
Finalize a write-mode image: flush all pending blocks, DDTs, and the index.
void process_geometry_block(aaruformat_context *ctx, const IndexEntry *entry)
Processes a logical geometry block from the image stream.
Definition metadata.c:252
void process_tape_files_block(aaruformat_context *ctx, const IndexEntry *entry)
Processes a tape file metadata block from the image stream.
Definition tape.c:127
void process_aaru_metadata_json_block(aaruformat_context *ctx, const IndexEntry *entry)
Processes an Aaru metadata JSON block from the image stream during image opening.
Definition metadata.c:476
void process_tape_partitions_block(aaruformat_context *ctx, const IndexEntry *entry)
Processes a tape partition metadata block from the image stream.
Definition tape.c:348
int32_t process_ddt_v1(aaruformat_context *ctx, IndexEntry *entry, bool *found_user_data_ddt)
Processes a DDT v1 block from the image stream.
Definition ddt_v1.c:86
aaru_options parse_options(const char *options, bool *table_shift_found)
Parses the options string for AaruFormat image creation/opening.
Definition options.c:47
int64_t aaru_off_t
Definition internal.h:42
UT_array * process_index_v3(aaruformat_context *ctx)
Processes an index block (version 3) from the image stream.
Definition index_v3.c:98
#define FATAL(fmt,...)
Definition log.h:40
#define TRACE(fmt,...)
Definition log.h:25
static void cleanup_open_failure(aaruformat_context *ctx)
Definition open.c:44
static void aaruf_set_open_error(const int error_code)
Definition open.c:36
void * aaruf_open(const char *filepath, const bool resume_mode, const char *options)
Opens an existing AaruFormat image file.
Definition open.c:236
Version 2 container header with GUID, alignment shifts, and feature negotiation bitmaps.
Definition header.h:107
uint8_t application[64]
UTF-8 creator application name (fixed 64 bytes).
Definition header.h:109
uint8_t applicationMajorVersion
Creator application major version.
Definition header.h:112
uint64_t identifier
File magic (AARU_MAGIC).
Definition header.h:108
uint64_t featureIncompatible
Feature bits: any unimplemented -> abort (cannot open safely).
Definition header.h:123
int64_t lastWrittenTime
Last modification FILETIME (100 ns since 1601-01-01 UTC).
Definition header.h:117
uint64_t indexOffset
Absolute byte offset to primary index block (MUST be > 0; 0 => corrupt/unreadable).
Definition header.h:115
uint8_t applicationMinorVersion
Creator application minor / patch version.
Definition header.h:113
uint32_t mediaType
Media type enumeration (value from MediaType).
Definition header.h:114
uint64_t featureCompatibleRo
Feature bits: unimplemented -> degrade to read-only access.
Definition header.h:122
uint16_t biggestSectorSize
size of biggest sector in the image (in bytes).
Definition header.h:120
uint8_t imageMinorVersion
Container format minor version.
Definition header.h:111
int64_t creationTime
Creation FILETIME (100 ns since 1601-01-01 UTC).
Definition header.h:116
uint8_t imageMajorVersion
Container format major version.
Definition header.h:110
Version 1 container header placed at offset 0 for legacy / initial format.
Definition header.h:77
Recovery footer written at the very end of the file (last 160 bytes).
Definition erasure.h:117
uint64_t headerCrc64
CRC64-ECMA of the original AaruHeaderV2 (128 bytes at offset 0).
Definition erasure.h:120
uint64_t footerMagic
Must be AARU_RECOVERY_FOOTER_MAGIC (0x52464D4345525641).
Definition erasure.h:122
AaruHeaderV2 backupHeader
Complete copy of AaruHeaderV2 from file offset 0.
Definition erasure.h:121
struct CacheEntry * cache
Hash root (uthash). NULL when empty.
Definition lru.h:44
uint64_t max_items
Hard limit for number of entries.
Definition lru.h:43
void(* free_func)(void *)
Optional callback to free cached values. NULL if not needed.
Definition lru.h:45
Lookup tables and state for Compact Disc EDC/ECC (P/Q) regeneration / verification.
Definition context.h:89
uint64_t blocks
Total internal span (negative + usable + overflow) in logical sectors.
Definition ddt.h:150
uint8_t blockAlignmentShift
2^blockAlignmentShift = block alignment boundary in bytes.
Definition ddt.h:154
uint32_t identifier
Block identifier, must be BlockType::GeometryBlock.
Definition data.h:92
uint32_t MediaType
Media type identifier (see MediaType enum; 0=Unknown).
Definition aaru.h:945
uint8_t MetadataMediaType
Media type for sidecar generation (internal archival use).
Definition aaru.h:946
uint32_t SectorSize
Size of each logical sector in bytes (512, 2048, 2352, 4096, etc.).
Definition aaru.h:939
char Application[64]
Name of application that created the image (NUL-terminated).
Definition aaru.h:941
uint64_t ImageSize
Size of the image payload in bytes (excludes headers/metadata).
Definition aaru.h:937
int64_t CreationTime
Image creation timestamp (Windows FILETIME: 100ns since 1601-01-01 UTC).
Definition aaru.h:943
int64_t LastModificationTime
Last modification timestamp (Windows FILETIME format).
Definition aaru.h:944
char Version[32]
Image format version string (NUL-terminated, e.g., "6.0").
Definition aaru.h:940
uint64_t Sectors
Total count of addressable logical sectors/blocks.
Definition aaru.h:938
char ApplicationVersion[32]
Version of the creating application (NUL-terminated).
Definition aaru.h:942
Single index entry describing a block's type, (optional) data classification, and file offset.
Definition index.h:109
uint32_t blockType
Block identifier of the referenced block (value from BlockType).
Definition index.h:110
uint64_t offset
Absolute byte offset in the image where the referenced block header begins.
Definition index.h:112
uint16_t dataType
Data classification (value from DataType) or unused for untyped blocks.
Definition index.h:111
Parsed user-specified tunables controlling compression, deduplication, hashing and DDT geometry.
Definition options.h:220
bool deduplicate
Storage dedup flag (DDT always exists).
Definition options.h:222
uint32_t dictionary
LZMA dictionary size in bytes (>= 4096 recommended). Default: 33554432 (32 MiB).
Definition options.h:224
bool compress
Enable adaptive compression (LZMA for data blocks, FLAC for audio). Default: true.
Definition options.h:221
Master context representing an open or in‑creation Aaru image.
Definition context.h:175
DdtHeader2 user_data_ddt_header
Active user data DDT v2 header (primary table meta).
Definition context.h:192
uint8_t library_major_version
Linked library major version.
Definition context.h:180
bool deduplicate
Storage deduplication active (duplicates coalesce).
Definition context.h:303
bool compression_enabled
True if block compression enabled (writing path).
Definition context.h:304
hash_map_t * sector_hash_map
Deduplication hash map (fingerprint->entry mapping).
Definition context.h:256
uint32_t cylinders
Cylinders of the media represented by the image.
Definition context.h:237
struct CacheHeader block_header_cache
LRU/Cache header for block headers.
Definition context.h:259
uint8_t shift
Legacy overall shift (deprecated by data_shift/table_shift).
Definition context.h:198
CdEccContext * ecc_cd_context
CD ECC/EDC helper tables (allocated on demand).
Definition context.h:251
bool rewinded
True if stream has been rewound after open (write path).
Definition context.h:296
struct CacheHeader block_cache
LRU/Cache header for block payloads.
Definition context.h:260
AaruHeaderV2 header
Parsed container header (v2).
Definition context.h:178
bool is_writing
True if context opened/created for writing.
Definition context.h:295
int32_t(* finalize_write)(struct aaruformat_context *ctx)
Writer finalization hook (NULL for reader).
Definition context.h:299
uint64_t magic
File magic (AARU_MAGIC) post-open.
Definition context.h:177
uint8_t library_minor_version
Linked library minor version;.
Definition context.h:181
uint64_t next_block_position
Absolute file offset where next block will be written.
Definition context.h:285
GeometryBlockHeader geometry_block
Logical geometry block (if present).
Definition context.h:232
uint32_t sectors_per_track
Sectors per track of the media represented by the image (for variable image, the smallest).
Definition context.h:239
uint32_t heads
Heads of the media represented by the image.
Definition context.h:238
FILE * imageStream
Underlying FILE* stream (binary mode).
Definition context.h:179
UT_array * index_entries
Flattened index entries (UT_array of IndexEntry).
Definition context.h:255
ImageInfo image_info
Exposed high-level image info summary.
Definition context.h:263
bool * readableSectorTags
Per-sector boolean array (optical tags read successfully?).
Definition context.h:266
uint32_t lzma_dict_size
LZMA dictionary size (writing path).
Definition context.h:302