56 if(phys_group >= regions[p].start_sector && phys_group < regions[p].end_sector)
63 if(in_part < 0)
return;
65 uint64_t group_idx = phys_group - regions[in_part].
start_sector;
80 int mid = lo + (hi - lo) / 2;
81 uint64_t entry_end = entries[mid].
offset + entries[mid].
length;
83 if(disc_off >= entry_end)
85 else if(disc_off < entries[mid].offset)
94 if(found < 0)
continue;
99 memcpy(seed_copy, entries[found].seed,
sizeof(seed_copy));
107 uint8_t discard[4096];
108 size_t adv = advance;
112 size_t step = adv >
sizeof(discard) ?
sizeof(discard) : adv;
186 const uint32_t initial_length = length == NULL ? 0U : *length;
188 TRACE(
"Entering aaruf_read_media_tag(%p, %p, %d, %u)", context, data, tag, initial_length);
194 FATAL(
"Invalid context");
195 TRACE(
"Exiting aaruf_read_media_tag() = AARUF_ERROR_NOT_AARUFORMAT");
201 FATAL(
"Invalid length pointer");
202 TRACE(
"Exiting aaruf_read_media_tag() = AARUF_ERROR_INCORRECT_DATA_SIZE");
211 FATAL(
"Invalid context");
212 TRACE(
"Exiting aaruf_read_media_tag() = AARUF_ERROR_NOT_AARUFORMAT");
216 TRACE(
"Finding media tag %d", tag);
217 HASH_FIND_INT(ctx->
mediaTags, &tag, item);
221 TRACE(
"Media tag not found");
224 TRACE(
"Exiting aaruf_read_media_tag() = AARUF_ERROR_MEDIA_TAG_NOT_PRESENT");
228 if(data == NULL || *length < item->length)
230 TRACE(
"Buffer too small for media tag %d, required %u bytes", tag, item->
length);
233 TRACE(
"Exiting aaruf_read_media_tag() = AARUF_ERROR_BUFFER_TOO_SMALL");
240 TRACE(
"Media tag %d read successfully, length %u", tag, *length);
241 TRACE(
"Exiting aaruf_read_media_tag() = AARUF_STATUS_OK");
353 uint8_t *data, uint32_t *length, uint8_t *sector_status)
355 const uint32_t initial_length = length == NULL ? 0U : *length;
357 TRACE(
"Entering aaruf_read_sector(%p, %" PRIu64
", %d, %p, %u)", context, sector_address, negative, data,
362 uint64_t block_offset = 0;
364 uint8_t *block = NULL;
365 size_t read_bytes = 0;
367 size_t lzma_size = 0;
368 uint8_t *cmp_data = NULL;
374 FATAL(
"Invalid context");
376 TRACE(
"Exiting aaruf_read_sector() = AARUF_ERROR_NOT_AARUFORMAT");
384 FATAL(
"Invalid length pointer");
386 TRACE(
"Exiting aaruf_read_sector() = AARUF_ERROR_INCORRECT_DATA_SIZE");
393 FATAL(
"Invalid context");
395 TRACE(
"Exiting aaruf_read_sector() = AARUF_ERROR_NOT_AARUFORMAT");
403 TRACE(
"Exiting aaruf_read_sector() = AARUF_ERROR_USER_DATA_NOT_PRESENT (flux-only image)");
409 FATAL(
"Sector address out of bounds");
411 TRACE(
"Exiting aaruf_read_sector() = AARUF_ERROR_SECTOR_OUT_OF_BOUNDS");
417 FATAL(
"Sector address out of bounds");
419 TRACE(
"Exiting aaruf_read_sector() = AARUF_ERROR_SECTOR_OUT_OF_BOUNDS");
427 FATAL(
"Negative sector addresses not supported in this image");
431 error_no =
decode_ddt_entry_v1(ctx, sector_address, &offset, &block_offset, sector_status);
434 error_no =
decode_ddt_entry_v2(ctx, sector_address, negative, &offset, &block_offset, sector_status);
438 FATAL(
"Error %d decoding DDT entry", error_no);
440 TRACE(
"Exiting aaruf_read_sector() = %d", error_no);
449 TRACE(
"Exiting aaruf_read_sector() = AARUF_STATUS_SECTOR_NOT_DUMPED");
466 TRACE(
"Exiting aaruf_read_sector() = AARUF_ERROR_BUFFER_TOO_SMALL (generable, NULL data)");
475 disc_offset, data, *length) == 0)
480 TRACE(
"Exiting aaruf_read_sector() = AARUF_STATUS_OK (GOD generable)");
511 uint64_t logical = first_logical + s;
513 if(logical == sector_address)
519 uint32_t s_len = *length;
520 uint8_t s_status = 0;
547 TRACE(
"Exiting aaruf_read_sector() = AARUF_STATUS_OK (WOD generable re-encrypted)");
553 memset(data, 0, *length);
555 TRACE(
"Exiting aaruf_read_sector() = AARUF_STATUS_OK (generable not in map)");
562 memset(data, 0, *length);
564 TRACE(
"Exiting aaruf_read_sector() = AARUF_STATUS_OK (no junk map)");
570 TRACE(
"Checking if block header is cached");
574 if(block_header == NULL)
576 TRACE(
"Allocating memory for block header");
578 if(block_header == NULL)
580 FATAL(
"Not enough memory for block header");
582 TRACE(
"Exiting aaruf_read_sector() = AARUF_ERROR_NOT_ENOUGH_MEMORY");
586 TRACE(
"Reading block header");
589 FATAL(
"Could not seek to block header");
592 TRACE(
"Exiting aaruf_read_sector() = AARUF_ERROR_CANNOT_READ_HEADER");
600 FATAL(
"Error reading block header");
603 TRACE(
"Exiting aaruf_read_sector() = AARUF_ERROR_CANNOT_READ_HEADER");
607 TRACE(
"Adding block header to cache");
612 FATAL(
"Could not seek past cached block header");
614 TRACE(
"Exiting aaruf_read_sector() = AARUF_ERROR_CANNOT_READ_HEADER");
623 TRACE(
"Block header at offset %" PRIu64
" appears corrupt (id=0x%08X sectorSize=%u)",
625 goto ec_try_recovery;
628 if(data == NULL || *length < block_header->sectorSize)
630 TRACE(
"Buffer too small for sector, required %u bytes", block_header->
sectorSize);
633 TRACE(
"Exiting aaruf_read_sector() = AARUF_ERROR_BUFFER_TOO_SMALL");
638 TRACE(
"Checking if block is cached");
643 TRACE(
"Getting data from cache");
696 uint64_t logical = first_logical + s;
698 if(logical == sector_address)
705 uint32_t s_len = *length;
706 uint8_t s_status = 0;
764 uint64_t logical = first_logical + s;
766 if(logical == sector_address)
772 uint32_t s_len = *length;
773 uint8_t s_status = 0;
802 TRACE(
"Exiting aaruf_read_sector() = AARUF_STATUS_OK");
810 TRACE(
"Allocating memory for block");
811 block = (uint8_t *)malloc(block_header->
length);
814 FATAL(
"Not enough memory for block");
816 TRACE(
"Exiting aaruf_read_sector() = AARUF_ERROR_NOT_ENOUGH_MEMORY");
820 TRACE(
"Reading block into memory");
823 if(read_bytes != block_header->
length)
825 FATAL(
"Could not read block");
828 TRACE(
"Exiting aaruf_read_sector() = AARUF_ERROR_CANNOT_READ_BLOCK");
836 FATAL(
"Invalid LZMA block lengths (cmpLength=%u, length=%u)", block_header->
cmpLength,
839 TRACE(
"Exiting aaruf_read_sector() = AARUF_ERROR_CANNOT_DECOMPRESS_BLOCK");
840 goto ec_try_recovery;
844 TRACE(
"Allocating memory for compressed data of size %zu bytes", lzma_size);
845 cmp_data = malloc(lzma_size);
849 FATAL(
"Cannot allocate memory for block...");
851 TRACE(
"Exiting aaruf_read_sector() = AARUF_ERROR_NOT_ENOUGH_MEMORY");
855 TRACE(
"Allocating memory for block of size %zu bytes", block_header->
length);
856 block = malloc(block_header->
length);
859 FATAL(
"Cannot allocate memory for block...");
862 TRACE(
"Exiting aaruf_read_sector() = AARUF_ERROR_NOT_ENOUGH_MEMORY");
870 FATAL(
"Could not read LZMA properties...");
874 TRACE(
"Exiting aaruf_read_sector() = AARUF_ERROR_CANNOT_DECOMPRESS_BLOCK");
875 goto ec_try_recovery;
878 read_bytes = fread(cmp_data, 1, lzma_size, ctx->
imageStream);
879 if(read_bytes != lzma_size)
881 FATAL(
"Could not read compressed block...");
885 TRACE(
"Exiting aaruf_read_sector() = AARUF_ERROR_CANNOT_DECOMPRESS_BLOCK");
886 goto ec_try_recovery;
889 TRACE(
"Decompressing block of size %zu bytes", block_header->
length);
890 read_bytes = block_header->
length;
896 FATAL(
"Got error %d from LZMA...", error_no);
900 TRACE(
"Exiting aaruf_read_sector() = AARUF_ERROR_CANNOT_DECOMPRESS_BLOCK");
901 goto ec_try_recovery;
904 if(read_bytes != block_header->
length)
906 FATAL(
"Error decompressing block, should be {0} bytes but got {1} bytes...");
910 TRACE(
"Exiting aaruf_read_sector() = AARUF_ERROR_CANNOT_DECOMPRESS_BLOCK");
911 goto ec_try_recovery;
920 FATAL(
"Invalid zstd block lengths (cmpLength=%u, length=%u)", block_header->
cmpLength,
922 TRACE(
"Exiting aaruf_read_sector() = AARUF_ERROR_CANNOT_DECOMPRESS_BLOCK");
923 goto ec_try_recovery;
926 TRACE(
"Allocating memory for block of size %zu bytes", block_header->
length);
927 block = (uint8_t *)malloc(block_header->
length);
930 FATAL(
"Not enough memory for block");
931 TRACE(
"Exiting aaruf_read_sector() = AARUF_ERROR_NOT_ENOUGH_MEMORY");
935 TRACE(
"Allocating memory for compressed data of size %zu bytes", block_header->
cmpLength);
936 cmp_data = malloc(block_header->
cmpLength);
939 FATAL(
"Not enough memory for compressed data");
941 TRACE(
"Exiting aaruf_read_sector() = AARUF_ERROR_NOT_ENOUGH_MEMORY");
948 if(read_bytes != block_header->
cmpLength)
950 FATAL(
"Could not read compressed block");
953 TRACE(
"Exiting aaruf_read_sector() = AARUF_ERROR_CANNOT_DECOMPRESS_BLOCK");
954 goto ec_try_recovery;
958 if(read_bytes != block_header->
length)
960 FATAL(
"Error decompressing zstd block, expected %u bytes got %zu", block_header->
length, read_bytes);
963 TRACE(
"Exiting aaruf_read_sector() = AARUF_ERROR_CANNOT_DECOMPRESS_BLOCK");
964 goto ec_try_recovery;
971 TRACE(
"Allocating memory for compressed data of size %zu bytes", block_header->
cmpLength);
972 cmp_data = malloc(block_header->
cmpLength);
976 FATAL(
"Cannot allocate memory for block...");
978 TRACE(
"Exiting aaruf_read_sector() = AARUF_ERROR_NOT_ENOUGH_MEMORY");
982 TRACE(
"Allocating memory for block of size %zu bytes", block_header->
length);
983 block = malloc(block_header->
length);
986 FATAL(
"Cannot allocate memory for block...");
989 TRACE(
"Exiting aaruf_read_sector() = AARUF_ERROR_NOT_ENOUGH_MEMORY");
993 TRACE(
"Reading compressed data into memory");
995 if(read_bytes != block_header->
cmpLength)
997 FATAL(
"Could not read compressed block...");
1001 TRACE(
"Exiting aaruf_read_sector() = AARUF_ERROR_CANNOT_DECOMPRESS_BLOCK");
1002 goto ec_try_recovery;
1005 TRACE(
"Decompressing block of size %zu bytes", block_header->
length);
1009 if(read_bytes != block_header->
length)
1011 FATAL(
"Error decompressing block, should be {0} bytes but got {1} bytes...");
1015 TRACE(
"Exiting aaruf_read_sector() = AARUF_ERROR_CANNOT_DECOMPRESS_BLOCK");
1016 goto ec_try_recovery;
1024 TRACE(
"Exiting aaruf_read_sector() = AARUF_ERROR_UNSUPPORTED_COMPRESSION");
1025 goto ec_try_recovery;
1029 TRACE(
"Adding block to cache");
1068 if(part_key != NULL)
1082 uint64_t logical = first_logical + s;
1084 if(logical == sector_address)
1091 uint32_t s_len = *length;
1092 uint8_t s_status = 0;
1136 if(part_key != NULL)
1149 uint64_t logical = first_logical + s;
1151 if(logical == sector_address)
1157 uint32_t s_len = *length;
1158 uint8_t s_status = 0;
1186 TRACE(
"Exiting aaruf_read_sector() = AARUF_STATUS_OK");
1196 TRACE(
"Attempting erasure coding recovery for block at offset %" PRIu64, block_offset);
1200 TRACE(
"Erasure coding recovery succeeded");
1203 TRACE(
"Erasure coding recovery failed: %d", rc);
1206 TRACE(
"Exiting aaruf_read_sector() = AARUF_ERROR_CANNOT_DECOMPRESS_BLOCK");
1283 uint32_t *length,
const uint8_t track, uint8_t *sector_status)
1285 const uint32_t initial_length = length == NULL ? 0U : *length;
1287 TRACE(
"Entering aaruf_read_track_sector(%p, %p, %" PRIu64
", %u, %d)", context, data, sector_address,
1288 initial_length, track);
1292 FATAL(
"Invalid context");
1294 TRACE(
"Exiting aaruf_read_track_sector() = AARUF_ERROR_NOT_AARUFORMAT");
1302 FATAL(
"Invalid length pointer");
1304 TRACE(
"Exiting aaruf_read_track_sector() = AARUF_ERROR_INCORRECT_DATA_SIZE");
1311 FATAL(
"Invalid context");
1313 TRACE(
"Exiting aaruf_read_track_sector() = AARUF_ERROR_NOT_AARUFORMAT");
1321 TRACE(
"Exiting aaruf_read_track_sector() = AARUF_ERROR_INCORRECT_MEDIA_TYPE");
1330 TRACE(
"Track %d not found", track);
1331 TRACE(
"Exiting aaruf_read_track_sector() = AARUF_ERROR_TRACK_NOT_FOUND");
1439 uint8_t *data, uint32_t *length, uint8_t *sector_status)
1441 const uint32_t initial_length = length == NULL ? 0U : *length;
1443 TRACE(
"Entering aaruf_read_sector_long(%p, %" PRIu64
", %d, %p, %u)", context, sector_address, data,
1447 uint32_t bare_length = 0;
1448 uint32_t tag_length = 0;
1449 uint8_t *bare_data = NULL;
1451 int32_t query_status;
1454 bool trk_found =
false;
1458 FATAL(
"Invalid context");
1460 TRACE(
"Exiting aaruf_read_sector_long() = AARUF_ERROR_NOT_AARUFORMAT");
1468 FATAL(
"Invalid length pointer");
1470 TRACE(
"Exiting aaruf_read_sector_long() = AARUF_ERROR_INCORRECT_DATA_SIZE");
1477 FATAL(
"Invalid context");
1479 TRACE(
"Exiting aaruf_read_sector_long() = AARUF_ERROR_NOT_AARUFORMAT");
1487 TRACE(
"Exiting aaruf_read_sector_long() = AARUF_ERROR_USER_DATA_NOT_PRESENT (flux-only image)");
1493 FATAL(
"Sector address out of bounds");
1495 TRACE(
"Exiting aaruf_read_sector_long() = AARUF_ERROR_SECTOR_OUT_OF_BOUNDS");
1501 FATAL(
"Sector address out of bounds");
1503 TRACE(
"Exiting aaruf_read_sector_long() = AARUF_ERROR_SECTOR_OUT_OF_BOUNDS");
1507 uint64_t corrected_sector_address = sector_address;
1516 const int64_t signed_lba = negative ? -(int64_t)sector_address : (int64_t)sector_address;
1532 return aaruf_read_sector(context, sector_address, negative, data, length, sector_status);
1534 if(*length < 2064 || data == NULL)
1537 FATAL(
"Buffer too small for sector, required %u bytes", *length);
1539 TRACE(
"Exiting aaruf_read_sector_long() = AARUF_ERROR_BUFFER_TOO_SMALL");
1544 query_status =
aaruf_read_sector(context, sector_address, negative, NULL, &bare_length, sector_status);
1548 TRACE(
"Exiting aaruf_read_sector_long() = %d", query_status);
1549 return query_status;
1552 if(bare_length == 0)
1554 FATAL(
"Invalid bare sector length (0)");
1556 TRACE(
"Exiting aaruf_read_sector_long() = AARUF_ERROR_INCORRECT_DATA_SIZE");
1560 TRACE(
"Allocating memory for bare data");
1561 bare_data = (uint8_t *)malloc(bare_length);
1563 if(bare_data == NULL)
1565 FATAL(
"Could not allocate memory for bare data");
1567 TRACE(
"Exiting aaruf_read_sector_long() = AARUF_ERROR_NOT_ENOUGH_MEMORY");
1571 res =
aaruf_read_sector(context, sector_address, negative, bare_data, &bare_length, sector_status);
1578 TRACE(
"Exiting aaruf_read_sector_long() = %d", res);
1582 memcpy(data, ctx->
sector_id + corrected_sector_address * 4, 4);
1583 memcpy(data + 4, ctx->
sector_ied + corrected_sector_address * 2, 2);
1584 memcpy(data + 6, ctx->
sector_cpr_mai + corrected_sector_address * 6, 6);
1585 memcpy(data + 12, bare_data, 2048);
1586 memcpy(data + 2060, ctx->
sector_edc + corrected_sector_address * 4, 4);
1598 return aaruf_read_sector(context, sector_address, negative, data, length, sector_status);
1600 if(*length < 2064 || data == NULL)
1603 FATAL(
"Buffer too small for sector, required %u bytes", *length);
1605 TRACE(
"Exiting aaruf_read_sector_long() = AARUF_ERROR_BUFFER_TOO_SMALL");
1610 query_status =
aaruf_read_sector(context, sector_address, negative, NULL, &bare_length, sector_status);
1614 TRACE(
"Exiting aaruf_read_sector_long() = %d", query_status);
1615 return query_status;
1618 if(bare_length == 0)
1620 FATAL(
"Invalid bare sector length (0)");
1622 TRACE(
"Exiting aaruf_read_sector_long() = AARUF_ERROR_INCORRECT_DATA_SIZE");
1626 TRACE(
"Allocating memory for bare data");
1627 bare_data = (uint8_t *)malloc(bare_length);
1629 if(bare_data == NULL)
1631 FATAL(
"Could not allocate memory for bare data");
1633 TRACE(
"Exiting aaruf_read_sector_long() = AARUF_ERROR_NOT_ENOUGH_MEMORY");
1637 res =
aaruf_read_sector(context, sector_address, negative, bare_data, &bare_length, sector_status);
1644 TRACE(
"Exiting aaruf_read_sector_long() = %d", res);
1648 memcpy(data, ctx->
sector_id + corrected_sector_address * 4, 4);
1649 memcpy(data + 4, ctx->
sector_ied + corrected_sector_address * 2, 2);
1650 memcpy(data + 6, bare_data, 2048);
1651 memcpy(data + 2054, ctx->
sector_cpr_mai + corrected_sector_address * 6, 6);
1652 memcpy(data + 2060, ctx->
sector_edc + corrected_sector_address * 4, 4);
1668 if(*length < 2052 || data == NULL)
1671 FATAL(
"Buffer too small for sector, required %u bytes", *length);
1673 TRACE(
"Exiting aaruf_read_sector_long() = AARUF_ERROR_BUFFER_TOO_SMALL");
1678 query_status =
aaruf_read_sector(context, sector_address, negative, NULL, &bare_length, sector_status);
1682 TRACE(
"Exiting aaruf_read_sector_long() = %d", query_status);
1683 return query_status;
1686 if(bare_length == 0)
1688 FATAL(
"Invalid bare sector length (0)");
1690 TRACE(
"Exiting aaruf_read_sector_long() = AARUF_ERROR_INCORRECT_DATA_SIZE");
1694 TRACE(
"Allocating memory for bare data");
1695 bare_data = (uint8_t *)malloc(bare_length);
1697 if(bare_data == NULL)
1699 FATAL(
"Could not allocate memory for bare data");
1701 TRACE(
"Exiting aaruf_read_sector_long() = AARUF_ERROR_NOT_ENOUGH_MEMORY");
1705 res =
aaruf_read_sector(context, sector_address, negative, bare_data, &bare_length, sector_status);
1711 TRACE(
"Exiting aaruf_read_sector_long() = %d", res);
1715 memcpy(data, bare_data, 2048);
1716 memcpy(data + 2048, ctx->
sector_edc + corrected_sector_address * 4, 4);
1724 if(*length < 2352 || data == NULL)
1727 FATAL(
"Buffer too small for sector, required %u bytes", *length);
1729 TRACE(
"Exiting aaruf_read_sector_long() = AARUF_ERROR_BUFFER_TOO_SMALL");
1736 return aaruf_read_sector(context, sector_address, negative, data, length, sector_status);
1739 query_status =
aaruf_read_sector(context, sector_address, negative, NULL, &bare_length, sector_status);
1743 TRACE(
"Exiting aaruf_read_sector_long() = %d", query_status);
1744 return query_status;
1747 if(bare_length == 0)
1749 FATAL(
"Invalid bare sector length (0)");
1751 TRACE(
"Exiting aaruf_read_sector_long() = AARUF_ERROR_INCORRECT_DATA_SIZE");
1755 TRACE(
"Allocating memory for bare data");
1756 bare_data = (uint8_t *)malloc(bare_length);
1758 if(bare_data == NULL)
1760 FATAL(
"Could not allocate memory for bare data");
1762 TRACE(
"Exiting aaruf_read_sector_long() = AARUF_ERROR_NOT_ENOUGH_MEMORY");
1766 res =
aaruf_read_sector(context, sector_address, negative, bare_data, &bare_length, sector_status);
1772 TRACE(
"Exiting aaruf_read_sector_long() = %d", res);
1779 if(sector_address >= ctx->
data_tracks[i].
start && sector_address <= ctx->data_tracks[i].end)
1788 FATAL(
"Track not found");
1791 TRACE(
"Exiting aaruf_read_sector_long() = AARUF_ERROR_TRACK_NOT_FOUND");
1799 memcpy(data, bare_data, bare_length);
1800 *length = bare_length;
1804 memcpy(data + 16, bare_data, 2048);
1809 const uint32_t prefix_status = prefix_ddt_entry >> 60;
1810 const uint64_t prefix_index = prefix_ddt_entry & 0x0FFFFFFFFFFFFFFF;
1821 FATAL(
"Sector prefix index %" PRIu64
" outside stored prefix block", prefix_index);
1825 TRACE(
"Exiting aaruf_read_sector_long() = AARUF_ERROR_CANNOT_READ_BLOCK");
1832 memcpy(data, ctx->
sector_prefix + corrected_sector_address * 16, 16);
1850 TRACE(
"Exiting aaruf_read_sector_long() = AARUF_ERROR_REACHED_UNREACHABLE_CODE");
1865 const uint64_t suffix_status = suffix_ddt_entry >> 60;
1866 const uint64_t suffix_index = suffix_ddt_entry & 0x0FFFFFFFFFFFFFFF;
1877 FATAL(
"Sector suffix index %" PRIu64
" outside stored suffix block", suffix_index);
1881 TRACE(
"Exiting aaruf_read_sector_long() = AARUF_ERROR_CANNOT_READ_BLOCK");
1885 memcpy(data + 2064, ctx->
sector_suffix + suffix_index * 288, 288);
1888 memcpy(data + 2064, ctx->
sector_suffix + corrected_sector_address * 288, 288);
1906 TRACE(
"Exiting aaruf_read_sector_long() = AARUF_ERROR_REACHED_UNREACHABLE_CODE");
1920 const uint64_t prefix_status = prefix_ddt_entry >> 60;
1921 const uint64_t prefix_index = prefix_ddt_entry & 0x0FFFFFFFFFFFFFFF;
1932 FATAL(
"Sector prefix index %" PRIu64
" outside stored prefix block", prefix_index);
1936 TRACE(
"Exiting aaruf_read_sector_long() = AARUF_ERROR_CANNOT_READ_BLOCK");
1943 memcpy(data, ctx->
sector_prefix + corrected_sector_address * 16, 16);
1961 TRACE(
"Exiting aaruf_read_sector_long() = AARUF_ERROR_REACHED_UNREACHABLE_CODE");
1975 memcpy(data + 16, ctx->
mode2_subheaders + corrected_sector_address * 8, 8);
1977 const uint64_t suffix_status = suffix_ddt_entry >> 60;
1978 const uint64_t suffix_index = suffix_ddt_entry & 0x0FFFFFFFFFFFFFFF;
1982 memcpy(data + 24, bare_data, 2048);
1988 memcpy(data + 24, bare_data, 2324);
1992 memset(data + 2348, 0, 4);
1998 FATAL(
"Sector suffix index %" PRIu64
" outside stored suffix block", suffix_index);
2002 TRACE(
"Exiting aaruf_read_sector_long() = AARUF_ERROR_CANNOT_READ_BLOCK");
2009 if((data[0x12] & 0x20) || (data[0x16] & 0x20))
2012 memcpy(data + 24, bare_data, 2324);
2013 memcpy(data + 2348, ctx->
sector_suffix + suffix_index * 288, 4);
2018 memcpy(data + 24, bare_data, 2048);
2019 memcpy(data + 2072, ctx->
sector_suffix + suffix_index * 288, 280);
2025 memcpy(data + 16, ctx->
mode2_subheaders + corrected_sector_address * 8, 8);
2029 memcpy(data + 24, bare_data, 2048);
2035 memcpy(data + 24, bare_data, 2324);
2039 memset(data + 2348, 0, 4);
2047 const uint32_t sfx_index =
2049 if((data[0x12] & 0x20) || (data[0x16] & 0x20))
2051 memcpy(data + 24, bare_data, 2324);
2056 memcpy(data + 24, bare_data, 2048);
2063 memcpy(data + 16, ctx->
mode2_subheaders + corrected_sector_address * 8, 8);
2064 memcpy(data + 24, bare_data, bare_length < 2328 ? bare_length : 2328);
2067 memcpy(data + 16, bare_data, bare_length < 2336 ? bare_length : 2336);
2073 FATAL(
"Invalid track type %d", trk.
type);
2076 TRACE(
"Exiting aaruf_read_sector_long() = AARUF_ERROR_INVALID_TRACK_FORMAT");
2089 return aaruf_read_sector(context, sector_address, negative, data, length, sector_status);
2108 TRACE(
"Exiting aaruf_read_sector_long() = AARUF_ERROR_INCORRECT_MEDIA_TYPE");
2114 if(*length < tag_length + bare_length || data == NULL)
2116 *length = tag_length + bare_length;
2117 FATAL(
"Buffer too small for sector, required %u bytes", *length);
2119 TRACE(
"Exiting aaruf_read_sector_long() = AARUF_ERROR_BUFFER_TOO_SMALL");
2123 TRACE(
"Allocating memory for bare data of size %u bytes", bare_length);
2124 bare_data = malloc(bare_length);
2126 if(bare_data == NULL)
2128 FATAL(
"Could not allocate memory for bare data");
2130 TRACE(
"Exiting aaruf_read_sector_long() = AARUF_ERROR_NOT_ENOUGH_MEMORY");
2134 res =
aaruf_read_sector(context, sector_address, negative, bare_data, &bare_length, sector_status);
2140 TRACE(
"Exiting aaruf_read_sector_long() = %d", res);
2144 if(bare_length != 512)
2146 FATAL(
"Bare data length is %u, expected 512", bare_length);
2149 TRACE(
"Exiting aaruf_read_sector_long() = AARUF_ERROR_INCORRECT_DATA_SIZE");
2153 memcpy(data + bare_length, ctx->
sector_subchannel + corrected_sector_address * tag_length,
2155 memcpy(data, bare_data, bare_length);
2156 *length = tag_length + bare_length;
2160 TRACE(
"Exiting aaruf_read_sector_long() = AARUF_STATUS_OK");
2165 TRACE(
"Exiting aaruf_read_sector_long() = AARUF_ERROR_INCORRECT_MEDIA_TYPE");
2171 TRACE(
"Exiting aaruf_read_sector_long() = AARUF_ERROR_INCORRECT_MEDIA_TYPE");
2296 const bool negative, uint8_t *
buffer, uint32_t *length,
2299 const uint32_t initial_length = length == NULL ? 0U : *length;
2301 TRACE(
"Entering aaruf_read_sector_tag(%p, %" PRIu64
", %d, %p, %u, %d)", context, sector_address, negative,
buffer,
2302 initial_length, tag);
2308 FATAL(
"Invalid context");
2310 TRACE(
"Exiting aaruf_read_sector_tag() = AARUF_ERROR_NOT_AARUFORMAT");
2318 FATAL(
"Invalid length pointer");
2320 TRACE(
"Exiting aaruf_read_sector_tag() = AARUF_ERROR_INCORRECT_DATA_SIZE");
2327 FATAL(
"Invalid context");
2329 TRACE(
"Exiting aaruf_read_sector_tag() = AARUF_ERROR_NOT_AARUFORMAT");
2336 TRACE(
"Exiting aaruf_read_sector_tag() = AARUF_ERROR_USER_DATA_NOT_PRESENT (flux-only image)");
2342 FATAL(
"Sector address out of bounds");
2344 TRACE(
"Exiting aaruf_read_sector_tag() = AARUF_ERROR_SECTOR_OUT_OF_BOUNDS");
2350 FATAL(
"Sector address out of bounds");
2352 TRACE(
"Exiting aaruf_read_sector_tag() = AARUF_ERROR_SECTOR_OUT_OF_BOUNDS");
2356 uint64_t corrected_sector_address = sector_address;
2369 FATAL(
"Invalid media type for tag");
2370 TRACE(
"Exiting aaruf_read_sector_tag() = AARUF_ERROR_INCORRECT_MEDIA_TYPE");
2374 if(*length != 1 ||
buffer == NULL)
2377 FATAL(
"Incorrect tag size");
2378 TRACE(
"Exiting aaruf_read_sector_tag() = AARUF_ERROR_INCORRECT_DATA_SIZE");
2383 if(sector_address >= ctx->
track_entries[i].
start && sector_address <= ctx->track_entries[i].end)
2386 TRACE(
"Exiting aaruf_read_sector_tag() = AARUF_STATUS_OK");
2390 FATAL(
"Track not found");
2395 FATAL(
"Invalid media type for tag");
2396 TRACE(
"Exiting aaruf_read_sector_tag() = AARUF_ERROR_INCORRECT_MEDIA_TYPE");
2400 if(*length != 12 ||
buffer == NULL)
2403 FATAL(
"Incorrect tag size");
2404 TRACE(
"Exiting aaruf_read_sector_tag() = AARUF_ERROR_INCORRECT_DATA_SIZE");
2409 if(sector_address >= ctx->
track_entries[i].
start && sector_address <= ctx->track_entries[i].end)
2412 TRACE(
"Exiting aaruf_read_sector_tag() = AARUF_STATUS_OK");
2416 FATAL(
"Track not found");
2421 FATAL(
"Invalid media type for tag");
2422 TRACE(
"Exiting aaruf_read_sector_tag() = AARUF_ERROR_INCORRECT_MEDIA_TYPE");
2426 if(*length != 96 ||
buffer == NULL)
2429 FATAL(
"Incorrect tag size");
2430 TRACE(
"Exiting aaruf_read_sector_tag() = AARUF_ERROR_INCORRECT_DATA_SIZE");
2436 FATAL(
"Sector tag not found");
2437 TRACE(
"Exiting aaruf_read_sector_tag() = AARUF_ERROR_SECTOR_TAG_NOT_PRESENT");
2442 TRACE(
"Exiting aaruf_read_sector_tag() = AARUF_STATUS_OK");
2447 FATAL(
"Invalid media type for tag");
2448 TRACE(
"Exiting aaruf_read_sector_tag() = AARUF_ERROR_INCORRECT_MEDIA_TYPE");
2452 if(*length != 1 ||
buffer == NULL)
2455 FATAL(
"Incorrect tag size");
2456 TRACE(
"Exiting aaruf_read_sector_tag() = AARUF_ERROR_INCORRECT_DATA_SIZE");
2462 FATAL(
"Sector tag not found");
2463 TRACE(
"Exiting aaruf_read_sector_tag() = AARUF_ERROR_SECTOR_TAG_NOT_PRESENT");
2468 TRACE(
"Exiting aaruf_read_sector_tag() = AARUF_STATUS_OK");
2473 FATAL(
"Invalid media type for tag");
2474 TRACE(
"Exiting aaruf_read_sector_tag() = AARUF_ERROR_INCORRECT_MEDIA_TYPE");
2478 if(*length != 1 ||
buffer == NULL)
2481 FATAL(
"Incorrect tag size");
2482 TRACE(
"Exiting aaruf_read_sector_tag() = AARUF_ERROR_INCORRECT_DATA_SIZE");
2488 FATAL(
"Sector tag not found");
2489 TRACE(
"Exiting aaruf_read_sector_tag() = AARUF_ERROR_SECTOR_TAG_NOT_PRESENT");
2494 TRACE(
"Exiting aaruf_read_sector_tag() = AARUF_STATUS_OK");
2499 FATAL(
"Invalid media type for tag");
2500 TRACE(
"Exiting aaruf_read_sector_tag() = AARUF_ERROR_INCORRECT_MEDIA_TYPE");
2504 if(*length != 3 ||
buffer == NULL)
2507 FATAL(
"Incorrect tag size");
2508 TRACE(
"Exiting aaruf_read_sector_tag() = AARUF_ERROR_INCORRECT_DATA_SIZE");
2514 FATAL(
"Sector tag not found");
2515 TRACE(
"Exiting aaruf_read_sector_tag() = AARUF_ERROR_SECTOR_TAG_NOT_PRESENT");
2520 TRACE(
"Exiting aaruf_read_sector_tag() = AARUF_STATUS_OK");
2525 FATAL(
"Invalid media type for tag");
2526 TRACE(
"Exiting aaruf_read_sector_tag() = AARUF_ERROR_INCORRECT_MEDIA_TYPE");
2530 if(*length != 2 ||
buffer == NULL)
2533 FATAL(
"Incorrect tag size");
2534 TRACE(
"Exiting aaruf_read_sector_tag() = AARUF_ERROR_INCORRECT_DATA_SIZE");
2540 FATAL(
"Sector tag not found");
2541 TRACE(
"Exiting aaruf_read_sector_tag() = AARUF_ERROR_SECTOR_TAG_NOT_PRESENT");
2546 TRACE(
"Exiting aaruf_read_sector_tag() = AARUF_STATUS_OK");
2551 FATAL(
"Invalid media type for tag");
2552 TRACE(
"Exiting aaruf_read_sector_tag() = AARUF_ERROR_INCORRECT_MEDIA_TYPE");
2556 if(*length != 4 ||
buffer == NULL)
2559 FATAL(
"Incorrect tag size");
2560 TRACE(
"Exiting aaruf_read_sector_tag() = AARUF_ERROR_INCORRECT_DATA_SIZE");
2566 FATAL(
"Sector tag not found");
2567 TRACE(
"Exiting aaruf_read_sector_tag() = AARUF_ERROR_SECTOR_TAG_NOT_PRESENT");
2572 TRACE(
"Exiting aaruf_read_sector_tag() = AARUF_STATUS_OK");
2577 FATAL(
"Invalid media type for tag");
2578 TRACE(
"Exiting aaruf_read_sector_tag() = AARUF_ERROR_INCORRECT_MEDIA_TYPE");
2582 if(*length != 5 ||
buffer == NULL)
2585 FATAL(
"Incorrect tag size");
2586 TRACE(
"Exiting aaruf_read_sector_tag() = AARUF_ERROR_INCORRECT_DATA_SIZE");
2592 FATAL(
"Sector tag not found");
2593 TRACE(
"Exiting aaruf_read_sector_tag() = AARUF_ERROR_SECTOR_TAG_NOT_PRESENT");
2598 TRACE(
"Exiting aaruf_read_sector_tag() = AARUF_STATUS_OK");
2603 FATAL(
"Invalid media type for tag");
2604 TRACE(
"Exiting aaruf_read_sector_tag() = AARUF_ERROR_INCORRECT_MEDIA_TYPE");
2608 if(*length != 12 ||
buffer == NULL)
2611 FATAL(
"Incorrect tag size");
2612 TRACE(
"Exiting aaruf_read_sector_tag() = AARUF_ERROR_INCORRECT_DATA_SIZE");
2618 FATAL(
"Sector tag not found");
2619 TRACE(
"Exiting aaruf_read_sector_tag() = AARUF_ERROR_SECTOR_TAG_NOT_PRESENT");
2624 TRACE(
"Exiting aaruf_read_sector_tag() = AARUF_STATUS_OK");
2629 FATAL(
"Invalid media type for tag");
2630 TRACE(
"Exiting aaruf_read_sector_tag() = AARUF_ERROR_INCORRECT_MEDIA_TYPE");
2634 if(*length != 20 ||
buffer == NULL)
2637 FATAL(
"Incorrect tag size");
2638 TRACE(
"Exiting aaruf_read_sector_tag() = AARUF_ERROR_INCORRECT_DATA_SIZE");
2644 FATAL(
"Sector tag not found");
2645 TRACE(
"Exiting aaruf_read_sector_tag() = AARUF_ERROR_SECTOR_TAG_NOT_PRESENT");
2650 TRACE(
"Exiting aaruf_read_sector_tag() = AARUF_STATUS_OK");
2655 FATAL(
"Invalid media type for tag");
2656 TRACE(
"Exiting aaruf_read_sector_tag() = AARUF_ERROR_INCORRECT_MEDIA_TYPE");
2660 if(*length != 24 ||
buffer == NULL)
2663 FATAL(
"Incorrect tag size");
2664 TRACE(
"Exiting aaruf_read_sector_tag() = AARUF_ERROR_INCORRECT_DATA_SIZE");
2670 FATAL(
"Sector tag not found");
2671 TRACE(
"Exiting aaruf_read_sector_tag() = AARUF_ERROR_SECTOR_TAG_NOT_PRESENT");
2676 TRACE(
"Exiting aaruf_read_sector_tag() = AARUF_STATUS_OK");
2679 TRACE(
"Do not know how to read sector tag %d", tag);
#define CD_DFIX_MASK
Mask for extracting positional index (lower 24 bits) in Compact Disc suffix/prefix deduplicated block...
#define LZMA_PROPERTIES_LENGTH
Size in bytes of the fixed LZMA properties header (lc/lp/pb + dictionary size).
#define AARU_MAGIC
Magic identifier for AaruFormat container (ASCII "AARUFRMT").
#define CD_XFIX_MASK
Mask for extracting correction / fix flags in Compact Disc suffix/prefix DDT entries.
int32_t aaruf_lzma_decode_buffer(uint8_t *dst_buffer, size_t *dst_size, const uint8_t *src_buffer, size_t *src_size, const uint8_t *props, size_t props_size)
Decodes an LZMA-compressed buffer.
int32_t aaruf_read_sector(void *context, uint64_t sector_address, bool negative, uint8_t *data, uint32_t *length, uint8_t *sector_status)
Reads a sector from the AaruFormat image.
int32_t aaruf_read_media_tag(void *context, uint8_t *data, int32_t tag, uint32_t *length)
Reads a media tag from the AaruFormat image.
void aaruf_ecc_cd_reconstruct_prefix(uint8_t *sector, uint8_t type, int64_t lba)
Reconstructs the prefix (sync, address, mode) of a CD sector.
void aaruf_ecc_cd_reconstruct(void *context, uint8_t *sector, uint8_t type)
Reconstructs the EDC and ECC fields of a CD sector.
size_t aaruf_zstd_decode_buffer(uint8_t *dst_buffer, size_t dst_size, const uint8_t *src_buffer, size_t src_size)
Decodes a Zstandard-compressed buffer.
int32_t aaruf_read_track_sector(void *context, uint8_t *data, uint64_t sector_address, uint32_t *length, uint8_t track, uint8_t *sector_status)
Reads a sector from a specific track in the AaruFormat image.
int32_t aaruf_read_sector_tag(const void *context, uint64_t sector_address, bool negative, uint8_t *buffer, uint32_t *length, int32_t tag)
Reads a specific sector tag from the AaruFormat image.
int32_t aaruf_read_sector_long(void *context, uint64_t sector_address, bool negative, uint8_t *data, uint32_t *length, uint8_t *sector_status)
Reads a complete sector with all metadata from the AaruFormat image.
size_t aaruf_flac_decode_redbook_buffer(uint8_t *dst_buffer, size_t dst_size, const uint8_t *src_buffer, size_t src_size)
Decodes a FLAC-compressed Red Book audio buffer.
@ DataBlock
Block containing data.
@ SectorStatusDumped
Sector(s) successfully dumped without error.
@ SectorStatusNotDumped
Sector(s) not yet acquired during image dumping.
@ SectorStatusGenerable
Content can be generated using a known algorithm.
@ SectorStatusUnencrypted
Content originally encrypted but stored decrypted in image.
@ SectorStatusMode2Form2NoCrc
Suffix matches MODE 2 Form 2 but CRC empty/missing.
@ SectorStatusMode1Correct
Valid MODE 1 data with regenerable suffix/prefix.
@ SectorStatusMode2Form2Ok
Suffix matches MODE 2 Form 2 with valid CRC.
@ SectorStatusErrored
Error during dumping; data may be incomplete or corrupt.
@ SectorStatusMode2Form1Ok
Suffix verified/regenerable for MODE 2 Form 1.
@ Correct
Sector(s) contain valid MODE 1 data with regenerable suffix/prefix.
@ Mode2Form2Ok
Sector suffix valid for MODE 2 Form 2 with correct CRC.
@ Mode2Form1Ok
Sector suffix valid for MODE 2 Form 1; regenerable.
@ NotDumped
Sector(s) have not yet been dumped.
@ Mode2Form2NoCrc
Sector suffix valid for MODE 2 Form 2 but CRC absent/empty.
@ OpticalDisc
Purely optical discs.
@ BlockMedia
Media that is physically block-based or abstracted like that.
@ kTrackTypeCdMode2Form2
Compact Disc Mode 2 Form 2 data track.
@ kTrackTypeData
Generic data track (not further specified).
@ kTrackTypeCdMode2Form1
Compact Disc Mode 2 Form 1 data track.
@ kTrackTypeAudio
Audio track.
@ kTrackTypeCdMode2Formless
Compact Disc Mode 2 (formless) data track.
@ kTrackTypeCdMode1
Compact Disc Mode 1 data track.
@ kCompressionLzma
LZMA compression.
@ kCompressionNone
Not compressed.
@ kCompressionZstd
Zstandard compression.
@ kCompressionFlac
FLAC compression.
int32_t ec_recover_data_block(aaruformat_context *ctx, uint64_t block_offset, uint64_t offset, uint8_t *data, uint32_t *length, uint8_t sector_status)
Attempt to recover a data block that failed decompression or CRC verification.
#define AARUF_STATUS_OK
Sector present and read without uncorrectable errors.
#define AARUF_ERROR_INCORRECT_MEDIA_TYPE
Operation incompatible with image media type.
#define AARUF_ERROR_USER_DATA_NOT_PRESENT
Image has no user-data DDT (e.g. flux-only image); sector data is unavailable.
#define AARUF_ERROR_TRACK_NOT_FOUND
Referenced track number not present.
#define AARUF_ERROR_CANNOT_READ_HEADER
Failed to read container header.
#define AARUF_ERROR_NOT_ENOUGH_MEMORY
Memory allocation failure (critical).
#define AARUF_ERROR_SECTOR_OUT_OF_BOUNDS
Requested logical sector outside media bounds.
#define AARUF_ERROR_INVALID_TRACK_FORMAT
Track metadata internally inconsistent or malformed.
#define AARUF_ERROR_CANNOT_READ_BLOCK
Generic block read failure (seek/read error).
#define AARUF_ERROR_INCORRECT_DATA_SIZE
Data size does not match expected size.
#define AARUF_ERROR_SECTOR_TAG_NOT_PRESENT
Requested sector tag (e.g. subchannel/prefix) not stored.
#define AARUF_STATUS_SECTOR_NOT_DUMPED
Sector not captured (gap / missing / intentionally skipped).
#define AARUF_ERROR_NOT_AARUFORMAT
Input file/stream failed magic or structural validation.
#define AARUF_ERROR_CANNOT_DECOMPRESS_BLOCK
Decompression routine failed or size mismatch.
#define AARUF_ERROR_INVALID_TAG
Invalid or unsupported media or sector tag format.
#define AARUF_ERROR_MEDIA_TAG_NOT_PRESENT
Requested media tag absent.
#define AARUF_ERROR_BUFFER_TOO_SMALL
Caller-supplied buffer insufficient for data.
#define AARUF_ERROR_REACHED_UNREACHABLE_CODE
Internal logic assertion hit unexpected path.
int32_t decode_ddt_entry_v1(aaruformat_context *ctx, uint64_t sector_address, uint64_t *offset, uint64_t *block_offset, uint8_t *sector_status)
Decodes a DDT v1 entry for a given sector address.
static int aaruf_fseek(FILE *stream, aaru_off_t offset, int origin)
int32_t decode_ddt_entry_v2(aaruformat_context *ctx, 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.
void ngc_lfg_get_bytes(struct ngc_lfg_ctx *ctx, uint8_t *out, size_t count)
Generate count bytes of junk data into out.
void ngc_lfg_set_seed(struct ngc_lfg_ctx *ctx, const uint32_t seed[17])
Initialize the LFG from a 17-word big-endian seed.
#define NGC_LFG_SEED_SIZE
Number of uint32 words needed to seed the LFG.
void add_to_cache_uint64(struct CacheHeader *cache, uint64_t key, void *value, size_t size)
Adds a value to the cache with a uint64_t key, evicting LRU entries if over budget.
void * find_in_cache_uint64(struct CacheHeader *cache, uint64_t key)
Finds a value in the cache by uint64_t key.
void ngcw_junk_lazy_init(aaruformat_context *ctx)
Lazy initialization: load junk map from media tags.
int ngcw_regenerate_junk_sector(const NgcwJunkEntry *entries, uint32_t entry_count, uint64_t disc_offset, uint8_t *output, uint32_t length)
Regenerate a junk sector from the junk map.
void ps3_lazy_init(aaruformat_context *ctx)
Lazy-initialize PS3 encryption state from context media tags.
void ps3_encrypt_sector(const uint8_t disc_key[16], uint64_t sector_num, uint8_t *data, uint32_t length)
Encrypt a sector using PS3 disc encryption (AES-128-CBC).
bool ps3_is_sector_encrypted(const Ps3PlaintextRegion *plaintext_regions, uint32_t region_count, uint64_t sector_address)
Check whether a sector is encrypted (i.e., not in any plaintext region).
static void wii_reconstruct_group_junk(aaruformat_context *ctx, uint64_t phys_group, uint8_t *group_cache)
Reconstruct junk in a Wii group's user data area before re-encryption.
uint32_t MediaType
Media type identifier (see MediaType enum; 0=Unknown).
uint8_t MetadataMediaType
Media type for sidecar generation (internal archival use).
uint32_t SectorSize
Size of each logical sector in bytes (512, 2048, 2352, 4096, etc.).
uint64_t Sectors
Total count of addressable logical sectors/blocks.
In-memory junk map entry.
uint64_t length
Length of junk region in bytes.
uint64_t offset
Disc byte offset where junk starts.
A plaintext (unencrypted) region on a PS3 disc.
Single optical disc track descriptor (sequence, type, LBAs, session, ISRC, flags).
uint8_t flags
Control / attribute bitfield (see file documentation for suggested bit mapping).
uint8_t sequence
Track number (1..99 typical for CD audio/data).
int64_t start
Inclusive starting LBA of the track.
uint8_t type
Track type (value from TrackType).
uint8_t isrc[13]
ISRC raw 13-byte code (no null terminator). All zeros if not present.
A Wii partition region entry (in-memory representation).
uint32_t start_sector
First physical sector of partition.
A Wii U partition region entry (in-memory representation).
Master context representing an open or in‑creation Aaru image.
uint8_t * ps3_disc_key
Cached disc key (16 bytes), NULL if not loaded.
bool wiiu_building_crypto_block
True while gathering sectors for re-encryption (suppresses recursion).
DdtHeader2 user_data_ddt_header
Active user data DDT v2 header (primary table meta).
void * wiiu_partition_regions
Parsed WiiuPartitionRegion array, NULL if not loaded.
size_t sector_suffix_length
Length of sector_suffix.
uint8_t * sector_cpr_mai
DVD sector CPR_MAI (6 bytes) if present.
uint32_t ps3_plaintext_region_count
Number of plaintext regions.
uint8_t * sector_prefix_corrected
Corrected variant (post error correction) if stored.
uint32_t wiiu_partition_region_count
Number of partition regions.
TrackEntry * data_tracks
Filtered list of data tracks (subset of trackEntries).
uint8_t * wiiu_encrypted_block_cache
Cached re-encrypted 0x8000-byte physical sector.
bool ec_recovery_in_progress
Recursion guard for recovery (prevents infinite loops).
void * ngcw_junk_entries
Parsed NgcwJunkEntry array, NULL if not loaded.
struct CacheHeader block_header_cache
LRU/Cache header for block headers.
uint8_t * sector_ied
DVD sector IED (2 bytes) if present.
uint8_t * sector_prefix
Raw per-sector prefix (e.g., sync+header) uncorrected.
uint64_t wii_cached_physical_group
Physical group number of cached block.
uint64_t * sector_suffix_ddt2
CD sector suffix DDT V2.
uint8_t * sector_edc
DVD or Blu-ray sector EDC (4 bytes) if present (see DvdSectorEdc / BdSectorEdc data types).
CdEccContext * ecc_cd_context
CD ECC/EDC helper tables (allocated on demand).
struct CacheHeader block_cache
LRU/Cache header for block payloads.
bool ps3_encryption_initialized
Whether lazy init has occurred.
uint64_t wiiu_cached_physical_sector
Physical sector number of cached block.
uint32_t * sector_suffix_ddt
Legacy CD sector suffix DDT.
uint8_t * sector_suffix
Raw per-sector suffix (EDC/ECC) uncorrected.
AaruHeaderV2 header
Parsed container header (v2).
int ddt_version
DDT version in use (1=legacy, 2=v2 hierarchical).
uint64_t magic
File magic (AARU_MAGIC) post-open.
uint64_t * sector_prefix_ddt2
CD sector prefix DDT V2.
bool wii_building_crypto_block
True while gathering sectors for re-encryption (suppresses recursion).
size_t sector_prefix_length
Length of sector_prefix.
mediaTagEntry * mediaTags
Hash table of extra media tags (uthash root).
uint32_t ngcw_junk_entry_count
Number of junk entries.
uint32_t wii_partition_region_count
Number of partition regions.
bool wiiu_encryption_initialized
Whether lazy init has occurred.
uint8_t * sector_decrypted_title_key
DVD decrypted title key (5 bytes) if present.
bool wii_encryption_initialized
Whether lazy init has occurred.
uint8_t * sector_subchannel
Raw 96-byte subchannel (if captured).
void * wii_partition_regions
Parsed WiiPartitionRegion array, NULL if not loaded.
FILE * imageStream
Underlying FILE* stream (binary mode).
bool no_user_data_ddt
True if image intentionally has no user-data DDT (e.g. flux-only image). When set,...
uint8_t * mode2_subheaders
MODE2 Form1/Form2 8-byte subheaders (concatenated).
ImageInfo image_info
Exposed high-level image info summary.
bool wii_cache_valid
Whether the encrypted group cache is valid.
uint8_t * sector_id
DVD sector ID (4 bytes) if present.
void * ps3_plaintext_regions
Parsed Ps3PlaintextRegion array (max 32), NULL if not loaded.
uint32_t * sector_prefix_ddt
Legacy CD sector prefix DDT (deprecated by *2).
bool wiiu_cache_valid
Whether the encrypted block cache is valid.
TrackEntry * track_entries
Full track list (tracksHeader.entries elements).
uint8_t number_of_data_tracks
Count of tracks considered "data" (sequence 1..99 heuristics).
uint8_t * sector_suffix_corrected
Corrected suffix if stored separately.
uint8_t * wii_encrypted_group_cache
Cached re-encrypted 0x8000-byte group.
bool ngcw_junk_initialized
Whether junk map has been loaded.
bool ec_recovery_available
True if ECMB loaded and recovery is possible.
TracksHeader tracks_header
Tracks header (optical) if present.
Hash table entry for an arbitrary media tag (e.g., proprietary drive/medium descriptor).
uint8_t * data
Tag data blob (opaque to library core); length bytes long.
uint32_t length
Length in bytes of data.
LFG context holding the 521-word circular buffer and byte position.
const uint8_t * wii_get_sector_key(const WiiPartitionRegion *regions, uint32_t region_count, uint64_t logical_sector)
Get the encryption key for a given logical sector (2048-byte).
void wii_encrypt_group(const uint8_t key[16], const uint8_t *hash_block, const uint8_t *data_in, uint8_t *out)
Encrypt a Wii group (0x8000 bytes) from separate hash_block + data.
void wii_lazy_init(aaruformat_context *ctx)
Lazy initialization: load partition key map from media tags.
#define WII_GROUP_SIZE
Wii physical group size (32 KiB).
#define WII_SECTOR_SIZE
Logical sector size in bytes.
#define WII_GROUP_DATA_SIZE
User data size within a group (31 KiB).
#define WII_GROUP_HASH_SIZE
Hash block size within a group (1 KiB).
#define WII_LOGICAL_PER_GROUP
Number of 2048-byte logical sectors per group.
void wiiu_encrypt_physical_sector(const uint8_t key[16], uint8_t *data, uint32_t length)
Encrypt a full 0x8000-byte physical sector in-place.
void wiiu_lazy_init(aaruformat_context *ctx)
Lazy initialization: load disc key and partition key map from media tags.
const uint8_t * wiiu_get_sector_key(const WiiuPartitionRegion *regions, uint32_t region_count, uint64_t logical_sector)
Get the encryption key for a given logical sector (2048-byte).
#define WIIU_CRYPTO_SECTOR_SIZE
Wii U physical sector size (32 KiB).
#define WIIU_LOGICAL_PER_PHYSICAL
Number of 2048-byte logical sectors per physical sector.