pgl: convert to cmif/tipc polyglot

This commit is contained in:
Michael Scire 2021-04-11 01:29:12 -07:00 committed by fincs
parent eb8ee97f1c
commit d6a1ef0af4
No known key found for this signature in database
GPG Key ID: 62C7609ADA219C60
2 changed files with 145 additions and 42 deletions

View File

@ -7,6 +7,7 @@
#pragma once #pragma once
#include "../types.h" #include "../types.h"
#include "../sf/service.h" #include "../sf/service.h"
#include "../sf/tipc.h"
#include "../services/ncm_types.h" #include "../services/ncm_types.h"
#include "../services/pm.h" #include "../services/pm.h"
@ -33,8 +34,9 @@ typedef struct {
u8 reserved_0E[2]; ///< Padding u8 reserved_0E[2]; ///< Padding
} PglContentMetaInfo; } PglContentMetaInfo;
typedef struct { typedef union {
Service s; Service s;
TipcService t;
} PglEventObserver; } PglEventObserver;
/// Initialize pgl. /// Initialize pgl.
@ -43,8 +45,11 @@ Result pglInitialize(void);
/// Exit pgl. /// Exit pgl.
void pglExit(void); void pglExit(void);
/// Gets the Service object for the actual pgl service session. /// Gets the Service object for the actual pgl service session. Requires < 12.0.0
Service* pglGetServiceSession(void); 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 pglLaunchProgram(u64 *out_pid, const NcmProgramLocation *loc, u32 pm_launch_flags, u8 pgl_launch_flags);
Result pglTerminateProcess(u64 pid); Result pglTerminateProcess(u64 pid);

View File

