From 0f5a4b37ee8e00210b211953969f10bfb48c5aaa Mon Sep 17 00:00:00 2001 From: JosJuice Date: Sun, 14 Jul 2019 15:49:42 +0200 Subject: [PATCH 1/2] DiscIO: Add functions CreateDisc and CreateWAD ...in addition to the existing function CreateVolume (renamed from CreateVolumeFromFilename). Lets code easily add constraints such as not letting the user select a WAD file when using the disc changing functionality. --- Source/Core/Core/Boot/Boot.cpp | 25 ++++----- Source/Core/Core/Boot/Boot.h | 14 ++--- Source/Core/Core/Boot/Boot_BS2Emu.cpp | 8 +-- Source/Core/Core/HW/DVD/DVDInterface.cpp | 9 ++-- Source/Core/Core/HW/DVD/DVDInterface.h | 4 +- Source/Core/Core/WiiUtils.cpp | 5 +- Source/Core/DiscIO/CompressedBlob.cpp | 4 +- Source/Core/DiscIO/FileSystemGCWii.cpp | 2 +- Source/Core/DiscIO/FileSystemGCWii.h | 4 +- Source/Core/DiscIO/Volume.cpp | 53 +++++++++++++++---- Source/Core/DiscIO/Volume.h | 9 +++- Source/Core/DiscIO/VolumeGC.h | 2 +- Source/Core/DiscIO/VolumeWii.h | 2 +- .../DolphinQt/Config/PropertiesDialog.cpp | 2 +- Source/Core/UICommon/GameFile.cpp | 2 +- 15 files changed, 91 insertions(+), 54 deletions(-) diff --git a/Source/Core/Core/Boot/Boot.cpp b/Source/Core/Core/Boot/Boot.cpp index 6803ddd413..a8c0bd762e 100644 --- a/Source/Core/Core/Boot/Boot.cpp +++ b/Source/Core/Core/Boot/Boot.cpp @@ -161,10 +161,10 @@ BootParameters::GenerateFromFile(std::vector paths, {".gcm", ".iso", ".tgc", ".wbfs", ".ciso", ".gcz", ".dol", ".elf"}}; if (disc_image_extensions.find(extension) != disc_image_extensions.end() || is_drive) { - std::unique_ptr volume = DiscIO::CreateVolumeFromFilename(path); - if (volume) + std::unique_ptr disc = DiscIO::CreateDisc(path); + if (disc) { - return std::make_unique(Disc{std::move(path), std::move(volume), paths}, + return std::make_unique(Disc{std::move(path), std::move(disc), paths}, savestate_path); } @@ -221,19 +221,19 @@ BootParameters::IPL::IPL(DiscIO::Region region_, Disc&& disc_) : IPL(region_) // Inserts a disc into the emulated disc drive and returns a pointer to it. // The returned pointer must only be used while we are still booting, // because DVDThread can do whatever it wants to the disc after that. -static const DiscIO::Volume* SetDisc(std::unique_ptr volume, - std::vector auto_disc_change_paths = {}) +static const DiscIO::VolumeDisc* SetDisc(std::unique_ptr disc, + std::vector auto_disc_change_paths = {}) { - const DiscIO::Volume* pointer = volume.get(); - DVDInterface::SetDisc(std::move(volume), auto_disc_change_paths); + const DiscIO::VolumeDisc* pointer = disc.get(); + DVDInterface::SetDisc(std::move(disc), auto_disc_change_paths); return pointer; } -bool CBoot::DVDRead(const DiscIO::Volume& volume, u64 dvd_offset, u32 output_address, u32 length, +bool CBoot::DVDRead(const DiscIO::VolumeDisc& disc, u64 dvd_offset, u32 output_address, u32 length, const DiscIO::Partition& partition) { std::vector buffer(length); - if (!volume.Read(dvd_offset, length, buffer.data(), partition)) + if (!disc.Read(dvd_offset, length, buffer.data(), partition)) return false; Memory::CopyToEmu(output_address, buffer.data(), length); return true; @@ -365,7 +365,7 @@ static void SetDefaultDisc() { const std::string default_iso = Config::Get(Config::MAIN_DEFAULT_ISO); if (!default_iso.empty()) - SetDisc(DiscIO::CreateVolumeFromFilename(default_iso)); + SetDisc(DiscIO::CreateDisc(default_iso)); } static void CopyDefaultExceptionHandlers() @@ -401,7 +401,8 @@ bool CBoot::BootUp(std::unique_ptr boot) bool operator()(BootParameters::Disc& disc) const { NOTICE_LOG(BOOT, "Booting from disc: %s", disc.path.c_str()); - const DiscIO::Volume* volume = SetDisc(std::move(disc.volume), disc.auto_disc_change_paths); + const DiscIO::VolumeDisc* volume = + SetDisc(std::move(disc.volume), disc.auto_disc_change_paths); if (!volume) return false; @@ -495,7 +496,7 @@ bool CBoot::BootUp(std::unique_ptr boot) if (ipl.disc) { NOTICE_LOG(BOOT, "Inserting disc: %s", ipl.disc->path.c_str()); - SetDisc(DiscIO::CreateVolumeFromFilename(ipl.disc->path), ipl.disc->auto_disc_change_paths); + SetDisc(DiscIO::CreateDisc(ipl.disc->path), ipl.disc->auto_disc_change_paths); } if (LoadMapFromFilename()) diff --git a/Source/Core/Core/Boot/Boot.h b/Source/Core/Core/Boot/Boot.h index 7cb7b39989..e294ee01c8 100644 --- a/Source/Core/Core/Boot/Boot.h +++ b/Source/Core/Core/Boot/Boot.h @@ -39,7 +39,7 @@ struct BootParameters struct Disc { std::string path; - std::unique_ptr volume; + std::unique_ptr volume; std::vector auto_disc_change_paths; }; @@ -102,8 +102,8 @@ public: static bool LoadMapFromFilename(); private: - static bool DVDRead(const DiscIO::Volume& volume, u64 dvd_offset, u32 output_address, u32 length, - const DiscIO::Partition& partition); + static bool DVDRead(const DiscIO::VolumeDisc& disc, u64 dvd_offset, u32 output_address, + u32 length, const DiscIO::Partition& partition); static void RunFunction(u32 address); static void UpdateDebugger_MapLoaded(); @@ -113,10 +113,10 @@ private: static void SetupMSR(); static void SetupBAT(bool is_wii); - static bool RunApploader(bool is_wii, const DiscIO::Volume& volume); - static bool EmulatedBS2_GC(const DiscIO::Volume& volume); - static bool EmulatedBS2_Wii(const DiscIO::Volume& volume); - static bool EmulatedBS2(bool is_wii, const DiscIO::Volume& volume); + static bool RunApploader(bool is_wii, const DiscIO::VolumeDisc& volume); + static bool EmulatedBS2_GC(const DiscIO::VolumeDisc& volume); + static bool EmulatedBS2_Wii(const DiscIO::VolumeDisc& volume); + static bool EmulatedBS2(bool is_wii, const DiscIO::VolumeDisc& volume); static bool Load_BS2(const std::string& boot_rom_filename); static void SetupGCMemory(); diff --git a/Source/Core/Core/Boot/Boot_BS2Emu.cpp b/Source/Core/Core/Boot/Boot_BS2Emu.cpp index d54df416fe..208c02e13a 100644 --- a/Source/Core/Core/Boot/Boot_BS2Emu.cpp +++ b/Source/Core/Core/Boot/Boot_BS2Emu.cpp @@ -85,7 +85,7 @@ void CBoot::SetupBAT(bool is_wii) PowerPC::IBATUpdated(); } -bool CBoot::RunApploader(bool is_wii, const DiscIO::Volume& volume) +bool CBoot::RunApploader(bool is_wii, const DiscIO::VolumeDisc& volume) { const DiscIO::Partition partition = volume.GetGamePartition(); @@ -200,7 +200,7 @@ void CBoot::SetupGCMemory() // GameCube Bootstrap 2 HLE: // copy the apploader to 0x81200000 // execute the apploader, function by function, using the above utility. -bool CBoot::EmulatedBS2_GC(const DiscIO::Volume& volume) +bool CBoot::EmulatedBS2_GC(const DiscIO::VolumeDisc& volume) { INFO_LOG(BOOT, "Faking GC BS2..."); @@ -366,7 +366,7 @@ static void WriteEmptyPlayRecord() // Wii Bootstrap 2 HLE: // copy the apploader to 0x81200000 // execute the apploader -bool CBoot::EmulatedBS2_Wii(const DiscIO::Volume& volume) +bool CBoot::EmulatedBS2_Wii(const DiscIO::VolumeDisc& volume) { INFO_LOG(BOOT, "Faking Wii BS2..."); if (volume.GetVolumeType() != DiscIO::Platform::WiiDisc) @@ -426,7 +426,7 @@ bool CBoot::EmulatedBS2_Wii(const DiscIO::Volume& volume) // Returns true if apploader has run successfully. If is_wii is true, the disc // that volume refers to must currently be inserted into the emulated disc drive. -bool CBoot::EmulatedBS2(bool is_wii, const DiscIO::Volume& volume) +bool CBoot::EmulatedBS2(bool is_wii, const DiscIO::VolumeDisc& volume) { return is_wii ? EmulatedBS2_Wii(volume) : EmulatedBS2_GC(volume); } diff --git a/Source/Core/Core/HW/DVD/DVDInterface.cpp b/Source/Core/Core/HW/DVD/DVDInterface.cpp index 775c67ca70..fdab3845e8 100644 --- a/Source/Core/Core/HW/DVD/DVDInterface.cpp +++ b/Source/Core/Core/HW/DVD/DVDInterface.cpp @@ -470,7 +470,7 @@ void Shutdown() DVDThread::Stop(); } -void SetDisc(std::unique_ptr disc, +void SetDisc(std::unique_ptr disc, std::optional> auto_disc_change_paths = {}) { if (disc) @@ -506,11 +506,10 @@ static void EjectDiscCallback(u64 userdata, s64 cyclesLate) static void InsertDiscCallback(u64 userdata, s64 cyclesLate) { - std::unique_ptr new_volume = - DiscIO::CreateVolumeFromFilename(s_disc_path_to_insert); + std::unique_ptr new_disc = DiscIO::CreateDisc(s_disc_path_to_insert); - if (new_volume) - SetDisc(std::move(new_volume), {}); + if (new_disc) + SetDisc(std::move(new_disc), {}); else PanicAlertT("The disc that was about to be inserted couldn't be found."); diff --git a/Source/Core/Core/HW/DVD/DVDInterface.h b/Source/Core/Core/HW/DVD/DVDInterface.h index 1239bbf5f1..f7da0728c9 100644 --- a/Source/Core/Core/HW/DVD/DVDInterface.h +++ b/Source/Core/Core/HW/DVD/DVDInterface.h @@ -14,7 +14,7 @@ class PointerWrap; namespace DiscIO { -class Volume; +class VolumeDisc; struct Partition; } // namespace DiscIO namespace MMIO @@ -81,7 +81,7 @@ void DoState(PointerWrap& p); void RegisterMMIO(MMIO::Mapping* mmio, u32 base); -void SetDisc(std::unique_ptr disc, +void SetDisc(std::unique_ptr disc, std::optional> auto_disc_change_paths); bool IsDiscInside(); void EjectDisc(); // Must only be called on the CPU thread diff --git a/Source/Core/Core/WiiUtils.cpp b/Source/Core/Core/WiiUtils.cpp index 4c68509f8a..78f0f0230a 100644 --- a/Source/Core/Core/WiiUtils.cpp +++ b/Source/Core/Core/WiiUtils.cpp @@ -581,8 +581,7 @@ class DiscSystemUpdater final : public SystemUpdater { public: DiscSystemUpdater(UpdateCallback update_callback, const std::string& image_path) - : m_update_callback{std::move(update_callback)}, m_volume{DiscIO::CreateVolumeFromFilename( - image_path)} + : m_update_callback{std::move(update_callback)}, m_volume{DiscIO::CreateDisc(image_path)} { } UpdateResult DoDiscUpdate(); @@ -621,7 +620,7 @@ private: std::string_view path); UpdateCallback m_update_callback; - std::unique_ptr m_volume; + std::unique_ptr m_volume; DiscIO::Partition m_partition; }; 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; + std::unique_ptr 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/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,23 +43,13 @@ std::map Volume::ReadWiiNames(const std::vector return names; } -std::unique_ptr CreateVolumeFromFilename(const std::string& filename) +static std::unique_ptr CreateDisc(std::unique_ptr& reader) { - std::unique_ptr reader(CreateBlobReader(filename)); - if (reader == nullptr) - return nullptr; - // Check for Wii const std::optional wii_magic = reader->ReadSwapped(0x18); if (wii_magic == u32(0x5D1C9EA3)) return std::make_unique(std::move(reader)); - // Check for WAD - // 0x206962 for boot2 wads - const std::optional wad_magic = reader->ReadSwapped(0x02); - if (wad_magic == u32(0x00204973) || wad_magic == u32(0x00206962)) - return std::make_unique(std::move(reader)); - // Check for GC const std::optional gc_magic = reader->ReadSwapped(0x1C); if (gc_magic == u32(0xC2339F3D)) @@ -69,4 +59,45 @@ std::unique_ptr CreateVolumeFromFilename(const std::string& filename) return nullptr; } +std::unique_ptr CreateDisc(const std::string& path) +{ + std::unique_ptr reader(CreateBlobReader(path)); + return reader ? CreateDisc(reader) : nullptr; +} + +static std::unique_ptr CreateWAD(std::unique_ptr& reader) +{ + // Check for WAD + // 0x206962 for boot2 wads + const std::optional wad_magic = reader->ReadSwapped(0x02); + if (wad_magic == u32(0x00204973) || wad_magic == u32(0x00206962)) + return std::make_unique(std::move(reader)); + + // No known magic words found + return nullptr; +} + +std::unique_ptr CreateWAD(const std::string& path) +{ + std::unique_ptr reader(CreateBlobReader(path)); + return reader ? CreateWAD(reader) : nullptr; +} + +std::unique_ptr CreateVolume(const std::string& path) +{ + std::unique_ptr reader(CreateBlobReader(path)); + if (reader == nullptr) + return nullptr; + + std::unique_ptr disc = CreateDisc(reader); + if (disc) + return disc; + + std::unique_ptr 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..e7b22ac878 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 { @@ -141,6 +142,12 @@ protected: static const std::vector INVALID_CERT_CHAIN; }; -std::unique_ptr CreateVolumeFromFilename(const std::string& filename); +class VolumeDisc : public Volume +{ +}; + +std::unique_ptr CreateDisc(const std::string& path); +std::unique_ptr CreateWAD(const std::string& path); +std::unique_ptr 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 reader); 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 reader); diff --git a/Source/Core/DolphinQt/Config/PropertiesDialog.cpp b/Source/Core/DolphinQt/Config/PropertiesDialog.cpp index 6aae9bef5d..e84ddc558a 100644 --- a/Source/Core/DolphinQt/Config/PropertiesDialog.cpp +++ b/Source/Core/DolphinQt/Config/PropertiesDialog.cpp @@ -60,7 +60,7 @@ PropertiesDialog::PropertiesDialog(QWidget* parent, const UICommon::GameFile& ga if (game.GetPlatform() != DiscIO::Platform::ELFOrDOL) { - std::shared_ptr volume = DiscIO::CreateVolumeFromFilename(game.GetFilePath()); + std::shared_ptr volume = DiscIO::CreateVolume(game.GetFilePath()); if (volume) { VerifyWidget* verify = new VerifyWidget(volume); diff --git a/Source/Core/UICommon/GameFile.cpp b/Source/Core/UICommon/GameFile.cpp index fb8c3d0a67..5431face3a 100644 --- a/Source/Core/UICommon/GameFile.cpp +++ b/Source/Core/UICommon/GameFile.cpp @@ -121,7 +121,7 @@ GameFile::GameFile(std::string path) : m_file_path(std::move(path)) SplitPath(m_file_path, nullptr, &name, &extension); m_file_name = name + extension; - std::unique_ptr volume(DiscIO::CreateVolumeFromFilename(m_file_path)); + std::unique_ptr volume(DiscIO::CreateVolume(m_file_path)); if (volume != nullptr) { m_platform = volume->GetVolumeType(); From 34f32898e63e7dd5d0251fd630f8d569432c9ac3 Mon Sep 17 00:00:00 2001 From: JosJuice Date: Sun, 14 Jul 2019 18:00:14 +0200 Subject: [PATCH 2/2] DiscIO: Merge WiiWAD into VolumeWAD These two classes are very similar, so let's merge them. --- Source/Core/Core/Boot/Boot.cpp | 9 +- Source/Core/Core/Boot/Boot.h | 6 +- Source/Core/Core/Boot/Boot_WiiWAD.cpp | 4 +- Source/Core/Core/ConfigManager.cpp | 6 +- Source/Core/Core/WiiUtils.cpp | 16 ++-- Source/Core/Core/WiiUtils.h | 6 +- Source/Core/DiscIO/CMakeLists.txt | 2 - Source/Core/DiscIO/DiscIO.vcxproj | 2 - Source/Core/DiscIO/DiscIO.vcxproj.filters | 6 -- Source/Core/DiscIO/Volume.h | 1 + Source/Core/DiscIO/VolumeVerifier.cpp | 9 +- Source/Core/DiscIO/VolumeWad.cpp | 22 ++++- Source/Core/DiscIO/VolumeWad.h | 2 +- Source/Core/DiscIO/WiiWad.cpp | 112 ---------------------- Source/Core/DiscIO/WiiWad.h | 49 ---------- 15 files changed, 51 insertions(+), 201 deletions(-) delete mode 100644 Source/Core/DiscIO/WiiWad.cpp delete mode 100644 Source/Core/DiscIO/WiiWad.h diff --git a/Source/Core/Core/Boot/Boot.cpp b/Source/Core/Core/Boot/Boot.cpp index a8c0bd762e..179afdaa92 100644 --- a/Source/Core/Core/Boot/Boot.cpp +++ b/Source/Core/Core/Boot/Boot.cpp @@ -59,6 +59,7 @@ namespace fs = std::filesystem; #include "DiscIO/Enums.h" #include "DiscIO/Volume.h" +#include "DiscIO/VolumeWad.h" static std::vector ReadM3UFile(const std::string& m3u_path, const std::string& folder_path) @@ -201,7 +202,11 @@ BootParameters::GenerateFromFile(std::vector paths, return std::make_unique(DFF{std::move(path)}, savestate_path); if (extension == ".wad") - return std::make_unique(DiscIO::WiiWAD{std::move(path)}, savestate_path); + { + std::unique_ptr wad = DiscIO::CreateWAD(std::move(path)); + if (wad) + return std::make_unique(std::move(*wad), savestate_path); + } PanicAlertT("Could not recognize file %s", path.c_str()); return {}; @@ -466,7 +471,7 @@ bool CBoot::BootUp(std::unique_ptr boot) return true; } - bool operator()(const DiscIO::WiiWAD& wad) const + bool operator()(const DiscIO::VolumeWAD& wad) const { SetDefaultDisc(); return Boot_WiiWAD(wad); diff --git a/Source/Core/Core/Boot/Boot.h b/Source/Core/Core/Boot/Boot.h index e294ee01c8..2118993ca0 100644 --- a/Source/Core/Core/Boot/Boot.h +++ b/Source/Core/Core/Boot/Boot.h @@ -17,7 +17,7 @@ #include "DiscIO/Blob.h" #include "DiscIO/Enums.h" #include "DiscIO/Volume.h" -#include "DiscIO/WiiWad.h" +#include "DiscIO/VolumeWad.h" namespace File { @@ -75,7 +75,7 @@ struct BootParameters GenerateFromFile(std::vector paths, const std::optional& savestate_path = {}); - using Parameters = std::variant; + using Parameters = std::variant; BootParameters(Parameters&& parameters_, const std::optional& savestate_path_ = {}); Parameters parameters; @@ -108,7 +108,7 @@ private: static void UpdateDebugger_MapLoaded(); - static bool Boot_WiiWAD(const DiscIO::WiiWAD& wad); + static bool Boot_WiiWAD(const DiscIO::VolumeWAD& wad); static bool BootNANDTitle(u64 title_id); static void SetupMSR(); diff --git a/Source/Core/Core/Boot/Boot_WiiWAD.cpp b/Source/Core/Core/Boot/Boot_WiiWAD.cpp index 8c0fed08dd..cf383371ca 100644 --- a/Source/Core/Core/Boot/Boot_WiiWAD.cpp +++ b/Source/Core/Core/Boot/Boot_WiiWAD.cpp @@ -15,7 +15,7 @@ #include "Core/IOS/IOS.h" #include "Core/IOS/IOSC.h" #include "Core/WiiUtils.h" -#include "DiscIO/WiiWad.h" +#include "DiscIO/VolumeWad.h" bool CBoot::BootNANDTitle(const u64 title_id) { @@ -34,7 +34,7 @@ bool CBoot::BootNANDTitle(const u64 title_id) return es->LaunchTitle(title_id); } -bool CBoot::Boot_WiiWAD(const DiscIO::WiiWAD& wad) +bool CBoot::Boot_WiiWAD(const DiscIO::VolumeWAD& wad) { if (!WiiUtils::InstallWAD(*IOS::HLE::GetIOS(), wad, WiiUtils::InstallType::Temporary)) { diff --git a/Source/Core/Core/ConfigManager.cpp b/Source/Core/Core/ConfigManager.cpp index 128829721d..68cf1457a1 100644 --- a/Source/Core/Core/ConfigManager.cpp +++ b/Source/Core/Core/ConfigManager.cpp @@ -49,7 +49,7 @@ #include "DiscIO/Enums.h" #include "DiscIO/Volume.h" -#include "DiscIO/WiiWad.h" +#include "DiscIO/VolumeWad.h" SConfig* SConfig::m_Instance; @@ -888,9 +888,9 @@ struct SetGameMetadata return true; } - bool operator()(const DiscIO::WiiWAD& wad) const + bool operator()(const DiscIO::VolumeWAD& wad) const { - if (!wad.IsValid() || !wad.GetTMD().IsValid()) + if (!wad.GetTMD().IsValid()) { PanicAlertT("This WAD is not valid."); return false; diff --git a/Source/Core/Core/WiiUtils.cpp b/Source/Core/Core/WiiUtils.cpp index 78f0f0230a..c8e8bf9b20 100644 --- a/Source/Core/Core/WiiUtils.cpp +++ b/Source/Core/Core/WiiUtils.cpp @@ -42,13 +42,13 @@ #include "DiscIO/Filesystem.h" #include "DiscIO/Volume.h" #include "DiscIO/VolumeFileBlobReader.h" -#include "DiscIO/WiiWad.h" +#include "DiscIO/VolumeWad.h" namespace WiiUtils { -static bool ImportWAD(IOS::HLE::Kernel& ios, const DiscIO::WiiWAD& wad) +static bool ImportWAD(IOS::HLE::Kernel& ios, const DiscIO::VolumeWAD& wad) { - if (!wad.IsValid()) + if (!wad.GetTicket().IsValid() || !wad.GetTMD().IsValid()) { PanicAlertT("WAD installation failed: The selected file is not a valid WAD."); return false; @@ -110,7 +110,7 @@ static bool ImportWAD(IOS::HLE::Kernel& ios, const DiscIO::WiiWAD& wad) return true; } -bool InstallWAD(IOS::HLE::Kernel& ios, const DiscIO::WiiWAD& wad, InstallType install_type) +bool InstallWAD(IOS::HLE::Kernel& ios, const DiscIO::VolumeWAD& wad, InstallType install_type) { if (!wad.GetTMD().IsValid()) return false; @@ -164,8 +164,12 @@ bool InstallWAD(IOS::HLE::Kernel& ios, const DiscIO::WiiWAD& wad, InstallType in bool InstallWAD(const std::string& wad_path) { + std::unique_ptr wad = DiscIO::CreateWAD(wad_path); + if (!wad) + return false; + IOS::HLE::Kernel ios; - return InstallWAD(ios, DiscIO::WiiWAD{wad_path}, InstallType::Permanent); + return InstallWAD(ios, *wad, InstallType::Permanent); } bool UninstallTitle(u64 title_id) @@ -734,7 +738,7 @@ UpdateResult DiscSystemUpdater::ProcessEntry(u32 type, std::bitset<32> attrs, ERROR_LOG(CORE, "Could not find %s", std::string(path).c_str()); return UpdateResult::DiscReadFailed; } - const DiscIO::WiiWAD wad{std::move(blob)}; + const DiscIO::VolumeWAD wad{std::move(blob)}; return ImportWAD(m_ios, wad) ? UpdateResult::Succeeded : UpdateResult::ImportFailed; } diff --git a/Source/Core/Core/WiiUtils.h b/Source/Core/Core/WiiUtils.h index 3004897bb6..3936dfac8a 100644 --- a/Source/Core/Core/WiiUtils.h +++ b/Source/Core/Core/WiiUtils.h @@ -15,7 +15,7 @@ namespace DiscIO { -class WiiWAD; +class VolumeWAD; } namespace IOS::HLE @@ -31,8 +31,8 @@ enum class InstallType Temporary, }; -bool InstallWAD(IOS::HLE::Kernel& ios, const DiscIO::WiiWAD& wad, InstallType type); -// Same as the above, but constructs a temporary IOS and WiiWAD instance for importing +bool InstallWAD(IOS::HLE::Kernel& ios, const DiscIO::VolumeWAD& wad, InstallType type); +// Same as the above, but constructs a temporary IOS and VolumeWAD instance for importing // and does a permanent install. bool InstallWAD(const std::string& wad_path); 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/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 @@ - @@ -81,7 +80,6 @@ - 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 @@ FileSystem - - NAND - NAND @@ -98,9 +95,6 @@ FileSystem - - NAND - NAND diff --git a/Source/Core/DiscIO/Volume.h b/Source/Core/DiscIO/Volume.h index e7b22ac878..ede7a2fc23 100644 --- a/Source/Core/DiscIO/Volume.h +++ b/Source/Core/DiscIO/Volume.h @@ -74,6 +74,7 @@ public: { return INVALID_CERT_CHAIN; } + virtual std::vector GetContent(u16 index) const { return {}; } virtual std::vector 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; 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 encrypted_data(padded_size); - m_volume.Read(m_content_offsets[m_content_index], padded_size, encrypted_data.data(), - PARTITION_NONE); + std::vector encrypted_data = m_volume.GetContent(content.index); mbedtls_aes_context context; const std::array key = m_volume.GetTicket(PARTITION_NONE).GetTitleKey(); @@ -783,8 +780,8 @@ bool VolumeVerifier::CheckContentIntegrity(const IOS::ES::Content& content) iv[0] = static_cast(content.index >> 8); iv[1] = static_cast(content.index & 0xFF); - std::vector decrypted_data(padded_size); - mbedtls_aes_crypt_cbc(&context, MBEDTLS_AES_DECRYPT, padded_size, iv.data(), + std::vector 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 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 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& VolumeWAD::GetCertificateChain(const Partition& partition return m_cert_chain; } +std::vector 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 data(aligned_size); + if (!m_reader->Read(offset, aligned_size, data.data())) + return {}; + return data; + } + offset += aligned_size; + } + return {}; +} + std::vector VolumeWAD::GetContentOffsets() const { const std::vector 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 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& GetCertificateChain(const Partition& partition = PARTITION_NONE) const override; + std::vector GetContent(u16 index) const override; std::vector 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/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 -#include -#include -#include - -#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 CreateWADEntry(BlobReader& reader, u32 size, u64 offset) -{ - if (size == 0) - return {}; - - std::vector 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 header_size = reader.ReadSwapped(0x0); - const std::optional header_type = reader.ReadSwapped(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 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 certificate_chain_size = m_reader->ReadSwapped(0x08); - std::optional reserved = m_reader->ReadSwapped(0x0C); - std::optional ticket_size = m_reader->ReadSwapped(0x10); - std::optional tmd_size = m_reader->ReadSwapped(0x14); - std::optional data_app_size = m_reader->ReadSwapped(0x18); - std::optional footer_size = m_reader->ReadSwapped(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 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 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 -#include -#include - -#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 blob_reader); - WiiWAD(WiiWAD&&) = default; - WiiWAD& operator=(WiiWAD&&) = default; - ~WiiWAD(); - - bool IsValid() const { return m_valid; } - const std::vector& 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& GetDataApp() const { return m_data_app; } - const std::vector& GetFooter() const { return m_footer; } - std::vector GetContent(u16 index) const; - -private: - bool ParseWAD(); - - bool m_valid = false; - - std::unique_ptr m_reader; - - u64 m_data_app_offset = 0; - std::vector m_certificate_chain; - IOS::ES::TicketReader m_ticket; - IOS::ES::TMDReader m_tmd; - std::vector m_data_app; - std::vector m_footer; -}; -} // namespace DiscIO