Core/DiscIO: Extract disc and partition constants to DiscUtils.h.

This commit is contained in:
Admiral H. Curtiss 2021-09-19 22:00:13 +02:00
parent 31ca114721
commit ad410009bb
No known key found for this signature in database
GPG Key ID: F051B4C4044F33FB
6 changed files with 74 additions and 54 deletions

View File

@ -471,10 +471,7 @@ u64 DirectoryBlobReader::GetDataSize() const
void DirectoryBlobReader::SetNonpartitionDiscHeader(const std::vector<u8>& partition_header, void DirectoryBlobReader::SetNonpartitionDiscHeader(const std::vector<u8>& partition_header,
const std::string& game_partition_root) const std::string& game_partition_root)
{ {
constexpr u64 NONPARTITION_DISCHEADER_ADDRESS = 0; m_disc_header_nonpartition.resize(WII_NONPARTITION_DISCHEADER_SIZE);
constexpr u64 NONPARTITION_DISCHEADER_SIZE = 0x100;
m_disc_header_nonpartition.resize(NONPARTITION_DISCHEADER_SIZE);
const size_t header_bin_bytes_read = const size_t header_bin_bytes_read =
ReadFileToVector(game_partition_root + "disc/header.bin", &m_disc_header_nonpartition); ReadFileToVector(game_partition_root + "disc/header.bin", &m_disc_header_nonpartition);
@ -492,7 +489,7 @@ void DirectoryBlobReader::SetNonpartitionDiscHeader(const std::vector<u8>& parti
m_encrypted = std::all_of(m_disc_header_nonpartition.data() + 0x60, m_encrypted = std::all_of(m_disc_header_nonpartition.data() + 0x60,
m_disc_header_nonpartition.data() + 0x64, [](u8 x) { return x == 0; }); m_disc_header_nonpartition.data() + 0x64, [](u8 x) { return x == 0; });
m_nonpartition_contents.Add(NONPARTITION_DISCHEADER_ADDRESS, m_disc_header_nonpartition); m_nonpartition_contents.Add(WII_NONPARTITION_DISCHEADER_ADDRESS, m_disc_header_nonpartition);
} }
void DirectoryBlobReader::SetWiiRegionData(const std::string& game_partition_root) void DirectoryBlobReader::SetWiiRegionData(const std::string& game_partition_root)
@ -508,8 +505,6 @@ void DirectoryBlobReader::SetWiiRegionData(const std::string& game_partition_roo
else if (bytes_read < 0x20) else if (bytes_read < 0x20)
ERROR_LOG_FMT(DISCIO, "Couldn't read age ratings from {}", region_bin_path); ERROR_LOG_FMT(DISCIO, "Couldn't read age ratings from {}", region_bin_path);
constexpr u64 WII_REGION_DATA_ADDRESS = 0x4E000;
[[maybe_unused]] constexpr u64 WII_REGION_DATA_SIZE = 0x20;
m_nonpartition_contents.Add(WII_REGION_DATA_ADDRESS, m_wii_region_data); m_nonpartition_contents.Add(WII_REGION_DATA_ADDRESS, m_wii_region_data);
} }
@ -584,16 +579,14 @@ void DirectoryBlobReader::SetPartitions(std::vector<PartitionWithType>&& partiti
void DirectoryBlobReader::SetPartitionHeader(DirectoryBlobPartition* partition, void DirectoryBlobReader::SetPartitionHeader(DirectoryBlobPartition* partition,
u64 partition_address) u64 partition_address)
{ {
constexpr u32 TICKET_OFFSET = 0x0;
constexpr u32 TICKET_SIZE = 0x2a4;
constexpr u32 TMD_OFFSET = 0x2c0; constexpr u32 TMD_OFFSET = 0x2c0;
constexpr u32 H3_OFFSET = 0x4000; constexpr u32 H3_OFFSET = 0x4000;
constexpr u32 H3_SIZE = 0x18000;
const std::string& partition_root = partition->GetRootDirectory(); const std::string& partition_root = partition->GetRootDirectory();
const u64 ticket_size = m_nonpartition_contents.CheckSizeAndAdd( const u64 ticket_size = m_nonpartition_contents.CheckSizeAndAdd(
partition_address + TICKET_OFFSET, TICKET_SIZE, partition_root + "ticket.bin"); partition_address + WII_PARTITION_TICKET_ADDRESS, WII_PARTITION_TICKET_SIZE,
partition_root + "ticket.bin");
const u64 tmd_size = m_nonpartition_contents.CheckSizeAndAdd( const u64 tmd_size = m_nonpartition_contents.CheckSizeAndAdd(
partition_address + TMD_OFFSET, IOS::ES::MAX_TMD_SIZE, partition_root + "tmd.bin"); partition_address + TMD_OFFSET, IOS::ES::MAX_TMD_SIZE, partition_root + "tmd.bin");
@ -603,7 +596,7 @@ void DirectoryBlobReader::SetPartitionHeader(DirectoryBlobPartition* partition,
const u64 cert_size = m_nonpartition_contents.CheckSizeAndAdd( const u64 cert_size = m_nonpartition_contents.CheckSizeAndAdd(
partition_address + cert_offset, max_cert_size, partition_root + "cert.bin"); partition_address + cert_offset, max_cert_size, partition_root + "cert.bin");
m_nonpartition_contents.CheckSizeAndAdd(partition_address + H3_OFFSET, H3_SIZE, m_nonpartition_contents.CheckSizeAndAdd(partition_address + H3_OFFSET, WII_PARTITION_H3_SIZE,
partition_root + "h3.bin"); partition_root + "h3.bin");
constexpr u32 PARTITION_HEADER_SIZE = 0x1c; constexpr u32 PARTITION_HEADER_SIZE = 0x1c;
@ -618,10 +611,10 @@ void DirectoryBlobReader::SetPartitionHeader(DirectoryBlobPartition* partition,
Write32(PARTITION_DATA_OFFSET >> 2, 0x14, &partition_header); Write32(PARTITION_DATA_OFFSET >> 2, 0x14, &partition_header);
Write32(static_cast<u32>(data_size >> 2), 0x18, &partition_header); Write32(static_cast<u32>(data_size >> 2), 0x18, &partition_header);
m_nonpartition_contents.Add(partition_address + TICKET_SIZE, partition_header); m_nonpartition_contents.Add(partition_address + WII_PARTITION_TICKET_SIZE, partition_header);
std::vector<u8> ticket_buffer(ticket_size); std::vector<u8> ticket_buffer(ticket_size);
m_nonpartition_contents.Read(partition_address + TICKET_OFFSET, ticket_size, m_nonpartition_contents.Read(partition_address + WII_PARTITION_TICKET_ADDRESS, ticket_size,
ticket_buffer.data()); ticket_buffer.data());
IOS::ES::TicketReader ticket(std::move(ticket_buffer)); IOS::ES::TicketReader ticket(std::move(ticket_buffer));
if (ticket.IsValid()) if (ticket.IsValid())
@ -639,9 +632,6 @@ DirectoryBlobPartition::DirectoryBlobPartition(const std::string& root_directory
void DirectoryBlobPartition::SetDiscHeaderAndDiscType(std::optional<bool> is_wii) void DirectoryBlobPartition::SetDiscHeaderAndDiscType(std::optional<bool> is_wii)
{ {
constexpr u64 DISCHEADER_ADDRESS = 0;
constexpr u64 DISCHEADER_SIZE = 0x440;
m_disc_header.resize(DISCHEADER_SIZE); m_disc_header.resize(DISCHEADER_SIZE);
const std::string boot_bin_path = m_root_directory + "sys/boot.bin"; const std::string boot_bin_path = m_root_directory + "sys/boot.bin";
if (ReadFileToVector(boot_bin_path, &m_disc_header) < 0x20) if (ReadFileToVector(boot_bin_path, &m_disc_header) < 0x20)
@ -666,8 +656,6 @@ void DirectoryBlobPartition::SetDiscHeaderAndDiscType(std::optional<bool> is_wii
void DirectoryBlobPartition::SetBI2() void DirectoryBlobPartition::SetBI2()
{ {
constexpr u64 BI2_ADDRESS = 0x440;
constexpr u64 BI2_SIZE = 0x2000;
m_bi2.resize(BI2_SIZE); m_bi2.resize(BI2_SIZE);
if (!m_is_wii) if (!m_is_wii)
@ -709,8 +697,6 @@ u64 DirectoryBlobPartition::SetApploader()
Write32(static_cast<u32>(-1), 0x10, &m_apploader); Write32(static_cast<u32>(-1), 0x10, &m_apploader);
} }
constexpr u64 APPLOADER_ADDRESS = 0x2440;
m_contents.Add(APPLOADER_ADDRESS, m_apploader); m_contents.Add(APPLOADER_ADDRESS, m_apploader);
// Return DOL address, 32 byte aligned (plus 32 byte padding) // Return DOL address, 32 byte aligned (plus 32 byte padding)

View File

@ -137,7 +137,8 @@ bool ExportWiiUnencryptedHeader(const Volume& volume, const std::string& export_
if (volume.GetVolumeType() != Platform::WiiDisc) if (volume.GetVolumeType() != Platform::WiiDisc)
return false; return false;
return ExportData(volume, PARTITION_NONE, 0, 0x100, export_filename); return ExportData(volume, PARTITION_NONE, WII_NONPARTITION_DISCHEADER_ADDRESS,
WII_NONPARTITION_DISCHEADER_SIZE, export_filename);
} }
bool ExportWiiRegionData(const Volume& volume, const std::string& export_filename) bool ExportWiiRegionData(const Volume& volume, const std::string& export_filename)
@ -145,7 +146,8 @@ bool ExportWiiRegionData(const Volume& volume, const std::string& export_filenam
if (volume.GetVolumeType() != Platform::WiiDisc) if (volume.GetVolumeType() != Platform::WiiDisc)
return false; return false;
return ExportData(volume, PARTITION_NONE, 0x4E000, 0x20, export_filename); return ExportData(volume, PARTITION_NONE, WII_REGION_DATA_ADDRESS, WII_REGION_DATA_SIZE,
export_filename);
} }
bool ExportTicket(const Volume& volume, const Partition& partition, bool ExportTicket(const Volume& volume, const Partition& partition,
@ -154,7 +156,8 @@ bool ExportTicket(const Volume& volume, const Partition& partition,
if (volume.GetVolumeType() != Platform::WiiDisc) if (volume.GetVolumeType() != Platform::WiiDisc)
return false; return false;
return ExportData(volume, PARTITION_NONE, partition.offset, 0x2a4, export_filename); return ExportData(volume, PARTITION_NONE, partition.offset + WII_PARTITION_TICKET_ADDRESS,
WII_PARTITION_TICKET_SIZE, export_filename);
} }
bool ExportTMD(const Volume& volume, const Partition& partition, const std::string& export_filename) bool ExportTMD(const Volume& volume, const Partition& partition, const std::string& export_filename)
@ -162,9 +165,10 @@ bool ExportTMD(const Volume& volume, const Partition& partition, const std::stri
if (volume.GetVolumeType() != Platform::WiiDisc) if (volume.GetVolumeType() != Platform::WiiDisc)
return false; return false;
const std::optional<u32> size = volume.ReadSwapped<u32>(partition.offset + 0x2a4, PARTITION_NONE); const std::optional<u32> size =
const std::optional<u64> offset = volume.ReadSwapped<u32>(partition.offset + WII_PARTITION_TMD_SIZE_ADDRESS, PARTITION_NONE);
volume.ReadSwappedAndShifted(partition.offset + 0x2a8, PARTITION_NONE); const std::optional<u64> offset = volume.ReadSwappedAndShifted(
partition.offset + WII_PARTITION_TMD_OFFSET_ADDRESS, PARTITION_NONE);
if (!size || !offset) if (!size || !offset)
return false; return false;
@ -177,9 +181,10 @@ bool ExportCertificateChain(const Volume& volume, const Partition& partition,
if (volume.GetVolumeType() != Platform::WiiDisc) if (volume.GetVolumeType() != Platform::WiiDisc)
return false; return false;
const std::optional<u32> size = volume.ReadSwapped<u32>(partition.offset + 0x2ac, PARTITION_NONE); const std::optional<u32> size = volume.ReadSwapped<u32>(
const std::optional<u64> offset = partition.offset + WII_PARTITION_CERT_CHAIN_SIZE_ADDRESS, PARTITION_NONE);
volume.ReadSwappedAndShifted(partition.offset + 0x2b0, PARTITION_NONE); const std::optional<u64> offset = volume.ReadSwappedAndShifted(
partition.offset + WII_PARTITION_CERT_CHAIN_OFFSET_ADDRESS, PARTITION_NONE);
if (!size || !offset) if (!size || !offset)
return false; return false;
@ -192,12 +197,13 @@ bool ExportH3Hashes(const Volume& volume, const Partition& partition,
if (volume.GetVolumeType() != Platform::WiiDisc) if (volume.GetVolumeType() != Platform::WiiDisc)
return false; return false;
const std::optional<u64> offset = const std::optional<u64> offset = volume.ReadSwappedAndShifted(
volume.ReadSwappedAndShifted(partition.offset + 0x2b4, PARTITION_NONE); partition.offset + WII_PARTITION_H3_OFFSET_ADDRESS, PARTITION_NONE);
if (!offset) if (!offset)
return false; return false;
return ExportData(volume, PARTITION_NONE, partition.offset + *offset, 0x18000, export_filename); return ExportData(volume, PARTITION_NONE, partition.offset + *offset, WII_PARTITION_H3_SIZE,
export_filename);
} }
bool ExportHeader(const Volume& volume, const Partition& partition, bool ExportHeader(const Volume& volume, const Partition& partition,
@ -206,7 +212,7 @@ bool ExportHeader(const Volume& volume, const Partition& partition,
if (!IsDisc(volume.GetVolumeType())) if (!IsDisc(volume.GetVolumeType()))
return false; return false;
return ExportData(volume, partition, 0, 0x440, export_filename); return ExportData(volume, partition, DISCHEADER_ADDRESS, DISCHEADER_SIZE, export_filename);
} }
bool ExportBI2Data(const Volume& volume, const Partition& partition, bool ExportBI2Data(const Volume& volume, const Partition& partition,
@ -215,7 +221,7 @@ bool ExportBI2Data(const Volume& volume, const Partition& partition,
if (!IsDisc(volume.GetVolumeType())) if (!IsDisc(volume.GetVolumeType()))
return false; return false;
return ExportData(volume, partition, 0x440, 0x2000, export_filename); return ExportData(volume, partition, BI2_ADDRESS, BI2_SIZE, export_filename);
} }
bool ExportApploader(const Volume& volume, const Partition& partition, bool ExportApploader(const Volume& volume, const Partition& partition,
@ -228,7 +234,7 @@ bool ExportApploader(const Volume& volume, const Partition& partition,
if (!apploader_size) if (!apploader_size)
return false; return false;
return ExportData(volume, partition, 0x2440, *apploader_size, export_filename); return ExportData(volume, partition, APPLOADER_ADDRESS, *apploader_size, export_filename);
} }
bool ExportDOL(const Volume& volume, const Partition& partition, const std::string& export_filename) bool ExportDOL(const Volume& volume, const Partition& partition, const std::string& export_filename)

View File

@ -132,11 +132,16 @@ bool DiscScrubber::ParseDisc()
u64 h3_offset; u64 h3_offset;
// The H3 size is always 0x18000 // The H3 size is always 0x18000
if (!ReadFromVolume(partition.offset + 0x2a4, tmd_size, PARTITION_NONE) || if (!ReadFromVolume(partition.offset + WII_PARTITION_TMD_SIZE_ADDRESS, tmd_size,
!ReadFromVolume(partition.offset + 0x2a8, tmd_offset, PARTITION_NONE) || PARTITION_NONE) ||
!ReadFromVolume(partition.offset + 0x2ac, cert_chain_size, PARTITION_NONE) || !ReadFromVolume(partition.offset + WII_PARTITION_TMD_OFFSET_ADDRESS, tmd_offset,
!ReadFromVolume(partition.offset + 0x2b0, cert_chain_offset, PARTITION_NONE) || PARTITION_NONE) ||
!ReadFromVolume(partition.offset + 0x2b4, h3_offset, PARTITION_NONE)) !ReadFromVolume(partition.offset + WII_PARTITION_CERT_CHAIN_SIZE_ADDRESS, cert_chain_size,
PARTITION_NONE) ||
!ReadFromVolume(partition.offset + WII_PARTITION_CERT_CHAIN_OFFSET_ADDRESS,
cert_chain_offset, PARTITION_NONE) ||
!ReadFromVolume(partition.offset + WII_PARTITION_H3_OFFSET_ADDRESS, h3_offset,
PARTITION_NONE))
{ {
return false; return false;
} }
@ -145,7 +150,7 @@ bool DiscScrubber::ParseDisc()
MarkAsUsed(partition.offset + tmd_offset, tmd_size); MarkAsUsed(partition.offset + tmd_offset, tmd_size);
MarkAsUsed(partition.offset + cert_chain_offset, cert_chain_size); MarkAsUsed(partition.offset + cert_chain_offset, cert_chain_size);
MarkAsUsed(partition.offset + h3_offset, 0x18000); MarkAsUsed(partition.offset + h3_offset, WII_PARTITION_H3_SIZE);
// Parse Data! This is where the big gain is // Parse Data! This is where the big gain is
if (!ParsePartitionData(partition)) if (!ParsePartitionData(partition))

View File

@ -29,6 +29,26 @@ constexpr u32 PARTITION_UPDATE = 1;
constexpr u32 PARTITION_CHANNEL = 2; // Mario Kart Wii, Wii Fit, Wii Fit Plus, Rabbids Go Home constexpr u32 PARTITION_CHANNEL = 2; // Mario Kart Wii, Wii Fit, Wii Fit Plus, Rabbids Go Home
constexpr u32 PARTITION_INSTALL = 3; // Dragon Quest X only constexpr u32 PARTITION_INSTALL = 3; // Dragon Quest X only
constexpr u32 DISCHEADER_ADDRESS = 0;
constexpr u32 DISCHEADER_SIZE = 0x440;
constexpr u32 BI2_ADDRESS = 0x440;
constexpr u32 BI2_SIZE = 0x2000;
constexpr u32 APPLOADER_ADDRESS = 0x2440;
constexpr u32 WII_PARTITION_TICKET_ADDRESS = 0;
constexpr u32 WII_PARTITION_TICKET_SIZE = 0x2a4;
constexpr u32 WII_PARTITION_TMD_SIZE_ADDRESS = 0x2a4;
constexpr u32 WII_PARTITION_TMD_OFFSET_ADDRESS = 0x2a8;
constexpr u32 WII_PARTITION_CERT_CHAIN_SIZE_ADDRESS = 0x2ac;
constexpr u32 WII_PARTITION_CERT_CHAIN_OFFSET_ADDRESS = 0x2b0;
constexpr u32 WII_PARTITION_H3_OFFSET_ADDRESS = 0x2b4;
constexpr u32 WII_PARTITION_H3_SIZE = 0x18000;
constexpr u32 WII_NONPARTITION_DISCHEADER_ADDRESS = 0;
constexpr u32 WII_NONPARTITION_DISCHEADER_SIZE = 0x100;
constexpr u32 WII_REGION_DATA_ADDRESS = 0x4E000;
constexpr u32 WII_REGION_DATA_SIZE = 0x20;
std::string NameForPartitionType(u32 partition_type, bool include_prefix); std::string NameForPartitionType(u32 partition_type, bool include_prefix);
std::optional<u64> GetApploaderSize(const Volume& volume, const Partition& partition); std::optional<u64> GetApploaderSize(const Volume& volume, const Partition& partition);

View File

@ -27,6 +27,7 @@
#include "DiscIO/Blob.h" #include "DiscIO/Blob.h"
#include "DiscIO/DiscExtractor.h" #include "DiscIO/DiscExtractor.h"
#include "DiscIO/DiscUtils.h"
#include "DiscIO/Enums.h" #include "DiscIO/Enums.h"
#include "DiscIO/FileSystemGCWii.h" #include "DiscIO/FileSystemGCWii.h"
#include "DiscIO/Filesystem.h" #include "DiscIO/Filesystem.h"
@ -81,9 +82,10 @@ VolumeWii::VolumeWii(std::unique_ptr<BlobReader> reader)
}; };
auto get_tmd = [this, partition]() -> IOS::ES::TMDReader { auto get_tmd = [this, partition]() -> IOS::ES::TMDReader {
const std::optional<u32> tmd_size = m_reader->ReadSwapped<u32>(partition.offset + 0x2a4); const std::optional<u32> tmd_size =
const std::optional<u64> tmd_address = m_reader->ReadSwapped<u32>(partition.offset + WII_PARTITION_TMD_SIZE_ADDRESS);
ReadSwappedAndShifted(partition.offset + 0x2a8, PARTITION_NONE); const std::optional<u64> tmd_address = ReadSwappedAndShifted(
partition.offset + WII_PARTITION_TMD_OFFSET_ADDRESS, PARTITION_NONE);
if (!tmd_size || !tmd_address) if (!tmd_size || !tmd_address)
return INVALID_TMD; return INVALID_TMD;
if (!IOS::ES::IsValidTMDSize(*tmd_size)) if (!IOS::ES::IsValidTMDSize(*tmd_size))
@ -100,9 +102,10 @@ VolumeWii::VolumeWii(std::unique_ptr<BlobReader> reader)
}; };
auto get_cert_chain = [this, partition]() -> std::vector<u8> { auto get_cert_chain = [this, partition]() -> std::vector<u8> {
const std::optional<u32> size = m_reader->ReadSwapped<u32>(partition.offset + 0x2ac); const std::optional<u32> size =
const std::optional<u64> address = m_reader->ReadSwapped<u32>(partition.offset + WII_PARTITION_CERT_CHAIN_SIZE_ADDRESS);
ReadSwappedAndShifted(partition.offset + 0x2b0, PARTITION_NONE); const std::optional<u64> address = ReadSwappedAndShifted(
partition.offset + WII_PARTITION_CERT_CHAIN_OFFSET_ADDRESS, PARTITION_NONE);
if (!size || !address) if (!size || !address)
return {}; return {};
std::vector<u8> cert_chain(*size); std::vector<u8> cert_chain(*size);
@ -114,12 +117,13 @@ VolumeWii::VolumeWii(std::unique_ptr<BlobReader> reader)
auto get_h3_table = [this, partition]() -> std::vector<u8> { auto get_h3_table = [this, partition]() -> std::vector<u8> {
if (!m_encrypted) if (!m_encrypted)
return {}; return {};
const std::optional<u64> h3_table_offset = const std::optional<u64> h3_table_offset = ReadSwappedAndShifted(
ReadSwappedAndShifted(partition.offset + 0x2b4, PARTITION_NONE); partition.offset + WII_PARTITION_H3_OFFSET_ADDRESS, PARTITION_NONE);
if (!h3_table_offset) if (!h3_table_offset)
return {}; return {};
std::vector<u8> h3_table(H3_TABLE_SIZE); std::vector<u8> h3_table(WII_PARTITION_H3_SIZE);
if (!m_reader->Read(partition.offset + *h3_table_offset, H3_TABLE_SIZE, h3_table.data())) if (!m_reader->Read(partition.offset + *h3_table_offset, WII_PARTITION_H3_SIZE,
h3_table.data()))
return {}; return {};
return h3_table; return h3_table;
}; };
@ -395,7 +399,7 @@ bool VolumeWii::CheckH3TableIntegrity(const Partition& partition) const
const PartitionDetails& partition_details = it->second; const PartitionDetails& partition_details = it->second;
const std::vector<u8>& h3_table = *partition_details.h3_table; const std::vector<u8>& h3_table = *partition_details.h3_table;
if (h3_table.size() != H3_TABLE_SIZE) if (h3_table.size() != WII_PARTITION_H3_SIZE)
return false; return false;
const IOS::ES::TMDReader& tmd = *partition_details.tmd; const IOS::ES::TMDReader& tmd = *partition_details.tmd;

View File

@ -36,7 +36,6 @@ public:
static constexpr size_t AES_KEY_SIZE = 16; static constexpr size_t AES_KEY_SIZE = 16;
static constexpr size_t SHA1_SIZE = 20; static constexpr size_t SHA1_SIZE = 20;
static constexpr u32 H3_TABLE_SIZE = 0x18000;
static constexpr u32 BLOCKS_PER_GROUP = 0x40; static constexpr u32 BLOCKS_PER_GROUP = 0x40;
static constexpr u64 BLOCK_HEADER_SIZE = 0x0400; static constexpr u64 BLOCK_HEADER_SIZE = 0x0400;