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");
401 FATAL(
"Sector address out of bounds");
403 TRACE(
"Exiting aaruf_read_sector() = AARUF_ERROR_SECTOR_OUT_OF_BOUNDS");
409 FATAL(
"Sector address out of bounds");
411 TRACE(
"Exiting aaruf_read_sector() = AARUF_ERROR_SECTOR_OUT_OF_BOUNDS");
419 FATAL(
"Negative sector addresses not supported in this image");
423 error_no =
decode_ddt_entry_v1(ctx, sector_address, &offset, &block_offset, sector_status);
426 error_no =
decode_ddt_entry_v2(ctx, sector_address, negative, &offset, &block_offset, sector_status);
430 FATAL(
"Error %d decoding DDT entry", error_no);
432 TRACE(
"Exiting aaruf_read_sector() = %d", error_no);
441 TRACE(
"Exiting aaruf_read_sector() = AARUF_STATUS_SECTOR_NOT_DUMPED");
458 TRACE(
"Exiting aaruf_read_sector() = AARUF_ERROR_BUFFER_TOO_SMALL (generable, NULL data)");
467 disc_offset, data, *length) == 0)
472 TRACE(
"Exiting aaruf_read_sector() = AARUF_STATUS_OK (GOD generable)");
503 uint64_t logical = first_logical + s;
505 if(logical == sector_address)
511 uint32_t s_len = *length;
512 uint8_t s_status = 0;
539 TRACE(
"Exiting aaruf_read_sector() = AARUF_STATUS_OK (WOD generable re-encrypted)");
545 memset(data, 0, *length);
547 TRACE(
"Exiting aaruf_read_sector() = AARUF_STATUS_OK (generable not in map)");
554 memset(data, 0, *length);
556 TRACE(
"Exiting aaruf_read_sector() = AARUF_STATUS_OK (no junk map)");
562 TRACE(
"Checking if block header is cached");
566 if(block_header == NULL)
568 TRACE(
"Allocating memory for block header");
570 if(block_header == NULL)
572 FATAL(
"Not enough memory for block header");
574 TRACE(
"Exiting aaruf_read_sector() = AARUF_ERROR_NOT_ENOUGH_MEMORY");
578 TRACE(
"Reading block header");
581 FATAL(
"Could not seek to block header");
584 TRACE(
"Exiting aaruf_read_sector() = AARUF_ERROR_CANNOT_READ_HEADER");
592 FATAL(
"Error reading block header");
595 TRACE(
"Exiting aaruf_read_sector() = AARUF_ERROR_CANNOT_READ_HEADER");
599 TRACE(
"Adding block header to cache");
604 FATAL(
"Could not seek past cached block header");
606 TRACE(
"Exiting aaruf_read_sector() = AARUF_ERROR_CANNOT_READ_HEADER");
615 TRACE(
"Block header at offset %" PRIu64
" appears corrupt (id=0x%08X sectorSize=%u)",
617 goto ec_try_recovery;
620 if(data == NULL || *length < block_header->sectorSize)
622 TRACE(
"Buffer too small for sector, required %u bytes", block_header->
sectorSize);
625 TRACE(
"Exiting aaruf_read_sector() = AARUF_ERROR_BUFFER_TOO_SMALL");
630 TRACE(
"Checking if block is cached");
635 TRACE(
"Getting data from cache");
688 uint64_t logical = first_logical + s;
690 if(logical == sector_address)
697 uint32_t s_len = *length;
698 uint8_t s_status = 0;
756 uint64_t logical = first_logical + s;
758 if(logical == sector_address)
764 uint32_t s_len = *length;
765 uint8_t s_status = 0;
794 TRACE(
"Exiting aaruf_read_sector() = AARUF_STATUS_OK");
802 TRACE(
"Allocating memory for block");
803 block = (uint8_t *)malloc(block_header->
length);
806 FATAL(
"Not enough memory for block");
808 TRACE(
"Exiting aaruf_read_sector() = AARUF_ERROR_NOT_ENOUGH_MEMORY");
812 TRACE(
"Reading block into memory");
815 if(read_bytes != block_header->
length)
817 FATAL(
"Could not read block");
820 TRACE(
"Exiting aaruf_read_sector() = AARUF_ERROR_CANNOT_READ_BLOCK");
828 FATAL(
"Invalid LZMA block lengths (cmpLength=%u, length=%u)", block_header->
cmpLength,
831 TRACE(
"Exiting aaruf_read_sector() = AARUF_ERROR_CANNOT_DECOMPRESS_BLOCK");
832 goto ec_try_recovery;
836 TRACE(
"Allocating memory for compressed data of size %zu bytes", lzma_size);
837 cmp_data = malloc(lzma_size);
841 FATAL(
"Cannot allocate memory for block...");
843 TRACE(
"Exiting aaruf_read_sector() = AARUF_ERROR_NOT_ENOUGH_MEMORY");
847 TRACE(
"Allocating memory for block of size %zu bytes", block_header->
length);
848 block = malloc(block_header->
length);
851 FATAL(
"Cannot allocate memory for block...");
854 TRACE(
"Exiting aaruf_read_sector() = AARUF_ERROR_NOT_ENOUGH_MEMORY");
862 FATAL(
"Could not read LZMA properties...");
866 TRACE(
"Exiting aaruf_read_sector() = AARUF_ERROR_CANNOT_DECOMPRESS_BLOCK");
867 goto ec_try_recovery;
870 read_bytes = fread(cmp_data, 1, lzma_size, ctx->
imageStream);
871 if(read_bytes != lzma_size)
873 FATAL(
"Could not read compressed block...");
877 TRACE(
"Exiting aaruf_read_sector() = AARUF_ERROR_CANNOT_DECOMPRESS_BLOCK");
878 goto ec_try_recovery;
881 TRACE(
"Decompressing block of size %zu bytes", block_header->
length);
882 read_bytes = block_header->
length;
888 FATAL(
"Got error %d from LZMA...", error_no);
892 TRACE(
"Exiting aaruf_read_sector() = AARUF_ERROR_CANNOT_DECOMPRESS_BLOCK");
893 goto ec_try_recovery;
896 if(read_bytes != block_header->
length)
898 FATAL(
"Error decompressing block, should be {0} bytes but got {1} bytes...");
902 TRACE(
"Exiting aaruf_read_sector() = AARUF_ERROR_CANNOT_DECOMPRESS_BLOCK");
903 goto ec_try_recovery;
912 FATAL(
"Invalid zstd block lengths (cmpLength=%u, length=%u)", block_header->
cmpLength,
914 TRACE(
"Exiting aaruf_read_sector() = AARUF_ERROR_CANNOT_DECOMPRESS_BLOCK");
915 goto ec_try_recovery;
918 TRACE(
"Allocating memory for block of size %zu bytes", block_header->
length);
919 block = (uint8_t *)malloc(block_header->
length);
922 FATAL(
"Not enough memory for block");
923 TRACE(
"Exiting aaruf_read_sector() = AARUF_ERROR_NOT_ENOUGH_MEMORY");
927 TRACE(
"Allocating memory for compressed data of size %zu bytes", block_header->
cmpLength);
928 cmp_data = malloc(block_header->
cmpLength);
931 FATAL(
"Not enough memory for compressed data");
933 TRACE(
"Exiting aaruf_read_sector() = AARUF_ERROR_NOT_ENOUGH_MEMORY");
940 if(read_bytes != block_header->
cmpLength)
942 FATAL(
"Could not read compressed block");
945 TRACE(
"Exiting aaruf_read_sector() = AARUF_ERROR_CANNOT_DECOMPRESS_BLOCK");
946 goto ec_try_recovery;
950 if(read_bytes != block_header->
length)
952 FATAL(
"Error decompressing zstd block, expected %u bytes got %zu", block_header->
length, read_bytes);
955 TRACE(
"Exiting aaruf_read_sector() = AARUF_ERROR_CANNOT_DECOMPRESS_BLOCK");
956 goto ec_try_recovery;
963 TRACE(
"Allocating memory for compressed data of size %zu bytes", block_header->
cmpLength);
964 cmp_data = malloc(block_header->
cmpLength);
968 FATAL(
"Cannot allocate memory for block...");
970 TRACE(
"Exiting aaruf_read_sector() = AARUF_ERROR_NOT_ENOUGH_MEMORY");
974 TRACE(
"Allocating memory for block of size %zu bytes", block_header->
length);
975 block = malloc(block_header->
length);
978 FATAL(
"Cannot allocate memory for block...");
981 TRACE(
"Exiting aaruf_read_sector() = AARUF_ERROR_NOT_ENOUGH_MEMORY");
985 TRACE(
"Reading compressed data into memory");
987 if(read_bytes != block_header->
cmpLength)
989 FATAL(
"Could not read compressed block...");
993 TRACE(
"Exiting aaruf_read_sector() = AARUF_ERROR_CANNOT_DECOMPRESS_BLOCK");
994 goto ec_try_recovery;
997 TRACE(
"Decompressing block of size %zu bytes", block_header->
length);
1001 if(read_bytes != block_header->
length)
1003 FATAL(
"Error decompressing block, should be {0} bytes but got {1} bytes...");
1007 TRACE(
"Exiting aaruf_read_sector() = AARUF_ERROR_CANNOT_DECOMPRESS_BLOCK");
1008 goto ec_try_recovery;
1016 TRACE(
"Exiting aaruf_read_sector() = AARUF_ERROR_UNSUPPORTED_COMPRESSION");
1017 goto ec_try_recovery;
1021 TRACE(
"Adding block to cache");
1060 if(part_key != NULL)
1074 uint64_t logical = first_logical + s;
1076 if(logical == sector_address)
1083 uint32_t s_len = *length;
1084 uint8_t s_status = 0;
1128 if(part_key != NULL)
1141 uint64_t logical = first_logical + s;
1143 if(logical == sector_address)
1149 uint32_t s_len = *length;
1150 uint8_t s_status = 0;
1178 TRACE(
"Exiting aaruf_read_sector() = AARUF_STATUS_OK");
1188 TRACE(
"Attempting erasure coding recovery for block at offset %" PRIu64, block_offset);
1192 TRACE(
"Erasure coding recovery succeeded");
1195 TRACE(
"Erasure coding recovery failed: %d", rc);
1198 TRACE(
"Exiting aaruf_read_sector() = AARUF_ERROR_CANNOT_DECOMPRESS_BLOCK");
1275 uint32_t *length,
const uint8_t track, uint8_t *sector_status)
1277 const uint32_t initial_length = length == NULL ? 0U : *length;
1279 TRACE(
"Entering aaruf_read_track_sector(%p, %p, %" PRIu64
", %u, %d)", context, data, sector_address,
1280 initial_length, track);
1284 FATAL(
"Invalid context");
1286 TRACE(
"Exiting aaruf_read_track_sector() = AARUF_ERROR_NOT_AARUFORMAT");
1294 FATAL(
"Invalid length pointer");
1296 TRACE(
"Exiting aaruf_read_track_sector() = AARUF_ERROR_INCORRECT_DATA_SIZE");
1303 FATAL(
"Invalid context");
1305 TRACE(
"Exiting aaruf_read_track_sector() = AARUF_ERROR_NOT_AARUFORMAT");
1313 TRACE(
"Exiting aaruf_read_track_sector() = AARUF_ERROR_INCORRECT_MEDIA_TYPE");
1322 TRACE(
"Track %d not found", track);
1323 TRACE(
"Exiting aaruf_read_track_sector() = AARUF_ERROR_TRACK_NOT_FOUND");
1431 uint8_t *data, uint32_t *length, uint8_t *sector_status)
1433 const uint32_t initial_length = length == NULL ? 0U : *length;
1435 TRACE(
"Entering aaruf_read_sector_long(%p, %" PRIu64
", %d, %p, %u)", context, sector_address, data,
1439 uint32_t bare_length = 0;
1440 uint32_t tag_length = 0;
1441 uint8_t *bare_data = NULL;
1443 int32_t query_status;
1446 bool trk_found =
false;
1450 FATAL(
"Invalid context");
1452 TRACE(
"Exiting aaruf_read_sector_long() = AARUF_ERROR_NOT_AARUFORMAT");
1460 FATAL(
"Invalid length pointer");
1462 TRACE(
"Exiting aaruf_read_sector_long() = AARUF_ERROR_INCORRECT_DATA_SIZE");
1469 FATAL(
"Invalid context");
1471 TRACE(
"Exiting aaruf_read_sector_long() = AARUF_ERROR_NOT_AARUFORMAT");
1477 FATAL(
"Sector address out of bounds");
1479 TRACE(
"Exiting aaruf_read_sector_long() = AARUF_ERROR_SECTOR_OUT_OF_BOUNDS");
1485 FATAL(
"Sector address out of bounds");
1487 TRACE(
"Exiting aaruf_read_sector_long() = AARUF_ERROR_SECTOR_OUT_OF_BOUNDS");
1491 uint64_t corrected_sector_address = sector_address;
1513 return aaruf_read_sector(context, sector_address, negative, data, length, sector_status);
1515 if(*length < 2064 || data == NULL)
1518 FATAL(
"Buffer too small for sector, required %u bytes", *length);
1520 TRACE(
"Exiting aaruf_read_sector_long() = AARUF_ERROR_BUFFER_TOO_SMALL");
1525 query_status =
aaruf_read_sector(context, sector_address, negative, NULL, &bare_length, sector_status);
1529 TRACE(
"Exiting aaruf_read_sector_long() = %d", query_status);
1530 return query_status;
1533 if(bare_length == 0)
1535 FATAL(
"Invalid bare sector length (0)");
1537 TRACE(
"Exiting aaruf_read_sector_long() = AARUF_ERROR_INCORRECT_DATA_SIZE");
1541 TRACE(
"Allocating memory for bare data");
1542 bare_data = (uint8_t *)malloc(bare_length);
1544 if(bare_data == NULL)
1546 FATAL(
"Could not allocate memory for bare data");
1548 TRACE(
"Exiting aaruf_read_sector_long() = AARUF_ERROR_NOT_ENOUGH_MEMORY");
1552 res =
aaruf_read_sector(context, sector_address, negative, bare_data, &bare_length, sector_status);
1559 TRACE(
"Exiting aaruf_read_sector_long() = %d", res);
1563 memcpy(data, ctx->
sector_id + corrected_sector_address * 4, 4);
1564 memcpy(data + 4, ctx->
sector_ied + corrected_sector_address * 2, 2);
1565 memcpy(data + 6, ctx->
sector_cpr_mai + corrected_sector_address * 6, 6);
1566 memcpy(data + 12, bare_data, 2048);
1567 memcpy(data + 2060, ctx->
sector_edc + corrected_sector_address * 4, 4);
1579 return aaruf_read_sector(context, sector_address, negative, data, length, sector_status);
1581 if(*length < 2064 || data == NULL)
1584 FATAL(
"Buffer too small for sector, required %u bytes", *length);
1586 TRACE(
"Exiting aaruf_read_sector_long() = AARUF_ERROR_BUFFER_TOO_SMALL");
1591 query_status =
aaruf_read_sector(context, sector_address, negative, NULL, &bare_length, sector_status);
1595 TRACE(
"Exiting aaruf_read_sector_long() = %d", query_status);
1596 return query_status;
1599 if(bare_length == 0)
1601 FATAL(
"Invalid bare sector length (0)");
1603 TRACE(
"Exiting aaruf_read_sector_long() = AARUF_ERROR_INCORRECT_DATA_SIZE");
1607 TRACE(
"Allocating memory for bare data");
1608 bare_data = (uint8_t *)malloc(bare_length);
1610 if(bare_data == NULL)
1612 FATAL(
"Could not allocate memory for bare data");
1614 TRACE(
"Exiting aaruf_read_sector_long() = AARUF_ERROR_NOT_ENOUGH_MEMORY");
1618 res =
aaruf_read_sector(context, sector_address, negative, bare_data, &bare_length, sector_status);
1625 TRACE(
"Exiting aaruf_read_sector_long() = %d", res);
1629 memcpy(data, ctx->
sector_id + corrected_sector_address * 4, 4);
1630 memcpy(data + 4, ctx->
sector_ied + corrected_sector_address * 2, 2);
1631 memcpy(data + 6, bare_data, 2048);
1632 memcpy(data + 2054, ctx->
sector_cpr_mai + corrected_sector_address * 6, 6);
1633 memcpy(data + 2060, ctx->
sector_edc + corrected_sector_address * 4, 4);
1649 if(*length < 2052 || data == NULL)
1652 FATAL(
"Buffer too small for sector, required %u bytes", *length);
1654 TRACE(
"Exiting aaruf_read_sector_long() = AARUF_ERROR_BUFFER_TOO_SMALL");
1659 query_status =
aaruf_read_sector(context, sector_address, negative, NULL, &bare_length, sector_status);
1663 TRACE(
"Exiting aaruf_read_sector_long() = %d", query_status);
1664 return query_status;
1667 if(bare_length == 0)
1669 FATAL(
"Invalid bare sector length (0)");
1671 TRACE(
"Exiting aaruf_read_sector_long() = AARUF_ERROR_INCORRECT_DATA_SIZE");
1675 TRACE(
"Allocating memory for bare data");
1676 bare_data = (uint8_t *)malloc(bare_length);
1678 if(bare_data == NULL)
1680 FATAL(
"Could not allocate memory for bare data");
1682 TRACE(
"Exiting aaruf_read_sector_long() = AARUF_ERROR_NOT_ENOUGH_MEMORY");
1686 res =
aaruf_read_sector(context, sector_address, negative, bare_data, &bare_length, sector_status);
1692 TRACE(
"Exiting aaruf_read_sector_long() = %d", res);
1696 memcpy(data, bare_data, 2048);
1697 memcpy(data + 2048, ctx->
sector_edc + corrected_sector_address * 4, 4);
1705 if(*length < 2352 || data == NULL)
1708 FATAL(
"Buffer too small for sector, required %u bytes", *length);
1710 TRACE(
"Exiting aaruf_read_sector_long() = AARUF_ERROR_BUFFER_TOO_SMALL");
1717 return aaruf_read_sector(context, sector_address, negative, data, length, sector_status);
1720 query_status =
aaruf_read_sector(context, sector_address, negative, NULL, &bare_length, sector_status);
1724 TRACE(
"Exiting aaruf_read_sector_long() = %d", query_status);
1725 return query_status;
1728 if(bare_length == 0)
1730 FATAL(
"Invalid bare sector length (0)");
1732 TRACE(
"Exiting aaruf_read_sector_long() = AARUF_ERROR_INCORRECT_DATA_SIZE");
1736 TRACE(
"Allocating memory for bare data");
1737 bare_data = (uint8_t *)malloc(bare_length);
1739 if(bare_data == NULL)
1741 FATAL(
"Could not allocate memory for bare data");
1743 TRACE(
"Exiting aaruf_read_sector_long() = AARUF_ERROR_NOT_ENOUGH_MEMORY");
1747 res =
aaruf_read_sector(context, sector_address, negative, bare_data, &bare_length, sector_status);
1753 TRACE(
"Exiting aaruf_read_sector_long() = %d", res);
1760 if(sector_address >= ctx->
data_tracks[i].
start && sector_address <= ctx->data_tracks[i].end)
1769 FATAL(
"Track not found");
1772 TRACE(
"Exiting aaruf_read_sector_long() = AARUF_ERROR_TRACK_NOT_FOUND");
1780 memcpy(data, bare_data, bare_length);
1781 *length = bare_length;
1785 memcpy(data + 16, bare_data, 2048);
1790 const uint32_t prefix_status = prefix_ddt_entry >> 60;
1791 const uint64_t prefix_index = prefix_ddt_entry & 0x0FFFFFFFFFFFFFFF;
1804 memcpy(data, ctx->
sector_prefix + corrected_sector_address * 16, 16);
1822 TRACE(
"Exiting aaruf_read_sector_long() = AARUF_ERROR_REACHED_UNREACHABLE_CODE");
1837 const uint64_t suffix_status = suffix_ddt_entry >> 60;
1838 const uint64_t suffix_index = suffix_ddt_entry & 0x0FFFFFFFFFFFFFFF;
1848 memcpy(data + 2064, ctx->
sector_suffix + suffix_index * 288, 288);
1851 memcpy(data + 2064, ctx->
sector_suffix + corrected_sector_address * 288, 288);
1869 TRACE(
"Exiting aaruf_read_sector_long() = AARUF_ERROR_REACHED_UNREACHABLE_CODE");
1883 const uint64_t prefix_status = prefix_ddt_entry >> 60;
1884 const uint64_t prefix_index = prefix_ddt_entry & 0x0FFFFFFFFFFFFFFF;
1897 memcpy(data, ctx->
sector_prefix + corrected_sector_address * 16, 16);
1915 TRACE(
"Exiting aaruf_read_sector_long() = AARUF_ERROR_REACHED_UNREACHABLE_CODE");
1929 memcpy(data + 16, ctx->
mode2_subheaders + corrected_sector_address * 8, 8);
1931 const uint64_t suffix_status = suffix_ddt_entry >> 60;
1932 const uint64_t suffix_index = suffix_ddt_entry & 0x0FFFFFFFFFFFFFFF;
1936 memcpy(data + 24, bare_data, 2048);
1942 memcpy(data + 24, bare_data, 2324);
1946 memset(data + 2348, 0, 4);
1954 if((data[0x12] & 0x20) || (data[0x16] & 0x20))
1957 memcpy(data + 24, bare_data, 2324);
1958 memcpy(data + 2348, ctx->
sector_suffix + suffix_index * 288, 4);
1963 memcpy(data + 24, bare_data, 2048);
1964 memcpy(data + 2072, ctx->
sector_suffix + suffix_index * 288, 280);
1970 memcpy(data + 16, ctx->
mode2_subheaders + corrected_sector_address * 8, 8);
1974 memcpy(data + 24, bare_data, 2048);
1980 memcpy(data + 24, bare_data, 2324);
1984 memset(data + 2348, 0, 4);
1992 const uint32_t sfx_index =
1994 if((data[0x12] & 0x20) || (data[0x16] & 0x20))
1996 memcpy(data + 24, bare_data, 2324);
2001 memcpy(data + 24, bare_data, 2048);
2008 memcpy(data + 16, ctx->
mode2_subheaders + corrected_sector_address * 8, 8);
2009 memcpy(data + 24, bare_data, 2328);
2012 memcpy(data + 16, bare_data, 2336);
2018 FATAL(
"Invalid track type %d", trk.
type);
2021 TRACE(
"Exiting aaruf_read_sector_long() = AARUF_ERROR_INVALID_TRACK_FORMAT");
2034 return aaruf_read_sector(context, sector_address, negative, data, length, sector_status);
2053 TRACE(
"Exiting aaruf_read_sector_long() = AARUF_ERROR_INCORRECT_MEDIA_TYPE");
2059 if(*length < tag_length + bare_length || data == NULL)
2061 *length = tag_length + bare_length;
2062 FATAL(
"Buffer too small for sector, required %u bytes", *length);
2064 TRACE(
"Exiting aaruf_read_sector_long() = AARUF_ERROR_BUFFER_TOO_SMALL");
2068 TRACE(
"Allocating memory for bare data of size %u bytes", bare_length);
2069 bare_data = malloc(bare_length);
2071 if(bare_data == NULL)
2073 FATAL(
"Could not allocate memory for bare data");
2075 TRACE(
"Exiting aaruf_read_sector_long() = AARUF_ERROR_NOT_ENOUGH_MEMORY");
2079 res =
aaruf_read_sector(context, sector_address, negative, bare_data, &bare_length, sector_status);
2085 TRACE(
"Exiting aaruf_read_sector_long() = %d", res);
2089 if(bare_length != 512)
2091 FATAL(
"Bare data length is %u, expected 512", bare_length);
2094 TRACE(
"Exiting aaruf_read_sector_long() = AARUF_ERROR_INCORRECT_DATA_SIZE");
2098 memcpy(data + bare_length, ctx->
sector_subchannel + corrected_sector_address * tag_length,
2100 memcpy(data, bare_data, bare_length);
2101 *length = tag_length + bare_length;
2105 TRACE(
"Exiting aaruf_read_sector_long() = AARUF_STATUS_OK");
2110 TRACE(
"Exiting aaruf_read_sector_long() = AARUF_ERROR_INCORRECT_MEDIA_TYPE");
2116 TRACE(
"Exiting aaruf_read_sector_long() = AARUF_ERROR_INCORRECT_MEDIA_TYPE");
2241 const bool negative, uint8_t *
buffer, uint32_t *length,
2244 const uint32_t initial_length = length == NULL ? 0U : *length;
2246 TRACE(
"Entering aaruf_read_sector_tag(%p, %" PRIu64
", %d, %p, %u, %d)", context, sector_address, negative,
buffer,
2247 initial_length, tag);
2253 FATAL(
"Invalid context");
2255 TRACE(
"Exiting aaruf_read_sector_tag() = AARUF_ERROR_NOT_AARUFORMAT");
2263 FATAL(
"Invalid length pointer");
2265 TRACE(
"Exiting aaruf_read_sector_tag() = AARUF_ERROR_INCORRECT_DATA_SIZE");
2272 FATAL(
"Invalid context");
2274 TRACE(
"Exiting aaruf_read_sector_tag() = AARUF_ERROR_NOT_AARUFORMAT");
2280 FATAL(
"Sector address out of bounds");
2282 TRACE(
"Exiting aaruf_read_sector_tag() = AARUF_ERROR_SECTOR_OUT_OF_BOUNDS");
2288 FATAL(
"Sector address out of bounds");
2290 TRACE(
"Exiting aaruf_read_sector_tag() = AARUF_ERROR_SECTOR_OUT_OF_BOUNDS");
2294 uint64_t corrected_sector_address = sector_address;
2307 FATAL(
"Invalid media type for tag");
2308 TRACE(
"Exiting aaruf_read_sector_tag() = AARUF_ERROR_INCORRECT_MEDIA_TYPE");
2312 if(*length != 1 ||
buffer == NULL)
2315 FATAL(
"Incorrect tag size");
2316 TRACE(
"Exiting aaruf_read_sector_tag() = AARUF_ERROR_INCORRECT_DATA_SIZE");
2321 if(sector_address >= ctx->
track_entries[i].
start && sector_address <= ctx->track_entries[i].end)
2324 TRACE(
"Exiting aaruf_read_sector_tag() = AARUF_STATUS_OK");
2328 FATAL(
"Track not found");
2333 FATAL(
"Invalid media type for tag");
2334 TRACE(
"Exiting aaruf_read_sector_tag() = AARUF_ERROR_INCORRECT_MEDIA_TYPE");
2338 if(*length != 12 ||
buffer == NULL)
2341 FATAL(
"Incorrect tag size");
2342 TRACE(
"Exiting aaruf_read_sector_tag() = AARUF_ERROR_INCORRECT_DATA_SIZE");
2347 if(sector_address >= ctx->
track_entries[i].
start && sector_address <= ctx->track_entries[i].end)
2350 TRACE(
"Exiting aaruf_read_sector_tag() = AARUF_STATUS_OK");
2354 FATAL(
"Track not found");
2359 FATAL(
"Invalid media type for tag");
2360 TRACE(
"Exiting aaruf_read_sector_tag() = AARUF_ERROR_INCORRECT_MEDIA_TYPE");
2364 if(*length != 96 ||
buffer == NULL)
2367 FATAL(
"Incorrect tag size");
2368 TRACE(
"Exiting aaruf_read_sector_tag() = AARUF_ERROR_INCORRECT_DATA_SIZE");
2374 FATAL(
"Sector tag not found");
2375 TRACE(
"Exiting aaruf_read_sector_tag() = AARUF_ERROR_SECTOR_TAG_NOT_PRESENT");
2380 TRACE(
"Exiting aaruf_read_sector_tag() = AARUF_STATUS_OK");
2385 FATAL(
"Invalid media type for tag");
2386 TRACE(
"Exiting aaruf_read_sector_tag() = AARUF_ERROR_INCORRECT_MEDIA_TYPE");
2390 if(*length != 1 ||
buffer == NULL)
2393 FATAL(
"Incorrect tag size");
2394 TRACE(
"Exiting aaruf_read_sector_tag() = AARUF_ERROR_INCORRECT_DATA_SIZE");
2400 FATAL(
"Sector tag not found");
2401 TRACE(
"Exiting aaruf_read_sector_tag() = AARUF_ERROR_SECTOR_TAG_NOT_PRESENT");
2406 TRACE(
"Exiting aaruf_read_sector_tag() = AARUF_STATUS_OK");
2411 FATAL(
"Invalid media type for tag");
2412 TRACE(
"Exiting aaruf_read_sector_tag() = AARUF_ERROR_INCORRECT_MEDIA_TYPE");
2416 if(*length != 1 ||
buffer == NULL)
2419 FATAL(
"Incorrect tag size");
2420 TRACE(
"Exiting aaruf_read_sector_tag() = AARUF_ERROR_INCORRECT_DATA_SIZE");
2426 FATAL(
"Sector tag not found");
2427 TRACE(
"Exiting aaruf_read_sector_tag() = AARUF_ERROR_SECTOR_TAG_NOT_PRESENT");
2432 TRACE(
"Exiting aaruf_read_sector_tag() = AARUF_STATUS_OK");
2437 FATAL(
"Invalid media type for tag");
2438 TRACE(
"Exiting aaruf_read_sector_tag() = AARUF_ERROR_INCORRECT_MEDIA_TYPE");
2442 if(*length != 3 ||
buffer == NULL)
2445 FATAL(
"Incorrect tag size");
2446 TRACE(
"Exiting aaruf_read_sector_tag() = AARUF_ERROR_INCORRECT_DATA_SIZE");
2452 FATAL(
"Sector tag not found");
2453 TRACE(
"Exiting aaruf_read_sector_tag() = AARUF_ERROR_SECTOR_TAG_NOT_PRESENT");
2458 TRACE(
"Exiting aaruf_read_sector_tag() = AARUF_STATUS_OK");
2463 FATAL(
"Invalid media type for tag");
2464 TRACE(
"Exiting aaruf_read_sector_tag() = AARUF_ERROR_INCORRECT_MEDIA_TYPE");
2468 if(*length != 2 ||
buffer == NULL)
2471 FATAL(
"Incorrect tag size");
2472 TRACE(
"Exiting aaruf_read_sector_tag() = AARUF_ERROR_INCORRECT_DATA_SIZE");
2478 FATAL(
"Sector tag not found");
2479 TRACE(
"Exiting aaruf_read_sector_tag() = AARUF_ERROR_SECTOR_TAG_NOT_PRESENT");
2484 TRACE(
"Exiting aaruf_read_sector_tag() = AARUF_STATUS_OK");
2489 FATAL(
"Invalid media type for tag");
2490 TRACE(
"Exiting aaruf_read_sector_tag() = AARUF_ERROR_INCORRECT_MEDIA_TYPE");
2494 if(*length != 4 ||
buffer == NULL)
2497 FATAL(
"Incorrect tag size");
2498 TRACE(
"Exiting aaruf_read_sector_tag() = AARUF_ERROR_INCORRECT_DATA_SIZE");
2504 FATAL(
"Sector tag not found");
2505 TRACE(
"Exiting aaruf_read_sector_tag() = AARUF_ERROR_SECTOR_TAG_NOT_PRESENT");
2510 TRACE(
"Exiting aaruf_read_sector_tag() = AARUF_STATUS_OK");
2515 FATAL(
"Invalid media type for tag");
2516 TRACE(
"Exiting aaruf_read_sector_tag() = AARUF_ERROR_INCORRECT_MEDIA_TYPE");
2520 if(*length != 5 ||
buffer == NULL)
2523 FATAL(
"Incorrect tag size");
2524 TRACE(
"Exiting aaruf_read_sector_tag() = AARUF_ERROR_INCORRECT_DATA_SIZE");
2530 FATAL(
"Sector tag not found");
2531 TRACE(
"Exiting aaruf_read_sector_tag() = AARUF_ERROR_SECTOR_TAG_NOT_PRESENT");
2536 TRACE(
"Exiting aaruf_read_sector_tag() = AARUF_STATUS_OK");
2541 FATAL(
"Invalid media type for tag");
2542 TRACE(
"Exiting aaruf_read_sector_tag() = AARUF_ERROR_INCORRECT_MEDIA_TYPE");
2546 if(*length != 12 ||
buffer == NULL)
2549 FATAL(
"Incorrect tag size");
2550 TRACE(
"Exiting aaruf_read_sector_tag() = AARUF_ERROR_INCORRECT_DATA_SIZE");
2556 FATAL(
"Sector tag not found");
2557 TRACE(
"Exiting aaruf_read_sector_tag() = AARUF_ERROR_SECTOR_TAG_NOT_PRESENT");
2562 TRACE(
"Exiting aaruf_read_sector_tag() = AARUF_STATUS_OK");
2567 FATAL(
"Invalid media type for tag");
2568 TRACE(
"Exiting aaruf_read_sector_tag() = AARUF_ERROR_INCORRECT_MEDIA_TYPE");
2572 if(*length != 20 ||
buffer == NULL)
2575 FATAL(
"Incorrect tag size");
2576 TRACE(
"Exiting aaruf_read_sector_tag() = AARUF_ERROR_INCORRECT_DATA_SIZE");
2582 FATAL(
"Sector tag not found");
2583 TRACE(
"Exiting aaruf_read_sector_tag() = AARUF_ERROR_SECTOR_TAG_NOT_PRESENT");
2588 TRACE(
"Exiting aaruf_read_sector_tag() = AARUF_STATUS_OK");
2593 FATAL(
"Invalid media type for tag");
2594 TRACE(
"Exiting aaruf_read_sector_tag() = AARUF_ERROR_INCORRECT_MEDIA_TYPE");
2598 if(*length != 24 ||
buffer == NULL)
2601 FATAL(
"Incorrect tag size");
2602 TRACE(
"Exiting aaruf_read_sector_tag() = AARUF_ERROR_INCORRECT_DATA_SIZE");
2608 FATAL(
"Sector tag not found");
2609 TRACE(
"Exiting aaruf_read_sector_tag() = AARUF_ERROR_SECTOR_TAG_NOT_PRESENT");
2614 TRACE(
"Exiting aaruf_read_sector_tag() = AARUF_STATUS_OK");
2617 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.
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.
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.
@ 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_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)
Adds a value to the cache with a uint64_t key, evicting LRU if full.
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.
int32_t aaruf_read_sector(void *context, const 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_sector_long(void *context, const 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.
int32_t aaruf_read_track_sector(void *context, uint8_t *data, const uint64_t sector_address, uint32_t *length, const uint8_t track, uint8_t *sector_status)
Reads a sector from a specific track in the AaruFormat image.
int32_t aaruf_read_media_tag(void *context, uint8_t *data, const int32_t tag, uint32_t *length)
Reads a media tag from the AaruFormat image.
int32_t aaruf_read_sector_tag(const void *context, const uint64_t sector_address, const bool negative, uint8_t *buffer, uint32_t *length, const int32_t tag)
Reads a specific sector tag from the AaruFormat image.
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). 0 may indicate placeholder/non-standard.
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.
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 sector EDC (4 bytes) if present.
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).
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).
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.