diff --git a/Source/Core/DiscIO/DirectoryBlob.cpp b/Source/Core/DiscIO/DirectoryBlob.cpp index 849ceef2a4..ab33013b4c 100644 --- a/Source/Core/DiscIO/DirectoryBlob.cpp +++ b/Source/Core/DiscIO/DirectoryBlob.cpp @@ -31,6 +31,10 @@ namespace DiscIO { +static const DiscContent& AddFileToContents(std::set* contents, + const std::string& path, u64 offset, + u64 max_size = UINT64_MAX); + static u32 ComputeNameSize(const File::FSTEntry& parent_entry); static std::string ASCIIToUppercase(std::string str); static void ConvertUTF8NamesToSHIFTJIS(File::FSTEntry& parent_entry); @@ -179,7 +183,20 @@ DirectoryBlobReader::DirectoryBlobReader(File::IOFile dol_file, const std::strin m_disk_header.data()); m_nonpartition_contents.emplace(PARTITION_TABLE_ADDRESS, PARTITION_TABLE.size() * sizeof(u32), reinterpret_cast(PARTITION_TABLE.data())); - // TODO: TMDs, tickets, more headers, the raw partition contents... + + constexpr u32 TICKET_OFFSET = 0x0; + constexpr u32 TICKET_SIZE = 0x2a4; + constexpr u32 TMD_OFFSET = 0x2c0; + constexpr u32 MAX_TMD_SIZE = 0x49e4; + AddFileToContents(&m_nonpartition_contents, m_root_directory + "ticket.bin", + GAME_PARTITION_ADDRESS + TICKET_OFFSET, TICKET_SIZE); + const DiscContent& tmd = + AddFileToContents(&m_nonpartition_contents, m_root_directory + "tmd.bin", + GAME_PARTITION_ADDRESS + TMD_OFFSET, MAX_TMD_SIZE); + m_tmd_header = {Common::swap32(static_cast(tmd.GetSize())), + Common::swap32(TMD_OFFSET >> m_address_shift)}; + m_nonpartition_contents.emplace(GAME_PARTITION_ADDRESS + TICKET_SIZE, sizeof(m_tmd_header), + reinterpret_cast(&m_tmd_header)); } } @@ -217,6 +234,8 @@ bool DirectoryBlobReader::ReadInternal(u64 offset, u64 length, u8* buffer, bool DirectoryBlobReader::Read(u64 offset, u64 length, u8* buffer) { + // TODO: We don't handle raw access to the encrypted area of Wii discs correctly. + return ReadInternal(offset, length, buffer, m_is_wii ? m_nonpartition_contents : m_virtual_disc); } @@ -455,6 +474,12 @@ void DirectoryBlobReader::WriteDirectory(const File::FSTEntry& parent_entry, u32 } } +static const DiscContent& AddFileToContents(std::set* contents, + const std::string& path, u64 offset, u64 max_size) +{ + return *(contents->emplace(offset, std::min(File::GetSize(path), max_size), path).first); +} + static u32 ComputeNameSize(const File::FSTEntry& parent_entry) { u32 name_size = 0; diff --git a/Source/Core/DiscIO/DirectoryBlob.h b/Source/Core/DiscIO/DirectoryBlob.h index 0d0a196be9..5e5eb0a50d 100644 --- a/Source/Core/DiscIO/DirectoryBlob.h +++ b/Source/Core/DiscIO/DirectoryBlob.h @@ -118,6 +118,13 @@ private: std::vector m_disk_header; #pragma pack(push, 1) + struct TMDHeader + { + u32 tmd_size; + u32 tmd_offset; + } m_tmd_header; + static_assert(sizeof(TMDHeader) == 8, "Wrong size for TMDHeader"); + struct SDiskHeaderInfo { u32 debug_monitor_size; @@ -144,6 +151,7 @@ private: unknown2 = 0; } }; + static_assert(sizeof(SDiskHeaderInfo) == 36, "Wrong size for SDiskHeaderInfo"); #pragma pack(pop) std::unique_ptr m_disk_header_info;