ns: Implement all of ns:dev

This commit is contained in:
Michael Scire 2018-12-09 03:14:06 -08:00 committed by fincs
parent bfad4d4557
commit 0a92b0eb07
2 changed files with 461 additions and 22 deletions

View File

@ -8,6 +8,7 @@
#include "../types.h" #include "../types.h"
#include "../nacp.h" #include "../nacp.h"
#include "../services/fs.h" #include "../services/fs.h"
#include "../kernel/event.h"
typedef struct { typedef struct {
NacpStruct nacp; NacpStruct nacp;
@ -34,6 +35,37 @@ typedef struct
u8 unk_x11[7]; u8 unk_x11[7];
} NsApplicationRecord; } NsApplicationRecord;
typedef struct {
u64 titleID;
u32 version;
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,
NsShellEvent_Start = 2,
NsShellEvent_Crash = 3,
NsShellEvent_Debug = 4,
} NsShellEvent;
typedef struct {
NsShellEvent event : 32;
u64 process_id;
} NsShellEventInfo;
Result nsInitialize(void); Result nsInitialize(void);
void nsExit(void); void nsExit(void);
@ -65,5 +97,15 @@ Result nsvmGetSafeSystemVersion(u16 *out);
Result nsdevInitialize(void); Result nsdevInitialize(void);
void nsdevExit(void); void nsdevExit(void);
Result nsdevLaunchProgram(u64* out_pid, NsLaunchProperties* properties, u32 flags);
Result nsdevTerminateProcess(u64 pid); Result nsdevTerminateProcess(u64 pid);
Result nsdevTerminateProgram(u64 tid); Result nsdevTerminateProgram(u64 tid);
Result nsdevGetShellEvent(Event* out);
Result nsdevGetShellEventInfo(NsShellEventInfo* out);
Result nsdevTerminateApplication(void);
Result nsdevPrepareLaunchProgramFromHost(NsLaunchProperties* out, const char* path, size_t path_len);
Result nsdevLaunchApplication(u64* out_pid, u64 app_title_id, u32 flags);
Result nsdevLaunchApplicationWithStorageId(u64* out_pid, u64 app_title_id, u32 flags, u8 app_storage_id, u8 patch_storage_id);
Result nsdevIsSystemMemoryResourceLimitBoosted(bool* out);
Result nsdevGetRunningApplicationProcessId(u64* out_pid);
Result nsdevSetCurrentApplicationRightsEnvironmentCanBeActive(bool can_be_active);

View File

