From d6a1ef0af412b32de56948abf858a845aa115a6a Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Sun, 11 Apr 2021 01:29:12 -0700 Subject: [PATCH] pgl: convert to cmif/tipc polyglot --- nx/include/switch/services/pgl.h | 13 ++- nx/source/services/pgl.c | 174 ++++++++++++++++++++++++------- 2 files changed, 145 insertions(+), 42 deletions(-) diff --git a/nx/include/switch/services/pgl.h b/nx/include/switch/services/pgl.h index c3525f56..5b3a8824 100644 --- a/nx/include/switch/services/pgl.h +++ b/nx/include/switch/services/pgl.h @@ -7,6 +7,7 @@ #pragma once #include "../types.h" #include "../sf/service.h" +#include "../sf/tipc.h" #include "../services/ncm_types.h" #include "../services/pm.h" @@ -33,8 +34,9 @@ typedef struct { u8 reserved_0E[2]; ///< Padding } PglContentMetaInfo; -typedef struct { - Service s; +typedef union { + Service s; + TipcService t; } PglEventObserver; /// Initialize pgl. @@ -43,8 +45,11 @@ Result pglInitialize(void); /// Exit pgl. void pglExit(void); -/// Gets the Service object for the actual pgl service session. -Service* pglGetServiceSession(void); +/// Gets the Service object for the actual pgl service session. Requires < 12.0.0 +Service* pglGetServiceSessionCmif(void); + +/// Gets the TipcService object for the actual pgl service session. Requires 12.0.0+ +TipcService* pglGetServiceSessionTipc(void); Result pglLaunchProgram(u64 *out_pid, const NcmProgramLocation *loc, u32 pm_launch_flags, u8 pgl_launch_flags); Result pglTerminateProcess(u64 pid); diff --git a/nx/source/services/pgl.c b/nx/source/services/pgl.c index 4d08c2b0..1542b4ef 100644 --- a/nx/source/services/pgl.c +++ b/nx/source/services/pgl.c @@ -4,40 +4,82 @@ #include "services/pgl.h" #include "runtime/hosversion.h" -static Service g_pglSrv; +static union { + Service cmif; + TipcService tipc; +} g_pglSrv; NX_GENERATE_SERVICE_GUARD(pgl); +static bool _pglShouldUseTipc(void) { + return hosversionAtLeast(12,0,0); +} + Result _pglInitialize(void) { if (hosversionBefore(10,0,0)) return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); - return smGetService(&g_pglSrv, "pgl"); + + if (_pglShouldUseTipc()) { + Handle handle; + Result rc = smGetServiceOriginal(&handle, smEncodeName("pgl")); + + if (R_SUCCEEDED(rc)) { + tipcCreate(&g_pglSrv.tipc, handle); + } + + return rc; + } else { + return smGetService(&g_pglSrv.cmif, "pgl"); + } } void _pglCleanup(void) { - serviceClose(&g_pglSrv); + if (_pglShouldUseTipc()) { + tipcClose(&g_pglSrv.tipc); + } else { + serviceClose(&g_pglSrv.cmif); + } } -Service* pglGetServiceSession(void) { - return &g_pglSrv; +Service* pglGetServiceSessionCmif(void) { + return &g_pglSrv.cmif; } -static Result _pglCmdInBool(Service* srv, bool inval, u32 cmd_id) { +TipcService* pglGetServiceSessionTipc(void) { + return &g_pglSrv.tipc; +} + +static Result _pglCmdInBool(bool inval, u32 cmd_id) { const u8 in = inval; - return serviceDispatchIn(srv, cmd_id, in); + if (_pglShouldUseTipc()) { + return tipcDispatchIn(&g_pglSrv.tipc, cmd_id, in); + } else { + return serviceDispatchIn(&g_pglSrv.cmif, cmd_id, in); + } } -static Result _pglCmdOutBool(Service* srv, bool *out, u32 cmd_id) { +static Result _pglCmdOutBool(bool *out, u32 cmd_id) { u8 outval = 0; - Result rc = serviceDispatchOut(srv, cmd_id, outval); + Result rc; + + if (_pglShouldUseTipc()) { + rc = tipcDispatchOut(&g_pglSrv.tipc, cmd_id, outval); + } else { + rc = serviceDispatchOut(&g_pglSrv.cmif, cmd_id, outval); + } + if (R_SUCCEEDED(rc)) { if (out) *out = outval & 1; } return rc; } -static Result _pglCmdInU64(Service* srv, u64 inval, u32 cmd_id) { - return serviceDispatchIn(srv, cmd_id, inval); +static Result _pglCmdInU64(u64 inval, u32 cmd_id) { + if (_pglShouldUseTipc()) { + return tipcDispatchIn(&g_pglSrv.tipc, cmd_id, inval); + } else { + return serviceDispatchIn(&g_pglSrv.cmif, cmd_id, inval); + } } Result pglLaunchProgram(u64 *out_pid, const NcmProgramLocation *loc, u32 pm_launch_flags, u8 pgl_launch_flags) { @@ -46,38 +88,68 @@ Result pglLaunchProgram(u64 *out_pid, const NcmProgramLocation *loc, u32 pm_laun u32 pm_flags; NcmProgramLocation loc; } in = { pgl_launch_flags, pm_launch_flags, *loc }; - return serviceDispatchInOut(&g_pglSrv, 0, in, *out_pid); + + if (_pglShouldUseTipc()) { + return tipcDispatchInOut(&g_pglSrv.tipc, 0, in, *out_pid); + } else { + return serviceDispatchInOut(&g_pglSrv.cmif, 0, in, *out_pid); + } } Result pglTerminateProcess(u64 pid) { - return _pglCmdInU64(&g_pglSrv, pid, 1); + return _pglCmdInU64(pid, 1); } Result pglLaunchProgramFromHost(u64 *out_pid, const char *content_path, u32 pm_launch_flags) { - return serviceDispatchInOut(&g_pglSrv, 2, pm_launch_flags, *out_pid, - .buffer_attrs = { SfBufferAttr_In | SfBufferAttr_HipcMapAlias }, - .buffers = { { content_path, strlen(content_path) + 1 } }, - ); + if (_pglShouldUseTipc()) { + return tipcDispatchInOut(&g_pglSrv.tipc, 2, pm_launch_flags, *out_pid, + .buffer_attrs = { SfBufferAttr_In | SfBufferAttr_HipcMapAlias }, + .buffers = { { content_path, strlen(content_path) + 1 } }, + ); + } else { + return serviceDispatchInOut(&g_pglSrv.cmif, 2, pm_launch_flags, *out_pid, + .buffer_attrs = { SfBufferAttr_In | SfBufferAttr_HipcMapAlias }, + .buffers = { { content_path, strlen(content_path) + 1 } }, + ); + } } Result pglGetHostContentMetaInfo(PglContentMetaInfo *out, const char *content_path) { - return serviceDispatchOut(&g_pglSrv, 4, *out, - .buffer_attrs = { SfBufferAttr_In | SfBufferAttr_HipcMapAlias }, - .buffers = { { content_path, strlen(content_path) + 1 } }, - ); + if (_pglShouldUseTipc()) { + return tipcDispatchOut(&g_pglSrv.tipc, 4, *out, + .buffer_attrs = { SfBufferAttr_In | SfBufferAttr_HipcMapAlias }, + .buffers = { { content_path, strlen(content_path) + 1 } }, + ); + } else { + return serviceDispatchOut(&g_pglSrv.cmif, 4, *out, + .buffer_attrs = { SfBufferAttr_In | SfBufferAttr_HipcMapAlias }, + .buffers = { { content_path, strlen(content_path) + 1 } }, + ); + } } Result pglGetApplicationProcessId(u64 *out) { - return serviceDispatchOut(&g_pglSrv, 5, *out); + if (_pglShouldUseTipc()) { + return tipcDispatchOut(&g_pglSrv.tipc, 5, *out); + } else { + return serviceDispatchOut(&g_pglSrv.cmif, 5, *out); + } } Result pglBoostSystemMemoryResourceLimit(u64 size) { - return _pglCmdInU64(&g_pglSrv, size, 6); + return _pglCmdInU64(size, 6); } Result pglIsProcessTracked(bool *out, u64 pid) { u8 outval = 0; - Result rc = serviceDispatchInOut(&g_pglSrv, 7, pid, outval); + Result rc; + + if (_pglShouldUseTipc()) { + rc = tipcDispatchInOut(&g_pglSrv.tipc, 7, pid, outval); + } else { + rc = serviceDispatchInOut(&g_pglSrv.cmif, 7, pid, outval); + } + if (R_SUCCEEDED(rc)) { if (out) *out = outval & 1; } @@ -85,38 +157,56 @@ Result pglIsProcessTracked(bool *out, u64 pid) { } Result pglEnableApplicationCrashReport(bool en) { - return _pglCmdInBool(&g_pglSrv, en, 8); + return _pglCmdInBool(en, 8); } Result pglIsApplicationCrashReportEnabled(bool *out) { - return _pglCmdOutBool(&g_pglSrv, out, 9); + return _pglCmdOutBool(out, 9); } Result pglEnableApplicationAllThreadDumpOnCrash(bool en) { - return _pglCmdInBool(&g_pglSrv, en, 10); + return _pglCmdInBool(en, 10); } Result pglTriggerApplicationSnapShotDumper(PglSnapShotDumpType dump_type, const char *arg) { + if (hosversionAtLeast(12,0,0)) return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); + _Static_assert(sizeof(dump_type) == sizeof(u32), "PglSnapShotDumpType"); - return serviceDispatchIn(&g_pglSrv, 12, dump_type, + return serviceDispatchIn(&g_pglSrv.cmif, 12, dump_type, .buffer_attrs = { SfBufferAttr_In | SfBufferAttr_HipcMapAlias }, .buffers = { { arg, strlen(arg) + 1 } }, ); } Result pglGetEventObserver(PglEventObserver *out) { - return serviceDispatch(&g_pglSrv, 20, - .out_num_objects = 1, - .out_objects = &out->s, - ); + if (_pglShouldUseTipc()) { + return tipcDispatch(&g_pglSrv.tipc, 20, + .out_num_objects = 1, + .out_objects = &out->t, + ); + } else { + return serviceDispatch(&g_pglSrv.cmif, 20, + .out_num_objects = 1, + .out_objects = &out->s, + ); + } } Result pglEventObserverGetProcessEvent(PglEventObserver *observer, Event *out) { Handle evt_handle; - Result rc = serviceDispatch(&observer->s, 0, - .out_handle_attrs = { SfOutHandleAttr_HipcCopy }, - .out_handles = &evt_handle, - ); + Result rc; + + if (_pglShouldUseTipc()) { + rc = tipcDispatch(&observer->t, 0, + .out_handle_attrs = { SfOutHandleAttr_HipcCopy }, + .out_handles = &evt_handle, + ); + } else { + rc = serviceDispatch(&observer->s, 0, + .out_handle_attrs = { SfOutHandleAttr_HipcCopy }, + .out_handles = &evt_handle, + ); + } if (R_SUCCEEDED(rc)) { eventLoadRemote(out, evt_handle, true); @@ -126,9 +216,17 @@ Result pglEventObserverGetProcessEvent(PglEventObserver *observer, Event *out) { } Result pglEventObserverGetProcessEventInfo(PglEventObserver *observer, PmProcessEventInfo *out) { - return serviceDispatchOut(&observer->s, 1, *out); + if (_pglShouldUseTipc()) { + return tipcDispatchOut(&observer->t, 1, *out); + } else { + return serviceDispatchOut(&observer->s, 1, *out); + } } void pglEventObserverClose(PglEventObserver *observer) { - serviceClose(&observer->s); + if (_pglShouldUseTipc()) { + tipcClose(&observer->t); + } else { + serviceClose(&observer->s); + } }