diff --git a/src/common/file_util.cpp b/src/common/file_util.cpp index 436d94406..9ec740b36 100644 --- a/src/common/file_util.cpp +++ b/src/common/file_util.cpp @@ -738,6 +738,10 @@ 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 cdd55b665..24198d80b 100644 --- a/src/common/file_util.h +++ b/src/common/file_util.h @@ -182,6 +182,8 @@ 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 ec29ab002..3e364ae43 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -324,6 +324,7 @@ System::ResultStatus System::Load(Frontend::EmuWindow& emu_window, const std::st status = ResultStatus::Success; m_emu_window = &emu_window; m_filepath = filepath; + self_delete_pending = false; // Reset counters and set time origin to current frame [[maybe_unused]] const PerfStats::Results result = GetAndResetPerfStats(); @@ -556,6 +557,10 @@ void System::Shutdown(bool is_deserializing) { memory.reset(); + if (self_delete_pending) + FileUtil::Delete(m_filepath); + self_delete_pending = false; + LOG_DEBUG(Core, "Shutdown OK"); } diff --git a/src/core/core.h b/src/core/core.h index 47edb49f3..4ec54018d 100644 --- a/src/core/core.h +++ b/src/core/core.h @@ -305,6 +305,12 @@ public: void LoadState(u32 slot); + /// Self delete ncch + void SetSelfDelete(const std::string& file) { + if (m_filepath == file) + self_delete_pending = true; + } + private: /** * Initialize the emulated system. @@ -374,6 +380,7 @@ private: Frontend::EmuWindow* m_emu_window; std::string m_filepath; u64 title_id; + bool self_delete_pending; std::mutex signal_mutex; Signal current_signal; diff --git a/src/core/hle/service/am/am.cpp b/src/core/hle/service/am/am.cpp index 5c2639eff..28a13044a 100644 --- a/src/core/hle/service/am/am.cpp +++ b/src/core/hle/service/am/am.cpp @@ -318,7 +318,12 @@ bool CIAFile::Close() const { if (abort) break; - FileUtil::Delete(GetTitleContentPath(media_type, old_tmd.GetTitleID(), old_index)); + // 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. + std::string toDelete = GetTitleContentPath(media_type, old_tmd.GetTitleID(), old_index); + if (!FileUtil::Delete(toDelete) && FileUtil::GetCurrentRomPath() == toDelete) + Core::System::GetInstance().SetSelfDelete(toDelete); } FileUtil::Delete(old_tmd_path);