@ -383,6 +383,49 @@ Result nsvmGetSafeSystemVersion(u16 *out)
return rc; return rc;
} }
Result nsdevLaunchProgram(u64* out_pid, NsLaunchProperties* properties, u32 flags) {
IpcCommand c;
ipcInitialize(&c);
struct {
u64 magic;
u64 cmd_id;
u32 flags;
u32 pad;
NsLaunchProperties properties;
} *raw;
raw = serviceIpcPrepareHeader(&g_nsdevSrv, &c, sizeof(*raw));
raw->magic = SFCI_MAGIC;
raw->cmd_id = 0;
raw->flags = flags;
raw->pad = 0;
raw->properties = *properties;
Result rc = serviceIpcDispatch(&g_nsdevSrv);
if (R_SUCCEEDED(rc)) {
IpcParsedCommand r;
struct {
u64 magic;
u64 result;
u64 pid;
} *resp;
serviceIpcParse(&g_nsdevSrv, &r, sizeof(*resp));
resp = r.Raw;
rc = resp->result;
if (R_SUCCEEDED(rc)) {
if (out_pid) *out_pid = resp->pid;
}
}
return rc;
}
Result nsdevTerminateProcess(u64 pid) { Result nsdevTerminateProcess(u64 pid) {
IpcCommand c; IpcCommand c;
ipcInitialize(&c); ipcInitialize(&c);
@ -393,7 +436,7 @@ Result nsdevTerminateProcess(u64 pid) {
u64 pid; u64 pid;
} *raw; } *raw;
raw = ipcPrepareHeader(&c, sizeof(*raw)); raw = serviceIpcPrepareHeader(&g_nsdevSrv, &c, sizeof(*raw));
raw->magic = SFCI_MAGIC; raw->magic = SFCI_MAGIC;
raw->cmd_id = 1; raw->cmd_id = 1;
@ -403,12 +446,13 @@ Result nsdevTerminateProcess(u64 pid) {
if (R_SUCCEEDED(rc)) { if (R_SUCCEEDED(rc)) {
IpcParsedCommand r; IpcParsedCommand r;
ipcParse(&r);
struct { struct {
u64 magic; u64 magic;
u64 result; u64 result;
} *resp = r.Raw; } *resp;
serviceIpcParse(&g_nsdevSrv, &r, sizeof(*resp));
resp = r.Raw;
rc = resp->result; rc = resp->result;
} }
@ -426,7 +470,7 @@ Result nsdevTerminateProgram(u64 tid) {
u64 tid; u64 tid;
} *raw; } *raw;
raw = ipcPrepareHeader(&c, sizeof(*raw)); raw = serviceIpcPrepareHeader(&g_nsdevSrv, &c, sizeof(*raw));
raw->magic = SFCI_MAGIC; raw->magic = SFCI_MAGIC;
raw->cmd_id = 2; raw->cmd_id = 2;
@ -436,12 +480,365 @@ Result nsdevTerminateProgram(u64 tid) {
if (R_SUCCEEDED(rc)) { if (R_SUCCEEDED(rc)) {
IpcParsedCommand r; IpcParsedCommand r;
ipcParse(&r);
struct { struct {
u64 magic; u64 magic;
u64 result; u64 result;
} *resp = r.Raw; } *resp;
serviceIpcParse(&g_nsdevSrv, &r, sizeof(*resp));
resp = r.Raw;
rc = resp->result;
}
return rc;
}
Result nsdevGetShellEvent(Event* out) {
IpcCommand c;
ipcInitialize(&c);
struct {
u64 magic;
u64 cmd_id;
} *raw;
raw = serviceIpcPrepareHeader(&g_nsdevSrv, &c, sizeof(*raw));
raw->magic = SFCI_MAGIC;
raw->cmd_id = 4;
Result rc = serviceIpcDispatch(&g_nsdevSrv);
if (R_SUCCEEDED(rc)) {
IpcParsedCommand r;
struct {
u64 magic;
u64 result;
} *resp;
serviceIpcParse(&g_nsdevSrv, &r, sizeof(*resp));
resp = r.Raw;
rc = resp->result;
if (R_SUCCEEDED(rc)) {
eventLoadRemote(out, r.Handles[0], true);
}
}
return rc;
}
Result nsdevGetShellEventInfo(NsShellEventInfo* out) {
IpcCommand c;
ipcInitialize(&c);
struct {
u64 magic;
u64 cmd_id;
} *raw;
raw = serviceIpcPrepareHeader(&g_nsdevSrv, &c, sizeof(*raw));
raw->magic = SFCI_MAGIC;
raw->cmd_id = 5;
Result rc = serviceIpcDispatch(&g_nsdevSrv);
if (R_SUCCEEDED(rc)) {
IpcParsedCommand r;
struct {
u64 magic;
u64 result;
u32 event;
u32 pad;
u64 process_id;
} *resp;
serviceIpcParse(&g_nsdevSrv, &r, sizeof(*resp));
resp = r.Raw;
rc = resp->result;
if (R_SUCCEEDED(rc)) {
if (out) {
out->event = (NsShellEvent)resp->event;
out->process_id = resp->process_id;
}
}
}
return rc;
}
Result nsdevTerminateApplication(void) {
IpcCommand c;
ipcInitialize(&c);
struct {
u64 magic;
u64 cmd_id;
} *raw;
raw = serviceIpcPrepareHeader(&g_nsdevSrv, &c, sizeof(*raw));
raw->magic = SFCI_MAGIC;
raw->cmd_id = 6;
Result rc = serviceIpcDispatch(&g_nsdevSrv);
if (R_SUCCEEDED(rc)) {
IpcParsedCommand r;
struct {
u64 magic;
u64 result;
} *resp;
serviceIpcParse(&g_nsdevSrv, &r, sizeof(*resp));
resp = r.Raw;
rc = resp->result;
}
return rc;
}
Result nsdevPrepareLaunchProgramFromHost(NsLaunchProperties* out, const char* path, size_t path_len) {
IpcCommand c;
ipcInitialize(&c);
ipcAddSendBuffer(&c, path, path_len, BufferType_Normal);
struct {
u64 magic;
u64 cmd_id;
} *raw;
raw = serviceIpcPrepareHeader(&g_nsdevSrv, &c, sizeof(*raw));
raw->magic = SFCI_MAGIC;
raw->cmd_id = 7;
Result rc = serviceIpcDispatch(&g_nsdevSrv);
if (R_SUCCEEDED(rc)) {
IpcParsedCommand r;
struct {
u64 magic;
u64 result;
NsLaunchProperties properties;
} *resp;
serviceIpcParse(&g_nsdevSrv, &r, sizeof(*resp));
resp = r.Raw;
rc = resp->result;
if (R_SUCCEEDED(rc)) {
if (out) *out = resp->properties;
}
}
return rc;
}
Result nsdevLaunchApplication(u64* out_pid, u64 app_title_id, u32 flags) {
IpcCommand c;
ipcInitialize(&c);
struct {
u64 magic;
u64 cmd_id;
u32 flags;
u32 pad;
u64 app_title_id;
} *raw;
raw = serviceIpcPrepareHeader(&g_nsdevSrv, &c, sizeof(*raw));
raw->magic = SFCI_MAGIC;
raw->cmd_id = 8;
raw->flags = flags;
raw->pad = 0;
raw->app_title_id = app_title_id;
Result rc = serviceIpcDispatch(&g_nsdevSrv);
if (R_SUCCEEDED(rc)) {
IpcParsedCommand r;
struct {
u64 magic;
u64 result;
u64 pid;
} *resp;
serviceIpcParse(&g_nsdevSrv, &r, sizeof(*resp));
resp = r.Raw;
rc = resp->result;
if (R_SUCCEEDED(rc)) {
if (out_pid) *out_pid = resp->pid;
}
}
return rc;
}
Result nsdevLaunchApplicationWithStorageId(u64* out_pid, u64 app_title_id, u32 flags, u8 app_storage_id, u8 patch_storage_id) {
IpcCommand c;
ipcInitialize(&c);
struct {
u64 magic;
u64 cmd_id;
u8 app_storage_id;
u8 patch_storage_id;
u16 pad;
u32 flags;
u64 app_title_id;
} *raw;
raw = serviceIpcPrepareHeader(&g_nsdevSrv, &c, sizeof(*raw));
raw->magic = SFCI_MAGIC;
raw->cmd_id = 9;
raw->app_storage_id = app_storage_id;
raw->patch_storage_id = patch_storage_id;
raw->pad = 0;
raw->flags = flags;
raw->app_title_id = app_title_id;
Result rc = serviceIpcDispatch(&g_nsdevSrv);
if (R_SUCCEEDED(rc)) {
IpcParsedCommand r;
struct {
u64 magic;
u64 result;
u64 pid;
} *resp;
serviceIpcParse(&g_nsdevSrv, &r, sizeof(*resp));
resp = r.Raw;
rc = resp->result;
if (R_SUCCEEDED(rc)) {
if (out_pid) *out_pid = resp->pid;
}
}
return rc;
}
Result nsdevIsSystemMemoryResourceLimitBoosted(bool* out) {
if (!kernelAbove600()) return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
IpcCommand c;
ipcInitialize(&c);
struct {
u64 magic;
u64 cmd_id;
} *raw;
raw = serviceIpcPrepareHeader(&g_nsdevSrv, &c, sizeof(*raw));
raw->magic = SFCI_MAGIC;
raw->cmd_id = 10;
Result rc = serviceIpcDispatch(&g_nsdevSrv);
if (R_SUCCEEDED(rc)) {
IpcParsedCommand r;
struct {
u64 magic;
u64 result;
u8 boosted;
} *resp;
serviceIpcParse(&g_nsdevSrv, &r, sizeof(*resp));
resp = r.Raw;
rc = resp->result;
if (R_SUCCEEDED(rc)) {
if (out) *out = resp->boosted != 0;
}
}
return rc;
}
Result nsdevGetRunningApplicationProcessId(u64* out_pid) {
if (!kernelAbove600()) return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
IpcCommand c;
ipcInitialize(&c);
struct {
u64 magic;
u64 cmd_id;
} *raw;
raw = serviceIpcPrepareHeader(&g_nsdevSrv, &c, sizeof(*raw));
raw->magic = SFCI_MAGIC;
raw->cmd_id = 11;
Result rc = serviceIpcDispatch(&g_nsdevSrv);
if (R_SUCCEEDED(rc)) {
IpcParsedCommand r;
struct {
u64 magic;
u64 result;
u64 pid;
} *resp;
serviceIpcParse(&g_nsdevSrv, &r, sizeof(*resp));
resp = r.Raw;
rc = resp->result;
if (R_SUCCEEDED(rc)) {
if (out_pid) *out_pid = resp->pid;
}
}
return rc;
}
Result nsdevSetCurrentApplicationRightsEnvironmentCanBeActive(bool can_be_active) {
if (!kernelAbove600()) return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
IpcCommand c;
ipcInitialize(&c);
struct {
u64 magic;
u64 cmd_id;
u8 can_be_active;
} *raw;
raw = serviceIpcPrepareHeader(&g_nsdevSrv, &c, sizeof(*raw));
raw->magic = SFCI_MAGIC;
raw->cmd_id = 12;
raw->can_be_active = can_be_active ? 1 : 0;
Result rc = serviceIpcDispatch(&g_nsdevSrv);
if (R_SUCCEEDED(rc)) {
IpcParsedCommand r;
struct {
u64 magic;
u64 result;
} *resp;
serviceIpcParse(&g_nsdevSrv, &r, sizeof(*resp));
resp = r.Raw;
rc = resp->result; rc = resp->result;
} }