@ -4,40 +4,82 @@
#include "services/pgl.h" #include "services/pgl.h"
#include "runtime/hosversion.h" #include "runtime/hosversion.h"
static Service g_pglSrv; static union {
Service cmif;
TipcService tipc;
} g_pglSrv;
NX_GENERATE_SERVICE_GUARD(pgl); NX_GENERATE_SERVICE_GUARD(pgl);
static bool _pglShouldUseTipc(void) {
return hosversionAtLeast(12,0,0);
}
Result _pglInitialize(void) { Result _pglInitialize(void) {
if (hosversionBefore(10,0,0)) if (hosversionBefore(10,0,0))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); 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) { void _pglCleanup(void) {
serviceClose(&g_pglSrv); if (_pglShouldUseTipc()) {
tipcClose(&g_pglSrv.tipc);
} else {
serviceClose(&g_pglSrv.cmif);
}
} }
Service* pglGetServiceSession(void) { Service* pglGetServiceSessionCmif(void) {
return &g_pglSrv; 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; 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; 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 (R_SUCCEEDED(rc)) {
if (out) *out = outval & 1; if (out) *out = outval & 1;
} }
return rc; return rc;
} }
static Result _pglCmdInU64(Service* srv, u64 inval, u32 cmd_id) { static Result _pglCmdInU64(u64 inval, u32 cmd_id) {
return serviceDispatchIn(srv, cmd_id, inval); 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) { 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; u32 pm_flags;
NcmProgramLocation loc; NcmProgramLocation loc;
} in = { pgl_launch_flags, pm_launch_flags, *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) { 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) { Result pglLaunchProgramFromHost(u64 *out_pid, const char *content_path, u32 pm_launch_flags) {
return serviceDispatchInOut(&g_pglSrv, 2, pm_launch_flags, *out_pid, if (_pglShouldUseTipc()) {
return tipcDispatchInOut(&g_pglSrv.tipc, 2, pm_launch_flags, *out_pid,
.buffer_attrs = { SfBufferAttr_In | SfBufferAttr_HipcMapAlias }, .buffer_attrs = { SfBufferAttr_In | SfBufferAttr_HipcMapAlias },
.buffers = { { content_path, strlen(content_path) + 1 } }, .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) { Result pglGetHostContentMetaInfo(PglContentMetaInfo *out, const char *content_path) {
return serviceDispatchOut(&g_pglSrv, 4, *out, if (_pglShouldUseTipc()) {
return tipcDispatchOut(&g_pglSrv.tipc, 4, *out,
.buffer_attrs = { SfBufferAttr_In | SfBufferAttr_HipcMapAlias }, .buffer_attrs = { SfBufferAttr_In | SfBufferAttr_HipcMapAlias },
.buffers = { { content_path, strlen(content_path) + 1 } }, .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) { 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) { Result pglBoostSystemMemoryResourceLimit(u64 size) {
return _pglCmdInU64(&g_pglSrv, size, 6); return _pglCmdInU64(size, 6);
} }
Result pglIsProcessTracked(bool *out, u64 pid) { Result pglIsProcessTracked(bool *out, u64 pid) {
u8 outval = 0; 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 (R_SUCCEEDED(rc)) {
if (out) *out = outval & 1; if (out) *out = outval & 1;
} }
@ -85,38 +157,56 @@ Result pglIsProcessTracked(bool *out, u64 pid) {
} }
Result pglEnableApplicationCrashReport(bool en) { Result pglEnableApplicationCrashReport(bool en) {
return _pglCmdInBool(&g_pglSrv, en, 8); return _pglCmdInBool(en, 8);
} }
Result pglIsApplicationCrashReportEnabled(bool *out) { Result pglIsApplicationCrashReportEnabled(bool *out) {
return _pglCmdOutBool(&g_pglSrv, out, 9); return _pglCmdOutBool(out, 9);
} }
Result pglEnableApplicationAllThreadDumpOnCrash(bool en) { Result pglEnableApplicationAllThreadDumpOnCrash(bool en) {
return _pglCmdInBool(&g_pglSrv, en, 10); return _pglCmdInBool(en, 10);
} }
Result pglTriggerApplicationSnapShotDumper(PglSnapShotDumpType dump_type, const char *arg) { 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"); _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 }, .buffer_attrs = { SfBufferAttr_In | SfBufferAttr_HipcMapAlias },
.buffers = { { arg, strlen(arg) + 1 } }, .buffers = { { arg, strlen(arg) + 1 } },
); );
} }
Result pglGetEventObserver(PglEventObserver *out) { Result pglGetEventObserver(PglEventObserver *out) {
return serviceDispatch(&g_pglSrv, 20, 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_num_objects = 1,
.out_objects = &out->s, .out_objects = &out->s,
); );
}
} }
Result pglEventObserverGetProcessEvent(PglEventObserver *observer, Event *out) { Result pglEventObserverGetProcessEvent(PglEventObserver *observer, Event *out) {
Handle evt_handle; Handle evt_handle;
Result rc = serviceDispatch(&observer->s, 0, Result rc;
if (_pglShouldUseTipc()) {
rc = tipcDispatch(&observer->t, 0,
.out_handle_attrs = { SfOutHandleAttr_HipcCopy }, .out_handle_attrs = { SfOutHandleAttr_HipcCopy },
.out_handles = &evt_handle, .out_handles = &evt_handle,
); );
} else {
rc = serviceDispatch(&observer->s, 0,
.out_handle_attrs = { SfOutHandleAttr_HipcCopy },
.out_handles = &evt_handle,
);
}
if (R_SUCCEEDED(rc)) { if (R_SUCCEEDED(rc)) {
eventLoadRemote(out, evt_handle, true); eventLoadRemote(out, evt_handle, true);
@ -126,9 +216,17 @@ Result pglEventObserverGetProcessEvent(PglEventObserver *observer, Event *out) {
} }
Result pglEventObserverGetProcessEventInfo(PglEventObserver *observer, PmProcessEventInfo *out) { Result pglEventObserverGetProcessEventInfo(PglEventObserver *observer, PmProcessEventInfo *out) {
if (_pglShouldUseTipc()) {
return tipcDispatchOut(&observer->t, 1, *out);
} else {
return serviceDispatchOut(&observer->s, 1, *out); return serviceDispatchOut(&observer->s, 1, *out);
}
} }
void pglEventObserverClose(PglEventObserver *observer) { void pglEventObserverClose(PglEventObserver *observer) {
if (_pglShouldUseTipc()) {
tipcClose(&observer->t);
} else {
serviceClose(&observer->s); serviceClose(&observer->s);
}
} }