From 76daefae78671ee13acdf91b677d1953b93e1e69 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Fri, 20 Sep 2019 12:17:57 -0700 Subject: [PATCH] ro: update to use new-ipc --- nx/source/services/ro.c | 305 +++++++--------------------------------- 1 file changed, 49 insertions(+), 256 deletions(-) diff --git a/nx/source/services/ro.c b/nx/source/services/ro.c index 79903a11..00e1e646 100644 --- a/nx/source/services/ro.c +++ b/nx/source/services/ro.c @@ -1,86 +1,60 @@ // Copyright 2018 SciresM +#define NX_SERVICE_ASSUME_NON_DOMAIN #include -#include "types.h" -#include "result.h" -#include "arm/atomics.h" -#include "kernel/ipc.h" +#include "service_guard.h" #include "runtime/hosversion.h" #include "services/ro.h" -#include "services/sm.h" static Service g_roSrv, g_ro1Srv, g_dmntSrv; -static u64 g_roRefCnt, g_ro1RefCnt, g_dmntRefCnt; -static Result _rosrvInitialize(Service* srv); -static Result _rosrvLoadNro(Service* srv, u64* out_address, u64 nro_address, u64 nro_size, u64 bss_address, u64 bss_size); -static Result _rosrvUnloadNro(Service* srv, u64 nro_address); -static Result _rosrvLoadNrr(Service* srv, u64 cmd_id, u64 nrr_address, u64 nrr_size); -static Result _rosrvUnloadNrr(Service* srv, u64 nrr_address); +NX_GENERATE_SERVICE_GUARD(ldrRo); +NX_GENERATE_SERVICE_GUARD(ro1); +NX_GENERATE_SERVICE_GUARD(roDmnt); -Result ldrRoInitialize(void) { - atomicIncrement64(&g_roRefCnt); - - if (serviceIsActive(&g_roSrv)) - return 0; +NX_INLINE Result _rosrvInitialize(Service* srv); +NX_INLINE Result _rosrvLoadNro(Service* srv, u64* out_address, u64 nro_address, u64 nro_size, u64 bss_address, u64 bss_size); +NX_INLINE Result _rosrvUnloadNro(Service* srv, u64 nro_address); +NX_INLINE Result _rosrvLoadNrr(Service* srv, u64 cmd_id, u64 nrr_address, u64 nrr_size); +NX_INLINE Result _rosrvUnloadNrr(Service* srv, u64 nrr_address); +Result _ldrRoInitialize(void) { Result rc = smGetService(&g_roSrv, "ldr:ro"); - - if (R_SUCCEEDED(rc)) { + if (R_SUCCEEDED(rc)) rc = _rosrvInitialize(&g_roSrv); - } - return rc; } -void ldrRoExit(void) { - if (atomicDecrement64(&g_roRefCnt) == 0) - serviceClose(&g_roSrv); +void _ldrRoCleanup(void) { + serviceClose(&g_roSrv); } Service* ldrRoGetServiceSession(void) { return &g_roSrv; } -Result ro1Initialize(void) { +Result _ro1Initialize(void) { if (hosversionBefore(7,0,0)) return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); - - atomicIncrement64(&g_ro1RefCnt); - - if (serviceIsActive(&g_ro1Srv)) - return 0; - Result rc = smGetService(&g_ro1Srv, "ro:1"); - - if (R_SUCCEEDED(rc)) { + if (R_SUCCEEDED(rc)) rc = _rosrvInitialize(&g_ro1Srv); - } - return rc; } -void ro1Exit(void) { - if (atomicDecrement64(&g_ro1RefCnt) == 0) - serviceClose(&g_ro1Srv); +void _ro1Cleanup(void) { + serviceClose(&g_ro1Srv); } Service* ro1GetServiceSession(void) { return &g_ro1Srv; } -Result roDmntInitialize(void) { +Result _roDmntInitialize(void) { if (hosversionBefore(3,0,0)) return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); - - atomicIncrement64(&g_dmntRefCnt); - - if (serviceIsActive(&g_dmntSrv)) - return 0; - return smGetService(&g_dmntSrv, "ro:dmnt"); } -void roDmntExit(void) { - if (atomicDecrement64(&g_dmntRefCnt) == 0) - serviceClose(&g_dmntSrv); +void _roDmntCleanup(void) { + serviceClose(&g_dmntSrv); } Service* roDmntGetServiceSession(void) { @@ -88,198 +62,46 @@ Service* roDmntGetServiceSession(void) { } Result _rosrvInitialize(Service* srv) { - IpcCommand c; - ipcInitialize(&c); - ipcSendHandleCopy(&c, CUR_PROCESS_HANDLE); - ipcSendPid(&c); - - struct { - u64 magic; - u64 cmd_id; - } *raw; - - raw = serviceIpcPrepareHeader(srv, &c, sizeof(*raw)); - - raw->magic = SFCI_MAGIC; - raw->cmd_id = 4; - - Result rc = serviceIpcDispatch(srv); - - if (R_SUCCEEDED(rc)) { - IpcParsedCommand r; - struct { - u64 magic; - u64 result; - } *resp; - - serviceIpcParse(srv, &r, sizeof(*resp)); - resp = r.Raw; - - rc = resp->result; - } - - return rc; + return serviceDispatch(srv, 4, + .in_num_handles = 1, + .in_handles = { CUR_PROCESS_HANDLE }, + ); } Result _rosrvLoadNro(Service* srv, u64* out_address, u64 nro_address, u64 nro_size, u64 bss_address, u64 bss_size) { - IpcCommand c; - ipcInitialize(&c); - ipcSendPid(&c); - - struct { - u64 magic; - u64 cmd_id; - u64 pid; + const struct { + u64 pid_placeholder; u64 nro_address; u64 nro_size; u64 bss_address; u64 bss_size; - } *raw; - - raw = serviceIpcPrepareHeader(srv, &c, sizeof(*raw)); - - raw->magic = SFCI_MAGIC; - raw->cmd_id = 0; - raw->pid = 0; - raw->nro_address = nro_address; - raw->nro_size = nro_size; - raw->bss_address = bss_address; - raw->bss_size = bss_size; - - Result rc = serviceIpcDispatch(srv); - - if (R_SUCCEEDED(rc)) { - IpcParsedCommand r; - struct { - u64 magic; - u64 result; - u64 out_address; - } *resp; - - serviceIpcParse(srv, &r, sizeof(*resp)); - resp = r.Raw; - - rc = resp->result; - - if (R_SUCCEEDED(rc)) { - if (out_address) *out_address = resp->out_address; - } - } - - return rc; + } in = { 0, nro_address, nro_size, bss_address, bss_size }; + return serviceDispatchInOut(srv, 0, in, *out_address, .in_send_pid = true); } Result _rosrvUnloadNro(Service* srv, u64 nro_address) { - IpcCommand c; - ipcInitialize(&c); - ipcSendPid(&c); - - struct { - u64 magic; - u64 cmd_id; - u64 pid; + const struct { + u64 pid_placeholder; u64 nro_address; - } *raw; - - raw = serviceIpcPrepareHeader(srv, &c, sizeof(*raw)); - - raw->magic = SFCI_MAGIC; - raw->cmd_id = 1; - raw->pid = 0; - raw->nro_address = nro_address; - - Result rc = serviceIpcDispatch(srv); - - if (R_SUCCEEDED(rc)) { - IpcParsedCommand r; - struct { - u64 magic; - u64 result; - } *resp; - - serviceIpcParse(srv, &r, sizeof(*resp)); - resp = r.Raw; - - rc = resp->result; - } - - return rc; + } in = { 0, nro_address }; + return serviceDispatchIn(srv, 1, in, .in_send_pid = true); } Result _rosrvLoadNrr(Service* srv, u64 cmd_id, u64 nrr_address, u64 nrr_size) { - IpcCommand c; - ipcInitialize(&c); - ipcSendPid(&c); - - struct { - u64 magic; - u64 cmd_id; - u64 pid; + const struct { + u64 pid_placeholder; u64 nrr_address; u64 nrr_size; - } *raw; - - raw = serviceIpcPrepareHeader(srv, &c, sizeof(*raw)); - - raw->magic = SFCI_MAGIC; - raw->cmd_id = cmd_id; - raw->pid = 0; - raw->nrr_address = nrr_address; - raw->nrr_size = nrr_size; - - Result rc = serviceIpcDispatch(srv); - - if (R_SUCCEEDED(rc)) { - IpcParsedCommand r; - struct { - u64 magic; - u64 result; - } *resp; - - serviceIpcParse(srv, &r, sizeof(*resp)); - resp = r.Raw; - - rc = resp->result; - } - - return rc; + } in = { 0, nrr_address, nrr_size }; + return serviceDispatchIn(srv, cmd_id, in, .in_send_pid = true); } Result _rosrvUnloadNrr(Service* srv, u64 nrr_address) { - IpcCommand c; - ipcInitialize(&c); - ipcSendPid(&c); - - struct { - u64 magic; - u64 cmd_id; - u64 pid; + const struct { + u64 pid_placeholder; u64 nrr_address; - } *raw; - - raw = serviceIpcPrepareHeader(srv, &c, sizeof(*raw)); - - raw->magic = SFCI_MAGIC; - raw->cmd_id = 3; - raw->pid = 0; - raw->nrr_address = nrr_address; - - Result rc = serviceIpcDispatch(srv); - - if (R_SUCCEEDED(rc)) { - IpcParsedCommand r; - struct { - u64 magic; - u64 result; - } *resp; - - serviceIpcParse(srv, &r, sizeof(*resp)); - resp = r.Raw; - - rc = resp->result; - } - - return rc; + } in = { 0, nrr_address }; + return serviceDispatchIn(srv, 3, in, .in_send_pid = true); } Result ldrRoLoadNro(u64* out_address, u64 nro_address, u64 nro_size, u64 bss_address, u64 bss_size) { @@ -326,41 +148,12 @@ Result ro1LoadNrrEx(u64 nrr_address, u64 nrr_size) { } Result roDmntGetModuleInfos(u64 pid, LoaderModuleInfo *out_module_infos, size_t max_out_modules, u32 *num_out) { - IpcCommand c; - ipcInitialize(&c); - - ipcAddRecvBuffer(&c, out_module_infos, max_out_modules * sizeof(*out_module_infos), BufferType_Normal); - - struct { - u64 magic; - u64 cmd_id; - u64 pid; - } *raw; - - raw = serviceIpcPrepareHeader(&g_dmntSrv, &c, sizeof(*raw)); - - raw->magic = SFCI_MAGIC; - raw->cmd_id = 0; - raw->pid = pid; - - Result rc = serviceIpcDispatch(&g_dmntSrv); - - if (R_SUCCEEDED(rc)) { - IpcParsedCommand r; - struct { - u64 magic; - u64 result; - u32 num_out; - } *resp; - - serviceIpcParse(&g_dmntSrv, &r, sizeof(*resp)); - resp = r.Raw; - - rc = resp->result; - if (R_SUCCEEDED(rc) && num_out != NULL) { - *num_out = resp->num_out; - } - } - - return rc; + return serviceDispatchInOut(&g_dmntSrv, 0, pid, *num_out, + .buffer_attrs = { + SfBufferAttr_HipcMapAlias | SfBufferAttr_Out, + }, + .buffers = { + { out_module_infos, max_out_modules * sizeof(*out_module_infos) }, + }, + ); }