diff --git a/sysmodules/pm/source/info.c b/sysmodules/pm/source/info.c index f75a4f0..9256a25 100644 --- a/sysmodules/pm/source/info.c +++ b/sysmodules/pm/source/info.c @@ -125,3 +125,14 @@ Result GetTitleExHeaderFlags(ExHeader_Arm11CoreInfo *outCoreInfo, ExHeader_Syste return res; } + +Result GetCurrentAppTitleId(u64 *outTitleId) +{ + if (g_manager.runningApplicationData != NULL) { + *outTitleId = g_manager.runningApplicationData->titleId; + return 0; + } else { + *outTitleId = 0; + return MAKERESULT(RL_TEMPORARY, RS_NOTFOUND, RM_PM, 0x100); + } +} diff --git a/sysmodules/pm/source/info.h b/sysmodules/pm/source/info.h index 1858fd9..38ce43d 100644 --- a/sysmodules/pm/source/info.h +++ b/sysmodules/pm/source/info.h @@ -10,3 +10,6 @@ Result listDependencies(u64 *dependencies, u32 *numDeps, const ExHeader_Info *ex Result listMergeUniqueDependencies(ProcessData **procs, u64 *dependencies, u32 *remrefcounts, u32 *numDeps, const ExHeader_Info *exheaderInfo); Result GetTitleExHeaderFlags(ExHeader_Arm11CoreInfo *outCoreInfo, ExHeader_SystemInfoFlags *outSiFlags, const FS_ProgramInfo *programInfo); + +// Custom +Result GetCurrentAppTitleId(u64 *outTitleId); diff --git a/sysmodules/pm/source/launch.c b/sysmodules/pm/source/launch.c index 1905f6d..17c80c4 100644 --- a/sysmodules/pm/source/launch.c +++ b/sysmodules/pm/source/launch.c @@ -9,6 +9,8 @@ #include "util.h" #include "luma.h" +static bool g_debugNextApplication = false; + // Note: official PM has two distinct functions for sysmodule vs. regular app. We refactor that into a single function. static Result launchTitleImpl(Handle *outDebug, ProcessData **outProcessData, const FS_ProgramInfo *programInfo, const FS_ProgramInfo *programInfoUpdate, u32 launchFlags, ExHeader_Info *exheaderInfo); @@ -304,8 +306,10 @@ static void LaunchTitleAsync(void *argdata) Result LaunchTitle(u32 *outPid, const FS_ProgramInfo *programInfo, u32 launchFlags) { ProcessData *process, *foundProcess = NULL; + bool originallyDebugged = launchFlags & PMLAUNCHFLAG_QUEUE_DEBUG_APPLICATION; launchFlags &= ~PMLAUNCHFLAG_USE_UPDATE_TITLE; + launchFlags |= g_debugNextApplication && (launchFlags & PMLAUNCHFLAG_NORMAL_APPLICATION) ? PMLAUNCHFLAG_QUEUE_DEBUG_APPLICATION : 0; if (g_manager.preparingForReboot) { return 0xC8A05801; @@ -340,7 +344,15 @@ Result LaunchTitle(u32 *outPid, const FS_ProgramInfo *programInfo, u32 launchFla return 0; } else { if (launchFlags & PMLAUNCHFLAG_QUEUE_DEBUG_APPLICATION || !(launchFlags & PMLAUNCHFLAG_NORMAL_APPLICATION)) { - return launchTitleImplWrapper(NULL, outPid, programInfo, programInfo, launchFlags); + Result res = launchTitleImplWrapper(NULL, outPid, programInfo, programInfo, launchFlags); + if (R_SUCCEEDED(res) && (launchFlags & PMLAUNCHFLAG_NORMAL_APPLICATION)) { + g_debugNextApplication = false; + if (!originallyDebugged) { + // Custom notification + notifySubscribers(0x1000); + } + } + return res; } else { struct { FS_ProgramInfo programInfo, programInfoUpdate; @@ -368,10 +380,21 @@ Result LaunchTitleUpdate(const FS_ProgramInfo *programInfo, const FS_ProgramInfo return 0xD8E05802; } + bool originallyDebugged = launchFlags & PMLAUNCHFLAG_QUEUE_DEBUG_APPLICATION; + launchFlags |= PMLAUNCHFLAG_USE_UPDATE_TITLE; + launchFlags |= g_debugNextApplication ? PMLAUNCHFLAG_QUEUE_DEBUG_APPLICATION : 0; if (launchFlags & PMLAUNCHFLAG_QUEUE_DEBUG_APPLICATION) { - return launchTitleImplWrapper(NULL, NULL, programInfo, programInfoUpdate, launchFlags); + Result res = launchTitleImplWrapper(NULL, NULL, programInfo, programInfoUpdate, launchFlags); + if (R_SUCCEEDED(res)) { + g_debugNextApplication = false; + if (!originallyDebugged) { + // Custom notification + notifySubscribers(0x1000); + } + } + return res; } else { struct { FS_ProgramInfo programInfo, programInfoUpdate; @@ -446,9 +469,17 @@ Result LaunchAppDebug(Handle *outDebug, const FS_ProgramInfo *programInfo, u32 l return 0xC8A05BF0; } + bool prevdbg = g_debugNextApplication; + g_debugNextApplication = false; + assertSuccess(setAppCpuTimeLimit(0)); - return launchTitleImplWrapper(outDebug, NULL, programInfo, programInfo, + Result res = launchTitleImplWrapper(outDebug, NULL, programInfo, programInfo, (launchFlags & ~PMLAUNCHFLAG_USE_UPDATE_TITLE) | PMLAUNCHFLAG_NORMAL_APPLICATION); + + if (R_FAILED(res)) { + g_debugNextApplication = prevdbg; + } + return res; } Result autolaunchSysmodules(void) @@ -464,3 +495,23 @@ Result autolaunchSysmodules(void) return res; } + +// Custom +Result DebugNextApplicationByForce(void) +{ + g_debugNextApplication = true; + return 0; +} + +Result LaunchTitleDebug(Handle *outDebug, const FS_ProgramInfo *programInfo, u32 launchFlags) +{ + if (launchFlags & PMLAUNCHFLAG_NORMAL_APPLICATION) { + return LaunchAppDebug(outDebug, programInfo, launchFlags); + } + + if (g_manager.debugData != NULL) { + return RunQueuedProcess(outDebug); + } + + return launchTitleImplWrapper(outDebug, NULL, programInfo, programInfo, launchFlags & ~PMLAUNCHFLAG_USE_UPDATE_TITLE); +} diff --git a/sysmodules/pm/source/launch.h b/sysmodules/pm/source/launch.h index bb4fdb8..101f4fe 100644 --- a/sysmodules/pm/source/launch.h +++ b/sysmodules/pm/source/launch.h @@ -11,3 +11,7 @@ Result RunQueuedProcess(Handle *outDebug); Result LaunchAppDebug(Handle *outDebug, const FS_ProgramInfo *programInfo, u32 launchFlags); Result autolaunchSysmodules(void); + +// Custom +Result DebugNextApplicationByForce(void); +Result LaunchTitleDebug(Handle *outDebug, const FS_ProgramInfo *programInfo, u32 launchFlags); diff --git a/sysmodules/pm/source/pmdbg.c b/sysmodules/pm/source/pmdbg.c index 461f200..0dd0fbf 100644 --- a/sysmodules/pm/source/pmdbg.c +++ b/sysmodules/pm/source/pmdbg.c @@ -1,6 +1,7 @@ #include <3ds.h> #include #include "launch.h" +#include "info.h" #include "util.h" void pmDbgHandleCommands(void *ctx) @@ -12,6 +13,8 @@ void pmDbgHandleCommands(void *ctx) FS_ProgramInfo programInfo; Handle debug; + u64 titleId; + switch (cmdhdr >> 16) { case 1: debug = 0; @@ -33,6 +36,27 @@ void pmDbgHandleCommands(void *ctx) cmdbuf[2] = IPC_Desc_MoveHandles(1); cmdbuf[3] = debug; break; + + // Custom + case 0x100: + titleId = 0; + cmdbuf[1] = GetCurrentAppTitleId(&titleId); + cmdbuf[0] = IPC_MakeHeader(0x100, 3, 0); + memcpy(cmdbuf + 2, &titleId, 8); + break; + case 0x101: + cmdbuf[1] = DebugNextApplicationByForce(); + cmdbuf[0] = IPC_MakeHeader(0x101, 1, 0); + break; + case 0x102: + debug = 0; + memcpy(&programInfo, cmdbuf + 1, sizeof(FS_ProgramInfo)); + cmdbuf[1] = LaunchTitleDebug(&debug, &programInfo, cmdbuf[5]); + cmdbuf[0] = IPC_MakeHeader(0x102, 1, 2); + cmdbuf[2] = IPC_Desc_MoveHandles(1); + cmdbuf[3] = debug; + break; + default: cmdbuf[0] = IPC_MakeHeader(0, 1, 0); cmdbuf[1] = 0xD900182F;