citra-emu
/
citra-canary
Archived
1
0
Fork 0

Merge pull request #6168 from PabloMK7/cia_update_fix

Fix handling of auto-updating ncch apps
This commit is contained in:
GPUCode 2022-11-09 17:35:16 +02:00 committed by GitHub
commit 38b8bf12de
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 54 additions and 10 deletions

View File

@ -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);

View File

@ -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;

View File

@ -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);

View File

@ -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() {