diff --git a/nx/include/switch/services/ns.h b/nx/include/switch/services/ns.h index ab435f30..ea040a7f 100644 --- a/nx/include/switch/services/ns.h +++ b/nx/include/switch/services/ns.h @@ -17,3 +17,9 @@ Result nsInitialize(void); void nsExit(void); Result nsGetApplicationControlData(u8 flag, u64 titleID, NsApplicationControlData* buffer, size_t size, size_t* actual_size); + +Result nsvmInitialize(void); +void nsvmExit(void); + +Result nsvmNeedsUpdateVulnerability(bool *out); +Result nsvmGetSafeSystemVersion(u16 *out); diff --git a/nx/include/switch/services/pm.h b/nx/include/switch/services/pm.h index 8ca894fa..a55c7e73 100644 --- a/nx/include/switch/services/pm.h +++ b/nx/include/switch/services/pm.h @@ -27,3 +27,4 @@ Result pmdmntEnableDebugForApplication(Handle* handle_out); Result pminfoGetTitleId(u64* title_id_out, u64 pid); Result pmshellLaunchProcess(u32 launch_flags, u64 titleID, u64 storageID, u64 *pid); +Result pmshellTerminateProcessByTitleId(u64 titleID); \ No newline at end of file diff --git a/nx/include/switch/services/set.h b/nx/include/switch/services/set.h index 41ae0b1f..02d59708 100644 --- a/nx/include/switch/services/set.h +++ b/nx/include/switch/services/set.h @@ -7,6 +7,8 @@ */ #include "../result.h" +#define SET_MAX_NAME_SIZE 0x48 + typedef enum { ColorSetId_Light=0, ColorSetId_Dark=1 @@ -67,6 +69,18 @@ void setsysExit(void); /// Gets the current system theme. Result setsysGetColorSetId(ColorSetId* out); +/** + * @brief Gets the size of a settings item value. + * @param out Pointer to output the size to. + */ +Result setsysGetSettingsItemValueSize(const char *name, const char *item_key, u64 *size_out); + +/** + * @brief Gets the value of a settings item. + * @param out Pointer to output the value to. + */ +Result setsysGetSettingsItemValue(const char *name, const char *item_key, void *value_out, size_t value_out_size); + /** * @brief Gets the system's serial number. * @param serial Pointer to output the serial to. (The buffer size needs to be at least 0x19 bytes) diff --git a/nx/source/services/ns.c b/nx/source/services/ns.c index 69661bed..1c64f6e6 100644 --- a/nx/source/services/ns.c +++ b/nx/source/services/ns.c @@ -6,8 +6,8 @@ #include "services/sm.h" #include "services/ns.h" -static Service g_nsAppManSrv, g_nsGetterSrv; -static u64 g_nsRefCnt; +static Service g_nsAppManSrv, g_nsGetterSrv, g_nsvmSrv; +static u64 g_nsRefCnt, g_nsvmRefCnt; static Result _nsGetInterface(Service* srv_out, u64 cmd_id); @@ -116,3 +116,103 @@ Result nsGetApplicationControlData(u8 flag, u64 titleID, NsApplicationControlDat return rc; } + +Result nsvmInitialize(void) +{ + if (!kernelAbove300()) + return 0; + + atomicIncrement64(&g_nsvmRefCnt); + + if (serviceIsActive(&g_nsvmSrv)) + return 0; + + return smGetService(&g_nsvmSrv, "ns:vm"); +} + +void nsvmExit(void) +{ + if (!kernelAbove300()) + return; + + if (atomicDecrement64(&g_nsvmRefCnt) == 0) { + serviceClose(&g_nsvmSrv); + } +} + +Result nsvmNeedsUpdateVulnerability(bool *out) { + IpcCommand c; + ipcInitialize(&c); + + struct { + u64 magic; + u64 cmd_id; + } *raw; + + raw = ipcPrepareHeader(&c, sizeof(*raw)); + + raw->magic = SFCI_MAGIC; + raw->cmd_id = 1200; + + Result rc; + + if (kernelAbove300()) + rc = serviceIpcDispatch(&g_nsvmSrv); + else + rc = serviceIpcDispatch(&g_nsAppManSrv); + + if (R_SUCCEEDED(rc)) { + IpcParsedCommand r; + ipcParse(&r); + + struct { + u64 magic; + u64 result; + u8 out; + } *resp = r.Raw; + + rc = resp->result; + + if (R_SUCCEEDED(rc) && out) *out = resp->out; + } + + return rc; +} + +Result nsvmGetSafeSystemVersion(u16 *out) +{ + if (!kernelAbove300()) + return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); + + IpcCommand c; + ipcInitialize(&c); + + struct { + u64 magic; + u64 cmd_id; + } *raw; + + raw = ipcPrepareHeader(&c, sizeof(*raw)); + + raw->magic = SFCI_MAGIC; + raw->cmd_id = 1202; + + Result rc = serviceIpcDispatch(&g_nsvmSrv); + + if (R_SUCCEEDED(rc)) { + IpcParsedCommand r; + ipcParse(&r); + + struct { + u64 magic; + u64 result; + u16 out; + } *resp = r.Raw; + + rc = resp->result; + + if (R_SUCCEEDED(rc) && out) *out = resp->out; + } + + return rc; +} \ No newline at end of file diff --git a/nx/source/services/pm.c b/nx/source/services/pm.c index c901767e..d75d8c6e 100644 --- a/nx/source/services/pm.c +++ b/nx/source/services/pm.c @@ -314,3 +314,36 @@ Result pmshellLaunchProcess(u32 launch_flags, u64 titleID, u64 storageID, u64 *p return rc; } + +Result pmshellTerminateProcessByTitleId(u64 titleID) { + IpcCommand c; + ipcInitialize(&c); + + struct { + u64 magic; + u64 cmd_id; + u64 titleID; + } *raw; + + raw = ipcPrepareHeader(&c, sizeof(*raw)); + + raw->magic = SFCI_MAGIC; + raw->cmd_id = 2; + raw->titleID = titleID; + + 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; +} \ No newline at end of file diff --git a/nx/source/services/set.c b/nx/source/services/set.c index 5fb2ff2a..3c0ee614 100644 --- a/nx/source/services/set.c +++ b/nx/source/services/set.c @@ -348,6 +348,92 @@ Result setsysGetColorSetId(ColorSetId* out) } +Result setsysGetSettingsItemValue(const char *name, const char *item_key, void *value_out, size_t value_out_size) { + char send_name[SET_MAX_NAME_SIZE]; + char send_item_key[SET_MAX_NAME_SIZE]; + + memset(send_name, 0, SET_MAX_NAME_SIZE); + memset(send_item_key, 0, SET_MAX_NAME_SIZE); + strncpy(send_name, name, SET_MAX_NAME_SIZE-1); + strncpy(send_item_key, item_key, SET_MAX_NAME_SIZE-1); + + IpcCommand c; + ipcInitialize(&c); + ipcAddSendStatic(&c, send_name, SET_MAX_NAME_SIZE, 0); + ipcAddSendStatic(&c, send_item_key, SET_MAX_NAME_SIZE, 0); + ipcAddRecvBuffer(&c, value_out, value_out_size, 0); + + struct { + u64 magic; + u64 cmd_id; + } *raw; + + raw = ipcPrepareHeader(&c, sizeof(*raw)); + + raw->magic = SFCI_MAGIC; + raw->cmd_id = 38; + + Result rc = serviceIpcDispatch(&g_setsysSrv); + + if (R_SUCCEEDED(rc)) { + IpcParsedCommand r; + ipcParse(&r); + + struct { + u64 magic; + u64 result; + } *resp = r.Raw; + + rc = resp->result; + } + + return rc; +} + +Result setsysGetSettingsItemValueSize(const char *name, const char *item_key, u64 *size_out) { + char send_name[SET_MAX_NAME_SIZE]; + char send_item_key[SET_MAX_NAME_SIZE]; + + memset(send_name, 0, SET_MAX_NAME_SIZE); + memset(send_item_key, 0, SET_MAX_NAME_SIZE); + strncpy(send_name, name, SET_MAX_NAME_SIZE-1); + strncpy(send_item_key, item_key, SET_MAX_NAME_SIZE-1); + + IpcCommand c; + ipcInitialize(&c); + ipcAddSendStatic(&c, send_name, SET_MAX_NAME_SIZE, 0); + ipcAddSendStatic(&c, send_item_key, SET_MAX_NAME_SIZE, 0); + + struct { + u64 magic; + u64 cmd_id; + } *raw; + + raw = ipcPrepareHeader(&c, sizeof(*raw)); + + raw->magic = SFCI_MAGIC; + raw->cmd_id = 37; + + Result rc = serviceIpcDispatch(&g_setsysSrv); + + if (R_SUCCEEDED(rc)) { + IpcParsedCommand r; + ipcParse(&r); + + struct { + u64 magic; + u64 result; + u64 size; + } *resp = r.Raw; + + rc = resp->result; + + if (R_SUCCEEDED(rc) && size_out) *size_out = resp->size; + } + + return rc; +} + Result setsysGetSerialNumber(char *serial) { IpcCommand c; ipcInitialize(&c);