diff --git a/nx/include/switch/applets/libapplet.h b/nx/include/switch/applets/libapplet.h index 77792c62..4c090a67 100644 --- a/nx/include/switch/applets/libapplet.h +++ b/nx/include/switch/applets/libapplet.h @@ -10,10 +10,10 @@ /// CommonArguments typedef struct { - u32 CommonArgs_version; - u32 CommonArgs_size; + u32 CommonArgs_version; ///< \ref libappletArgsCreate sets this to 1, and \ref libappletArgsPop requires value 1. v0 is not supported. + u32 CommonArgs_size; ///< Size of this struct. - u32 LaVersion; ///< LibraryApplet API version + u32 LaVersion; ///< LibraryApplet API version. s32 ExpectedThemeColor; ///< Set to the output from \ref appletGetThemeColorType by \ref libappletArgsCreate. u8 PlayStartupSound; ///< bool flag, default is false. u8 pad[7]; @@ -58,6 +58,12 @@ Result libappletReadStorage(AppletStorage* s, void* buffer, size_t size, size_t */ Result libappletArgsPush(LibAppletArgs* a, AppletHolder *h); +/** + * @brief Uses \ref appletPopInData and reads it to the specified LibAppletArgs. The LibAppletArgs is validated, an error is thrown when invalid. + * @param[out] a LibAppletArgs struct. + */ +Result libappletArgsPop(LibAppletArgs* a); + /** * @brief Creates a storage using the input buffer which is pushed to the AppletHolder via \ref appletHolderPushInData. * @param h AppletHolder object. diff --git a/nx/source/applets/libapplet.c b/nx/source/applets/libapplet.c index c431ce5d..c7e5773e 100644 --- a/nx/source/applets/libapplet.c +++ b/nx/source/applets/libapplet.c @@ -69,6 +69,28 @@ Result libappletArgsPush(LibAppletArgs* a, AppletHolder *h) { return _libappletPushInData(h, a, sizeof(LibAppletArgs)); } +Result libappletArgsPop(LibAppletArgs* a) { + //Official sw stores the header in LibAppletArgs seperately (first 8-bytes), but here we're including it with the LibAppletCommonArguments struct. + //Official sw uses appletStorageRead twice, for reading the header then the rest of the struct. + + AppletStorage storage; + s64 tmpsize=0; + size_t tmpsize2=0; + Result rc=0; + memset(a, 0, sizeof(LibAppletArgs)); + rc = appletPopInData(&storage); + + if (R_SUCCEEDED(rc)) rc = appletStorageGetSize(&storage, &tmpsize); + if (R_SUCCEEDED(rc) && tmpsize != sizeof(LibAppletArgs)) rc = MAKERESULT(Module_Libnx, LibnxError_BadInput); + + if (R_SUCCEEDED(rc)) rc = libappletReadStorage(&storage, a, sizeof(LibAppletArgs), &tmpsize2); + if (R_SUCCEEDED(rc) && tmpsize2 != sizeof(LibAppletArgs)) rc = MAKERESULT(Module_Libnx, LibnxError_BadInput); + if (R_SUCCEEDED(rc)) { + if (a->CommonArgs_version != 1 || a->CommonArgs_size != sizeof(LibAppletArgs)) rc = MAKERESULT(Module_Libnx, LibnxError_BadInput); + } + return rc; +} + static Result _libappletQlaunchRequest(u8* buf, size_t size) { Result rc=0; AppletStorage storage;