libnx/nx/source/applets/libapplet.c

146 lines
4.2 KiB
C

#include <string.h>
#include "types.h"
#include "result.h"
#include "arm/counter.h"
#include "services/applet.h"
#include "applets/libapplet.h"
void libappletArgsCreate(LibAppletArgs* a, u32 version) {
memset(a, 0, sizeof(LibAppletArgs));
a->CommonArgs_version = 1;
a->CommonArgs_size = sizeof(LibAppletArgs);
a->LaVersion = version;
a->ExpectedThemeColor = appletGetThemeColorType();
}
void libappletArgsSetPlayStartupSound(LibAppletArgs* a, bool flag) {
a->PlayStartupSound = flag!=0;
}
Result libappletCreateWriteStorage(AppletStorage* s, const void* buffer, size_t size) {
Result rc=0;
rc = appletCreateStorage(s, size);
if (R_FAILED(rc)) return rc;
rc = appletStorageWrite(s, 0, buffer, size);
if (R_FAILED(rc)) {
appletStorageClose(s);
return rc;
}
return rc;
}
Result libappletReadStorage(AppletStorage* s, void* buffer, size_t size, size_t *transfer_size) {
Result rc=0;
s64 tmpsize=0;
rc = appletStorageGetSize(s, &tmpsize);
if (R_SUCCEEDED(rc)) {
if (tmpsize < size) size = tmpsize;
rc = appletStorageRead(s, 0, buffer, size);
}
if (R_SUCCEEDED(rc) && transfer_size) *transfer_size = size;
return rc;
}
static Result _libappletPushInData(AppletHolder *h, const void* buffer, size_t size) {
Result rc=0;
AppletStorage storage;
rc = libappletCreateWriteStorage(&storage, buffer, size);
if (R_FAILED(rc)) return rc;
return appletHolderPushInData(h, &storage);
}
Result libappletArgsPush(LibAppletArgs* a, AppletHolder *h) {
//Official sw stores the header in LibAppletArgs seperately (first 8-bytes), but here we're including it with the LibAppletCommonArguments struct.
//Official sw uses appletStorageWrite twice, for writing the header then the rest of the struct.
a->tick = armGetSystemTick();
return _libappletPushInData(h, a, sizeof(LibAppletArgs));
}
static Result _libappletQlaunchRequest(u8* buf, size_t size) {
Result rc=0;
AppletStorage storage;
rc = libappletCreateWriteStorage(&storage, buf, size);
if (R_FAILED(rc)) return rc;
return appletPushToGeneralChannel(&storage);
}
Result libappletPushInData(AppletHolder *h, const void* buffer, size_t size) {
return _libappletPushInData(h, buffer, size);
}
Result libappletPopOutData(AppletHolder *h, void* buffer, size_t size, size_t *transfer_size) {
Result rc=0;
AppletStorage storage;
rc = appletHolderPopOutData(h, &storage);
if (R_FAILED(rc)) return rc;
rc = libappletReadStorage(&storage, buffer, size, transfer_size);
appletStorageClose(&storage);
return rc;
}
Result libappletStart(AppletHolder *h) {
Result rc=0;
rc = appletHolderStart(h);
if (R_SUCCEEDED(rc)) {
appletHolderJoin(h);
LibAppletExitReason reason = appletHolderGetExitReason(h);
if (reason == LibAppletExitReason_Canceled || reason == LibAppletExitReason_Abnormal || reason == LibAppletExitReason_Unexpected) {
rc = MAKERESULT(Module_Libnx, LibnxError_LibAppletBadExit);
}
}
return rc;
}
Result libappletLaunch(AppletId id, LibAppletArgs *commonargs, const void* arg, size_t arg_size, void* reply, size_t reply_size, size_t *out_reply_size) {
Result rc=0;
AppletHolder holder;
rc = appletCreateLibraryApplet(&holder, id, LibAppletMode_AllForeground);
if (R_FAILED(rc)) return rc;
rc = libappletArgsPush(commonargs, &holder);
if (R_SUCCEEDED(rc) && arg && arg_size) rc = libappletPushInData(&holder, arg, arg_size);
if (R_SUCCEEDED(rc)) rc = libappletStart(&holder);
if (R_SUCCEEDED(rc) && reply && reply_size) rc = libappletPopOutData(&holder, reply, reply_size, out_reply_size);
appletHolderClose(&holder);
return rc;
}
Result libappletRequestHomeMenu(void) {
u8 storagedata[0x10] = {0x53, 0x41, 0x4d, 0x53, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00};//RequestHomeMenu
return _libappletQlaunchRequest(storagedata, sizeof(storagedata));
}
Result libappletRequestJumpToSystemUpdate(void) {
u8 storagedata[0x10] = {0x53, 0x41, 0x4d, 0x53, 0x01, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00};//RequestJumpToSystemUpdate
return _libappletQlaunchRequest(storagedata, sizeof(storagedata));
}