Added support for nifmLa. Added nifmRequestGetAppletInfo.

This commit is contained in:
yellows8 2020-06-11 19:00:07 -04:00
parent 05badbdc29
commit 29dd63e5db
No known key found for this signature in database
GPG Key ID: 0AF90DA3F1E60E43
5 changed files with 146 additions and 0 deletions

View File

@ -137,6 +137,7 @@ extern "C" {
#include "switch/applets/hid_la.h" #include "switch/applets/hid_la.h"
#include "switch/applets/mii_la.h" #include "switch/applets/mii_la.h"
#include "switch/applets/nfp_la.h" #include "switch/applets/nfp_la.h"
#include "switch/applets/nifm_la.h"
#include "switch/applets/pctlauth.h" #include "switch/applets/pctlauth.h"
#include "switch/applets/psel.h" #include "switch/applets/psel.h"
#include "switch/applets/error.h" #include "switch/applets/error.h"

View File

@ -0,0 +1,16 @@
/**
* @file nifm_la.h
* @brief Wrapper for using the nifm LibraryApplet (the launched applet varies).
* @author yellows8
* @copyright libnx Authors
*/
#pragma once
#include "../types.h"
#include "../services/nifm.h"
/**
* @brief Uses \ref nifmGetResult, then on failure launches the applet.
* @param r \ref NifmRequest
*/
Result nifmLaHandleNetworkRequestResult(NifmRequest* r);

View File

@ -269,5 +269,18 @@ Result nifmRequestSubmit(NifmRequest* r);
*/ */
Result nifmRequestSubmitAndWait(NifmRequest* r); Result nifmRequestSubmitAndWait(NifmRequest* r);
/**
* @brief GetAppletInfo
* @note This is used by \ref nifmLaHandleNetworkRequestResult.
* @param r \ref NifmRequest
* @param[in] theme_color ThemeColor
* @param[out] buffer Output buffer for storage data.
* @param[in] size Output buffer size.
* @param[out] applet_id \ref AppletId
* @param[out] mode \ref LibAppletMode
* @param[out] out_size Total data size written to the output buffer.
*/
Result nifmRequestGetAppletInfo(NifmRequest* r, u32 theme_color, void* buffer, size_t size, u32 *applet_id, u32 *mode, u32 *out_size);
///@} ///@}

View File

@ -0,0 +1,93 @@
#include <string.h>
#include "libapplet_internal.h"
#include "applets/nifm_la.h"
static Result _nifmLaPrepare(NifmRequest* r, AppletHolder *holder) {
Result rc=0;
u32 applet_id=0;
u32 mode=0;
u32 out_size=0;
u8 buf[0x1000];
u8 *data_ptr = buf;
memset(buf, 0, sizeof(buf));
rc = nifmRequestGetAppletInfo(r, appletGetThemeColorType(), buf, sizeof(buf), &applet_id, &mode, &out_size);
if (R_FAILED(rc)) return rc;
rc = appletCreateLibraryApplet(holder, applet_id, mode);
if (R_FAILED(rc)) return rc;
while(out_size >= sizeof(s32)) {
s32 storage_size = *((s32*)data_ptr);
data_ptr+= sizeof(s32);
out_size-= sizeof(s32);
if (storage_size == -1) return 0;
if (out_size <= storage_size) break;
rc = libappletPushInData(holder, data_ptr, storage_size);
if (R_FAILED(rc)) return rc;
data_ptr+= storage_size;
out_size-= storage_size;
}
return MAKERESULT(Module_Libnx, LibnxError_ShouldNotHappen);
}
static Result _nifmLaFinish(AppletHolder *holder) {
Result rc=0;
AppletStorage storage;
s64 storage_size=0;
appletHolderJoin(holder);
LibAppletExitReason reason = appletHolderGetExitReason(holder);
if (reason == LibAppletExitReason_Canceled || reason == LibAppletExitReason_Abnormal || reason == LibAppletExitReason_Unexpected) {
rc = MAKERESULT(Module_Libnx, LibnxError_LibAppletBadExit);
}
if (R_SUCCEEDED(rc)) rc = appletHolderPopOutData(holder, &storage);
if (R_SUCCEEDED(rc)) rc = appletStorageGetSize(&storage, &storage_size);
if (R_SUCCEEDED(rc)) {
s32 ret=-1;
if (storage_size == sizeof(ret)) {
rc = appletStorageRead(&storage, 0, &ret, sizeof(ret));
if (R_SUCCEEDED(rc)) rc = ret==0 ? MAKERESULT(110, 190) : MAKERESULT(110, 2900);
}
else if (storage_size >= sizeof(ret)) {
storage_size-= sizeof(ret);
Result tmprc=0;
rc = appletStorageRead(&storage, 0, &ret, sizeof(ret));
if (R_SUCCEEDED(rc)) rc = appletStorageRead(&storage, sizeof(ret), &tmprc, storage_size < sizeof(tmprc) ? storage_size : sizeof(tmprc));
if (R_SUCCEEDED(rc)) {
if ((!ret && storage_size != sizeof(tmprc)) || (ret && storage_size < sizeof(tmprc)))
rc = MAKERESULT(Module_Libnx, LibnxError_LibAppletBadExit);
}
if (R_SUCCEEDED(rc)) rc = tmprc;
}
else
rc = MAKERESULT(Module_Libnx, LibnxError_LibAppletBadExit);
appletStorageClose(&storage);
}
return rc;
}
Result nifmLaHandleNetworkRequestResult(NifmRequest* r) {
Result rc=0;
AppletHolder holder={0};
rc = nifmGetResult(r);
if (R_SUCCEEDED(rc)) return rc;
rc = _nifmLaPrepare(r, &holder);
if (R_SUCCEEDED(rc)) rc = appletHolderStart(&holder);
if (R_SUCCEEDED(rc)) rc = _nifmLaFinish(&holder);
appletHolderClose(&holder);
return rc;
}

View File

@ -429,3 +429,26 @@ Result nifmRequestSubmitAndWait(NifmRequest* r) {
return rc; return rc;
} }
Result nifmRequestGetAppletInfo(NifmRequest* r, u32 theme_color, void* buffer, size_t size, u32 *applet_id, u32 *mode, u32 *out_size) {
if (!serviceIsActive(&r->s))
return MAKERESULT(Module_Libnx, LibnxError_NotInitialized);
struct {
u32 applet_id;
u32 mode;
u32 out_size;
} out;
serviceAssumeDomain(&r->s);
Result rc = serviceDispatchInOut(&r->s, 21, theme_color, out,
.buffer_attrs = { SfBufferAttr_HipcMapAlias | SfBufferAttr_Out },
.buffers = { { buffer, size } },
);
if (R_SUCCEEDED(rc)) {
if (applet_id) *applet_id = out.applet_id;
if (mode) *mode = out.mode;
if (out_size) *out_size = out.out_size;
}
return rc;
}