From fcb2c5bd294334a2c00419b38c64a9fed22b6b85 Mon Sep 17 00:00:00 2001 From: JosJuice Date: Fri, 19 May 2017 21:23:00 +0200 Subject: [PATCH 1/2] Remove CBlobBigEndianReader We can simply put ReadSwapped directly in IBlobReader. --- Source/Core/DiscIO/Blob.h | 28 +++++++++---------------- Source/Core/DiscIO/Volume.cpp | 9 ++++---- Source/Core/DiscIO/VolumeWiiCrypted.cpp | 11 +++++----- Source/Core/DiscIO/WiiWad.cpp | 18 +++++++--------- 4 files changed, 27 insertions(+), 39 deletions(-) diff --git a/Source/Core/DiscIO/Blob.h b/Source/Core/DiscIO/Blob.h index cf04789b01..07dc969bd0 100644 --- a/Source/Core/DiscIO/Blob.h +++ b/Source/Core/DiscIO/Blob.h @@ -42,8 +42,18 @@ public: virtual BlobType GetBlobType() const = 0; virtual u64 GetRawSize() const = 0; virtual u64 GetDataSize() const = 0; + // NOT thread-safe - can't call this from multiple threads. virtual bool Read(u64 offset, u64 size, u8* out_ptr) = 0; + template + bool ReadSwapped(u64 offset, T* buffer) + { + T temp; + if (!Read(offset, sizeof(T), reinterpret_cast(&temp))) + return false; + *buffer = Common::FromBigEndian(temp); + return true; + } protected: IBlobReader() {} @@ -137,24 +147,6 @@ private: std::array m_cache; }; -class CBlobBigEndianReader -{ -public: - CBlobBigEndianReader(IBlobReader& reader) : m_reader(reader) {} - template - bool ReadSwapped(u64 offset, T* buffer) const - { - T temp; - if (!m_reader.Read(offset, sizeof(T), reinterpret_cast(&temp))) - return false; - *buffer = Common::FromBigEndian(temp); - return true; - } - -private: - IBlobReader& m_reader; -}; - // Factory function - examines the path to choose the right type of IBlobReader, and returns one. std::unique_ptr CreateBlobReader(const std::string& filename); diff --git a/Source/Core/DiscIO/Volume.cpp b/Source/Core/DiscIO/Volume.cpp index 21fece4484..d91272a329 100644 --- a/Source/Core/DiscIO/Volume.cpp +++ b/Source/Core/DiscIO/Volume.cpp @@ -88,13 +88,12 @@ std::unique_ptr CreateVolumeFromFilename(const std::string& filename) std::unique_ptr reader(CreateBlobReader(filename)); if (reader == nullptr) return nullptr; - CBlobBigEndianReader be_reader(*reader); // Check for Wii u32 wii_magic = 0; - be_reader.ReadSwapped(0x18, &wii_magic); + reader->ReadSwapped(0x18, &wii_magic); u32 wii_container_magic = 0; - be_reader.ReadSwapped(0x60, &wii_container_magic); + reader->ReadSwapped(0x60, &wii_container_magic); if (wii_magic == 0x5D1C9EA3 && wii_container_magic != 0) return std::make_unique(std::move(reader)); if (wii_magic == 0x5D1C9EA3 && wii_container_magic == 0) @@ -103,13 +102,13 @@ std::unique_ptr CreateVolumeFromFilename(const std::string& filename) // Check for WAD // 0x206962 for boot2 wads u32 wad_magic = 0; - be_reader.ReadSwapped(0x02, &wad_magic); + reader->ReadSwapped(0x02, &wad_magic); if (wad_magic == 0x00204973 || wad_magic == 0x00206962) return std::make_unique(std::move(reader)); // Check for GC u32 gc_magic = 0; - be_reader.ReadSwapped(0x1C, &gc_magic); + reader->ReadSwapped(0x1C, &gc_magic); if (gc_magic == 0xC2339F3D) return std::make_unique(std::move(reader)); diff --git a/Source/Core/DiscIO/VolumeWiiCrypted.cpp b/Source/Core/DiscIO/VolumeWiiCrypted.cpp index 1572c8493b..cde3f8fda4 100644 --- a/Source/Core/DiscIO/VolumeWiiCrypted.cpp +++ b/Source/Core/DiscIO/VolumeWiiCrypted.cpp @@ -36,28 +36,27 @@ CVolumeWiiCrypted::CVolumeWiiCrypted(std::unique_ptr reader) _assert_(m_pReader); // Get decryption keys for all partitions - CBlobBigEndianReader big_endian_reader(*m_pReader.get()); for (u32 partition_group = 0; partition_group < 4; ++partition_group) { u32 number_of_partitions; - if (!big_endian_reader.ReadSwapped(0x40000 + (partition_group * 8), &number_of_partitions)) + if (!m_pReader->ReadSwapped(0x40000 + (partition_group * 8), &number_of_partitions)) continue; u32 read_buffer; - if (!big_endian_reader.ReadSwapped(0x40000 + (partition_group * 8) + 4, &read_buffer)) + if (!m_pReader->ReadSwapped(0x40000 + (partition_group * 8) + 4, &read_buffer)) continue; const u64 partition_table_offset = (u64)read_buffer << 2; for (u32 i = 0; i < number_of_partitions; i++) { - if (!big_endian_reader.ReadSwapped(partition_table_offset + (i * 8), &read_buffer)) + if (!m_pReader->ReadSwapped(partition_table_offset + (i * 8), &read_buffer)) continue; const u64 partition_offset = (u64)read_buffer << 2; if (m_game_partition == PARTITION_NONE) { u32 partition_type; - if (!big_endian_reader.ReadSwapped(partition_table_offset + (i * 8) + 4, &partition_type)) + if (!m_pReader->ReadSwapped(partition_table_offset + (i * 8) + 4, &partition_type)) continue; if (partition_type == 0) @@ -95,7 +94,7 @@ CVolumeWiiCrypted::CVolumeWiiCrypted(std::unique_ptr reader) else { u8 key_number = 0; - if (!big_endian_reader.ReadSwapped(partition_offset + 0x1f1, &key_number)) + if (!m_pReader->ReadSwapped(partition_offset + 0x1f1, &key_number)) continue; common_key = (key_number == 1) ? common_key_korean : common_key_standard; } diff --git a/Source/Core/DiscIO/WiiWad.cpp b/Source/Core/DiscIO/WiiWad.cpp index 89b687eb95..06d8d57070 100644 --- a/Source/Core/DiscIO/WiiWad.cpp +++ b/Source/Core/DiscIO/WiiWad.cpp @@ -34,7 +34,7 @@ std::vector CreateWADEntry(IBlobReader& reader, u32 size, u64 offset) return buffer; } -bool IsWiiWAD(const CBlobBigEndianReader& reader) +bool IsWiiWAD(IBlobReader& reader) { u32 header_size = 0; u32 header_type = 0; @@ -61,9 +61,7 @@ WiiWAD::~WiiWAD() bool WiiWAD::ParseWAD() { - CBlobBigEndianReader big_endian_reader(*m_reader); - - if (!IsWiiWAD(big_endian_reader)) + if (!IsWiiWAD(*m_reader)) return false; u32 certificate_chain_size; @@ -73,12 +71,12 @@ bool WiiWAD::ParseWAD() u32 data_app_size; u32 footer_size; - if (!big_endian_reader.ReadSwapped(0x08, &certificate_chain_size) || - !big_endian_reader.ReadSwapped(0x0C, &reserved) || - !big_endian_reader.ReadSwapped(0x10, &ticket_size) || - !big_endian_reader.ReadSwapped(0x14, &tmd_size) || - !big_endian_reader.ReadSwapped(0x18, &data_app_size) || - !big_endian_reader.ReadSwapped(0x1C, &footer_size)) + if (!m_reader->ReadSwapped(0x08, &certificate_chain_size) || + !m_reader->ReadSwapped(0x0C, &reserved) || + !m_reader->ReadSwapped(0x10, &ticket_size) || + !m_reader->ReadSwapped(0x14, &tmd_size) || + !m_reader->ReadSwapped(0x18, &data_app_size) || + !m_reader->ReadSwapped(0x1C, &footer_size)) return false; if (MAX_LOGLEVEL >= LogTypes::LOG_LEVELS::LDEBUG) From 78effbabc6e4b3131ac9eef3f9b8fd7e56a885f0 Mon Sep 17 00:00:00 2001 From: JosJuice Date: Fri, 19 May 2017 21:31:47 +0200 Subject: [PATCH 2/2] Replace some usages of IVolume::ReadSwapped with IBlobReader::ReadSwapped Skips needing to specify PARTITION_NONE. --- Source/Core/DiscIO/VolumeWad.cpp | 10 +++++----- Source/Core/DiscIO/VolumeWiiCrypted.cpp | 16 ++++++++-------- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/Source/Core/DiscIO/VolumeWad.cpp b/Source/Core/DiscIO/VolumeWad.cpp index a8316c9e04..b401a3787e 100644 --- a/Source/Core/DiscIO/VolumeWad.cpp +++ b/Source/Core/DiscIO/VolumeWad.cpp @@ -29,11 +29,11 @@ CVolumeWAD::CVolumeWAD(std::unique_ptr reader) : m_reader(std::move _assert_(m_reader); // Source: http://wiibrew.org/wiki/WAD_files - ReadSwapped(0x00, &m_hdr_size, PARTITION_NONE); - ReadSwapped(0x08, &m_cert_size, PARTITION_NONE); - ReadSwapped(0x10, &m_tick_size, PARTITION_NONE); - ReadSwapped(0x14, &m_tmd_size, PARTITION_NONE); - ReadSwapped(0x18, &m_data_size, PARTITION_NONE); + m_reader->ReadSwapped(0x00, &m_hdr_size); + m_reader->ReadSwapped(0x08, &m_cert_size); + m_reader->ReadSwapped(0x10, &m_tick_size); + m_reader->ReadSwapped(0x14, &m_tmd_size); + m_reader->ReadSwapped(0x18, &m_data_size); m_offset = Common::AlignUp(m_hdr_size, 0x40) + Common::AlignUp(m_cert_size, 0x40); m_tmd_offset = Common::AlignUp(m_hdr_size, 0x40) + Common::AlignUp(m_cert_size, 0x40) + diff --git a/Source/Core/DiscIO/VolumeWiiCrypted.cpp b/Source/Core/DiscIO/VolumeWiiCrypted.cpp index cde3f8fda4..b77294640e 100644 --- a/Source/Core/DiscIO/VolumeWiiCrypted.cpp +++ b/Source/Core/DiscIO/VolumeWiiCrypted.cpp @@ -186,13 +186,13 @@ Partition CVolumeWiiCrypted::GetGamePartition() const bool CVolumeWiiCrypted::GetTitleID(u64* buffer, const Partition& partition) const { - return ReadSwapped(partition.offset + 0x1DC, buffer, PARTITION_NONE); + return m_pReader->ReadSwapped(partition.offset + 0x1DC, buffer); } IOS::ES::TicketReader CVolumeWiiCrypted::GetTicket(const Partition& partition) const { std::vector buffer(0x2a4); - Read(partition.offset, buffer.size(), buffer.data(), PARTITION_NONE); + m_pReader->Read(partition.offset, buffer.size(), buffer.data()); return IOS::ES::TicketReader{std::move(buffer)}; } @@ -201,9 +201,9 @@ IOS::ES::TMDReader CVolumeWiiCrypted::GetTMD(const Partition& partition) const u32 tmd_size = 0; u32 tmd_address = 0; - if (!ReadSwapped(partition.offset + 0x2a4, &tmd_size, PARTITION_NONE)) + if (!m_pReader->ReadSwapped(partition.offset + 0x2a4, &tmd_size)) return {}; - if (!ReadSwapped(partition.offset + 0x2a8, &tmd_address, PARTITION_NONE)) + if (!m_pReader->ReadSwapped(partition.offset + 0x2a8, &tmd_address)) return {}; tmd_address <<= 2; @@ -218,7 +218,7 @@ IOS::ES::TMDReader CVolumeWiiCrypted::GetTMD(const Partition& partition) const } std::vector buffer(tmd_size); - if (!Read(partition.offset + tmd_address, tmd_size, buffer.data(), PARTITION_NONE)) + if (!m_pReader->Read(partition.offset + tmd_address, tmd_size, buffer.data())) return {}; return IOS::ES::TMDReader{std::move(buffer)}; @@ -246,7 +246,7 @@ std::string CVolumeWiiCrypted::GetGameID(const Partition& partition) const Region CVolumeWiiCrypted::GetRegion() const { u32 region_code; - if (!ReadSwapped(0x4E000, ®ion_code, PARTITION_NONE)) + if (!m_pReader->ReadSwapped(0x4E000, ®ion_code)) return Region::UNKNOWN_REGION; return static_cast(region_code); @@ -375,7 +375,7 @@ bool CVolumeWiiCrypted::CheckIntegrity(const Partition& partition) const // Get partition data size u32 partSizeDiv4; - Read(partition.offset + 0x2BC, 4, (u8*)&partSizeDiv4, PARTITION_NONE); + m_pReader->Read(partition.offset + 0x2BC, 4, (u8*)&partSizeDiv4); u64 partDataSize = (u64)Common::swap32(partSizeDiv4) * 4; u32 nClusters = (u32)(partDataSize / 0x8000); @@ -387,7 +387,7 @@ bool CVolumeWiiCrypted::CheckIntegrity(const Partition& partition) const u8 clusterMDCrypted[0x400]; u8 clusterMD[0x400]; u8 IV[16] = {0}; - if (!Read(clusterOff, 0x400, clusterMDCrypted, PARTITION_NONE)) + if (!m_pReader->Read(clusterOff, 0x400, clusterMDCrypted)) { WARN_LOG(DISCIO, "Integrity Check: fail at cluster %d: could not read metadata", clusterID); return false;