diff --git a/nx/include/switch/applets/error.h b/nx/include/switch/applets/error.h index 8d7744f2..aaa706eb 100644 --- a/nx/include/switch/applets/error.h +++ b/nx/include/switch/applets/error.h @@ -1,24 +1,28 @@ /** * @file error.h * @brief Wrapper for using the error LibraryApplet. - * @author StuntHacks + * @author StuntHacks, yellows8 * @copyright libnx Authors */ #pragma once #include "../types.h" #include "../services/applet.h" -/// Error configuration struct +/// Error configuration struct (SystemErrorArg) typedef struct { u8 custom_text; ///< Whether to show a custom error message. If this is false, a default message will be shown. u8 unk[7]; u32 module; ///< Module code. u32 description; ///< Description code. - u8 unk2[8]; + u64 languageCode; char short_description[0x800]; ///< Short description. - char detailed_description[0x800]; ///< Detailed description (displayed when the user clicks, on "Details"). + char detailed_description[0x800]; ///< Detailed description (displayed when the user clicks, on "Details"). } ErrorConfig; +typedef struct { + u8 unk_x0[0x200]; +} ErrorContext; + /** * @brief Creates an ErrorConfg struct. * @param c ErrorConfg struct. @@ -37,7 +41,7 @@ void errorClose(ErrorConfig* c); * @brief Launches with the specified config. * @param c ErrorConfig struct. */ -void errorShow(ErrorConfig* c); +Result errorShow(ErrorConfig* c); /** * @brief Sets the error module. diff --git a/nx/source/applets/error.c b/nx/source/applets/error.c index fe2fa634..f72c48e7 100644 --- a/nx/source/applets/error.c +++ b/nx/source/applets/error.c @@ -6,6 +6,64 @@ #include "applets/libapplet.h" #include "applets/error.h" +static Result _errorAppletCreate(AppletHolder* holder, const void* indata, size_t insize, const void* indata2, size_t insize2) { + Result rc=0; + LibAppletArgs commonargs; + + rc = appletCreateLibraryApplet(holder, AppletId_error, LibAppletMode_AllForeground); + if (R_FAILED(rc)) return rc; + + libappletArgsCreate(&commonargs, 0); + if (R_SUCCEEDED(rc)) rc = libappletArgsPush(&commonargs, holder); + if (R_SUCCEEDED(rc)) rc = libappletPushInData(holder, indata, insize); + if (R_SUCCEEDED(rc) && indata2 && insize2) rc = libappletPushInData(holder, indata2, insize2); + + return rc; +} + +static Result _errorRun(AppletHolder* holder) { + Result rc=0; + u8 reply[2]={0}; + size_t transfer_size = 0; + u8 status=0;//Official sw doesn't use the output status. + + if (R_SUCCEEDED(rc)) rc = appletHolderStart(holder); + + if (R_SUCCEEDED(rc)) { + appletHolderJoin(holder); + LibAppletExitReason reason = appletHolderGetExitReason(holder); + + if (reason == LibAppletExitReason_Normal) { + if (R_SUCCEEDED(libappletPopOutData(holder, reply, sizeof(reply), &transfer_size))) { + if (transfer_size != sizeof(reply)) rc = MAKERESULT(Module_Libnx, LibnxError_LibAppletBadExit); + if (R_SUCCEEDED(rc)) status = reply[1]; + } + } + else if (reason == LibAppletExitReason_Canceled) { + status = 0; + } + else { + rc = MAKERESULT(Module_Libnx, LibnxError_LibAppletBadExit); + } + + if (R_SUCCEEDED(rc) && status!=0) rc = MAKERESULT(Module_Libnx, LibnxError_LibAppletBadExit); + } + + return rc; +} + +static Result _errorShow(const void* indata, size_t insize, const void* indata2, size_t insize2) { + Result rc=0; + AppletHolder holder; + + rc = _errorAppletCreate(&holder, indata, insize, indata2, insize2); + if (R_SUCCEEDED(rc)) rc = _errorRun(&holder); + + appletHolderClose(&holder); + + return rc; +} + void errorCreate(ErrorConfig* c) { memset(c, 0, sizeof(ErrorConfig)); c->custom_text = false; @@ -16,18 +74,8 @@ void errorClose(ErrorConfig* c) { memset(c, 0, sizeof(ErrorConfig)); } -void errorShow(ErrorConfig* c) { - AppletHolder err; - LibAppletArgs errArgs; - - appletCreateLibraryApplet(&err, AppletId_error, LibAppletMode_AllForeground); - libappletArgsCreate(&errArgs, 1); - libappletArgsPush(&errArgs, &err); - libappletPushInData(&err, c, sizeof(ErrorConfig)); - - appletHolderStart(&err); - appletHolderJoin(&err); - appletHolderClose(&err); +Result errorShow(ErrorConfig* c) { + return _errorShow(c, sizeof(ErrorConfig), NULL, 0); } void errorConfigSetModule(ErrorConfig* c, u32 code) {