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,
const uint32_t length, uint32_t *remaining,
65 uint8_t **destination)
67 if(length == 0)
return true;
69 if(*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 = malloc(length);
80 TRACE(
"Could not allocate %s buffer of length %u", field_name, length);
84 const 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);
94 *destination = buffer;
109 TRACE(
"Entering process_dumphw_block(%p, %p)", ctx, entry);
110 size_t read_bytes = 0;
112 if(ctx == NULL || ctx->
imageStream == NULL || entry == NULL)
114 FATAL(
"Invalid context, image stream, or index entry pointer.");
115 TRACE(
"Exiting process_dumphw_block()");
122 TRACE(
"Index entry block type %u is not DumpHardwareBlock, skipping.", entry->
blockType);
123 TRACE(
"Exiting process_dumphw_block()");
129 FATAL(
"Could not seek to %" PRIu64
" as indicated by index entry...", entry->
offset);
131 TRACE(
"Exiting process_dumphw_block()");
135 TRACE(
"Reading dump hardware block header at position %" PRIu64, entry->
offset);
137 read_bytes = fread(&header, 1,
sizeof(header), ctx->
imageStream);
139 if(read_bytes !=
sizeof(header))
141 TRACE(
"Could not read dump hardware block header (read %zu bytes)", read_bytes);
143 TRACE(
"Exiting process_dumphw_block()");
149 TRACE(
"Incorrect identifier 0x%08" PRIx32
" for dump hardware block at position %" PRIu64, header.
identifier,
152 TRACE(
"Exiting process_dumphw_block()");
158 TRACE(
"Dump hardware header indicates %u entries but zero payload length", header.
entries);
160 TRACE(
"Exiting process_dumphw_block()");
164 const uint32_t payload_length = header.
length;
166 if(payload_length > 0)
168 uint8_t *payload = malloc(payload_length);
172 TRACE(
"Could not allocate %u bytes for dump hardware payload", payload_length);
174 TRACE(
"Exiting process_dumphw_block()");
178 read_bytes = fread(payload, 1, payload_length, ctx->
imageStream);
180 if(read_bytes != payload_length)
182 TRACE(
"Could not read dump hardware payload, expected %u bytes got %zu", payload_length, read_bytes);
185 TRACE(
"Exiting process_dumphw_block()");
193 if(crc64 != header.
crc64)
195 TRACE(
"Dump hardware block CRC mismatch: computed 0x%" PRIx64
" expected 0x%" PRIx64, crc64, header.
crc64);
198 TRACE(
"Exiting process_dumphw_block()");
204 if(fseek(ctx->
imageStream, -(
long)payload_length, SEEK_CUR) != 0)
206 TRACE(
"Could not rewind after CRC verification");
208 TRACE(
"Exiting process_dumphw_block()");
217 TRACE(
"Dump hardware block contains no entries. Clearing existing metadata.");
218 TRACE(
"Exiting process_dumphw_block()");
226 TRACE(
"Dump hardware entries multiplication overflow (%u entries)", header.
entries);
228 TRACE(
"Exiting process_dumphw_block()");
236 TRACE(
"Could not allocate %zu bytes for dump hardware entries", allocation_size);
238 TRACE(
"Exiting process_dumphw_block()");
242 uint32_t remaining_payload = payload_length;
243 uint16_t processed_entry = 0;
245 TRACE(
"Processing %u dump hardware block entries", header.
entries);
247 for(uint16_t e = 0; e < header.
entries; e++)
254 TRACE(
"Remaining payload %u too small for dump hardware entry %u", remaining_payload, e);
262 TRACE(
"Could not read dump hardware entry %u header (read %zu bytes)", e, read_bytes);
303 if(extent_count == 0)
continue;
305 const size_t extent_bytes = (size_t)extent_count *
sizeof(
DumpExtent);
307 if(extent_bytes /
sizeof(
DumpExtent) != extent_count || extent_bytes > remaining_payload)
309 TRACE(
"Extent array for entry %u exceeds remaining payload (%zu bytes requested, %u left)", e, extent_bytes,
318 TRACE(
"Could not allocate %zu bytes for dump hardware entry %u extents", extent_bytes, e);
324 if(extents_read != extent_count)
326 TRACE(
"Could not read %u dump hardware extents for entry %u (read %zu)", extent_count, e, extents_read);
330 remaining_payload -= (uint32_t)extent_bytes;
333 TRACE(
"Sorted %u extents for entry %u", extent_count, e);
340 if(remaining_payload != 0)
342 TRACE(
"Dump hardware block parsing completed with %u trailing payload bytes", remaining_payload);
345 TRACE(
"Exiting process_dumphw_block()");
352 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, const 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.