diff --git a/sysmodules/loader/source/luma_shared_config.h b/sysmodules/loader/source/luma_shared_config.h index ac7eab2..165b130 100644 --- a/sysmodules/loader/source/luma_shared_config.h +++ b/sysmodules/loader/source/luma_shared_config.h @@ -18,10 +18,11 @@ #include <3ds/types.h> -/// Luma shared config type. +/// Luma shared config type (private!). typedef struct LumaSharedConfig { - u64 hbldr_3dsx_tid; ///< Title ID to use for 3DSX loading. - bool use_hbldr; ///< Whether or not Loader should use hb:ldr (reset to true). + u64 hbldr_3dsx_tid; ///< Title ID to use for 3DSX loading (current). + u64 selected_hbldr_3dsx_tid; ///< Title ID to use for 3DSX loading (to be moved to "current" when the current app closes). + bool use_hbldr; ///< Whether or not Loader should use hb:ldr (reset to true). } LumaSharedConfig; /// Luma shared config. diff --git a/sysmodules/loader/source/main.c b/sysmodules/loader/source/main.c index 17f3458..29581ac 100644 --- a/sysmodules/loader/source/main.c +++ b/sysmodules/loader/source/main.c @@ -66,7 +66,9 @@ static inline void loadCFWInfo(void) isSdMode = true; } - Luma_SharedConfig->hbldr_3dsx_tid = hbldrTid == 0 ? HBLDR_DEFAULT_3DSX_TID : hbldrTid; + hbldrTid = hbldrTid == 0 ? HBLDR_DEFAULT_3DSX_TID : hbldrTid; + Luma_SharedConfig->hbldr_3dsx_tid = hbldrTid; + Luma_SharedConfig->selected_hbldr_3dsx_tid = hbldrTid; Luma_SharedConfig->use_hbldr = true; } diff --git a/sysmodules/pm/pm.rsf b/sysmodules/pm/pm.rsf index f98f095..41c1ec7 100644 --- a/sysmodules/pm/pm.rsf +++ b/sysmodules/pm/pm.rsf @@ -25,7 +25,7 @@ AccessControlInfo: DisableDebug : false EnableForceDebug : false - CanWriteSharedPage : false + CanWriteSharedPage : true # changed CanUsePrivilegedPriority : false CanUseNonAlphabetAndNumber : false PermitMainFunctionArgument : false diff --git a/sysmodules/pm/source/luma_shared_config.h b/sysmodules/pm/source/luma_shared_config.h new file mode 100644 index 0000000..165b130 --- /dev/null +++ b/sysmodules/pm/source/luma_shared_config.h @@ -0,0 +1,29 @@ +/* This paricular file is licensed under the following terms: */ + +/* +* This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable +* for any damages arising from the use of this software. +* +* Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it +* and redistribute it freely, subject to the following restrictions: +* +* The origin of this software must not be misrepresented; you must not claim that you wrote the original software. +* If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +* +* Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +* This notice may not be removed or altered from any source distribution. +*/ + +#pragma once + +#include <3ds/types.h> + +/// Luma shared config type (private!). +typedef struct LumaSharedConfig { + u64 hbldr_3dsx_tid; ///< Title ID to use for 3DSX loading (current). + u64 selected_hbldr_3dsx_tid; ///< Title ID to use for 3DSX loading (to be moved to "current" when the current app closes). + bool use_hbldr; ///< Whether or not Loader should use hb:ldr (reset to true). +} LumaSharedConfig; + +/// Luma shared config. +#define Luma_SharedConfig ((volatile LumaSharedConfig *)(OS_SHAREDCFG_VADDR + 0x800)) diff --git a/sysmodules/pm/source/process_monitor.c b/sysmodules/pm/source/process_monitor.c index c2847d6..0e05d4a 100644 --- a/sysmodules/pm/source/process_monitor.c +++ b/sysmodules/pm/source/process_monitor.c @@ -6,6 +6,7 @@ #include "reslimit.h" #include "manager.h" #include "util.h" +#include "luma_shared_config.h" static void cleanupProcess(ProcessData *process) { @@ -33,6 +34,11 @@ static void cleanupProcess(ProcessData *process) assertSuccess(resetAppMemLimit()); } g_manager.runningApplicationData = NULL; + + // We need to do this here to ensure that the ExHeader at init matches the ExHeader + // at termination at all times, otherwise the process refcounts of sysmodules + // get all messed up. + Luma_SharedConfig->hbldr_3dsx_tid = Luma_SharedConfig->selected_hbldr_3dsx_tid; } if (g_manager.debugData != NULL && process->handle == g_manager.debugData->handle) { diff --git a/sysmodules/rosalina/include/luma_shared_config.h b/sysmodules/rosalina/include/luma_shared_config.h index ac7eab2..165b130 100644 --- a/sysmodules/rosalina/include/luma_shared_config.h +++ b/sysmodules/rosalina/include/luma_shared_config.h @@ -18,10 +18,11 @@ #include <3ds/types.h> -/// Luma shared config type. +/// Luma shared config type (private!). typedef struct LumaSharedConfig { - u64 hbldr_3dsx_tid; ///< Title ID to use for 3DSX loading. - bool use_hbldr; ///< Whether or not Loader should use hb:ldr (reset to true). + u64 hbldr_3dsx_tid; ///< Title ID to use for 3DSX loading (current). + u64 selected_hbldr_3dsx_tid; ///< Title ID to use for 3DSX loading (to be moved to "current" when the current app closes). + bool use_hbldr; ///< Whether or not Loader should use hb:ldr (reset to true). } LumaSharedConfig; /// Luma shared config. diff --git a/sysmodules/rosalina/source/luma_config.c b/sysmodules/rosalina/source/luma_config.c index a2cb809..5f1bb49 100644 --- a/sysmodules/rosalina/source/luma_config.c +++ b/sysmodules/rosalina/source/luma_config.c @@ -220,7 +220,7 @@ Result LumaConfig_SaveSettings(void) configData.multiConfig = multiConfig; configData.bootConfig = bootConfig; configData.splashDurationMsec = splashDurationMsec; - configData.hbldr3dsxTitleId = Luma_SharedConfig->hbldr_3dsx_tid; + configData.hbldr3dsxTitleId = Luma_SharedConfig->selected_hbldr_3dsx_tid; configData.rosalinaMenuCombo = menuCombo; configData.ntpTzOffetMinutes = (s16)lastNtpTzOffset; configData.topScreenFilter = topScreenFilter; diff --git a/sysmodules/rosalina/source/main.c b/sysmodules/rosalina/source/main.c index eb0bbef..d61b740 100644 --- a/sysmodules/rosalina/source/main.c +++ b/sysmodules/rosalina/source/main.c @@ -87,10 +87,6 @@ void initSystem(void) svcGetSystemInfo(&out, 0x10000, 0x103); lastNtpTzOffset = (s16)out; - miscellaneousMenu.items[0].title = Luma_SharedConfig->hbldr_3dsx_tid == HBLDR_DEFAULT_3DSX_TID ? - "Switch the hb. title to the current app." : - "Switch the hb. title to " HBLDR_DEFAULT_3DSX_TITLE_NAME; - for(res = 0xD88007FA; res == (Result)0xD88007FA; svcSleepThread(500 * 1000LL)) { res = srvInit(); @@ -107,6 +103,10 @@ void initSystem(void) if (R_FAILED(FSUSER_SetPriority(-16))) svcBreak(USERBREAK_PANIC); + miscellaneousMenu.items[0].title = Luma_SharedConfig->selected_hbldr_3dsx_tid == HBLDR_DEFAULT_3DSX_TID ? + "Switch the hb. title to the current app." : + "Switch the hb. title to " HBLDR_DEFAULT_3DSX_TITLE_NAME; + // **** DO NOT init services that don't come from KIPs here **** // Instead, init the service only where it's actually init (then deinit it). diff --git a/sysmodules/rosalina/source/menus/miscellaneous.c b/sysmodules/rosalina/source/menus/miscellaneous.c index 7ed33ec..534e2c2 100644 --- a/sysmodules/rosalina/source/menus/miscellaneous.c +++ b/sysmodules/rosalina/source/menus/miscellaneous.c @@ -88,20 +88,19 @@ void MiscellaneousMenu_SwitchBoot3dsxTargetTitle(void) { Result res; char failureReason[64]; - u64 currentTid = Luma_SharedConfig->hbldr_3dsx_tid; + u64 currentTid = Luma_SharedConfig->selected_hbldr_3dsx_tid; u64 newTid = currentTid; + FS_ProgramInfo progInfo; + u32 pid; + u32 launchFlags; + res = PMDBG_GetCurrentAppInfo(&progInfo, &pid, &launchFlags); + bool appRunning = R_SUCCEEDED(res); + if(compareTids(currentTid, HBLDR_DEFAULT_3DSX_TID)) { - FS_ProgramInfo progInfo; - u32 pid; - u32 launchFlags; - res = PMDBG_GetCurrentAppInfo(&progInfo, &pid, &launchFlags); - if(R_SUCCEEDED(res)) - { + if(appRunning) newTid = progInfo.programId; - Luma_SharedConfig->hbldr_3dsx_tid = progInfo.programId; - } else { res = -1; @@ -114,7 +113,18 @@ void MiscellaneousMenu_SwitchBoot3dsxTargetTitle(void) newTid = HBLDR_DEFAULT_3DSX_TID; } - Luma_SharedConfig->hbldr_3dsx_tid = newTid; + Luma_SharedConfig->selected_hbldr_3dsx_tid = newTid; + + // Move "selected" field to "current" if no app is currently running. + // Otherwise, PM will do it on app exit. + // There's a small possibility of race condition but it shouldn't matter + // here. + // We need to do that to ensure that the ExHeader at init matches the ExHeader + // at termination at all times, otherwise the process refcounts of sysmodules + // get all messed up. + if (!appRunning) + Luma_SharedConfig->hbldr_3dsx_tid = newTid; + if (compareTids(newTid, HBLDR_DEFAULT_3DSX_TID)) miscellaneousMenu.items[0].title = "Switch the hb. title to the current app."; else