mirror of
https://github.com/switchbrew/libnx.git
synced 2025-06-25 06:12:40 +02:00
Initial impl for LibraryApplet creation.
This commit is contained in:
parent
c8f732fda8
commit
8f22e9e213
@ -8,6 +8,7 @@
|
||||
#include "../types.h"
|
||||
#include "../services/sm.h"
|
||||
#include "../kernel/tmem.h"
|
||||
#include "../kernel/event.h"
|
||||
|
||||
typedef enum {
|
||||
AppletType_None = -2,
|
||||
@ -55,6 +56,37 @@ typedef enum {
|
||||
AppletLaunchParameterKind_Unknown = 3, ///< Unknown if used by anything?
|
||||
} AppletLaunchParameterKind;
|
||||
|
||||
typedef enum {
|
||||
AppletId_overlayDisp = 0x02, ///< 010000000000100C "overlayDisp"
|
||||
AppletId_qlaunch = 0x03, ///< 0100000000001000 "qlaunch" (SystemAppletMenu)
|
||||
AppletId_starter = 0x04, ///< 0100000000001012 "starter"
|
||||
AppletId_auth = 0x0A, ///< 0100000000001001 "auth"
|
||||
AppletId_cabinet = 0x0B, ///< 0100000000001002 "cabinet"
|
||||
AppletId_controller = 0x0C, ///< 0100000000001003 "controller"
|
||||
AppletId_dataErase = 0x0D, ///< 0100000000001004 "dataErase"
|
||||
AppletId_error = 0x0E, ///< 0100000000001005 "error"
|
||||
AppletId_netConnect = 0x0F, ///< 0100000000001006 "netConnect"
|
||||
AppletId_playerSelect = 0x10, ///< 0100000000001007 "playerSelect"
|
||||
AppletId_swkbd = 0x11, ///< 0100000000001008 "swkbd"
|
||||
AppletId_miiEdit = 0x12, ///< 0100000000001009 "miiEdit"
|
||||
AppletId_web = 0x13, ///< 010000000000100A "LibAppletWeb" WebApplet applet
|
||||
AppletId_shop = 0x14, ///< 010000000000100B "LibAppletShop" ShopN applet
|
||||
AppletId_photoViewer = 0x15, ///< 010000000000100D "photoViewer"
|
||||
AppletId_set = 0x16, ///< 010000000000100E "set" (This title is currently not present on retail devices.)
|
||||
AppletId_offlineWeb = 0x17, ///< 010000000000100F "LibAppletOff" Offline web-applet
|
||||
AppletId_loginShare = 0x18, ///< 0100000000001010 "LibAppletLns" Whitelisted web-applet
|
||||
AppletId_wifiWebAuth = 0x19, ///< 0100000000001011 "LibAppletAuth" WifiWebAuth applet
|
||||
AppletId_myPage = 0x1A, ///< 0100000000001013 "myPage"
|
||||
} AppletId;
|
||||
|
||||
/// LibraryAppletMode
|
||||
typedef enum {
|
||||
LibAppletMode_AllForeground = 0,
|
||||
LibAppletMode_Background = 1,
|
||||
LibAppletMode_Unknown2 = 2,
|
||||
LibAppletMode_Unknown3 = 3,
|
||||
} LibAppletMode;
|
||||
|
||||
/// applet hook function.
|
||||
typedef void (*AppletHookFn)(AppletHookType hook, void* param);
|
||||
|
||||
@ -74,6 +106,14 @@ typedef struct {
|
||||
TransferMemory tmem;
|
||||
} AppletStorage;
|
||||
|
||||
/// LibraryApplet state.
|
||||
typedef struct {
|
||||
Service s; ///< ILibraryAppletAccessor
|
||||
Event StateChangedEvent; ///< Output from GetAppletStateChangedEvent, autoclear=false.
|
||||
LibAppletMode mode; ///< See ref \ref LibAppletMode.
|
||||
u64 layer_handle; ///< Output from GetIndirectLayerConsumerHandle on 2.0.0+.
|
||||
} AppletHolder;
|
||||
|
||||
Result appletInitialize(void);
|
||||
void appletExit(void);
|
||||
Result appletGetAppletResourceUserId(u64 *out);
|
||||
@ -141,6 +181,25 @@ Result appletSetScreenShotImageOrientation(s32 val);
|
||||
*/
|
||||
Result appletPushToGeneralChannel(AppletStorage *s);
|
||||
|
||||
/**
|
||||
* @brief Creates a LibraryApplet.
|
||||
* @param h AppletHolder object.
|
||||
* @param id See \ref AppletId.
|
||||
* @param mode See \ref LibAppletMode.
|
||||
*/
|
||||
Result appletCreateLibraryApplet(AppletHolder *h, AppletId id, LibAppletMode mode);
|
||||
|
||||
/// Closes an AppletHolder object.
|
||||
void appletHolderClose(AppletHolder *h);
|
||||
|
||||
/**
|
||||
* @brief Gets the IndirectLayerConsumerHandle loaded during \ref appletCreateLibraryApplet, on 2.0.0+.
|
||||
* @note Only available when \ref LibAppletMode is \ref LibAppletMode_Unknown3.
|
||||
* @param h AppletHolder object.
|
||||
* @param out Output IndirectLayerConsumerHandle.
|
||||
*/
|
||||
Result appletHolderGetIndirectLayerConsumerHandle(AppletHolder *h, u64 *out);
|
||||
|
||||
/**
|
||||
* @brief Creates a storage.
|
||||
* @param s Storage object.
|
||||
|
@ -1437,6 +1437,125 @@ static Result _appletExitProcessAndReturn(void) {
|
||||
|
||||
// ILibraryAppletCreator
|
||||
|
||||
static Result _appletCreateLibraryApplet(Service* srv_out, AppletId id, LibAppletMode mode) {
|
||||
IpcCommand c;
|
||||
ipcInitialize(&c);
|
||||
|
||||
struct {
|
||||
u64 magic;
|
||||
u64 cmd_id;
|
||||
u32 id;
|
||||
u32 mode;
|
||||
} *raw;
|
||||
|
||||
raw = serviceIpcPrepareHeader(&g_appletILibraryAppletCreator, &c, sizeof(*raw));
|
||||
|
||||
raw->magic = SFCI_MAGIC;
|
||||
raw->cmd_id = 0;
|
||||
raw->id = id;
|
||||
raw->mode = mode;
|
||||
|
||||
Result rc = serviceIpcDispatch(&g_appletILibraryAppletCreator);
|
||||
|
||||
if (R_SUCCEEDED(rc)) {
|
||||
IpcParsedCommand r;
|
||||
struct {
|
||||
u64 magic;
|
||||
u64 result;
|
||||
} *resp;
|
||||
|
||||
serviceIpcParse(&g_appletILibraryAppletCreator, &r, sizeof(*resp));
|
||||
resp = r.Raw;
|
||||
|
||||
rc = resp->result;
|
||||
|
||||
if (R_SUCCEEDED(rc) && srv_out) {
|
||||
serviceCreateSubservice(srv_out, &g_appletILibraryAppletCreator, &r, 0);
|
||||
}
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static Result _appletGetIndirectLayerConsumerHandle(Service* srv, u64 *out) {
|
||||
Result rc;
|
||||
u64 AppletResourceUserId;
|
||||
|
||||
rc = appletGetAppletResourceUserId(&AppletResourceUserId);
|
||||
if (R_FAILED(rc)) return rc;
|
||||
|
||||
IpcCommand c;
|
||||
ipcInitialize(&c);
|
||||
|
||||
struct {
|
||||
u64 magic;
|
||||
u64 cmd_id;
|
||||
u64 AppletResourceUserId;
|
||||
} *raw;
|
||||
|
||||
ipcSendPid(&c);
|
||||
|
||||
raw = serviceIpcPrepareHeader(srv, &c, sizeof(*raw));
|
||||
|
||||
raw->magic = SFCI_MAGIC;
|
||||
raw->cmd_id = 160;
|
||||
raw->AppletResourceUserId = AppletResourceUserId;
|
||||
|
||||
rc = serviceIpcDispatch(srv);
|
||||
|
||||
if (R_SUCCEEDED(rc)) {
|
||||
IpcParsedCommand r;
|
||||
struct {
|
||||
u64 magic;
|
||||
u64 result;
|
||||
u64 out;
|
||||
} *resp;
|
||||
|
||||
serviceIpcParse(srv, &r, sizeof(*resp));
|
||||
resp = r.Raw;
|
||||
|
||||
rc = resp->result;
|
||||
|
||||
if (R_SUCCEEDED(rc) && out) *out = resp->out;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
Result appletCreateLibraryApplet(AppletHolder *h, AppletId id, LibAppletMode mode) {
|
||||
Result rc=0;
|
||||
|
||||
memset(h, 0, sizeof(AppletHolder));
|
||||
h->mode = mode;
|
||||
|
||||
rc = _appletCreateLibraryApplet(&h->s, id, mode);
|
||||
|
||||
if (R_SUCCEEDED(rc)) rc = _appletGetEvent(&h->s, &h->StateChangedEvent, 0, false);//GetAppletStateChangedEvent
|
||||
|
||||
if (R_SUCCEEDED(rc) && kernelAbove200() && h->mode == LibAppletMode_Unknown3) rc = _appletGetIndirectLayerConsumerHandle(&h->s, &h->layer_handle);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
void appletHolderClose(AppletHolder *h) {
|
||||
eventClose(&h->StateChangedEvent);
|
||||
serviceClose(&h->s);
|
||||
memset(h, 0, sizeof(AppletHolder));
|
||||
}
|
||||
|
||||
Result appletHolderGetIndirectLayerConsumerHandle(AppletHolder *h, u64 *out) {
|
||||
if (!serviceIsActive(&h->s))
|
||||
return MAKERESULT(Module_Libnx, LibnxError_NotInitialized);
|
||||
if (h->mode!=LibAppletMode_Unknown3)
|
||||
return MAKERESULT(Module_Libnx, LibnxError_BadInput);
|
||||
if (!kernelAbove200())
|
||||
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
|
||||
|
||||
if (out) *out = h->layer_handle;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Result appletCreateStorage(AppletStorage *s, s64 size) {
|
||||
memset(s, 0, sizeof(AppletStorage));
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user