Add remaining pm:shell services, address issues

This commit is contained in:
Michael Scire 2018-12-09 03:41:09 -08:00
parent 1224a0243f
commit 8017d56932
4 changed files with 294 additions and 16 deletions

View File

@ -41,18 +41,8 @@ typedef struct {
u8 storageID;
u8 index;
u8 is_application;
u8 padding[1];
} NsLaunchProperties;
typedef enum {
NsLaunchFlag_SignalOnExit = (1 << 0),
NsLaunchFlag_SignalOnStart = (1 << 1),
NsLaunchFlag_SignalOnCrash = (1 << 2),
NsLaunchFlag_SignalOnDebug = (1 << 3),
NsLaunchFlag_StartSuspended = (1 << 4),
NsLaunchFlag_DisableAslr = (1 << 5),
} NsLaunchFlag;
typedef enum {
NsShellEvent_None = 0,
NsShellEvent_Exit = 1,
@ -62,7 +52,7 @@ typedef enum {
} NsShellEvent;
typedef struct {
NsShellEvent event : 32;
NsShellEvent event;
u64 process_id;
} NsShellEventInfo;
@ -97,10 +87,10 @@ Result nsvmGetSafeSystemVersion(u16 *out);
Result nsdevInitialize(void);
void nsdevExit(void);
Result nsdevLaunchProgram(u64* out_pid, NsLaunchProperties* properties, u32 flags);
Result nsdevLaunchProgram(u64* out_pid, const NsLaunchProperties* properties, u32 flags);
Result nsdevTerminateProcess(u64 pid);
Result nsdevTerminateProgram(u64 tid);
Result nsdevGetShellEvent(Event* out);
Result nsdevGetShellEvent(Event* out); // Autoclear for nsdevShellEvent is always true.
Result nsdevGetShellEventInfo(NsShellEventInfo* out);
Result nsdevTerminateApplication(void);
Result nsdevPrepareLaunchProgramFromHost(NsLaunchProperties* out, const char* path, size_t path_len);

View File

@ -8,6 +8,42 @@
*/
#pragma once
#include "../types.h"
#include "../kernel/event.h"
typedef enum {
PmLaunchFlag_None = 0,
///< PmLaunchFlag_* should be used on 5.0.0+.
PmLaunchFlag_SignalOnExit = (1 << 0),
PmLaunchFlag_SignalOnStart = (1 << 1),
PmLaunchFlag_SignalOnCrash = (1 << 2),
PmLaunchFlag_SignalOnDebug = (1 << 3),
PmLaunchFlag_StartSuspended = (1 << 4),
PmLaunchFlag_DisableAslr = (1 << 5),
///< PmLaunchFlagOld_* should be used on 1.0.0-4.1.0.
PmLaunchFlagOld_SignalOnExit = (1 << 0),
PmLaunchFlagOld_StartSuspended = (1 << 1),
PmLaunchFlagOld_SignalOnCrash = (1 << 2),
PmLaunchFlagOld_DisableAslr = (1 << 3),
PmLaunchFlagOld_SignalOnDebug = (1 << 4),
///< PmLaunchFlagOld_SignalOnStart was added in 2.0.0.
PmLaunchFlagOld_SignalOnStart = (1 << 5),
} PmLaunchFlag;
typedef enum {
PmProcessEvent_None = 0,
PmProcessEvent_Exit = 1,
PmProcessEvent_Start = 2,
PmProcessEvent_Crash = 3,
PmProcessEvent_DebugStart = 4,
PmProcessEvent_DebugBreak = 5,
} PmProcessEvent;
typedef struct {
PmProcessEvent event;
u64 process_id;
} PmProcessEventInfo;
Result pmdmntInitialize(void);
void pmdmntExit(void);
@ -29,5 +65,12 @@ Result pmdmntDisableDebug(void);
Result pminfoGetTitleId(u64* title_id_out, u64 pid);
Result pmshellLaunchProcess(u32 launch_flags, u64 titleID, u64 storageID, u64 *pid);
Result pmshellTerminateProcessByProcessId(u64 processID);
Result pmshellTerminateProcessByTitleId(u64 titleID);
Result pmshellGetProcessEvent(Event* out); // Autoclear for pmshellProcessEvent is always true.
Result pmshellGetProcessEventInfo(PmProcessEventInfo* out);
Result pmshellFinalizeDeadProcess(u64 pid);
Result pmshellClearProcessExceptionOccurred(u64 pid);
Result pmshellNotifyBootFinished(void);
Result pmshellGetApplicationPid(u64* pid_out);
Result pmshellBoostSystemMemoryResourceLimit(u64 boost_size);

View File

@ -383,7 +383,7 @@ Result nsvmGetSafeSystemVersion(u16 *out)
return rc;
}
Result nsdevLaunchProgram(u64* out_pid, NsLaunchProperties* properties, u32 flags) {
Result nsdevLaunchProgram(u64* out_pid, const NsLaunchProperties* properties, u32 flags) {
IpcCommand c;
ipcInitialize(&c);

View File

@ -386,6 +386,39 @@ Result pmshellLaunchProcess(u32 launch_flags, u64 titleID, u64 storageID, u64 *p
return rc;
}
Result pmshellTerminateProcessByProcessId(u64 processID) {
IpcCommand c;
ipcInitialize(&c);
struct {
u64 magic;
u64 cmd_id;
u64 processID;
} *raw;
raw = ipcPrepareHeader(&c, sizeof(*raw));
raw->magic = SFCI_MAGIC;
raw->cmd_id = 1;
raw->processID = processID;
Result rc = serviceIpcDispatch(&g_pmshellSrv);
if (R_SUCCEEDED(rc)) {
IpcParsedCommand r;
ipcParse(&r);
struct {
u64 magic;
u64 result;
} *resp = r.Raw;
rc = resp->result;
}
return rc;
}
Result pmshellTerminateProcessByTitleId(u64 titleID) {
IpcCommand c;
ipcInitialize(&c);
@ -419,6 +452,183 @@ Result pmshellTerminateProcessByTitleId(u64 titleID) {
return rc;
}
Result pmshellGetProcessEvent(Event* out) {
IpcCommand c;
ipcInitialize(&c);
struct {
u64 magic;
u64 cmd_id;
} *raw;
raw = ipcPrepareHeader(&c, sizeof(*raw));
raw->magic = SFCI_MAGIC;
raw->cmd_id = 3;
Result rc = serviceIpcDispatch(&g_pmshellSrv);
if (R_SUCCEEDED(rc)) {
IpcParsedCommand r;
ipcParse(&r);
struct {
u64 magic;
u64 result;
} *resp = r.Raw;
rc = resp->result;
if (R_SUCCEEDED(rc)) {
eventLoadRemote(out, r.Handles[0], true);
}
}
return rc;
}
Result pmshellGetProcessEventInfo(PmProcessEventInfo* out) {
IpcCommand c;
ipcInitialize(&c);
struct {
u64 magic;
u64 cmd_id;
} *raw;
raw = ipcPrepareHeader(&c, sizeof(*raw));
raw->magic = SFCI_MAGIC;
raw->cmd_id = 4;
Result rc = serviceIpcDispatch(&g_pmshellSrv);
if (R_SUCCEEDED(rc)) {
IpcParsedCommand r;
ipcParse(&r);
struct {
u64 magic;
u64 result;
u32 event;
u32 pad;
u64 process_id;
} *resp = r.Raw;
rc = resp->result;
if (R_SUCCEEDED(rc)) {
if (out) {
out->event = (PmProcessEvent)resp->event;
out->process_id = resp->process_id;
}
}
}
return rc;
}
Result pmshellFinalizeDeadProcess(u64 pid) {
if (kernelAbove500()) return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
IpcCommand c;
ipcInitialize(&c);
struct {
u64 magic;
u64 cmd_id;
u64 pid;
} *raw;
raw = ipcPrepareHeader(&c, sizeof(*raw));
raw->magic = SFCI_MAGIC;
raw->cmd_id = 5;
raw->pid = pid;
Result rc = serviceIpcDispatch(&g_pmshellSrv);
if (R_SUCCEEDED(rc)) {
IpcParsedCommand r;
ipcParse(&r);
struct {
u64 magic;
u64 result;
} *resp = r.Raw;
rc = resp->result;
}
return rc;
}
Result pmshellClearProcessExceptionOccurred(u64 pid) {
if (kernelAbove500()) return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
IpcCommand c;
ipcInitialize(&c);
struct {
u64 magic;
u64 cmd_id;
u64 pid;
} *raw;
raw = ipcPrepareHeader(&c, sizeof(*raw));
raw->magic = SFCI_MAGIC;
raw->cmd_id = 6;
raw->pid = pid;
Result rc = serviceIpcDispatch(&g_pmshellSrv);
if (R_SUCCEEDED(rc)) {
IpcParsedCommand r;
ipcParse(&r);
struct {
u64 magic;
u64 result;
} *resp = r.Raw;
rc = resp->result;
}
return rc;
}
Result pmshellNotifyBootFinished(void) {
IpcCommand c;
ipcInitialize(&c);
struct {
u64 magic;
u64 cmd_id;
} *raw;
raw = ipcPrepareHeader(&c, sizeof(*raw));
raw->magic = SFCI_MAGIC;
raw->cmd_id = kernelAbove500() ? 5 : 7;
Result rc = serviceIpcDispatch(&g_pmshellSrv);
if (R_SUCCEEDED(rc)) {
IpcParsedCommand r;
ipcParse(&r);
struct {
u64 magic;
u64 result;
} *resp = r.Raw;
rc = resp->result;
}
return rc;
}
Result pmshellGetApplicationPid(u64* pid_out) {
IpcCommand c;
ipcInitialize(&c);
@ -454,3 +664,38 @@ Result pmshellGetApplicationPid(u64* pid_out) {
return rc;
}
Result pmshellBoostSystemMemoryResourceLimit(u64 boost_size) {
if (!kernelAbove400()) return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
IpcCommand c;
ipcInitialize(&c);
struct {
u64 magic;
u64 cmd_id;
u64 boost_size;
} *raw;
raw = ipcPrepareHeader(&c, sizeof(*raw));
raw->magic = SFCI_MAGIC;
raw->cmd_id = kernelAbove500() ? 7 : 9;
raw->boost_size = boost_size;
Result rc = serviceIpcDispatch(&g_pmshellSrv);
if (R_SUCCEEDED(rc)) {
IpcParsedCommand r;
ipcParse(&r);
struct {
u64 magic;
u64 result;
} *resp = r.Raw;
rc = resp->result;
}
return rc;
}