libaaruformat 1.0 Aaru Data Preservation Suite - Format Library

Loading...
Searching...
No Matches
dump.c File Reference
`#include <stdint.h>`
`#include <stdlib.h>`
`#include "aaruformat.h"`
`#include "internal.h"`
`#include "log.h"`

Go to the source code of this file.

## Macros
#define | COPY_STRING_FIELD(field)

## Functions
static void | free_dump_hardware_entries (DumpHardwareEntriesWithData *entries, uint32_t count)
int32_t | aaruf_get_dumphw (void *context, uint8_t *buffer, size_t *length)
| Retrieves the dump hardware block containing acquisition environment information.
int32_t | aaruf_set_dumphw (void *context, uint8_t *data, size_t length)
| Sets the dump hardware block for the image during creation.

## Macro Definition Documentation

## ◆ COPY_STRING_FIELD

#define COPY_STRING_FIELD | ( |  | field | ) |

Value:
do { \
const size_t field##_length = copy[e].entry.field##Length; \
if(field##_length > 0) \
{ \
if(field##_length > length - pos) goto invalid_data; \
/* Allocate only field##_length bytes, since input is NUL-terminated */ \
copy[e].field = (uint8_t *)calloc(1, field##_length); \
if(copy[e].field == NULL) goto free_copy_and_error; \
memcpy(copy[e].field, data + pos, field##_length); \
/* Ensure NUL-termination in case input is malformed */ \
copy[e].field[field##_length - 1] = '\0'; \
pos += field##_length; \
} \
} while(0)

Referenced by aaruf_set_dumphw().

## Function Documentation

## ◆ aaruf_get_dumphw()

int32_t aaruf_get_dumphw | ( | void * | context,
|  | uint8_t * | buffer,
|  | size_t * | length )

Retrieves the dump hardware block containing acquisition environment information.

Extracts the complete DumpHardwareBlock from the image, which documents the hardware and software environments used to create the image. A dump hardware block records one or more "dump environments" – typically combinations of physical devices (drives, controllers, adapters) and the software stacks that performed the read operations. This metadata is essential for understanding the imaging context, validating acquisition integrity, reproducing imaging conditions, and supporting forensic or archival documentation requirements.

Each environment entry includes hardware identification (manufacturer, model, revision, firmware, serial number), software identification (name, version, operating system), and optional extent ranges that specify which logical sectors or units were contributed by that particular environment. This structure supports complex imaging scenarios where multiple devices or software configurations were used to create a composite image.

The function reconstructs the complete on-disk binary representation of the dump hardware block, including the DumpHardwareHeader followed by all entries with their variable-length UTF-8 strings and extent arrays. The reconstructed block includes a calculated CRC64 checksum over the payload data for integrity verification.

This function supports a two-call pattern for buffer size determination:

1. First call with insufficient buffer (or NULL) returns AARUF_ERROR_BUFFER_TOO_SMALL and sets *length to the required size (sizeof(DumpHardwareHeader) + total payload length)
2. Second call with properly sized buffer retrieves the complete block data

Alternatively, if the caller already knows the buffer is large enough, a single call will succeed and populate the buffer with the complete dump hardware block.

Parameters

  context | Pointer to the aaruformat context (must be a valid, opened image context).
  buffer | Pointer to a buffer that will receive the dump hardware block data. Must be large enough to hold the complete block (at least *length bytes on input). May be NULL to query the required buffer size. The buffer will contain the DumpHardwareHeader followed by serialized entries, strings, and extent arrays on success.
  length | Pointer to a size_t that serves dual purpose: On input: size of the provided buffer in bytes (ignored if buffer is NULL) On output: actual size required/used for the dump hardware block in bytes If the function returns AARUF_ERROR_BUFFER_TOO_SMALL, this will be updated to contain the required buffer size for a subsequent successful call.

Returns
  Returns one of the following status codes:

Return values

  AARUF_STATUS_OK | (0) Successfully retrieved dump hardware block. This is returned when: The context is valid and properly initialized The dump hardware block is present (identifier == DumpHardwareBlock) The provided buffer is large enough (>= required length) All hardware entries with their strings and extents are copied to the buffer The DumpHardwareHeader is written with calculated CRC64 at buffer offset 0 The *length parameter is set to the actual block size
  AARUF_ERROR_NOT_AARUFORMAT | (-1) The context is invalid. This occurs when: The context parameter is NULL The context magic number doesn't match AARU_MAGIC (invalid context type) The context was not properly initialized by aaruf_open() or aaruf_create()
  AARUF_ERROR_CANNOT_READ_BLOCK | (-6) The dump hardware block is not present. This occurs when: The image was created without dump hardware information ctx->dumpHardwareEntriesWithData is NULL (no data loaded) ctx->dumpHardwareHeader.entries == 0 (no hardware entries) ctx->dumpHardwareHeader.identifier doesn't equal DumpHardwareBlock The dump hardware block was not found during image opening
  AARUF_ERROR_BUFFER_TOO_SMALL | (-12) The provided buffer is insufficient. This occurs when: buffer is NULL (size query mode) The input *length is less than sizeof(DumpHardwareHeader) + payload length The *length parameter is updated to contain the required buffer size No data is copied to the buffer The caller should allocate a larger buffer and call again Also returned if calculated entry size exceeds buffer during iteration (sanity check)

Note
  Dump Hardware Block Structure:
  - DumpHardwareHeader (16 bytes): identifier, entries count, payload length, CRC64
  - For each entry (variable size):
    - DumpHardwareEntry (36 bytes): length fields for all strings and extent count
    - Variable-length UTF-8 strings (in order): manufacturer, model, revision, firmware, serial, software name, software version, software operating system
    - Array of DumpExtent structures (16 bytes each) if extent count > 0
  - All strings are UTF-8 encoded and NOT null-terminated in the serialized block
  - String lengths are in bytes, not character counts
  Dump Hardware Environments:
  - Each entry represents one hardware/software combination used during imaging
  - Multiple entries support scenarios where different devices contributed different sectors
  - Extent arrays specify which logical sector ranges each environment contributed
  - Empty extent arrays (extents == 0) indicate the environment dumped the entire medium
  - Overlapping extents between entries may indicate verification passes or redundancy
  Hardware Identification Fields:
  - manufacturer: Device manufacturer (e.g., "Plextor", "Sony", "Samsung")
  - model: Device model number (e.g., "PX-716A", "DRU-820A")
  - revision: Hardware revision identifier
  - firmware: Firmware version (e.g., "1.11", "KY08")
  - serial: Device serial number for unique identification
  Software Identification Fields:
  - softwareName: Dumping software name (e.g., "Aaru", "ddrescue", "IsoBuster")
  - softwareVersion: Software version (e.g., "5.3.0", "1.25")
  - softwareOperatingSystem: Host OS (e.g., "Linux 5.10.0", "Windows 10", "macOS 12.0")
  CRC64 Calculation:
  - The function calculates CRC64-ECMA over the payload (everything after the header)
  - The calculated CRC64 is stored in the returned DumpHardwareHeader
  - This allows verification of the serialized block integrity
  - The CRC64 is computed from buffer data, not from the original context
  Buffer Layout After Successful Call:
  - Offset 0: DumpHardwareHeader with calculated CRC64
  - Offset 16: First DumpHardwareEntry
  - Followed by: First entry's UTF-8 strings (in documented order)
  - Followed by: First entry's DumpExtent array (if extents > 0)
  - Repeated for all remaining entries
  Use Cases:
  - Forensic documentation requiring complete equipment chain of custody
  - Archival metadata for long-term preservation requirements
  - Reproducing imaging conditions for verification or re-imaging
  - Identifying firmware-specific issues or drive-specific behaviors
  - Multi-device imaging scenario documentation
  - Correlating imaging artifacts with specific hardware/software combinations

Warning
  This function reads from the in-memory dump hardware data loaded during aaruf_open(). It does not perform file I/O operations. The data is reconstructed from the parsed context structures into the on-disk binary format.
  The buffer must be valid and large enough to hold the entire dump hardware block. Passing a buffer smaller than required will result in AARUF_ERROR_BUFFER_TOO_SMALL.
  String data in the serialized block is NOT null-terminated. Applications parsing the buffer must use the length fields in DumpHardwareEntry to determine string boundaries. The library adds null terminators only for in-memory convenience.
  The function performs bounds checking during serialization. If calculated entry sizes exceed the buffer length, AARUF_ERROR_BUFFER_TOO_SMALL is returned even after the initial size check. This should not occur with properly sized buffers but protects against data corruption.

See also
  DumpHardwareHeader for the block header structure definition.
  DumpHardwareEntry for the per-environment entry structure definition.
  DumpExtent for the extent range structure definition.
  process_dumphw_block() for the loading process during image opening.

Definition at line 186 of file dump.c.

References AARU_CALL, AARU_EXPORT, AARU_MAGIC, aaruf_crc64_data(), AARUF_ERROR_BUFFER_TOO_SMALL, AARUF_ERROR_CANNOT_READ_BLOCK, AARUF_ERROR_INCORRECT_DATA_SIZE, AARUF_ERROR_NOT_AARUFORMAT, AARUF_STATUS_OK, DumpHardwareHeader::crc64, aaruformat_context::dump_hardware_entries_with_data, aaruformat_context::dump_hardware_header, DumpHardwareBlock, DumpHardwareHeader::entries, DumpHardwareEntriesWithData::entry, DumpHardwareEntriesWithData::extents, DumpHardwareEntry::extents, FATAL, DumpHardwareEntriesWithData::firmware, DumpHardwareEntry::firmwareLength, DumpHardwareHeader::identifier, DumpHardwareHeader::length, aaruformat_context::magic, DumpHardwareEntriesWithData::manufacturer, DumpHardwareEntry::manufacturerLength, DumpHardwareEntriesWithData::model, DumpHardwareEntry::modelLength, DumpHardwareEntriesWithData::revision, DumpHardwareEntry::revisionLength, DumpHardwareEntriesWithData::serial, DumpHardwareEntry::serialLength, DumpHardwareEntriesWithData::softwareName, DumpHardwareEntry::softwareNameLength, DumpHardwareEntriesWithData::softwareOperatingSystem, DumpHardwareEntry::softwareOperatingSystemLength, DumpHardwareEntriesWithData::softwareVersion, DumpHardwareEntry::softwareVersionLength, and TRACE.

## ◆ aaruf_set_dumphw()

int32_t aaruf_set_dumphw | ( | void * | context,
|  | uint8_t * | data,
|  | size_t | length )

Sets the dump hardware block for the image during creation.

Embeds dump hardware information into the image being created. The dump hardware block documents the hardware and software environments used to create the image, recording one or more "dump environments" – typically combinations of physical devices (drives, controllers, adapters) and the software stacks that performed the read operations. This metadata is essential for understanding the imaging context, validating acquisition integrity, reproducing imaging conditions, and supporting forensic or archival documentation requirements.

Each environment entry includes hardware identification (manufacturer, model, revision, firmware, serial number), software identification (name, version, operating system), and optional extent ranges that specify which logical sectors or units were contributed by that particular environment. This structure supports complex imaging scenarios where multiple devices or software configurations were used to create a composite image.

The function accepts a complete, pre-serialized DumpHardwareBlock in the on-disk binary format (as returned by aaruf_get_dumphw() or manually constructed). The block is validated for correct identifier, length consistency, and CRC64 integrity before being parsed and stored in the context. The function deserializes the binary block, extracts all entries with their variable-length UTF-8 strings and extent arrays, and creates null-terminated in-memory copies for internal use.

Validation performed:

1. Context validation (non-NULL, correct magic, write mode)
2. Data buffer validation (non-NULL, non-zero length)
3. Block identifier validation (must be DumpHardwareBlock)
4. Length consistency (buffer length must equal sizeof(DumpHardwareHeader) + header.length)
5. CRC64 integrity verification (calculated CRC64 must match header.crc64)

Parsing process:

1. Read and validate the DumpHardwareHeader from the buffer
2. Allocate array for all dump hardware entries
3. For each entry:
   - Read the DumpHardwareEntry structure (36 bytes)
   - Allocate and copy each non-empty UTF-8 string with +1 byte for null terminator
   - Allocate and copy the DumpExtent array if extents > 0
4. Free any previously set dump hardware data
5. Store the new parsed data in ctx->dumpHardwareEntriesWithData
6. Store the header in ctx->dumpHardwareHeader

Memory management: If any memory allocation fails during parsing, all previously allocated memory for the new data is freed via the free_copy_and_error label, and AARUF_ERROR_NOT_ENOUGH_MEMORY is returned. Any existing dump hardware data in the context is freed before storing new data, ensuring no memory leaks when replacing dump hardware information.

Parameters

  context | Pointer to the aaruformat context (must be a valid, write-enabled image context).
  data | Pointer to the dump hardware block data in on-disk binary format. Must contain a complete DumpHardwareBlock starting with DumpHardwareHeader followed by all entries, strings, and extent arrays. Must not be NULL.
  length | Length of the dump hardware block data in bytes. Must equal sizeof(DumpHardwareHeader) + header.length for validation to succeed.

Returns
  Returns one of the following status codes:

Return values

  AARUF_STATUS_OK | (0) Successfully set dump hardware block. This is returned when: The context is valid and properly initialized The context is opened in write mode (ctx->isWriting is true) The data buffer contains a valid DumpHardwareBlock The block identifier is DumpHardwareBlock The length is consistent (buffer length == header size + payload length) The CRC64 checksum is valid All memory allocations succeeded All entries with strings and extents are parsed and stored Any previous dump hardware data is freed ctx->dumpHardwareEntriesWithData is populated with parsed entries ctx->dumpHardwareHeader is updated with the new header
  AARUF_ERROR_NOT_AARUFORMAT | (-1) The context is invalid. This occurs when: The context parameter is NULL The context magic number doesn't match AARU_MAGIC (invalid context type) The context was not properly initialized by aaruf_create()
  AARUF_READ_ONLY | (-13) The context is not opened for writing. This occurs when: The image was opened with aaruf_open() instead of aaruf_create() The context's isWriting flag is false Attempting to modify a read-only image
  AARUF_ERROR_CANNOT_READ_BLOCK | (-6) Invalid block identifier. This occurs when: The identifier field in the DumpHardwareHeader doesn't equal DumpHardwareBlock The data buffer doesn't contain a valid dump hardware block The block type is incorrect or corrupted
  AARUF_ERROR_INCORRECT_DATA_SIZE | (-11) Invalid data or length. This occurs when: The data parameter is NULL The length parameter is 0 (empty block) The buffer length doesn't match sizeof(DumpHardwareHeader) + header.length Length inconsistency indicates corrupted or incomplete block data
  AARUF_ERROR_INVALID_BLOCK_CRC | (-10) CRC64 checksum mismatch. This occurs when: The calculated CRC64 over the payload doesn't match header.crc64 Block data is corrupted or tampered with Block was not properly constructed or serialized
  AARUF_ERROR_NOT_ENOUGH_MEMORY | (-8) Memory allocation failed. This occurs when: calloc() or malloc() failed to allocate memory for entries array Failed to allocate memory for any string field (manufacturer, model, etc.) Failed to allocate memory for extent arrays System is out of memory or memory is severely fragmented All partially allocated memory is freed before returning

Note
  Dump Hardware Block Format:
  - The data buffer must contain a complete serialized DumpHardwareBlock
  - Format: DumpHardwareHeader + repeated entries with strings and extents
  - All strings are UTF-8 encoded and NOT null-terminated in the buffer
  - The function adds null terminators when copying strings to internal storage
  - String lengths are in bytes, not character counts
  Creating Block Data:
  - Use aaruf_get_dumphw() to retrieve a block from an existing image
  - Manually construct by serializing DumpHardwareHeader, entries, strings, and extents
  - Calculate CRC64-ECMA over the payload (everything after the header)
  - Ensure all length fields accurately reflect the data sizes
  - Ensure total buffer size equals sizeof(DumpHardwareHeader) + payload length
  Hardware Identification Fields:
  - manufacturer: Device manufacturer (e.g., "Plextor", "Sony", "Samsung")
  - model: Device model number (e.g., "PX-716A", "DRU-820A")
  - revision: Hardware revision identifier
  - firmware: Firmware version (e.g., "1.11", "KY08")
  - serial: Device serial number for unique identification
  Software Identification Fields:
  - softwareName: Dumping software name (e.g., "Aaru", "ddrescue", "IsoBuster")
  - softwareVersion: Software version (e.g., "5.3.0", "1.25")
  - softwareOperatingSystem: Host OS (e.g., "Linux 5.10.0", "Windows 10", "macOS 12.0")
  Extent Arrays:
  - Each DumpExtent specifies a [start, end] logical sector range
  - Extents indicate which sectors this environment contributed
  - Empty extent arrays (extents == 0) mean the environment dumped entire medium
  - Extents are stored in the order provided in the input buffer
  Memory Ownership:
  - The function creates internal copies of all data
  - The caller retains ownership of the input data buffer
  - The caller may free the input buffer immediately after this function returns
  - Internal copies are freed during aaruf_close() or when replaced by another call
  Replacing Existing Data:
  - Calling this function multiple times replaces previous dump hardware data
  - All previous entries, strings, and extents are freed before storing new data
  - No memory leaks occur when updating dump hardware information

Warning
  The dump hardware block is only written to the image file during aaruf_close(). Changes made by this function are not immediately persisted to disk.
  CRC64 validation protects against corrupted blocks, but construction errors in the input buffer (incorrect lengths, misaligned data) may cause parsing to fail or produce incorrect results even with a valid checksum.
  The function assumes the input buffer is properly formatted and packed according to the DumpHardwareBlock specification. Malformed input may cause crashes or memory corruption.

See also
  DumpHardwareHeader for the block header structure definition.
  DumpHardwareEntry for the per-environment entry structure definition.
  DumpExtent for the extent range structure definition.
  aaruf_get_dumphw() for retrieving dump hardware from opened images.
  write_dumphw_block() for the serialization process during image closing.

Definition at line 531 of file dump.c.

References AARU_CALL, AARU_EXPORT, AARU_MAGIC, aaruf_crc64_data(), AARUF_ERROR_CANNOT_READ_BLOCK, AARUF_ERROR_INCORRECT_DATA_SIZE, AARUF_ERROR_INVALID_BLOCK_CRC, AARUF_ERROR_NOT_AARUFORMAT, AARUF_ERROR_NOT_ENOUGH_MEMORY, AARUF_READ_ONLY, AARUF_STATUS_OK, compare_extents(), COPY_STRING_FIELD, DumpHardwareHeader::crc64, aaruformat_context::dump_hardware_entries_with_data, aaruformat_context::dump_hardware_header, DumpHardwareBlock, DumpHardwareHeader::entries, DumpHardwareEntriesWithData::entry, DumpHardwareEntriesWithData::extents, DumpHardwareEntry::extents, FATAL, free_dump_hardware_entries(), DumpHardwareHeader::identifier, aaruformat_context::is_writing, DumpHardwareHeader::length, aaruformat_context::magic, and TRACE.

## ◆ free_dump_hardware_entries()

void free_dump_hardware_entries | ( | DumpHardwareEntriesWithData * | entries,
|  | uint32_t | count )
| static

Definition at line 26 of file dump.c.

Referenced by aaruf_set_dumphw().