From 42e7cf44cb47d2061923c650ae499f3a62ec37a8 Mon Sep 17 00:00:00 2001 From: yellows8 Date: Sun, 16 Dec 2018 18:16:01 -0500 Subject: [PATCH] Implemented applet IPC code for pushing storages/objects. Added appletPushToGeneralChannel(). --- nx/include/switch/services/applet.h | 9 ++++++ nx/source/services/applet.c | 44 +++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+) diff --git a/nx/include/switch/services/applet.h b/nx/include/switch/services/applet.h index d65396da..0f9bdde8 100644 --- a/nx/include/switch/services/applet.h +++ b/nx/include/switch/services/applet.h @@ -133,6 +133,14 @@ Result appletSetScreenShotPermission(s32 val); Result appletSetScreenShotImageOrientation(s32 val); +/** + * @brief Pushes a storage to the general channel. Used for sending requests to qlaunch. + * @note This is not usable under an Application, however it is usable under a LibraryApplet. + * @note This uses \ref appletStorageClose automatically. + * @param s Storage object. + */ +Result appletPushToGeneralChannel(AppletStorage *s); + /** * @brief Creates a storage. * @param s Storage object. @@ -164,6 +172,7 @@ Result appletCreateHandleStorage(AppletStorage *s, s64 inval, Handle handle); Result appletCreateHandleStorageTmem(AppletStorage *s, s64 size); /// Closes the storage object. TransferMemory closing is seperate, see \ref appletStorageCloseTmem. +/// Other applet functions which push an input storage will automatically call this. void appletStorageClose(AppletStorage *s); /// Closes the TransferMemory in the storage object. For TransferMemory storage created by the current process, this must be called after the LibraryApplet finishes using it (if sent to one). diff --git a/nx/source/services/applet.c b/nx/source/services/applet.c index 1f00d3c4..652270db 100644 --- a/nx/source/services/applet.c +++ b/nx/source/services/applet.c @@ -699,6 +699,46 @@ static Result _appletCmdInTmem(Service* srv, Service* srv_out, u64 cmd_id, Trans return _appletCmdInHandle64(srv, srv_out, cmd_id, tmem->handle, tmem->size); } +static Result _appletCmdInSession(Service* srv, Service* srv_in, u64 cmd_id) { + IpcCommand c; + ipcInitialize(&c); + + serviceSendObject(srv_in, &c); + + struct { + u64 magic; + u64 cmd_id; + } *raw; + + raw = serviceIpcPrepareHeader(srv, &c, sizeof(*raw)); + + raw->magic = SFCI_MAGIC; + raw->cmd_id = cmd_id; + + 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; +} + +static Result _appletCmdInStorage(Service* srv, AppletStorage* s, u64 cmd_id) { + Result rc = _appletCmdInSession(srv, &s->s, cmd_id); + appletStorageClose(s); + return rc; +} + // IWindowController static Result _appletGetAppletResourceUserId(u64 *out) { @@ -1122,6 +1162,10 @@ static Result _appletGetCurrentFocusState(u8 *out) { return rc; } +Result appletPushToGeneralChannel(AppletStorage *s) { + return _appletCmdInStorage(&g_appletICommonStateGetter, s, 20); +} + // ISelfController static Result _appletSelfExit(void) {