Merge pull request #6168 from PabloMK7/cia_update_fix
Fix handling of auto-updating ncch apps
This commit is contained in:
		| @@ -325,6 +325,7 @@ System::ResultStatus System::Load(Frontend::EmuWindow& emu_window, const std::st | |||||||
|     status = ResultStatus::Success; |     status = ResultStatus::Success; | ||||||
|     m_emu_window = &emu_window; |     m_emu_window = &emu_window; | ||||||
|     m_filepath = filepath; |     m_filepath = filepath; | ||||||
|  |     self_delete_pending = false; | ||||||
|  |  | ||||||
|     // Reset counters and set time origin to current frame |     // Reset counters and set time origin to current frame | ||||||
|     [[maybe_unused]] const PerfStats::Results result = GetAndResetPerfStats(); |     [[maybe_unused]] const PerfStats::Results result = GetAndResetPerfStats(); | ||||||
| @@ -559,6 +560,10 @@ void System::Shutdown(bool is_deserializing) { | |||||||
|  |  | ||||||
|     memory.reset(); |     memory.reset(); | ||||||
|  |  | ||||||
|  |     if (self_delete_pending) | ||||||
|  |         FileUtil::Delete(m_filepath); | ||||||
|  |     self_delete_pending = false; | ||||||
|  |  | ||||||
|     LOG_DEBUG(Core, "Shutdown OK"); |     LOG_DEBUG(Core, "Shutdown OK"); | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -575,6 +580,11 @@ void System::Reset() { | |||||||
|  |  | ||||||
|     Shutdown(); |     Shutdown(); | ||||||
|  |  | ||||||
|  |     if (!m_chainloadpath.empty()) { | ||||||
|  |         m_filepath = m_chainloadpath; | ||||||
|  |         m_chainloadpath.clear(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|     // Reload the system with the same setting |     // Reload the system with the same setting | ||||||
|     [[maybe_unused]] const System::ResultStatus result = Load(*m_emu_window, m_filepath); |     [[maybe_unused]] const System::ResultStatus result = Load(*m_emu_window, m_filepath); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -126,7 +126,8 @@ public: | |||||||
|     bool SendSignal(Signal signal, u32 param = 0); |     bool SendSignal(Signal signal, u32 param = 0); | ||||||
|  |  | ||||||
|     /// Request reset of the system |     /// Request reset of the system | ||||||
|     void RequestReset() { |     void RequestReset(const std::string& chainload = "") { | ||||||
|  |         m_chainloadpath = chainload; | ||||||
|         SendSignal(Signal::Reset); |         SendSignal(Signal::Reset); | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -306,6 +307,15 @@ public: | |||||||
|  |  | ||||||
|     void LoadState(u32 slot); |     void LoadState(u32 slot); | ||||||
|  |  | ||||||
|  |     /// Self delete ncch | ||||||
|  |     bool SetSelfDelete(const std::string& file) { | ||||||
|  |         if (m_filepath == file) { | ||||||
|  |             self_delete_pending = true; | ||||||
|  |             return true; | ||||||
|  |         } | ||||||
|  |         return false; | ||||||
|  |     } | ||||||
|  |  | ||||||
| private: | private: | ||||||
|     /** |     /** | ||||||
|      * Initialize the emulated system. |      * Initialize the emulated system. | ||||||
| @@ -376,7 +386,9 @@ private: | |||||||
|     /// Saved variables for reset |     /// Saved variables for reset | ||||||
|     Frontend::EmuWindow* m_emu_window; |     Frontend::EmuWindow* m_emu_window; | ||||||
|     std::string m_filepath; |     std::string m_filepath; | ||||||
|  |     std::string m_chainloadpath; | ||||||
|     u64 title_id; |     u64 title_id; | ||||||
|  |     bool self_delete_pending; | ||||||
|  |  | ||||||
|     std::mutex signal_mutex; |     std::mutex signal_mutex; | ||||||
|     Signal current_signal; |     Signal current_signal; | ||||||
|   | |||||||
| @@ -315,7 +315,14 @@ bool CIAFile::Close() const { | |||||||
|             if (abort) |             if (abort) | ||||||
|                 break; |                 break; | ||||||
|  |  | ||||||
|             FileUtil::Delete(GetTitleContentPath(media_type, old_tmd.GetTitleID(), old_index)); |             // 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 to_delete = | ||||||
|  |                 GetTitleContentPath(media_type, old_tmd.GetTitleID(), old_index); | ||||||
|  |             if (!(Core::System::GetInstance().IsPoweredOn() && | ||||||
|  |                   Core::System::GetInstance().SetSelfDelete(to_delete))) | ||||||
|  |                 FileUtil::Delete(to_delete); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         FileUtil::Delete(old_tmd_path); |         FileUtil::Delete(old_tmd_path); | ||||||
|   | |||||||
| @@ -4,6 +4,7 @@ | |||||||
|  |  | ||||||
| #include "core/core.h" | #include "core/core.h" | ||||||
| #include "core/hle/applets/applet.h" | #include "core/hle/applets/applet.h" | ||||||
|  | #include "core/hle/service/am/am.h" | ||||||
| #include "core/hle/service/apt/applet_manager.h" | #include "core/hle/service/apt/applet_manager.h" | ||||||
| #include "core/hle/service/apt/errors.h" | #include "core/hle/service/apt/errors.h" | ||||||
| #include "core/hle/service/apt/ns.h" | #include "core/hle/service/apt/ns.h" | ||||||
| @@ -545,17 +546,30 @@ ResultCode AppletManager::DoApplicationJump(DeliverArg arg) { | |||||||
|     // prompts it to call GetProgramIdOnApplicationJump and |     // prompts it to call GetProgramIdOnApplicationJump and | ||||||
|     // PrepareToStartApplication/StartApplication on the title to launch. |     // PrepareToStartApplication/StartApplication on the title to launch. | ||||||
|  |  | ||||||
|     if (app_jump_parameters.next_title_id == app_jump_parameters.current_title_id) { |     // Perform a soft-reset if we're trying to relaunch the same title. | ||||||
|         // Perform a soft-reset if we're trying to relaunch the same title. |     // TODO(Subv): Note that this reboots the entire emulated system, a better way would be to | ||||||
|         // TODO(Subv): Note that this reboots the entire emulated system, a better way would be to |     // simply re-launch the title without closing all services, but this would only work for | ||||||
|         // simply re-launch the title without closing all services, but this would only work for |     // installed titles since we have no way of getting the file path of an arbitrary game dump | ||||||
|         // installed titles since we have no way of getting the file path of an arbitrary game dump |     // based only on the title id. | ||||||
|         // based only on the title id. |  | ||||||
|         system.RequestReset(); |     std::string new_path = Service::AM::GetTitleContentPath(app_jump_parameters.next_media_type, | ||||||
|         return RESULT_SUCCESS; |                                                             app_jump_parameters.next_title_id); | ||||||
|  |     if (new_path.empty() || !FileUtil::Exists(new_path)) { | ||||||
|  |         LOG_CRITICAL( | ||||||
|  |             Service_APT, | ||||||
|  |             "Failed to find title during application jump: {} Resetting current title instead.", | ||||||
|  |             new_path); | ||||||
|  |         new_path.clear(); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     system.RequestReset(new_path); | ||||||
|  |     return RESULT_SUCCESS; | ||||||
|  |  | ||||||
|     // Launch the title directly. |     // Launch the title directly. | ||||||
|  |     // The emulator does not suport terminating old processes, would require a lot of cleanup | ||||||
|  |     // This code is left commented for when this is implemented, for now we cannot use NS | ||||||
|  |     // as the old process resources would interfere with the new ones | ||||||
|  |     /* | ||||||
|     auto process = |     auto process = | ||||||
|         NS::LaunchTitle(app_jump_parameters.next_media_type, app_jump_parameters.next_title_id); |         NS::LaunchTitle(app_jump_parameters.next_media_type, app_jump_parameters.next_title_id); | ||||||
|     if (!process) { |     if (!process) { | ||||||
| @@ -563,6 +577,7 @@ ResultCode AppletManager::DoApplicationJump(DeliverArg arg) { | |||||||
|         system.RequestShutdown(); |         system.RequestShutdown(); | ||||||
|     } |     } | ||||||
|     return RESULT_SUCCESS; |     return RESULT_SUCCESS; | ||||||
|  |     */ | ||||||
| } | } | ||||||
|  |  | ||||||
| void AppletManager::EnsureHomeMenuLoaded() { | void AppletManager::EnsureHomeMenuLoaded() { | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user