mirror of
https://github.com/switchbrew/libnx.git
synced 2025-08-05 07:59:24 +02:00
Added appletExecuteProgram, appletJumpToSubApplicationProgramForDevelopment, appletRestartProgram, and appletGetPreviousProgramIndex. Added AppletProgramSpecifyKind.
This commit is contained in:
parent
79e6db16be
commit
c7cab0351c
@ -189,6 +189,13 @@ typedef enum {
|
||||
AppletCaptureSharedBuffer_CallerApplet = 2, ///< CallerApplet
|
||||
} AppletCaptureSharedBuffer;
|
||||
|
||||
/// ProgramSpecifyKind for the ExecuteProgram cmd. Controls the type of the u64 passed to the ExecuteProgram cmd.
|
||||
typedef enum {
|
||||
AppletProgramSpecifyKind_ExecuteProgram = 0, ///< u8 ProgramIndex.
|
||||
AppletProgramSpecifyKind_JumpToSubApplicationProgramForDevelopment = 1, ///< u64 titleID. Only available when DebugMode is enabled.
|
||||
AppletProgramSpecifyKind_RestartProgram = 2, ///< u64 = value 0.
|
||||
} AppletProgramSpecifyKind;
|
||||
|
||||
/// applet hook function.
|
||||
typedef void (*AppletHookFn)(AppletHookType hook, void* param);
|
||||
|
||||
@ -1345,6 +1352,42 @@ Result appletQueryApplicationPlayStatistics(PdmApplicationPlayStatistics *stats,
|
||||
*/
|
||||
Result appletQueryApplicationPlayStatisticsByUid(u128 userID, PdmApplicationPlayStatistics *stats, const u64 *titleIDs, s32 count, s32 *total_out);
|
||||
|
||||
/**
|
||||
* @brief Launches Application title {current_titleID}+programIndex. This will enter an infinite-sleep-loop on success.
|
||||
* @note Only available with AppletType_*Application on [5.0.0+].
|
||||
* @note Creates the storage if needed. Uses cmd ClearUserChannel. Uses cmd UnpopToUserChannel when the storage was created. Lastly cmd ExecuteProgramCmd is used.
|
||||
* @param[in] programIndex ProgramIndex, must be 0x0-0xFF. 0 is the same as the current titleID. ProgramIndex values where the title is not installed should not be used.
|
||||
* @param[in] buffer Optional buffer containing the storage data which will be used for ::AppletLaunchParameterKind_UserChannel with the launched Application, can be NULL.
|
||||
* @param[in] size Size of the above buffer, 0 to not use the storage. Must be <=0x1000.
|
||||
*/
|
||||
Result appletExecuteProgram(s32 programIndex, const void* buffer, size_t size);
|
||||
|
||||
/**
|
||||
* @brief Launches the specified Application titleID.
|
||||
* @note Only available with AppletType_*Application on [5.0.0+], with DebugMode enabled.
|
||||
* @note Creates the storage if needed. Uses cmd ClearUserChannel. Uses cmd UnpopToUserChannel when the storage was created. Lastly cmd ExecuteProgramCmd is used.
|
||||
* @param[in] titleID Application titleID.
|
||||
* @param[in] buffer Optional buffer containing the storage data which will be used for ::AppletLaunchParameterKind_UserChannel with the launched Application, can be NULL.
|
||||
* @param[in] size Size of the above buffer, 0 to not use the storage. Must be <=0x1000.
|
||||
*/
|
||||
Result appletJumpToSubApplicationProgramForDevelopment(u64 titleID, const void* buffer, size_t size);
|
||||
|
||||
/**
|
||||
* @brief Relaunches the current Application.
|
||||
* @note Only available with AppletType_*Application on [5.0.0+].
|
||||
* @note Creates the storage if needed. Uses cmd ClearUserChannel. Uses cmd UnpopToUserChannel when the storage was created. Lastly cmd ExecuteProgramCmd is used.
|
||||
* @param[in] buffer Optional buffer containing the storage data which will be used for ::AppletLaunchParameterKind_UserChannel with the launched Application, can be NULL.
|
||||
* @param[in] size Size of the above buffer, 0 to not use the storage. Must be <=0x1000.
|
||||
*/
|
||||
Result appletRestartProgram(const void* buffer, size_t size);
|
||||
|
||||
/**
|
||||
* @brief Gets the ProgramIndex of the Application which launched this title.
|
||||
* @note Only available with AppletType_*Application on [5.0.0+].
|
||||
* @param[out] programIndex ProgramIndex, -1 when there was no previous title.
|
||||
*/
|
||||
Result appletGetPreviousProgramIndex(s32 *programIndex);
|
||||
|
||||
/**
|
||||
* @brief Gets an Event which is signaled for GpuErrorDetected.
|
||||
* @note Only available with AppletType_*Application on [8.0.0+].
|
||||
|
@ -4277,6 +4277,112 @@ Result appletQueryApplicationPlayStatisticsByUid(u128 userID, PdmApplicationPlay
|
||||
return rc;
|
||||
}
|
||||
|
||||
static Result _appletExecuteProgramCmd(AppletProgramSpecifyKind kind, u64 inval) {
|
||||
if (!serviceIsActive(&g_appletSrv) || !_appletIsApplication())
|
||||
return MAKERESULT(Module_Libnx, LibnxError_NotInitialized);
|
||||
if (hosversionBefore(5,0,0))
|
||||
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
|
||||
|
||||
IpcCommand c;
|
||||
ipcInitialize(&c);
|
||||
|
||||
struct {
|
||||
u64 magic;
|
||||
u64 cmd_id;
|
||||
u32 kind;
|
||||
u64 inval;
|
||||
} *raw;
|
||||
|
||||
raw = serviceIpcPrepareHeader(&g_appletIFunctions, &c, sizeof(*raw));
|
||||
|
||||
raw->magic = SFCI_MAGIC;
|
||||
raw->cmd_id = 120;
|
||||
raw->kind = kind;
|
||||
raw->inval = inval;
|
||||
|
||||
Result rc = serviceIpcDispatch(&g_appletIFunctions);
|
||||
|
||||
if (R_SUCCEEDED(rc)) {
|
||||
IpcParsedCommand r;
|
||||
struct {
|
||||
u64 magic;
|
||||
u64 result;
|
||||
} *resp;
|
||||
|
||||
serviceIpcParse(&g_appletIFunctions, &r, sizeof(*resp));
|
||||
resp = r.Raw;
|
||||
|
||||
rc = resp->result;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static Result _appletClearUserChannel(void) {
|
||||
if (!serviceIsActive(&g_appletSrv) || !_appletIsApplication())
|
||||
return MAKERESULT(Module_Libnx, LibnxError_NotInitialized);
|
||||
if (hosversionBefore(5,0,0))
|
||||
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
|
||||
|
||||
return _appletCmdNoIO(&g_appletIFunctions, 121);
|
||||
}
|
||||
|
||||
static Result _appletUnpopToUserChannel(AppletStorage *s) {
|
||||
if (!serviceIsActive(&g_appletSrv) || !_appletIsApplication())
|
||||
return MAKERESULT(Module_Libnx, LibnxError_NotInitialized);
|
||||
if (hosversionBefore(5,0,0))
|
||||
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
|
||||
|
||||
return _appletCmdInStorage(&g_appletIFunctions, s, 122);
|
||||
}
|
||||
|
||||
static Result _appletExecuteProgram(AppletProgramSpecifyKind kind, u64 inval, const void* buffer, size_t size) {
|
||||
Result rc=0;
|
||||
AppletStorage storage={0};
|
||||
|
||||
if (size > 0x1000)
|
||||
return MAKERESULT(Module_Libnx, LibnxError_BadInput);
|
||||
|
||||
if (buffer!=NULL && size!=0) {
|
||||
rc = appletCreateStorage(&storage, size);
|
||||
if (R_SUCCEEDED(rc)) rc = appletStorageWrite(&storage, 0, buffer, size);
|
||||
}
|
||||
|
||||
if (R_SUCCEEDED(rc)) rc = _appletClearUserChannel();
|
||||
if (R_SUCCEEDED(rc) && buffer!=0 && size!=0) rc = _appletUnpopToUserChannel(&storage);
|
||||
if (R_SUCCEEDED(rc)) rc = _appletExecuteProgramCmd(kind, inval);
|
||||
|
||||
appletStorageClose(&storage);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
Result appletExecuteProgram(s32 programIndex, const void* buffer, size_t size) {
|
||||
Result rc=0;
|
||||
|
||||
if (programIndex<0 || programIndex>0xff) rc = MAKERESULT(Module_Libnx, LibnxError_BadInput);
|
||||
if (R_SUCCEEDED(rc)) rc = _appletExecuteProgram(AppletProgramSpecifyKind_ExecuteProgram, (u64)programIndex, buffer, size);
|
||||
if (R_SUCCEEDED(rc)) _appletInfiniteSleepLoop();
|
||||
return rc;
|
||||
}
|
||||
|
||||
Result appletJumpToSubApplicationProgramForDevelopment(u64 titleID, const void* buffer, size_t size) {
|
||||
return _appletExecuteProgram(AppletProgramSpecifyKind_JumpToSubApplicationProgramForDevelopment, titleID, buffer, size);
|
||||
}
|
||||
|
||||
Result appletRestartProgram(const void* buffer, size_t size) {
|
||||
return _appletExecuteProgram(AppletProgramSpecifyKind_RestartProgram, 0, buffer, size);
|
||||
}
|
||||
|
||||
Result appletGetPreviousProgramIndex(s32 *programIndex) {
|
||||
if (!serviceIsActive(&g_appletSrv) || !_appletIsApplication())
|
||||
return MAKERESULT(Module_Libnx, LibnxError_NotInitialized);
|
||||
if (hosversionBefore(5,0,0))
|
||||
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
|
||||
|
||||
return _appletCmdNoInOut32(&g_appletIFunctions, (u32*)programIndex, 123);
|
||||
}
|
||||
|
||||
Result appletGetGpuErrorDetectedSystemEvent(Event *out_event) {
|
||||
if (!serviceIsActive(&g_appletSrv) || !_appletIsApplication())
|
||||
return MAKERESULT(Module_Libnx, LibnxError_NotInitialized);
|
||||
|
Loading…
Reference in New Issue
Block a user