|
libaaruformat 1.0
Aaru Data Preservation Suite - Format Library
|
#include <inttypes.h>#include <stdint.h>#include <stdio.h>#include <stdlib.h>#include "aaruformat.h"#include "internal.h"#include "log.h"Go to the source code of this file.
Functions | |
| int32_t | process_ddt_v2 (aaruformat_context *ctx, IndexEntry *entry, bool *found_user_data_ddt) |
| Processes a DDT v2 block from the image stream. | |
| int32_t | decode_ddt_entry_v2 (aaruformat_context *ctx, const uint64_t sector_address, bool negative, uint64_t *offset, uint64_t *block_offset, uint8_t *sector_status) |
| Decodes a DDT v2 entry for a given sector address. | |
| int32_t | decode_ddt_single_level_v2 (aaruformat_context *ctx, uint64_t sector_address, bool negative, uint64_t *offset, uint64_t *block_offset, uint8_t *sector_status) |
| Decodes a single-level DDT v2 entry for a given sector address. | |
| int32_t | decode_ddt_multi_level_v2 (aaruformat_context *ctx, uint64_t sector_address, bool negative, uint64_t *offset, uint64_t *block_offset, uint8_t *sector_status) |
| Decodes a multi-level DDT v2 entry for a given sector address. | |
| bool | set_ddt_entry_v2 (aaruformat_context *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) |
| Sets a DDT v2 entry for a given sector address. | |
| bool | set_ddt_single_level_v2 (aaruformat_context *ctx, uint64_t sector_address, const bool negative, const uint64_t offset, const uint64_t block_offset, const uint8_t sector_status, uint64_t *ddt_entry) |
| Sets a single-level DDT v2 entry for a given sector address. | |
| bool | set_ddt_multi_level_v2 (aaruformat_context *ctx, uint64_t sector_address, bool negative, uint64_t offset, uint64_t block_offset, uint8_t sector_status, uint64_t *ddt_entry) |
| Sets a multi-level DDT v2 entry for a given sector address. | |
| bool | set_ddt_tape (aaruformat_context *ctx, uint64_t sector_address, const uint64_t offset, const uint64_t block_offset, const uint8_t sector_status, uint64_t *ddt_entry) |
| Sets a DDT entry for tape media using a hash-based lookup table. | |
| int32_t decode_ddt_entry_v2 | ( | aaruformat_context * | ctx, |
| const uint64_t | sector_address, | ||
| bool | negative, | ||
| uint64_t * | offset, | ||
| uint64_t * | block_offset, | ||
| uint8_t * | sector_status ) |
Decodes a DDT v2 entry for a given sector address.
Determines the offset and block offset for a sector using the DDT v2 table(s). This function acts as a dispatcher that automatically selects between single-level and multi-level DDT decoding based on the tableShift parameter in the DDT header. It provides a unified interface for DDT v2 entry decoding regardless of the underlying table structure complexity.
| ctx | Pointer to the aaruformat context containing the loaded DDT structures. |
| sector_address | Logical sector address to decode (will be adjusted for negative sectors). |
| negative | Indicates if the sector address is negative. |
| offset | Pointer to store the resulting sector offset within the block. |
| block_offset | Pointer to store the resulting block offset in the image. |
| sector_status | Pointer to store the sector status (dumped, not dumped, etc.). |
| AARUF_STATUS_OK | (0) Successfully decoded the DDT entry. This is always returned when:
|
| AARUF_ERROR_NOT_AARUFORMAT | (-1) The context or image stream is invalid (NULL pointers). This is the only error condition that can occur at this dispatcher level. |
| Other | error codes may be returned by the underlying decoding functions:
|
Definition at line 507 of file ddt_v2.c.
References AARUF_ERROR_NOT_AARUFORMAT, decode_ddt_multi_level_v2(), decode_ddt_single_level_v2(), FATAL, aaruformat_context::imageStream, DdtHeader2::tableShift, TRACE, and aaruformat_context::user_data_ddt_header.
Referenced by aaruf_read_sector().
| int32_t decode_ddt_multi_level_v2 | ( | aaruformat_context * | ctx, |
| uint64_t | sector_address, | ||
| bool | negative, | ||
| uint64_t * | offset, | ||
| uint64_t * | block_offset, | ||
| uint8_t * | sector_status ) |
Decodes a multi-level DDT v2 entry for a given sector address.
Used when the DDT table uses multi-level indirection (tableShift > 0). This function handles the complex process of navigating a hierarchical DDT structure where the primary table points to secondary tables that contain the actual sector mappings. It includes caching mechanisms for secondary tables, supports both compressed and uncompressed secondary tables, and performs comprehensive validation including CRC verification.
| ctx | Pointer to the aaruformat context containing the loaded primary DDT table. |
| sector_address | Logical sector address to decode (adjusted for negative sectors). |
| negative | Indicates if the sector address is negative. |
| offset | Pointer to store the resulting sector offset within the block. |
| block_offset | Pointer to store the resulting block offset in the image. |
| sector_status | Pointer to store the sector status (dumped, not dumped, etc.). |
| AARUF_STATUS_OK | (0) Successfully decoded the DDT entry. This is returned when:
|
| AARUF_ERROR_NOT_AARUFORMAT | (-1) The context or image stream is invalid (NULL pointers). |
| AARUF_ERROR_CANNOT_READ_BLOCK | (-7) Configuration, validation, or file access errors. This occurs when:
|
| AARUF_ERROR_CANNOT_DECOMPRESS_BLOCK | (-17) LZMA decompression failed for secondary DDT. This occurs when:
|
| AARUF_ERROR_INVALID_BLOCK_CRC | (-18) CRC64 validation failed for secondary DDT. This occurs when:
|
Definition at line 724 of file ddt_v2.c.
References aaruf_crc64_final(), aaruf_crc64_init(), aaruf_crc64_update(), AARUF_ERROR_CANNOT_DECOMPRESS_BLOCK, AARUF_ERROR_CANNOT_READ_BLOCK, AARUF_ERROR_INVALID_BLOCK_CRC, AARUF_ERROR_NOT_AARUFORMAT, aaruf_lzma_decode_buffer(), AARUF_STATUS_OK, DdtHeader2::blockAlignmentShift, aaruformat_context::cached_ddt_offset, aaruformat_context::cached_secondary_ddt2, DdtHeader2::cmpLength, DdtHeader2::compression, DdtHeader2::crc64, DdtHeader2::dataShift, DeDuplicationTableSecondary, FATAL, DdtHeader2::identifier, aaruformat_context::imageStream, DdtHeader2::length, Lzma, LZMA_PROPERTIES_LENGTH, DdtHeader2::negative, None, SectorStatusNotDumped, DdtHeader2::tableShift, TRACE, DdtHeader2::type, aaruformat_context::user_data_ddt2, aaruformat_context::user_data_ddt_header, and UserData.
Referenced by decode_ddt_entry_v2().
| int32_t decode_ddt_single_level_v2 | ( | aaruformat_context * | ctx, |
| uint64_t | sector_address, | ||
| bool | negative, | ||
| uint64_t * | offset, | ||
| uint64_t * | block_offset, | ||
| uint8_t * | sector_status ) |
Decodes a single-level DDT v2 entry for a given sector address.
Used when the DDT table does not use multi-level indirection (tableShift = 0). This function performs direct lookup in the primary DDT table to extract sector offset, block offset, and sector status information. It performs bit manipulation to decode the packed DDT entry values.
| ctx | Pointer to the aaruformat context containing the loaded DDT table. |
| sector_address | Logical sector address to decode (adjusted for negative sectors). |
| negative | Indicates if the sector address is negative. |
| offset | Pointer to store the resulting sector offset within the block. |
| block_offset | Pointer to store the resulting block offset in the image. |
| sector_status | Pointer to store the sector status (dumped, not dumped, etc.). |
| AARUF_STATUS_OK | (0) Successfully decoded the DDT entry. This is always returned when:
|
| AARUF_ERROR_NOT_AARUFORMAT | (-1) The context or image stream is invalid (NULL pointers). |
| AARUF_ERROR_CANNOT_READ_BLOCK | (-7) Configuration or validation errors. This occurs when:
|
Definition at line 581 of file ddt_v2.c.
References AARUF_ERROR_CANNOT_READ_BLOCK, AARUF_ERROR_NOT_AARUFORMAT, AARUF_STATUS_OK, DdtHeader2::blockAlignmentShift, DdtHeader2::dataShift, FATAL, aaruformat_context::imageStream, DdtHeader2::negative, SectorStatusNotDumped, DdtHeader2::tableShift, TRACE, aaruformat_context::user_data_ddt2, and aaruformat_context::user_data_ddt_header.
Referenced by decode_ddt_entry_v2().
| int32_t process_ddt_v2 | ( | aaruformat_context * | ctx, |
| IndexEntry * | entry, | ||
| bool * | found_user_data_ddt ) |
Processes a DDT v2 block from the image stream.
Reads and decompresses (if needed) a DDT v2 block, verifies its CRC, and loads it into memory. This function handles both user data DDT blocks and CD sector prefix/suffix corrected DDT blocks, supporting both LZMA compression and uncompressed formats. It performs CRC64 validation and stores the processed DDT data in the appropriate context fields based on size type (small/big).
| ctx | Pointer to the aaruformat context. |
| entry | Pointer to the index entry describing the DDT block. |
| found_user_data_ddt | Pointer to a boolean that will be set to true if a user data DDT was found and loaded. |
| AARUF_STATUS_OK | (0) Successfully processed the DDT block. This is returned when:
|
| AARUF_ERROR_NOT_AARUFORMAT | (-1) The context or image stream is invalid (NULL pointers). |
| AARUF_ERROR_CANNOT_READ_BLOCK | (-7) Failed to access the DDT block in the image stream. This occurs when:
|
| AARUF_ERROR_CANNOT_DECOMPRESS_BLOCK | (-17) LZMA decompression failed. This can happen when:
|
| AARUF_ERROR_INVALID_BLOCK_CRC | (-18) CRC64 validation failed. This occurs when:
|
Definition at line 96 of file ddt_v2.c.
References aaruf_crc64_final(), aaruf_crc64_init(), aaruf_crc64_update(), AARUF_ERROR_CANNOT_DECOMPRESS_BLOCK, AARUF_ERROR_CANNOT_READ_BLOCK, AARUF_ERROR_INVALID_BLOCK_CRC, AARUF_ERROR_NOT_AARUFORMAT, aaruf_lzma_decode_buffer(), AARUF_STATUS_OK, DdtHeader2::blocks, CdSectorPrefix, CdSectorSuffix, DdtHeader2::cmpLength, DdtHeader2::compression, DdtHeader2::crc64, IndexEntry::dataType, aaruformat_context::ddt_version, FATAL, aaruformat_context::image_info, ImageInfo::ImageSize, aaruformat_context::imageStream, aaruformat_context::in_memory_ddt, DdtHeader2::length, Lzma, LZMA_PROPERTIES_LENGTH, DdtHeader2::negative, None, IndexEntry::offset, DdtHeader2::overflow, aaruformat_context::primary_ddt_offset, aaruformat_context::sector_prefix_ddt2, aaruformat_context::sector_suffix_ddt2, ImageInfo::Sectors, TRACE, aaruformat_context::user_data_ddt2, aaruformat_context::user_data_ddt_header, and UserData.
Referenced by aaruf_open().
| bool set_ddt_entry_v2 | ( | aaruformat_context * | 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 ) |
Sets a DDT v2 entry for a given sector address.
Updates the DDT v2 table(s) with the specified offset, block offset, and sector status for a sector.
| ctx | Pointer to the aaruformat context. |
| sector_address | Logical sector address to set. |
| negative | Indicates if the sector address is negative. |
| offset | Offset to set for the sector. |
| block_offset | Block offset to set for the sector. |
| sector_status | Status to set for the sector. |
| ddt_entry | Existing DDT entry or 0 to create a new one. If 0, a new entry is returned. |
| true | if the entry was set successfully, false otherwise. |
Definition at line 988 of file ddt_v2.c.
References FATAL, aaruformat_context::imageStream, set_ddt_multi_level_v2(), set_ddt_single_level_v2(), DdtHeader2::tableShift, TRACE, and aaruformat_context::user_data_ddt_header.
Referenced by aaruf_write_sector().
| bool set_ddt_multi_level_v2 | ( | aaruformat_context * | ctx, |
| uint64_t | sector_address, | ||
| bool | negative, | ||
| uint64_t | offset, | ||
| uint64_t | block_offset, | ||
| uint8_t | sector_status, | ||
| uint64_t * | ddt_entry ) |
Sets a multi-level DDT v2 entry for a given sector address.
Used when the DDT table uses multi-level indirection (tableShift > 0).
| ctx | Pointer to the aaruformat context. |
| sector_address | Logical sector address to set. |
| negative | Indicates if the sector address is negative. |
| offset | Offset to set for the sector. |
| block_offset | Block offset to set for the sector. |
| sector_status | Status to set for the sector. |
| ddt_entry | Existing DDT entry or 0 to create a new one. If 0, a new entry is returned. |
| true | if the entry was set successfully, false otherwise. |
Definition at line 1092 of file ddt_v2.c.
References aaruf_close_current_block(), aaruf_crc64_data(), aaruf_crc64_final(), aaruf_crc64_init(), aaruf_crc64_update(), AARUF_ERROR_NOT_ENOUGH_MEMORY, aaruf_lzma_encode_buffer(), DdtHeader2::blockAlignmentShift, DdtHeader2::blocks, IndexEntry::blockType, aaruformat_context::cached_ddt_offset, aaruformat_context::cached_ddt_position, aaruformat_context::cached_secondary_ddt2, DdtHeader2::cmpCrc64, DdtHeader2::cmpLength, DdtHeader2::compression, aaruformat_context::compression_enabled, DdtHeader2::crc64, DdtHeader2::dataShift, IndexEntry::dataType, DeDuplicationTable2, DeDuplicationTableSecondary, DdtHeader2::entries, FATAL, DdtHeader2::identifier, aaruformat_context::imageStream, aaruformat_context::index_entries, DdtHeader2::length, DdtHeader2::levels, Lzma, aaruformat_context::lzma_dict_size, LZMA_PROPERTIES_LENGTH, DdtHeader2::negative, aaruformat_context::next_block_position, None, IndexEntry::offset, DdtHeader2::overflow, DdtHeader2::previousLevelOffset, aaruformat_context::primary_ddt_offset, DdtHeader2::start, DdtHeader2::tableLevel, DdtHeader2::tableShift, TRACE, DdtHeader2::type, aaruformat_context::user_data_ddt2, aaruformat_context::user_data_ddt_header, UserData, and aaruformat_context::writing_buffer.
Referenced by set_ddt_entry_v2().
| bool set_ddt_single_level_v2 | ( | aaruformat_context * | ctx, |
| uint64_t | sector_address, | ||
| const bool | negative, | ||
| const uint64_t | offset, | ||
| const uint64_t | block_offset, | ||
| const uint8_t | sector_status, | ||
| uint64_t * | ddt_entry ) |
Sets a single-level DDT v2 entry for a given sector address.
Used when the DDT table does not use multi-level indirection.
| ctx | Pointer to the aaruformat context. |
| sector_address | Logical sector address to set. |
| negative | Indicates if the sector address is negative. |
| offset | Offset to set for the sector. |
| block_offset | Block offset to set for the sector. |
| sector_status | Status to set for the sector. |
| ddt_entry | Existing DDT entry or 0 to create a new one. If 0, a new entry is returned. |
| true | if the entry was set successfully, false otherwise. |
Definition at line 1023 of file ddt_v2.c.
References DdtHeader2::blockAlignmentShift, DdtHeader2::dataShift, FATAL, aaruformat_context::imageStream, DdtHeader2::negative, DdtHeader2::tableShift, TRACE, aaruformat_context::user_data_ddt2, and aaruformat_context::user_data_ddt_header.
Referenced by set_ddt_entry_v2().
| bool set_ddt_tape | ( | aaruformat_context * | ctx, |
| uint64_t | sector_address, | ||
| const uint64_t | offset, | ||
| const uint64_t | block_offset, | ||
| const uint8_t | sector_status, | ||
| uint64_t * | ddt_entry ) |
Sets a DDT entry for tape media using a hash-based lookup table.
This function is specifically designed for tape media images where sectors are accessed non-sequentially and the traditional DDT array structure is inefficient. Instead of using a large contiguous array, it uses a hash table (UTHASH) to store only the sectors that have been written, providing sparse storage for tape media.
The function performs the following operations:
DDT Entry Format: The DDT entry is a 64-bit value with the following bit layout:
Hash Table Management: Uses HASH_REPLACE macro from UTHASH library which:
Overflow Detection: The function checks if the constructed DDT entry exceeds 28 bits (0xFFFFFFF). This limit ensures the sector status can fit in the upper 4 bits while leaving room for future extensions in the upper 32 bits.
| ctx | Pointer to the aaruformat context. Must not be NULL. The context must have a valid imageStream and is_tape must be true. The ctx->tapeDdt hash table will be updated with the new entry. The ctx->userDataDdtHeader contains alignment and shift parameters. |
| sector_address | Logical sector address on the tape to set. This serves as the unique key in the hash table. Multiple calls with the same sector_address will replace the previous entry. |
| offset | Byte offset within the aligned block where the sector data begins. This value is masked by (1 << dataShift) - 1 to extract only the lower bits representing the offset within the block. |
| block_offset | Absolute byte offset in the image file where the data block starts. This is right-shifted by blockAlignmentShift to get the block index, which is stored in the DDT entry's middle bits. |
| sector_status | Status flags for the sector (4 bits). Common values include:
|
| ddt_entry | Pointer to a 64-bit value that will receive the constructed DDT entry.
|
| true | Successfully created and inserted the DDT entry. This occurs when:
|
| false | Failed to set the DDT entry. This can happen when:
|
Definition at line 1768 of file ddt_v2.c.
References DdtHeader2::blockAlignmentShift, DdtHeader2::dataShift, FATAL, aaruformat_context::imageStream, aaruformat_context::is_tape, TapeDdtHashEntry::key, aaruformat_context::tape_ddt, TRACE, aaruformat_context::user_data_ddt_header, and TapeDdtHashEntry::value.