summaryrefslogtreecommitdiff
path: root/Source/Core/DiscIO
diff options
context:
space:
mode:
authorLéo Lam <leo@innovatetechnologi.es>2019-07-21 15:32:52 +0800
committerGitHub <noreply@github.com>2019-07-21 15:32:52 +0800
commitda1fbbc5d5d0eda5fcdccadd20207b4b525f8a7e (patch)
tree28afb7bb2892547e824f688261ec50c0616ef15b /Source/Core/DiscIO
parentcd7a374ab91f1f1dd46e5631309bea7ed5efc23d (diff)
parent34f32898e63e7dd5d0251fd630f8d569432c9ac3 (diff)
Merge pull request #8243 from JosJuice/merge-wad-classes
DiscIO: Merge WiiWAD into VolumeWAD
Diffstat (limited to 'Source/Core/DiscIO')
-rw-r--r--Source/Core/DiscIO/CMakeLists.txt2
-rw-r--r--Source/Core/DiscIO/CompressedBlob.cpp4
-rw-r--r--Source/Core/DiscIO/DiscIO.vcxproj2
-rw-r--r--Source/Core/DiscIO/DiscIO.vcxproj.filters6
-rw-r--r--Source/Core/DiscIO/FileSystemGCWii.cpp2
-rw-r--r--Source/Core/DiscIO/FileSystemGCWii.h4
-rw-r--r--Source/Core/DiscIO/Volume.cpp51
-rw-r--r--Source/Core/DiscIO/Volume.h10
-rw-r--r--Source/Core/DiscIO/VolumeGC.h2
-rw-r--r--Source/Core/DiscIO/VolumeVerifier.cpp9
-rw-r--r--Source/Core/DiscIO/VolumeWad.cpp22
-rw-r--r--Source/Core/DiscIO/VolumeWad.h2
-rw-r--r--Source/Core/DiscIO/VolumeWii.h2
-rw-r--r--Source/Core/DiscIO/WiiWad.cpp112
-rw-r--r--Source/Core/DiscIO/WiiWad.h49
15 files changed, 79 insertions, 200 deletions
diff --git a/Source/Core/DiscIO/CMakeLists.txt b/Source/Core/DiscIO/CMakeLists.txt
index fedfe6f406..4e5faa6cd4 100644
--- a/Source/Core/DiscIO/CMakeLists.txt
+++ b/Source/Core/DiscIO/CMakeLists.txt
@@ -41,8 +41,6 @@ add_library(discio
WbfsBlob.h
WiiSaveBanner.cpp
WiiSaveBanner.h
- WiiWad.cpp
- WiiWad.h
)
target_link_libraries(discio
diff --git a/Source/Core/DiscIO/CompressedBlob.cpp b/Source/Core/DiscIO/CompressedBlob.cpp
index 76b7506cb2..37af397b38 100644
--- a/Source/Core/DiscIO/CompressedBlob.cpp
+++ b/Source/Core/DiscIO/CompressedBlob.cpp
@@ -182,10 +182,10 @@ bool CompressFileToBlob(const std::string& infile_path, const std::string& outfi
}
DiscScrubber disc_scrubber;
- std::unique_ptr<Volume> volume;
+ std::unique_ptr<VolumeDisc> volume;
if (sub_type == 1)
{
- volume = CreateVolumeFromFilename(infile_path);
+ volume = CreateDisc(infile_path);
if (!volume || !disc_scrubber.SetupScrub(volume.get(), block_size))
{
PanicAlertT("\"%s\" failed to be scrubbed. Probably the image is corrupt.",
diff --git a/Source/Core/DiscIO/DiscIO.vcxproj b/Source/Core/DiscIO/DiscIO.vcxproj
index 830834bd48..7ad3731fc6 100644
--- a/Source/Core/DiscIO/DiscIO.vcxproj
+++ b/Source/Core/DiscIO/DiscIO.vcxproj
@@ -57,7 +57,6 @@
<ClCompile Include="VolumeWii.cpp" />
<ClCompile Include="WbfsBlob.cpp" />
<ClCompile Include="WiiSaveBanner.cpp" />
- <ClCompile Include="WiiWad.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="Blob.h" />
@@ -81,7 +80,6 @@
<ClInclude Include="VolumeWii.h" />
<ClInclude Include="WbfsBlob.h" />
<ClInclude Include="WiiSaveBanner.h" />
- <ClInclude Include="WiiWad.h" />
</ItemGroup>
<ItemGroup>
<Text Include="CMakeLists.txt" />
diff --git a/Source/Core/DiscIO/DiscIO.vcxproj.filters b/Source/Core/DiscIO/DiscIO.vcxproj.filters
index c6240a5b6e..87fdbfadbc 100644
--- a/Source/Core/DiscIO/DiscIO.vcxproj.filters
+++ b/Source/Core/DiscIO/DiscIO.vcxproj.filters
@@ -30,9 +30,6 @@
<ClCompile Include="FileSystemGCWii.cpp">
<Filter>FileSystem</Filter>
</ClCompile>
- <ClCompile Include="WiiWad.cpp">
- <Filter>NAND</Filter>
- </ClCompile>
<ClCompile Include="NANDImporter.cpp">
<Filter>NAND</Filter>
</ClCompile>
@@ -98,9 +95,6 @@
<ClInclude Include="FileSystemGCWii.h">
<Filter>FileSystem</Filter>
</ClInclude>
- <ClInclude Include="WiiWad.h">
- <Filter>NAND</Filter>
- </ClInclude>
<ClInclude Include="NANDImporter.h">
<Filter>NAND</Filter>
</ClInclude>
diff --git a/Source/Core/DiscIO/FileSystemGCWii.cpp b/Source/Core/DiscIO/FileSystemGCWii.cpp
index c4e8d4a48e..7e1a3a0015 100644
--- a/Source/Core/DiscIO/FileSystemGCWii.cpp
+++ b/Source/Core/DiscIO/FileSystemGCWii.cpp
@@ -223,7 +223,7 @@ bool FileInfoGCWii::IsValid(u64 fst_size, const FileInfoGCWii& parent_directory)
return true;
}
-FileSystemGCWii::FileSystemGCWii(const Volume* volume, const Partition& partition)
+FileSystemGCWii::FileSystemGCWii(const VolumeDisc* volume, const Partition& partition)
: m_valid(false), m_root(nullptr, 0, 0, 0)
{
u8 offset_shift;
diff --git a/Source/Core/DiscIO/FileSystemGCWii.h b/Source/Core/DiscIO/FileSystemGCWii.h
index 9f7f8f2e6a..8f56c7620f 100644
--- a/Source/Core/DiscIO/FileSystemGCWii.h
+++ b/Source/Core/DiscIO/FileSystemGCWii.h
@@ -17,7 +17,7 @@
namespace DiscIO
{
-class Volume;
+class VolumeDisc;
struct Partition;
class FileInfoGCWii : public FileInfo
@@ -87,7 +87,7 @@ private:
class FileSystemGCWii : public FileSystem
{
public:
- FileSystemGCWii(const Volume* volume, const Partition& partition);
+ FileSystemGCWii(const VolumeDisc* volume, const Partition& partition);
~FileSystemGCWii() override;
bool IsValid() const override { return m_valid; }
diff --git a/Source/Core/DiscIO/Volume.cpp b/Source/Core/DiscIO/Volume.cpp
index e699e46a93..e1f1bbae4e 100644
--- a/Source/Core/DiscIO/Volume.cpp
+++ b/Source/Core/DiscIO/Volume.cpp
@@ -43,30 +43,61 @@ std::map<Language, std::string> Volume::ReadWiiNames(const std::vector<char16_t>
return names;
}
-std::unique_ptr<Volume> CreateVolumeFromFilename(const std::string& filename)
+static std::unique_ptr<VolumeDisc> CreateDisc(std::unique_ptr<BlobReader>& reader)
{
- std::unique_ptr<BlobReader> reader(CreateBlobReader(filename));
- if (reader == nullptr)
- return nullptr;
-
// Check for Wii
const std::optional<u32> wii_magic = reader->ReadSwapped<u32>(0x18);
if (wii_magic == u32(0x5D1C9EA3))
return std::make_unique<VolumeWii>(std::move(reader));
+ // Check for GC
+ const std::optional<u32> gc_magic = reader->ReadSwapped<u32>(0x1C);
+ if (gc_magic == u32(0xC2339F3D))
+ return std::make_unique<VolumeGC>(std::move(reader));
+
+ // No known magic words found
+ return nullptr;
+}
+
+std::unique_ptr<VolumeDisc> CreateDisc(const std::string& path)
+{
+ std::unique_ptr<BlobReader> reader(CreateBlobReader(path));
+ return reader ? CreateDisc(reader) : nullptr;
+}
+
+static std::unique_ptr<VolumeWAD> CreateWAD(std::unique_ptr<BlobReader>& reader)
+{
// Check for WAD
// 0x206962 for boot2 wads
const std::optional<u32> wad_magic = reader->ReadSwapped<u32>(0x02);
if (wad_magic == u32(0x00204973) || wad_magic == u32(0x00206962))
return std::make_unique<VolumeWAD>(std::move(reader));
- // Check for GC
- const std::optional<u32> gc_magic = reader->ReadSwapped<u32>(0x1C);
- if (gc_magic == u32(0xC2339F3D))
- return std::make_unique<VolumeGC>(std::move(reader));
-
// No known magic words found
return nullptr;
}
+std::unique_ptr<VolumeWAD> CreateWAD(const std::string& path)
+{
+ std::unique_ptr<BlobReader> reader(CreateBlobReader(path));
+ return reader ? CreateWAD(reader) : nullptr;
+}
+
+std::unique_ptr<Volume> CreateVolume(const std::string& path)
+{
+ std::unique_ptr<BlobReader> reader(CreateBlobReader(path));
+ if (reader == nullptr)
+ return nullptr;
+
+ std::unique_ptr<VolumeDisc> disc = CreateDisc(reader);
+ if (disc)
+ return disc;
+
+ std::unique_ptr<VolumeWAD> wad = CreateWAD(reader);
+ if (wad)
+ return wad;
+
+ return nullptr;
+}
+
} // namespace DiscIO
diff --git a/Source/Core/DiscIO/Volume.h b/Source/Core/DiscIO/Volume.h
index d331a3d881..ede7a2fc23 100644
--- a/Source/Core/DiscIO/Volume.h
+++ b/Source/Core/DiscIO/Volume.h
@@ -22,6 +22,7 @@ namespace DiscIO
{
enum class BlobType;
class FileSystem;
+class VolumeWAD;
struct Partition final
{
@@ -73,6 +74,7 @@ public:
{
return INVALID_CERT_CHAIN;
}
+ virtual std::vector<u8> GetContent(u16 index) const { return {}; }
virtual std::vector<u64> GetContentOffsets() const { return {}; }
// Returns a non-owning pointer. Returns nullptr if the file system couldn't be read.
virtual const FileSystem* GetFileSystem(const Partition& partition) const = 0;
@@ -141,6 +143,12 @@ protected:
static const std::vector<u8> INVALID_CERT_CHAIN;
};
-std::unique_ptr<Volume> CreateVolumeFromFilename(const std::string& filename);
+class VolumeDisc : public Volume
+{
+};
+
+std::unique_ptr<VolumeDisc> CreateDisc(const std::string& path);
+std::unique_ptr<VolumeWAD> CreateWAD(const std::string& path);
+std::unique_ptr<Volume> CreateVolume(const std::string& path);
} // namespace DiscIO
diff --git a/Source/Core/DiscIO/VolumeGC.h b/Source/Core/DiscIO/VolumeGC.h
index 55ca206d7f..ad950919cf 100644
--- a/Source/Core/DiscIO/VolumeGC.h
+++ b/Source/Core/DiscIO/VolumeGC.h
@@ -25,7 +25,7 @@ enum class Language;
enum class Region;
enum class Platform;
-class VolumeGC : public Volume
+class VolumeGC : public VolumeDisc
{
public:
VolumeGC(std::unique_ptr<BlobReader> reader);
diff --git a/Source/Core/DiscIO/VolumeVerifier.cpp b/Source/Core/DiscIO/VolumeVerifier.cpp
index 5e20803651..55da0d27c6 100644
--- a/Source/Core/DiscIO/VolumeVerifier.cpp
+++ b/Source/Core/DiscIO/VolumeVerifier.cpp
@@ -770,10 +770,7 @@ void VolumeVerifier::Process()
bool VolumeVerifier::CheckContentIntegrity(const IOS::ES::Content& content)
{
- const u64 padded_size = Common::AlignUp(content.size, 0x40);
- std::vector<u8> encrypted_data(padded_size);
- m_volume.Read(m_content_offsets[m_content_index], padded_size, encrypted_data.data(),
- PARTITION_NONE);
+ std::vector<u8> encrypted_data = m_volume.GetContent(content.index);
mbedtls_aes_context context;
const std::array<u8, 16> key = m_volume.GetTicket(PARTITION_NONE).GetTitleKey();
@@ -783,8 +780,8 @@ bool VolumeVerifier::CheckContentIntegrity(const IOS::ES::Content& content)
iv[0] = static_cast<u8>(content.index >> 8);
iv[1] = static_cast<u8>(content.index & 0xFF);
- std::vector<u8> decrypted_data(padded_size);
- mbedtls_aes_crypt_cbc(&context, MBEDTLS_AES_DECRYPT, padded_size, iv.data(),
+ std::vector<u8> decrypted_data(Common::AlignUp(content.size, 0x40));
+ mbedtls_aes_crypt_cbc(&context, MBEDTLS_AES_DECRYPT, decrypted_data.size(), iv.data(),
encrypted_data.data(), decrypted_data.data());
std::array<u8, 20> sha1;
diff --git a/Source/Core/DiscIO/VolumeWad.cpp b/Source/Core/DiscIO/VolumeWad.cpp
index 911708b7c8..e0dda7ebc4 100644
--- a/Source/Core/DiscIO/VolumeWad.cpp
+++ b/Source/Core/DiscIO/VolumeWad.cpp
@@ -61,10 +61,6 @@ VolumeWAD::VolumeWAD(std::unique_ptr<BlobReader> reader) : m_reader(std::move(re
Read(m_cert_chain_offset, m_cert_chain_size, m_cert_chain.data());
}
-VolumeWAD::~VolumeWAD()
-{
-}
-
bool VolumeWAD::Read(u64 offset, u64 length, u8* buffer, const Partition& partition) const
{
if (partition != PARTITION_NONE)
@@ -118,6 +114,24 @@ const std::vector<u8>& VolumeWAD::GetCertificateChain(const Partition& partition
return m_cert_chain;
}
+std::vector<u8> VolumeWAD::GetContent(u16 index) const
+{
+ u64 offset = m_data_offset;
+ for (const IOS::ES::Content& content : m_tmd.GetContents())
+ {
+ const u64 aligned_size = Common::AlignUp(content.size, 0x40);
+ if (content.index == index)
+ {
+ std::vector<u8> data(aligned_size);
+ if (!m_reader->Read(offset, aligned_size, data.data()))
+ return {};
+ return data;
+ }
+ offset += aligned_size;
+ }
+ return {};
+}
+
std::vector<u64> VolumeWAD::GetContentOffsets() const
{
const std::vector<IOS::ES::Content> contents = m_tmd.GetContents();
diff --git a/Source/Core/DiscIO/VolumeWad.h b/Source/Core/DiscIO/VolumeWad.h
index 0052338edb..eb85167a96 100644
--- a/Source/Core/DiscIO/VolumeWad.h
+++ b/Source/Core/DiscIO/VolumeWad.h
@@ -28,7 +28,6 @@ class VolumeWAD : public Volume
{
public:
VolumeWAD(std::unique_ptr<BlobReader> reader);
- ~VolumeWAD();
bool Read(u64 offset, u64 length, u8* buffer,
const Partition& partition = PARTITION_NONE) const override;
const FileSystem* GetFileSystem(const Partition& partition = PARTITION_NONE) const override;
@@ -38,6 +37,7 @@ public:
const IOS::ES::TMDReader& GetTMD(const Partition& partition = PARTITION_NONE) const override;
const std::vector<u8>&
GetCertificateChain(const Partition& partition = PARTITION_NONE) const override;
+ std::vector<u8> GetContent(u16 index) const override;
std::vector<u64> GetContentOffsets() const override;
std::string GetGameID(const Partition& partition = PARTITION_NONE) const override;
std::string GetGameTDBID(const Partition& partition = PARTITION_NONE) const override;
diff --git a/Source/Core/DiscIO/VolumeWii.h b/Source/Core/DiscIO/VolumeWii.h
index 538c52a0b9..38dfc1290b 100644
--- a/Source/Core/DiscIO/VolumeWii.h
+++ b/Source/Core/DiscIO/VolumeWii.h
@@ -27,7 +27,7 @@ enum class Language;
enum class Region;
enum class Platform;
-class VolumeWii : public Volume
+class VolumeWii : public VolumeDisc
{
public:
VolumeWii(std::unique_ptr<BlobReader> reader);
diff --git a/Source/Core/DiscIO/WiiWad.cpp b/Source/Core/DiscIO/WiiWad.cpp
deleted file mode 100644
index e980455779..0000000000
--- a/Source/Core/DiscIO/WiiWad.cpp
+++ /dev/null
@@ -1,112 +0,0 @@
-// Copyright 2009 Dolphin Emulator Project
-// Licensed under GPLv2+
-// Refer to the license.txt file included.
-
-#include <cstddef>
-#include <memory>
-#include <optional>
-#include <string>
-
-#include "Common/Align.h"
-#include "Common/Assert.h"
-#include "Common/CommonTypes.h"
-#include "Common/FileUtil.h"
-#include "Common/Logging/Log.h"
-#include "DiscIO/Blob.h"
-#include "DiscIO/WiiWad.h"
-
-namespace DiscIO
-{
-namespace
-{
-std::vector<u8> CreateWADEntry(BlobReader& reader, u32 size, u64 offset)
-{
- if (size == 0)
- return {};
-
- std::vector<u8> buffer(size);
-
- if (!reader.Read(offset, size, buffer.data()))
- {
- ERROR_LOG(DISCIO, "WiiWAD: Could not read from file");
- PanicAlertT("WiiWAD: Could not read from file");
- }
-
- return buffer;
-}
-
-bool IsWiiWAD(BlobReader& reader)
-{
- const std::optional<u32> header_size = reader.ReadSwapped<u32>(0x0);
- const std::optional<u32> header_type = reader.ReadSwapped<u32>(0x4);
- return header_size == u32(0x20) &&
- (header_type == u32(0x49730000) || header_type == u32(0x69620000));
-}
-} // Anonymous namespace
-
-WiiWAD::WiiWAD(const std::string& name) : WiiWAD(CreateBlobReader(name))
-{
-}
-
-WiiWAD::WiiWAD(std::unique_ptr<BlobReader> blob_reader) : m_reader(std::move(blob_reader))
-{
- if (m_reader)
- m_valid = ParseWAD();
-}
-
-WiiWAD::~WiiWAD() = default;
-
-bool WiiWAD::ParseWAD()
-{
- if (!IsWiiWAD(*m_reader))
- return false;
-
- std::optional<u32> certificate_chain_size = m_reader->ReadSwapped<u32>(0x08);
- std::optional<u32> reserved = m_reader->ReadSwapped<u32>(0x0C);
- std::optional<u32> ticket_size = m_reader->ReadSwapped<u32>(0x10);
- std::optional<u32> tmd_size = m_reader->ReadSwapped<u32>(0x14);
- std::optional<u32> data_app_size = m_reader->ReadSwapped<u32>(0x18);
- std::optional<u32> footer_size = m_reader->ReadSwapped<u32>(0x1C);
- if (!certificate_chain_size || !reserved || !ticket_size || !tmd_size || !data_app_size ||
- !footer_size)
- {
- return false;
- }
-
- if (MAX_LOGLEVEL >= LogTypes::LOG_LEVELS::LDEBUG)
- DEBUG_ASSERT_MSG(BOOT, *reserved == 0x00, "WiiWAD: Reserved must be 0x00");
-
- u32 offset = 0x40;
- m_certificate_chain = CreateWADEntry(*m_reader, *certificate_chain_size, offset);
- offset += Common::AlignUp(*certificate_chain_size, 0x40);
- m_ticket.SetBytes(CreateWADEntry(*m_reader, *ticket_size, offset));
- offset += Common::AlignUp(*ticket_size, 0x40);
- m_tmd.SetBytes(CreateWADEntry(*m_reader, *tmd_size, offset));
- offset += Common::AlignUp(*tmd_size, 0x40);
- m_data_app_offset = offset;
- m_data_app = CreateWADEntry(*m_reader, *data_app_size, offset);
- offset += Common::AlignUp(*data_app_size, 0x40);
- m_footer = CreateWADEntry(*m_reader, *footer_size, offset);
- offset += Common::AlignUp(*footer_size, 0x40);
-
- return true;
-}
-
-std::vector<u8> WiiWAD::GetContent(u16 index) const
-{
- u64 offset = m_data_app_offset;
- for (const IOS::ES::Content& content : m_tmd.GetContents())
- {
- const u64 aligned_size = Common::AlignUp(content.size, 0x40);
- if (content.index == index)
- {
- std::vector<u8> data(aligned_size);
- if (!m_reader->Read(offset, aligned_size, data.data()))
- return {};
- return data;
- }
- offset += aligned_size;
- }
- return {};
-}
-} // namespace DiscIO
diff --git a/Source/Core/DiscIO/WiiWad.h b/Source/Core/DiscIO/WiiWad.h
deleted file mode 100644
index 3e23392c52..0000000000
--- a/Source/Core/DiscIO/WiiWad.h
+++ /dev/null
@@ -1,49 +0,0 @@
-// Copyright 2009 Dolphin Emulator Project
-// Licensed under GPLv2+
-// Refer to the license.txt file included.
-
-#pragma once
-
-#include <memory>
-#include <string>
-#include <vector>
-
-#include "Common/CommonTypes.h"
-#include "Core/IOS/ES/Formats.h"
-
-namespace DiscIO
-{
-class BlobReader;
-
-class WiiWAD
-{
-public:
- explicit WiiWAD(const std::string& name);
- explicit WiiWAD(std::unique_ptr<BlobReader> blob_reader);
- WiiWAD(WiiWAD&&) = default;
- WiiWAD& operator=(WiiWAD&&) = default;
- ~WiiWAD();
-
- bool IsValid() const { return m_valid; }
- const std::vector<u8>& GetCertificateChain() const { return m_certificate_chain; }
- const IOS::ES::TicketReader& GetTicket() const { return m_ticket; }
- const IOS::ES::TMDReader& GetTMD() const { return m_tmd; }
- const std::vector<u8>& GetDataApp() const { return m_data_app; }
- const std::vector<u8>& GetFooter() const { return m_footer; }
- std::vector<u8> GetContent(u16 index) const;
-
-private:
- bool ParseWAD();
-
- bool m_valid = false;
-
- std::unique_ptr<BlobReader> m_reader;
-
- u64 m_data_app_offset = 0;
- std::vector<u8> m_certificate_chain;
- IOS::ES::TicketReader m_ticket;
- IOS::ES::TMDReader m_tmd;
- std::vector<u8> m_data_app;
- std::vector<u8> m_footer;
-};
-} // namespace DiscIO