DirectoryBlob: Write partition headers properly

This commit is contained in:
JosJuice 2017-06-13 15:52:02 +02:00
parent 09832caf41
commit 3fd0d39a85
2 changed files with 36 additions and 11 deletions

View File

@ -491,7 +491,7 @@ void DirectoryBlobReader::SetPartitions(std::vector<PartitionWithType>&& partiti
Write32(static_cast<u32>(partitions[i].type), offset_in_table, &m_partition_table); Write32(static_cast<u32>(partitions[i].type), offset_in_table, &m_partition_table);
offset_in_table += 4; offset_in_table += 4;
SetTMDAndTicket(partitions[i].partition.GetRootDirectory(), partition_address); SetPartitionHeader(partitions[i].partition, partition_address);
const u64 partition_data_size = partitions[i].partition.GetDataSize(); const u64 partition_data_size = partitions[i].partition.GetDataSize();
m_partitions.emplace(partition_address, std::move(partitions[i].partition)); m_partitions.emplace(partition_address, std::move(partitions[i].partition));
@ -505,24 +505,49 @@ void DirectoryBlobReader::SetPartitions(std::vector<PartitionWithType>&& partiti
m_partition_table.data()); m_partition_table.data());
} }
void DirectoryBlobReader::SetTMDAndTicket(const std::string& partition_root, u64 partition_address) // This function sets the header that's shortly before the start of the encrypted
// area, not the header that's right at the beginning of the encrypted area
void DirectoryBlobReader::SetPartitionHeader(const DirectoryBlobPartition& partition,
u64 partition_address)
{ {
constexpr u32 TICKET_OFFSET = 0x0; constexpr u32 TICKET_OFFSET = 0x0;
constexpr u32 TICKET_SIZE = 0x2a4; constexpr u32 TICKET_SIZE = 0x2a4;
constexpr u32 TMD_OFFSET = 0x2c0; constexpr u32 TMD_OFFSET = 0x2c0;
constexpr u32 MAX_TMD_SIZE = 0x49e4; constexpr u32 MAX_TMD_SIZE = 0x49e4;
constexpr u32 H3_OFFSET = 0x4000;
constexpr u32 H3_SIZE = 0x18000;
const std::string& partition_root = partition.GetRootDirectory();
AddFileToContents(&m_nonpartition_contents, partition_root + "ticket.bin", AddFileToContents(&m_nonpartition_contents, partition_root + "ticket.bin",
partition_address + TICKET_OFFSET, TICKET_SIZE); partition_address + TICKET_OFFSET, TICKET_SIZE);
const DiscContent& tmd = AddFileToContents(&m_nonpartition_contents, partition_root + "tmd.bin", const DiscContent& tmd = AddFileToContents(&m_nonpartition_contents, partition_root + "tmd.bin",
partition_address + TMD_OFFSET, MAX_TMD_SIZE); partition_address + TMD_OFFSET, MAX_TMD_SIZE);
constexpr u32 TMD_HEADER_SIZE = 8; const u64 cert_offset = Common::AlignUp(TMD_OFFSET + tmd.GetSize(), 0x20ull);
m_tmd_headers.emplace_back(TMD_HEADER_SIZE); const u64 max_cert_size = H3_OFFSET - cert_offset;
std::vector<u8>& tmd_header = m_tmd_headers.back(); const DiscContent& cert = AddFileToContents(&m_nonpartition_contents, partition_root + "cert.bin",
Write32(static_cast<u32>(tmd.GetSize()), 0x0, &tmd_header); partition_address + cert_offset, max_cert_size);
Write32(TMD_OFFSET >> 2, 0x4, &tmd_header);
m_nonpartition_contents.emplace(partition_address + TICKET_SIZE, TMD_HEADER_SIZE, AddFileToContents(&m_nonpartition_contents, partition_root + "h3.bin",
tmd_header.data()); partition_address + H3_OFFSET, H3_SIZE);
constexpr u32 PARTITION_HEADER_SIZE = 0x1c;
constexpr u32 DATA_OFFSET = 0x20000;
const u64 data_size = Common::AlignUp(partition.GetDataSize(), 0x7c00) / 0x7c00 * 0x8000;
m_partition_headers.emplace_back(PARTITION_HEADER_SIZE);
std::vector<u8>& partition_header = m_partition_headers.back();
Write32(static_cast<u32>(tmd.GetSize()), 0x0, &partition_header);
Write32(TMD_OFFSET >> 2, 0x4, &partition_header);
Write32(static_cast<u32>(cert.GetSize()), 0x8, &partition_header);
Write32(static_cast<u32>(cert_offset >> 2), 0x0C, &partition_header);
Write32(H3_OFFSET >> 2, 0x10, &partition_header);
Write32(DATA_OFFSET >> 2, 0x14, &partition_header);
Write32(static_cast<u32>(data_size >> 2), 0x18, &partition_header);
m_nonpartition_contents.emplace(partition_address + TICKET_SIZE, PARTITION_HEADER_SIZE,
partition_header.data());
} }
DirectoryBlobPartition::DirectoryBlobPartition(const std::string& root_directory, DirectoryBlobPartition::DirectoryBlobPartition(const std::string& root_directory,

View File

@ -146,7 +146,7 @@ private:
const std::string& game_partition_root); const std::string& game_partition_root);
void SetWiiRegionData(const std::string& game_partition_root); void SetWiiRegionData(const std::string& game_partition_root);
void SetPartitions(std::vector<PartitionWithType>&& partitions); void SetPartitions(std::vector<PartitionWithType>&& partitions);
void SetTMDAndTicket(const std::string& partition_root, u64 partition_address); void SetPartitionHeader(const DirectoryBlobPartition& partition, u64 partition_address);
// For GameCube: // For GameCube:
DirectoryBlobPartition m_gamecube_pseudopartition; DirectoryBlobPartition m_gamecube_pseudopartition;
@ -160,7 +160,7 @@ private:
std::vector<u8> m_disk_header_nonpartition; std::vector<u8> m_disk_header_nonpartition;
std::vector<u8> m_partition_table; std::vector<u8> m_partition_table;
std::vector<u8> m_wii_region_data; std::vector<u8> m_wii_region_data;
std::vector<std::vector<u8>> m_tmd_headers; std::vector<std::vector<u8>> m_partition_headers;
u64 m_data_size; u64 m_data_size;
}; };