diff --git a/nx/include/switch/services/pm.h b/nx/include/switch/services/pm.h index 4312c49a..8ca894fa 100644 --- a/nx/include/switch/services/pm.h +++ b/nx/include/switch/services/pm.h @@ -3,6 +3,7 @@ * @brief Process management (pm*) service IPC wrapper. * @author plutoo * @author yellows8 + * @author mdbell * @copyright libnx Authors */ #pragma once @@ -11,6 +12,9 @@ Result pmdmntInitialize(void); void pmdmntExit(void); +Result pminfoInitialize(void); +void pminfoExit(void); + Result pmshellInitialize(void); void pmshellExit(void); @@ -20,4 +24,6 @@ Result pmdmntEnableDebugForTitleId(Handle* handle_out, u64 title_id); Result pmdmntGetApplicationPid(u64* pid_out); Result pmdmntEnableDebugForApplication(Handle* handle_out); +Result pminfoGetTitleId(u64* title_id_out, u64 pid); + Result pmshellLaunchProcess(u32 launch_flags, u64 titleID, u64 storageID, u64 *pid); diff --git a/nx/source/services/pm.c b/nx/source/services/pm.c index f7321de9..c901767e 100644 --- a/nx/source/services/pm.c +++ b/nx/source/services/pm.c @@ -6,8 +6,8 @@ #include "services/pm.h" #include "services/sm.h" -static Service g_pmdmntSrv, g_pmshellSrv; -static u64 g_pmdmntRefCnt, g_pmshellRefCnt; +static Service g_pmdmntSrv, g_pmshellSrv, g_pminfoSrv; +static u64 g_pmdmntRefCnt, g_pmshellRefCnt, g_pminfoRefCnt; Result pmdmntInitialize(void) { @@ -26,6 +26,23 @@ void pmdmntExit(void) } } +Result pminfoInitialize(void) +{ + atomicIncrement64(&g_pminfoRefCnt); + + if (serviceIsActive(&g_pminfoSrv)) + return 0; + + return smGetService(&g_pminfoSrv, "pm:info"); +} + +void pminfoExit(void) +{ + if (atomicDecrement64(&g_pminfoRefCnt) == 0) { + serviceClose(&g_pminfoSrv); + } +} + Result pmshellInitialize(void) { atomicIncrement64(&g_pmshellRefCnt); @@ -151,6 +168,42 @@ Result pmdmntEnableDebugForTitleId(Handle* handle_out, u64 title_id) { return rc; } +Result pminfoGetTitleId(u64* title_id_out, u64 pid) { + IpcCommand c; + ipcInitialize(&c); + + struct { + u64 magic; + u64 cmd_id; + u64 pid; + } *raw; + + raw = ipcPrepareHeader(&c, sizeof(*raw)); + + raw->magic = SFCI_MAGIC; + raw->cmd_id = 0; + raw->pid = pid; + + Result rc = serviceIpcDispatch(&g_pminfoSrv); + + if (R_SUCCEEDED(rc)) { + IpcParsedCommand r; + ipcParse(&r); + + struct { + u64 magic; + u64 result; + u64 title_id; + } *resp = r.Raw; + + rc = resp->result; + if (R_SUCCEEDED(rc)) { + *title_id_out = resp->title_id; + } + } + return rc; +} + Result pmdmntGetApplicationPid(u64* pid_out) { IpcCommand c; ipcInitialize(&c);