From 601c76b5086397cedd2966ac1b30b226f3f3442d Mon Sep 17 00:00:00 2001 From: yellows8 Date: Wed, 20 Feb 2019 23:42:17 -0500 Subject: [PATCH] Initial support for WebApplet/non-webWifi. --- nx/include/switch/applets/web.h | 50 ++++++++++++++++++++++++- nx/source/applets/web.c | 66 ++++++++++++++++++++++++++++++++- 2 files changed, 114 insertions(+), 2 deletions(-) diff --git a/nx/include/switch/applets/web.h b/nx/include/switch/applets/web.h index 6575251a..f55e37db 100644 --- a/nx/include/switch/applets/web.h +++ b/nx/include/switch/applets/web.h @@ -8,8 +8,17 @@ #include "../types.h" #include "../services/applet.h" +/// This indicates the type of web-applet. +typedef enum { + WebShimKind_Login = 2, + WebShimKind_Share = 4, + WebShimKind_Web = 5, + WebShimKind_Wifi = 6, + WebShimKind_Lobby = 7, +} WebShimKind; + typedef struct { - u32 unk_x0; ///< Official sw sets this to 0 with appletStorageWrite, seperately from the rest of the config struct. + u32 unk_x0; ///< Official sw sets this to 0 with appletStorageWrite, separately from the rest of the config struct. char conntest_url[0x100]; char initial_url[0x400]; u128 userID; @@ -25,6 +34,31 @@ typedef struct { WebWifiPageArg arg; } WebWifiConfig; +typedef struct { + u8 arg[0x2000]; +} WebPageConfig; + +typedef struct { + u32 webExitReason; + u32 pad; + char lastUrl[0x1000]; + u64 lastUrlSize; +} WebPageReturnValue; + +/// Header struct at offset 0 in the web Arg storage (non-webWifi). +typedef struct { + u16 total_entries; ///< Total \ref WebArgTLV entries following this struct. + u16 pad; + WebShimKind shimKind; +} PACKED WebArgHeader; + +/// Web TLV used in the web Arg storage. +typedef struct { + u16 type; ///< Type of this arg. + u16 size; ///< Size of the arg data following this struct. + u8 pad[4]; +} PACKED WebArgTLV; + /** * @brief Creates the config for WifiWebAuthApplet. * @param config WebWifiConfig object. @@ -42,3 +76,17 @@ void webWifiCreate(WebWifiConfig* config, const char* conntest_url, const char* */ Result webWifiShow(WebWifiConfig* config, WebWifiReturnValue *out); +/** + * @brief Creates the config for WebApplet. + * @param config WebPageConfig object. + * @param url Optional initial URL navigated to by the applet, can be NULL. + */ +void webPageCreate(WebPageConfig* config, const char* url); + +/** + * @brief Launches WebApplet with the specified config and waits for it to exit. + * @param config WebPageConfig object. + * @param out Optional output applet reply data, can be NULL. + */ +Result webPageShow(WebPageConfig* config, WebPageReturnValue *out); + diff --git a/nx/source/applets/web.c b/nx/source/applets/web.c index b04ce771..6ab418af 100644 --- a/nx/source/applets/web.c +++ b/nx/source/applets/web.c @@ -55,8 +55,53 @@ static Result _webShow(AppletId id, u32 version, void* arg, size_t arg_size, voi return rc; } +static void _webArgInitialize(void* buffer, size_t size, WebShimKind shimKind) { + WebArgHeader *hdr = (WebArgHeader*)buffer; + + memset(buffer, 0, size); + hdr->shimKind = shimKind; +} + +static void _webTLVWrite(void* buffer, size_t size, u16 type, const void* argdata, u16 argdata_size) { + size_t i, count, offset; + WebArgHeader *hdr = (WebArgHeader*)buffer; + WebArgTLV *tlv; + u8 *dataptr = (u8*)buffer; + + offset = sizeof(WebArgHeader); + if (size < offset) return; + + count = hdr->total_entries; + tlv = (WebArgTLV*)&dataptr[offset]; + + for (i=0; itype == type) { + if (tlv->size != argdata_size) return; + break; + } + + offset+= sizeof(WebArgTLV) + tlv->size; + if (size < offset) return; + } + + if (size < offset + sizeof(WebArgTLV) + argdata_size) return; + + if (tlv->type != type) { + tlv->type = type; + tlv->size = argdata_size; + hdr->total_entries++; + } + + offset+= sizeof(WebArgTLV); + memcpy(&dataptr[offset], argdata, argdata_size); +} + void webWifiCreate(WebWifiConfig* config, const char* conntest_url, const char* initial_url, u128 userID, u32 unk) { - memset(config, 0, sizeof(WebWifiConfig)); + memset(config, 0, sizeof(*config)); if (conntest_url==NULL) conntest_url = initial_url; @@ -71,3 +116,22 @@ Result webWifiShow(WebWifiConfig* config, WebWifiReturnValue *out) { return _webShow(AppletId_wifiWebAuth, 0, &config->arg, sizeof(config->arg), out, sizeof(*out)); } +void webPageCreate(WebPageConfig* config, const char* url) { + char tmpurl[0xc00]; + + _webArgInitialize(config->arg, sizeof(config->arg), WebShimKind_Web); + + u8 tmpval=1; + _webTLVWrite(config->arg, sizeof(config->arg), 0x12, &tmpval, sizeof(tmpval)); /// Type was changed to 0xD with a newer version. + + if (url) { + memset(tmpurl, 0, sizeof(tmpurl)); + strncpy(tmpurl, url, sizeof(tmpurl)-1); + _webTLVWrite(config->arg, sizeof(config->arg), 0x1, tmpurl, sizeof(tmpurl)); + } +} + +Result webPageShow(WebPageConfig* config, WebPageReturnValue *out) { + return _webShow(AppletId_web, 0x20000, config->arg, sizeof(config->arg), out, sizeof(*out)); +} +