From a33fc6445726faf4dcda49b3a3415d4c233dd0f1 Mon Sep 17 00:00:00 2001 From: yellows8 Date: Sun, 15 Apr 2018 22:13:07 -0400 Subject: [PATCH] Implemented 3.0.0+ support for ns. --- nx/source/services/ns.c | 65 ++++++++++++++++++++++++++++++++++++----- 1 file changed, 58 insertions(+), 7 deletions(-) diff --git a/nx/source/services/ns.c b/nx/source/services/ns.c index 50764e85..69661bed 100644 --- a/nx/source/services/ns.c +++ b/nx/source/services/ns.c @@ -2,31 +2,82 @@ #include "result.h" #include "arm/atomics.h" #include "kernel/ipc.h" +#include "kernel/detect.h" #include "services/sm.h" #include "services/ns.h" -//TODO: >=3.0.0 support. - -static Service g_nsSrv; +static Service g_nsAppManSrv, g_nsGetterSrv; static u64 g_nsRefCnt; +static Result _nsGetInterface(Service* srv_out, u64 cmd_id); + Result nsInitialize(void) { + Result rc=0; + atomicIncrement64(&g_nsRefCnt); - if (serviceIsActive(&g_nsSrv)) + if (serviceIsActive(&g_nsGetterSrv) || serviceIsActive(&g_nsAppManSrv)) return 0; - return smGetService(&g_nsSrv, "ns:am");//This will fail on >=3.0.0. + if(!kernelAbove300()) + return smGetService(&g_nsAppManSrv, "ns:am"); + + rc = smGetService(&g_nsGetterSrv, "ns:am2");//TODO: Support the other services?(Only useful when ns:am2 isn't accessible) + if (R_FAILED(rc)) return rc; + + rc = _nsGetInterface(&g_nsAppManSrv, 7996); + + if (R_FAILED(rc)) serviceClose(&g_nsGetterSrv); + + return rc; } void nsExit(void) { if (atomicDecrement64(&g_nsRefCnt) == 0) { - serviceClose(&g_nsSrv); + serviceClose(&g_nsAppManSrv); + if(!kernelAbove300()) return; + + serviceClose(&g_nsGetterSrv); } } +static Result _nsGetInterface(Service* srv_out, u64 cmd_id) { + IpcCommand c; + ipcInitialize(&c); + + struct { + u64 magic; + u64 cmd_id; + } *raw; + + raw = ipcPrepareHeader(&c, sizeof(*raw)); + + raw->magic = SFCI_MAGIC; + raw->cmd_id = cmd_id; + + Result rc = serviceIpcDispatch(&g_nsGetterSrv); + + if (R_SUCCEEDED(rc)) { + IpcParsedCommand r; + ipcParse(&r); + + struct { + u64 magic; + u64 result; + } *resp = r.Raw; + + rc = resp->result; + + if (R_SUCCEEDED(rc)) { + serviceCreate(srv_out, r.Handles[0]); + } + } + + return rc; +} + Result nsGetApplicationControlData(u8 flag, u64 titleID, NsApplicationControlData* buffer, size_t size, size_t* actual_size) { IpcCommand c; ipcInitialize(&c); @@ -46,7 +97,7 @@ Result nsGetApplicationControlData(u8 flag, u64 titleID, NsApplicationControlDat raw->flag = flag; raw->titleID = titleID; - Result rc = serviceIpcDispatch(&g_nsSrv); + Result rc = serviceIpcDispatch(&g_nsAppManSrv); if (R_SUCCEEDED(rc)) { IpcParsedCommand r;