38 if(entries == NULL)
return;
40 for(uint16_t e = 0; e < count; e++)
42 free(entries[e].manufacturer);
43 free(entries[e].model);
44 free(entries[e].revision);
45 free(entries[e].firmware);
46 free(entries[e].serial);
47 free(entries[e].softwareName);
48 free(entries[e].softwareVersion);
49 free(entries[e].softwareOperatingSystem);
50 free(entries[e].extents);
56 if(ctx == NULL)
return;
64static bool read_dump_string(FILE *stream,
const char *field_name, uint32_t length, uint32_t *remaining,
65 uint8_t **destination)
67 if(length == 0)
return true;
69 if(remaining == NULL || *remaining < length)
71 TRACE(
"Dump hardware %s length %u exceeds remaining payload %u", field_name, length,
72 remaining == NULL ? 0 : *remaining);
76 uint8_t *buffer = (uint8_t *)malloc((
size_t)length + 1);
80 TRACE(
"Could not allocate %s buffer of length %u", field_name, length);
84 size_t bytes_read = fread(buffer, 1, length, stream);
86 if(bytes_read != length)
88 TRACE(
"Could not read %s field, expected %u bytes got %zu", field_name, length, bytes_read);
95 *destination = buffer;
110 TRACE(
"Entering process_dumphw_block(%p, %p)", ctx, entry);
111 size_t read_bytes = 0;
113 if(ctx == NULL || ctx->
imageStream == NULL || entry == NULL)
115 FATAL(
"Invalid context, image stream, or index entry pointer.");
116 TRACE(
"Exiting process_dumphw_block()");
123 TRACE(
"Index entry block type %u is not DumpHardwareBlock, skipping.", entry->
blockType);
124 TRACE(
"Exiting process_dumphw_block()");
130 FATAL(
"Could not seek to %" PRIu64
" as indicated by index entry...", entry->
offset);
132 TRACE(
"Exiting process_dumphw_block()");
136 TRACE(
"Reading dump hardware block header at position %" PRIu64, entry->
offset);
138 read_bytes = fread(&header, 1,
sizeof(header), ctx->
imageStream);
140 if(read_bytes !=
sizeof(header))
142 TRACE(
"Could not read dump hardware block header (read %zu bytes)", read_bytes);
144 TRACE(
"Exiting process_dumphw_block()");
150 TRACE(
"Incorrect identifier 0x%08" PRIx32
" for dump hardware block at position %" PRIu64, header.
identifier,
153 TRACE(
"Exiting process_dumphw_block()");
159 TRACE(
"Dump hardware header indicates %u entries but zero payload length", header.
entries);
161 TRACE(
"Exiting process_dumphw_block()");
165 const uint32_t payload_length = header.
length;
167 if(payload_length > 0)
169 uint8_t *payload = (uint8_t *)malloc(payload_length);
173 TRACE(
"Could not allocate %u bytes for dump hardware payload", payload_length);
175 TRACE(
"Exiting process_dumphw_block()");
179 read_bytes = fread(payload, 1, payload_length, ctx->
imageStream);
181 if(read_bytes != payload_length)
183 TRACE(
"Could not read dump hardware payload, expected %u bytes got %zu", payload_length, read_bytes);
186 TRACE(
"Exiting process_dumphw_block()");
194 if(crc64 != header.
crc64)
196 TRACE(
"Dump hardware block CRC mismatch: computed 0x%" PRIx64
" expected 0x%" PRIx64, crc64, header.
crc64);
199 TRACE(
"Exiting process_dumphw_block()");
205 if(fseek(ctx->
imageStream, -(
long)payload_length, SEEK_CUR) != 0)
207 TRACE(
"Could not rewind after CRC verification");
209 TRACE(
"Exiting process_dumphw_block()");
218 TRACE(
"Dump hardware block contains no entries. Clearing existing metadata.");
219 TRACE(
"Exiting process_dumphw_block()");
227 TRACE(
"Dump hardware entries multiplication overflow (%u entries)", header.
entries);
229 TRACE(
"Exiting process_dumphw_block()");
238 TRACE(
"Could not allocate %zu bytes for dump hardware entries", allocation_size);
240 TRACE(
"Exiting process_dumphw_block()");
244 uint32_t remaining_payload = payload_length;
245 uint16_t processed_entry = 0;
247 TRACE(
"Processing %u dump hardware block entries", header.
entries);
249 for(uint16_t e = 0; e < header.
entries; e++)
256 TRACE(
"Remaining payload %u too small for dump hardware entry %u", remaining_payload, e);
264 TRACE(
"Could not read dump hardware entry %u header (read %zu bytes)", e, read_bytes);
305 if(extent_count == 0)
continue;
307 const size_t extent_bytes = (size_t)extent_count *
sizeof(
DumpExtent);
309 if(extent_bytes /
sizeof(
DumpExtent) != extent_count || extent_bytes > remaining_payload)
311 TRACE(
"Extent array for entry %u exceeds remaining payload (%zu bytes requested, %u left)", e, extent_bytes,
320 TRACE(
"Could not allocate %zu bytes for dump hardware entry %u extents", extent_bytes, e);
326 if(extents_read != extent_count)
328 TRACE(
"Could not read %u dump hardware extents for entry %u (read %zu)", extent_count, e, extents_read);
332 remaining_payload -= (uint32_t)extent_bytes;
335 TRACE(
"Sorted %u extents for entry %u", extent_count, e);
342 if(remaining_payload != 0)
344 TRACE(
"Dump hardware block parsing completed with %u trailing payload bytes", remaining_payload);
347 TRACE(
"Exiting process_dumphw_block()");
354 TRACE(
"Exiting process_dumphw_block()");
void process_dumphw_block(aaruformat_context *ctx, const IndexEntry *entry)
Processes a dump hardware block from the image stream.
static void reset_dump_hardware_context(aaruformat_context *ctx)
static void free_dump_hardware_entries_array(DumpHardwareEntriesWithData *entries, uint16_t count)
static bool read_dump_string(FILE *stream, const char *field_name, uint32_t length, uint32_t *remaining, uint8_t **destination)
Core public constants and compile‑time limits for the Aaru container format implementation.
#define AARUF_VERSION_V1
First on‑disk version (C# implementation).
Central runtime context structures for libaaruformat (image state, caches, checksum buffers).
uint64_t aaruf_crc64_data(const uint8_t *data, uint32_t len)
Packed on-disk structures describing hardware and software used during image acquisition.
@ DumpHardwareBlock
Block containing an array of hardware used to create the image.
On‑disk index block header and entry structures (versions 1, 2 and 3).
int compare_extents(const void *a, const void *b)
Comparison function for sorting DumpExtent arrays by start sector.
Inclusive [start,end] logical sector range contributed by a single hardware environment.
In-memory representation of a dump hardware entry plus decoded variable-length fields & extents.
uint8_t * firmware
Firmware version string or NULL.
uint8_t * revision
Hardware revision string or NULL.
uint8_t * model
Model string or NULL.
uint8_t * softwareName
Dump software name or NULL.
struct DumpExtent * extents
Array of extents (entry.extents elements) or NULL.
uint8_t * manufacturer
Manufacturer string (UTF-8) or NULL.
uint8_t * softwareVersion
Dump software version or NULL.
uint8_t * serial
Serial number string or NULL.
DumpHardwareEntry entry
Fixed-size header with lengths & counts.
uint8_t * softwareOperatingSystem
Host operating system string or NULL.
Per-environment length table describing subsequent UTF-8 strings and optional extent array.
uint32_t softwareNameLength
Length in bytes of dumping software name string.
uint32_t manufacturerLength
Length in bytes of manufacturer UTF-8 string.
uint32_t softwareVersionLength
Length in bytes of dumping software version string.
uint32_t firmwareLength
Length in bytes of firmware version string.
uint32_t extents
Number of DumpExtent records following the strings (0 = none).
uint32_t modelLength
Length in bytes of model UTF-8 string.
uint32_t serialLength
Length in bytes of device serial number string.
uint32_t revisionLength
Length in bytes of revision / hardware revision string.
uint32_t softwareOperatingSystemLength
Length in bytes of host operating system string.
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.
Master context representing an open or in‑creation Aaru image.
AaruHeaderV2 header
Parsed container header (v2).
struct DumpHardwareEntriesWithData * dump_hardware_entries_with_data
Array of dump hardware entries + strings.
FILE * imageStream
Underlying FILE* stream (binary mode).
DumpHardwareHeader dump_hardware_header
Dump hardware header.