From d396944487d27f85800f4a3a3f8c1645e8120ab5 Mon Sep 17 00:00:00 2001 From: PabloMK7 Date: Fri, 21 Oct 2022 01:12:29 +0200 Subject: [PATCH] Fix self updating ncch app jump --- src/common/file_util.cpp | 4 ---- src/common/file_util.h | 2 -- src/core/core.cpp | 18 ++++++++++++++++++ src/core/core.h | 7 +++++-- src/core/hle/service/am/am.cpp | 11 ++++++----- 5 files changed, 29 insertions(+), 13 deletions(-) diff --git a/src/common/file_util.cpp b/src/common/file_util.cpp index 9ec740b36..436d94406 100644 --- a/src/common/file_util.cpp +++ b/src/common/file_util.cpp @@ -738,10 +738,6 @@ void SetCurrentRomPath(const std::string& path) { g_currentRomPath = path; } -const std::string& GetCurrentRomPath() { - return g_currentRomPath; -} - bool StringReplace(std::string& haystack, const std::string& a, const std::string& b, bool swap) { const auto& needle = swap ? b : a; const auto& replacement = swap ? a : b; diff --git a/src/common/file_util.h b/src/common/file_util.h index 24198d80b..cdd55b665 100644 --- a/src/common/file_util.h +++ b/src/common/file_util.h @@ -182,8 +182,6 @@ void SetUserPath(const std::string& path = ""); void SetCurrentRomPath(const std::string& path); -const std::string& GetCurrentRomPath(); - // Returns a pointer to a string with a Citra data dir in the user's home // directory. To be used in "multi-user" mode (that is, installed). [[nodiscard]] const std::string& GetUserPath(UserPath path); diff --git a/src/core/core.cpp b/src/core/core.cpp index 3e364ae43..7c4f557b8 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -31,6 +31,7 @@ #include "core/hle/kernel/kernel.h" #include "core/hle/kernel/process.h" #include "core/hle/kernel/thread.h" +#include "core/hle/service/am/am.h" #include "core/hle/service/apt/applet_manager.h" #include "core/hle/service/apt/apt.h" #include "core/hle/service/fs/archive.h" @@ -575,8 +576,25 @@ void System::Reset() { deliver_arg = apt->GetAppletManager()->ReceiveDeliverArg(); } + bool was_self_delete_pending = self_delete_pending; + Shutdown(); + // Self updating apps may launch themselves after the update, if that's the case + // find the new path to launch. + if (was_self_delete_pending) { + // TODO: We can get the title id, but not the MediaType, so we + // check both NAND and SDMC mediatypes. + m_filepath = Service::AM::GetTitleContentPath(Service::FS::MediaType::NAND, title_id); + if (m_filepath.empty() || !FileUtil::Exists(m_filepath)) { + m_filepath = Service::AM::GetTitleContentPath(Service::FS::MediaType::SDMC, title_id); + if (m_filepath.empty() || !FileUtil::Exists(m_filepath)) { + LOG_CRITICAL(Core, "Failed to get application path for system reset"); + return; + } + } + } + // Reload the system with the same setting [[maybe_unused]] const System::ResultStatus result = Load(*m_emu_window, m_filepath); diff --git a/src/core/core.h b/src/core/core.h index 4ec54018d..b8e80f9f9 100644 --- a/src/core/core.h +++ b/src/core/core.h @@ -306,9 +306,12 @@ public: void LoadState(u32 slot); /// Self delete ncch - void SetSelfDelete(const std::string& file) { - if (m_filepath == file) + bool SetSelfDelete(const std::string& file) { + if (m_filepath == file) { self_delete_pending = true; + return true; + } + return false; } private: diff --git a/src/core/hle/service/am/am.cpp b/src/core/hle/service/am/am.cpp index 28a13044a..dddd2aacf 100644 --- a/src/core/hle/service/am/am.cpp +++ b/src/core/hle/service/am/am.cpp @@ -318,12 +318,13 @@ bool CIAFile::Close() const { if (abort) break; - // Try deleting the file, if it fails it's because it's the currently running file - // and we are on windows. In that case, let system know to delete the currently - // running file once it shuts down. + // If the file to delete is the current launched rom, signal the system to delete + // the current rom instead of deleting it now, once all the handles to the file + // are closed. std::string toDelete = GetTitleContentPath(media_type, old_tmd.GetTitleID(), old_index); - if (!FileUtil::Delete(toDelete) && FileUtil::GetCurrentRomPath() == toDelete) - Core::System::GetInstance().SetSelfDelete(toDelete); + if (!(Core::System::GetInstance().IsPoweredOn() && + Core::System::GetInstance().SetSelfDelete(toDelete))) + FileUtil::Delete(toDelete); } FileUtil::Delete(old_tmd_path);