From dedb61e5bfec7827166b0a3b5d2b21e414b8c35a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9o=20Lam?= Date: Tue, 3 Oct 2017 16:07:28 +0200 Subject: [PATCH] Boot: Install WADs temporarily Because the Wii NAND size is finite, mark titles that were installed only for booting as temporary, and remove them whenever we need to install another title (to make room). This is exactly what the System Menu does for temporary SD card title data. --- Source/Core/Core/Boot/Boot_WiiWAD.cpp | 2 +- Source/Core/Core/WiiUtils.cpp | 35 ++++++++++++++++++++++----- Source/Core/Core/WiiUtils.h | 11 +++++++-- 3 files changed, 39 insertions(+), 9 deletions(-) diff --git a/Source/Core/Core/Boot/Boot_WiiWAD.cpp b/Source/Core/Core/Boot/Boot_WiiWAD.cpp index 58af4ae961..fd62f17cf8 100644 --- a/Source/Core/Core/Boot/Boot_WiiWAD.cpp +++ b/Source/Core/Core/Boot/Boot_WiiWAD.cpp @@ -38,7 +38,7 @@ bool CBoot::BootNANDTitle(const u64 title_id) bool CBoot::Boot_WiiWAD(const DiscIO::WiiWAD& wad) { - if (!WiiUtils::InstallWAD(*IOS::HLE::GetIOS(), wad)) + if (!WiiUtils::InstallWAD(*IOS::HLE::GetIOS(), wad, WiiUtils::InstallType::Temporary)) { PanicAlertT("Cannot boot this WAD because it could not be installed to the NAND."); return false; diff --git a/Source/Core/Core/WiiUtils.cpp b/Source/Core/Core/WiiUtils.cpp index 2f2c2287bc..bde5e04a10 100644 --- a/Source/Core/Core/WiiUtils.cpp +++ b/Source/Core/Core/WiiUtils.cpp @@ -29,6 +29,7 @@ #include "Common/NandPaths.h" #include "Common/StringUtil.h" #include "Common/Swap.h" +#include "Common/SysConf.h" #include "Core/CommonTitles.h" #include "Core/ConfigManager.h" #include "Core/IOS/Device.h" @@ -109,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) +bool InstallWAD(IOS::HLE::Kernel& ios, const DiscIO::WiiWAD& wad, InstallType install_type) { if (!wad.GetTMD().IsValid()) return false; @@ -121,20 +122,42 @@ bool InstallWAD(IOS::HLE::Kernel& ios, const DiscIO::WiiWAD& wad) // If a different version is currently installed, warn the user to make sure // they don't overwrite the current version by mistake. - if (ios.GetES()->FindInstalledTMD(wad.GetTMD().GetTitleId()).IsValid() && - !AskYesNoT("A different version of this title is already installed on the NAND. " - "Installing this WAD will replace it irreversibly. Continue?")) + const u64 title_id = wad.GetTMD().GetTitleId(); + const IOS::ES::TMDReader installed_tmd = ios.GetES()->FindInstalledTMD(title_id); + const bool has_another_version = + installed_tmd.IsValid() && installed_tmd.GetTitleVersion() != wad.GetTMD().GetTitleVersion(); + if (has_another_version && + !AskYesNoT("A different version of this title is already installed on the NAND.\n\n" + "Installed version: %u\nWAD version: %u\n\n" + "Installing this WAD will replace it irreversibly. Continue?", + installed_tmd.GetTitleVersion(), wad.GetTMD().GetTitleVersion())) { return false; } - return ImportWAD(ios, wad); + // Delete a previous temporary title, if it exists. + SysConf sysconf{Common::FROM_SESSION_ROOT}; + SysConf::Entry* tid_entry = sysconf.GetOrAddEntry("IPL.TID", SysConf::Entry::Type::LongLong); + if (const u64 previous_temporary_title_id = Common::swap64(tid_entry->GetData(0))) + ios.GetES()->DeleteTitleContent(previous_temporary_title_id); + + if (!ImportWAD(ios, wad)) + return false; + + // Keep track of the title ID so this title can be removed to make room for any future install. + // We use the same mechanism as the System Menu for temporary SD card title data. + if (!has_another_version && install_type == InstallType::Temporary) + tid_entry->SetData(Common::swap64(title_id)); + else + tid_entry->SetData(0); + + return true; } bool InstallWAD(const std::string& wad_path) { IOS::HLE::Kernel ios; - return InstallWAD(ios, DiscIO::WiiWAD{wad_path}); + return InstallWAD(ios, DiscIO::WiiWAD{wad_path}, InstallType::Permanent); } // Common functionality for system updaters. diff --git a/Source/Core/Core/WiiUtils.h b/Source/Core/Core/WiiUtils.h index eb7d669672..b07863fa3b 100644 --- a/Source/Core/Core/WiiUtils.h +++ b/Source/Core/Core/WiiUtils.h @@ -27,8 +27,15 @@ class Kernel; namespace WiiUtils { -bool InstallWAD(IOS::HLE::Kernel& ios, const DiscIO::WiiWAD& wad); -// Same as the above, but constructs a temporary IOS and WiiWAD instance for importing. +enum class InstallType +{ + Permanent, + 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 +// and does a permanent install. bool InstallWAD(const std::string& wad_path); enum class UpdateResult