From ecd9127bedf00001726043cb73fe1d2b61a80fb0 Mon Sep 17 00:00:00 2001 From: yellows8 Date: Sun, 18 Aug 2019 23:15:41 -0400 Subject: [PATCH] Added appletHolderRequestExitOrTerminate and appletApplicationRequestExitLibraryAppletOrTerminate. Minor internal improvements. --- nx/include/switch/services/applet.h | 14 ++++++ nx/source/services/applet.c | 77 +++++++++++++++++++++++------ 2 files changed, 77 insertions(+), 14 deletions(-) diff --git a/nx/include/switch/services/applet.h b/nx/include/switch/services/applet.h index e2b9c31e..b9da3e5d 100644 --- a/nx/include/switch/services/applet.h +++ b/nx/include/switch/services/applet.h @@ -979,6 +979,13 @@ Result appletHolderJump(AppletHolder *h); */ Result appletHolderRequestExit(AppletHolder *h); +/** + * @brief Uses cmds GetAppletStateChangedEvent and RequestExit, then waits for the LibraryApplet to exit with the specified timeout. If a timeout occurs, the Terminate cmd is used. + * @param h AppletHolder object. + * @param[in] timeout Timeout in nanoseconds. U64_MAX for no timeout. + */ +Result appletHolderRequestExitOrTerminate(AppletHolder *h, u64 timeout); + /** * @brief Waits for the LibraryApplet to exit. * @param h AppletHolder object. @@ -1518,6 +1525,13 @@ AppletApplicationExitReason appletApplicationGetExitReason(AppletApplication *a) */ Result appletApplicationRequestForApplicationToGetForeground(AppletApplication *a); +/** + * @brief Calls the same func as \ref appletHolderRequestExitOrTerminate with the output IAppletAccessor from the GetCurrentLibraryApplet cmd. + * @param a \ref AppletApplication + * @param[in] timeout Timeout in nanoseconds. U64_MAX for no timeout. + */ +Result appletApplicationRequestExitLibraryAppletOrTerminate(AppletApplication *a, u64 timeout); + /** * @brief Gets the titleID for the Application. * @param a \ref AppletApplication diff --git a/nx/source/services/applet.c b/nx/source/services/applet.c index a3b2e132..2050adae 100644 --- a/nx/source/services/applet.c +++ b/nx/source/services/applet.c @@ -115,6 +115,7 @@ static Result _appletGetLaunchReason(AppletProcessLaunchReason *reason); static Result _appletOpenCallingLibraryApplet(AppletHolder *h); static Result _appletHolderCreateState(AppletHolder *h, LibAppletMode mode, bool creating_self); +static Result _appletOpenExistingLibraryApplet(AppletHolder *h, Service* srv, u64 cmd_id); Result appletInitialize(void) { @@ -2661,20 +2662,7 @@ static Result _appletOpenCallingLibraryApplet(AppletHolder *h) { if (__nx_applet_type != AppletType_LibraryApplet) return MAKERESULT(Module_Libnx, LibnxError_NotInitialized); - Result rc=0; - LibAppletInfo info={0}; - - memset(h, 0, sizeof(AppletHolder)); - - rc = _appletGetSession(&g_appletIProcessWindingController, &h->s, 11); - - if (R_SUCCEEDED(rc)) rc = appletHolderGetLibraryAppletInfo(h, &info); - - if (R_SUCCEEDED(rc)) rc = _appletHolderCreateState(h, info.mode, false); - - if (R_FAILED(rc)) appletHolderClose(h); - - return rc; + return _appletOpenExistingLibraryApplet(h, &g_appletIProcessWindingController, 11); } Result appletPushContext(AppletStorage *s) { @@ -2908,6 +2896,26 @@ static Result _appletHolderCreate(AppletHolder *h, AppletId id, LibAppletMode mo return rc; } +static Result _appletOpenExistingLibraryApplet(AppletHolder *h, Service* srv, u64 cmd_id) { + if (__nx_applet_type != AppletType_LibraryApplet) + return MAKERESULT(Module_Libnx, LibnxError_NotInitialized); + + Result rc=0; + LibAppletInfo info={0}; + + memset(h, 0, sizeof(AppletHolder)); + + rc = _appletGetSession(srv, &h->s, cmd_id); + + if (R_SUCCEEDED(rc)) rc = appletHolderGetLibraryAppletInfo(h, &info); + + if (R_SUCCEEDED(rc)) rc = _appletHolderCreateState(h, info.mode, false); + + if (R_FAILED(rc)) appletHolderClose(h); + + return rc; +} + Result appletCreateLibraryApplet(AppletHolder *h, AppletId id, LibAppletMode mode) { return _appletHolderCreate(h, id, mode, false); } @@ -2985,6 +2993,33 @@ Result appletHolderRequestExit(AppletHolder *h) { return rc; } +static Result _appletAccessorRequestExitOrTerminate(Service* srv, u64 timeout) { + Result rc=0; + Event StateChangedEvent={0}; + + if (!serviceIsActive(srv)) + return MAKERESULT(Module_Libnx, LibnxError_NotInitialized); + + rc = _appletGetEvent(srv, &StateChangedEvent, 0, false);//GetAppletStateChangedEvent + + if (R_SUCCEEDED(rc)) rc = _appletCmdNoIO(srv, 20);//RequestExit + + if (R_SUCCEEDED(rc)) { + rc = eventWait(&StateChangedEvent, timeout); + + if (R_FAILED(rc) && R_VALUE(rc) == KERNELRESULT(TimedOut)) + rc = _appletCmdNoIO(srv, 25);//Terminate + } + + eventClose(&StateChangedEvent); + + return rc; +} + +Result appletHolderRequestExitOrTerminate(AppletHolder *h, u64 timeout) { + return _appletAccessorRequestExitOrTerminate(&h->s, timeout); +} + void appletHolderJoin(AppletHolder *h) { Result rc=0; LibAppletExitReason res = LibAppletExitReason_Normal; @@ -4466,6 +4501,20 @@ Result appletApplicationRequestForApplicationToGetForeground(AppletApplication * return rc; } +Result appletApplicationRequestExitLibraryAppletOrTerminate(AppletApplication *a, u64 timeout) { + Result rc=0; + Service srv={0}; + + if (!serviceIsActive(&a->s)) + return MAKERESULT(Module_Libnx, LibnxError_NotInitialized); + + rc = _appletGetSession(&a->s, &srv, 112);//GetCurrentLibraryApplet + if (R_SUCCEEDED(rc)) rc = _appletAccessorRequestExitOrTerminate(&srv, timeout); + serviceClose(&srv); + + return rc; +} + Result appletApplicationGetApplicationId(AppletApplication *a, u64 *titleID) { Result rc=0;