diff --git a/nx/include/switch/services/ns.h b/nx/include/switch/services/ns.h index cf80ccd9..e8f7190b 100644 --- a/nx/include/switch/services/ns.h +++ b/nx/include/switch/services/ns.h @@ -1,6 +1,6 @@ /** * @file ns.h - * @brief NS service IPC wrapper. + * @brief NS services IPC wrapper. * @author yellows8 * @copyright libnx Authors */ @@ -10,70 +10,99 @@ #include "../services/fs.h" #include "../kernel/event.h" +/// ApplicationControlData typedef struct { - NacpStruct nacp; - u8 icon[0x20000];//JPEG + NacpStruct nacp; ///< \ref NacpStruct + u8 icon[0x20000]; ///< JPEG } NsApplicationControlData; -typedef struct -{ - u8 title_type; - u8 storageID; - u8 unk_x02; - u8 padding; - u32 title_version; - u64 titleID; +/// NsApplicationContentMetaStatus +typedef struct { + u8 title_type; ///< \ref NcmContentMetaType + u8 storageID; ///< \ref FsStorageId + u8 unk_x02; ///< Unknown. + u8 padding; ///< Padding. + u32 title_version; ///< Title version. + u64 titleID; ///< titleID. } NsApplicationContentMetaStatus; -typedef struct -{ - u64 titleID; - u8 type; - u8 unk_x09; - u8 unk_x0A[6]; - u8 unk_x10; - u8 unk_x11[7]; +/// ApplicationRecord +typedef struct { + u64 titleID; ///< titleID. + u8 type; ///< Type. + u8 unk_x09; ///< Unknown. + u8 unk_x0A[6]; ///< Unknown. + u8 unk_x10; ///< Unknown. + u8 unk_x11[7]; ///< Unknown. } NsApplicationRecord; +/// LaunchProperties typedef struct { - u64 titleID; - u32 version; - u8 storageID; - u8 index; - u8 is_application; + u64 titleID; ///< titleID. + u32 version; ///< Title version. + u8 storageID; ///< \ref FsStorageId + u8 index; ///< Index. + u8 is_application; ///< Whether this is an Application. } NsLaunchProperties; +/// ShellEvent typedef enum { - NsShellEvent_None = 0, - NsShellEvent_Exit = 1, - NsShellEvent_Start = 2, - NsShellEvent_Crash = 3, - NsShellEvent_Debug = 4, + NsShellEvent_None = 0, ///< None + NsShellEvent_Exit = 1, ///< Exit + NsShellEvent_Start = 2, ///< Start + NsShellEvent_Crash = 3, ///< Crash + NsShellEvent_Debug = 4, ///< Debug } NsShellEvent; +/// ShellEventInfo typedef struct { - NsShellEvent event; - u64 process_id; + NsShellEvent event; ///< \ref NsShellEvent + u64 process_id; ///< processID. } NsShellEventInfo; Result nsInitialize(void); void nsExit(void); -Result nsListApplicationRecord(NsApplicationRecord* buffer, size_t size, size_t entry_offset, size_t* out_entrycount); -Result nsListApplicationContentMetaStatus(u64 titleID, u32 index, NsApplicationContentMetaStatus* buffer, size_t size, size_t* out_entrycount); -Result nsGetApplicationControlData(u8 flag, u64 titleID, NsApplicationControlData* buffer, size_t size, size_t* actual_size); +/** + * @brief Gets an listing of \ref NsApplicationRecord. + * @param[out] records Output array of \ref NsApplicationRecord. + * @param[in] count Size of the records array in entries. + * @param[in] entry_offset Starting entry offset. + * @param[out] out_entrycount Total output entries. + */ +Result nsListApplicationRecord(NsApplicationRecord* records, s32 count, s32 entry_offset, s32* out_entrycount); + +/** + * @brief Gets an listing of \ref NsApplicationContentMetaStatus. + * @param[in] titleID titleID. + * @param[in] index Starting entry index. + * @param[out] list Output array of \ref NsApplicationContentMetaStatus. + * @param[in] count Size of the list array in entries. + * @param[out] out_entrycount Total output entries. + */ +Result nsListApplicationContentMetaStatus(u64 titleID, s32 index, NsApplicationContentMetaStatus* list, s32 count, s32* out_entrycount); + +/** + * @brief Gets the \ref NsApplicationControlData for the specified title. + * @param[in] flag Flag, official sw uses value 1. + * @param[in] titleID titleID. + * @param[out] buffer \ref NsApplicationControlData + * @param[in] size Size of the buffer. + * @param[out] actual_size Actual output size. + */ +Result nsGetApplicationControlData(u8 flag, u64 titleID, NsApplicationControlData* buffer, size_t size, u64* actual_size); /** * @brief Returns the total storage capacity (used + free) from content manager services. - * @param storage_id Specified FsStorageId. (Must be FsStorageId_SdCard) - * @param size Pointer to output the total storage size to. + * @param[in] storage_id Specified FsStorageId. (Must be FsStorageId_SdCard) + * @param[out] size Pointer to output the total storage size to. */ Result nsGetTotalSpaceSize(FsStorageId storage_id, u64 *size); /** * @brief Returns the available storage capacity from content manager services. - * @param storage_id Specified FsStorageId. (Must be FsStorageId_SdCard) - * @param size Pointer to output the free storage size to. + * @param[in] storage_id Specified FsStorageId. (Must be FsStorageId_SdCard) + * @param[out] size Pointer to output the free storage size to. */ Result nsGetFreeSpaceSize(FsStorageId storage_id, u64 *size); @@ -90,12 +119,12 @@ void nsdevExit(void); Result nsdevLaunchProgram(u64* out_pid, const NsLaunchProperties* properties, u32 flags); Result nsdevTerminateProcess(u64 pid); Result nsdevTerminateProgram(u64 tid); -Result nsdevGetShellEvent(Event* out); ///< Autoclear for nsdevShellEvent is always true. +Result nsdevGetShellEvent(Event* out_event); ///< Autoclear for nsdevShellEvent is always true. Result nsdevGetShellEventInfo(NsShellEventInfo* out); Result nsdevTerminateApplication(void); Result nsdevPrepareLaunchProgramFromHost(NsLaunchProperties* out, const char* path, size_t path_len); Result nsdevLaunchApplicationForDevelop(u64* out_pid, u64 app_title_id, u32 flags); Result nsdevLaunchApplicationWithStorageIdForDevelop(u64* out_pid, u64 app_title_id, u32 flags, u8 app_storage_id, u8 patch_storage_id); Result nsdevIsSystemMemoryResourceLimitBoosted(bool* out); ///< [6.0.0-8.1.0] -Result nsdevGetRunningApplicationProcessIdForDevelop(u64* out_pid); -Result nsdevSetCurrentApplicationRightsEnvironmentCanBeActiveForDevelop(bool can_be_active); +Result nsdevGetRunningApplicationProcessIdForDevelop(u64* out_pid); ///< [6.0.0+] +Result nsdevSetCurrentApplicationRightsEnvironmentCanBeActiveForDevelop(bool can_be_active); ///< [6.0.0+] diff --git a/nx/source/services/ns.c b/nx/source/services/ns.c index ba46c740..0c507868 100644 --- a/nx/source/services/ns.c +++ b/nx/source/services/ns.c @@ -1,25 +1,18 @@ -#include "types.h" -#include "result.h" -#include "arm/atomics.h" -#include "kernel/ipc.h" +#define NX_SERVICE_ASSUME_NON_DOMAIN +#include "service_guard.h" #include "runtime/hosversion.h" -#include "services/sm.h" #include "services/ns.h" static Service g_nsAppManSrv, g_nsGetterSrv, g_nsvmSrv, g_nsdevSrv; -static u64 g_nsRefCnt, g_nsvmRefCnt, g_nsdevRefCnt; -static Result _nsGetInterface(Service* srv_out, u64 cmd_id); +static Result _nsGetInterface(Service* srv_out, u32 cmd_id); -Result nsInitialize(void) +NX_GENERATE_SERVICE_GUARD(ns); + +Result _nsInitialize(void) { Result rc=0; - atomicIncrement64(&g_nsRefCnt); - - if (serviceIsActive(&g_nsGetterSrv) || serviceIsActive(&g_nsAppManSrv)) - return 0; - if(hosversionBefore(3,0,0)) return smGetService(&g_nsAppManSrv, "ns:am"); @@ -33,815 +26,224 @@ Result nsInitialize(void) return rc; } -void nsExit(void) +void _nsCleanup(void) { - if (atomicDecrement64(&g_nsRefCnt) == 0) { - serviceClose(&g_nsAppManSrv); - if(hosversionBefore(3,0,0)) return; + serviceClose(&g_nsAppManSrv); + if(hosversionBefore(3,0,0)) return; - serviceClose(&g_nsGetterSrv); - } + serviceClose(&g_nsGetterSrv); } -Result nsdevInitialize(void) { - atomicIncrement64(&g_nsdevRefCnt); - - if (serviceIsActive(&g_nsdevSrv)) - return 0; - - return smGetService(&g_nsdevSrv, "ns:dev"); +static Result _nsGetInterface(Service* srv_out, u32 cmd_id) { + return serviceDispatch(&g_nsGetterSrv, cmd_id, + .out_num_objects = 1, + .out_objects = srv_out, + ); } -void nsdevExit(void) { - if (atomicDecrement64(&g_nsdevRefCnt) == 0) - serviceClose(&g_nsdevSrv); -} +static Result _appletGetEvent(Service* srv, u32 cmd_id, Event* out_event, bool autoclear) { + Handle event = INVALID_HANDLE; + Result rc = serviceDispatch(srv, cmd_id, + .out_handle_attrs = { SfOutHandleAttr_HipcCopy }, + .out_handles = &event, + ); -static Result _nsGetInterface(Service* srv_out, u64 cmd_id) { - IpcCommand c; - ipcInitialize(&c); - - struct { - u64 magic; - u64 cmd_id; - } *raw; - - raw = ipcPrepareHeader(&c, sizeof(*raw)); - - raw->magic = SFCI_MAGIC; - raw->cmd_id = cmd_id; - - Result rc = serviceIpcDispatch(&g_nsGetterSrv); - - if (R_SUCCEEDED(rc)) { - IpcParsedCommand r; - ipcParse(&r); - - struct { - u64 magic; - u64 result; - } *resp = r.Raw; - - rc = resp->result; - - if (R_SUCCEEDED(rc)) { - serviceCreate(srv_out, r.Handles[0]); - } - } + if (R_SUCCEEDED(rc)) + eventLoadRemote(out_event, event, autoclear); return rc; } -Result nsListApplicationRecord(NsApplicationRecord* buffer, size_t size, size_t entry_offset, size_t* out_entrycount) -{ - IpcCommand c; - ipcInitialize(&c); - ipcAddRecvBuffer(&c, buffer, size, 0); +static Result _nsCmdNoIO(Service* srv, u32 cmd_id) { + return serviceDispatch(srv, cmd_id); +} - struct { - u64 magic; - u64 cmd_id; - u32 entry_offset; - } *raw; +static Result _nsCmdInBool(Service* srv, u32 cmd_id, bool inval) { + u8 in = inval!=0; - raw = ipcPrepareHeader(&c, sizeof(*raw)); + return serviceDispatchIn(srv, cmd_id, in); +} - raw->magic = SFCI_MAGIC; - raw->cmd_id = 0; - raw->entry_offset = entry_offset; +static Result _nsCmdInU64(Service* srv, u32 cmd_id, u64 inval) { + return serviceDispatchIn(srv, cmd_id, inval); +} - Result rc = serviceIpcDispatch(&g_nsAppManSrv); - - if (R_SUCCEEDED(rc)) { - IpcParsedCommand r; - ipcParse(&r); - - struct { - u64 magic; - u64 result; - u32 entry_count; - } *resp = r.Raw; - - rc = resp->result; - - if (R_SUCCEEDED(rc) && out_entrycount) *out_entrycount = resp->entry_count; - } +static Result _nsCmdInU64OutU64(Service* srv, u32 cmd_id, u64 inval, u64 *out) { + return serviceDispatchInOut(srv, cmd_id, inval, *out); +} +static Result _nsCmdNoInOutBool(Service* srv, u32 cmd_id, bool *out) { + u8 tmpout=0; + Result rc = serviceDispatchOut(srv, cmd_id, tmpout); + if (R_SUCCEEDED(rc) && out) *out = tmpout!=0; return rc; } -Result nsListApplicationContentMetaStatus(u64 titleID, u32 index, NsApplicationContentMetaStatus* buffer, size_t size, size_t* out_entrycount) -{ - IpcCommand c; - ipcInitialize(&c); - ipcAddRecvBuffer(&c, buffer, size, 0); +static Result _nsCmdNoInOutU64(Service* srv, u32 cmd_id, u64 *out) { + return serviceDispatchOut(srv, cmd_id, *out); +} - struct { - u64 magic; - u64 cmd_id; - u32 index; +Result nsListApplicationRecord(NsApplicationRecord* records, s32 count, s32 entry_offset, s32* out_entrycount) { + return serviceDispatchInOut(&g_nsAppManSrv, 0, entry_offset, *out_entrycount, + .buffer_attrs = { SfBufferAttr_HipcMapAlias | SfBufferAttr_Out }, + .buffers = { { records, count*sizeof(NsApplicationRecord) } }, + ); +} + +Result nsListApplicationContentMetaStatus(u64 titleID, s32 index, NsApplicationContentMetaStatus* list, s32 count, s32* out_entrycount) { + const struct { + s32 index; u64 titleID; - } *raw; + } in = { index, titleID }; - raw = ipcPrepareHeader(&c, sizeof(*raw)); - - raw->magic = SFCI_MAGIC; - raw->cmd_id = 601; - raw->index = index; - raw->titleID = titleID; - - Result rc = serviceIpcDispatch(&g_nsAppManSrv); - - if (R_SUCCEEDED(rc)) { - IpcParsedCommand r; - ipcParse(&r); - - struct { - u64 magic; - u64 result; - u32 entry_count; - } *resp = r.Raw; - - rc = resp->result; - - if (R_SUCCEEDED(rc) && out_entrycount) *out_entrycount = resp->entry_count; - } - - return rc; + return serviceDispatchInOut(&g_nsAppManSrv, 601, in, *out_entrycount, + .buffer_attrs = { SfBufferAttr_HipcMapAlias | SfBufferAttr_Out }, + .buffers = { { list, count*sizeof(NsApplicationContentMetaStatus) } }, + ); } -Result nsGetApplicationControlData(u8 flag, u64 titleID, NsApplicationControlData* buffer, size_t size, size_t* actual_size) { - IpcCommand c; - ipcInitialize(&c); - ipcAddRecvBuffer(&c, buffer, size, 0); - - struct { - u64 magic; - u64 cmd_id; +Result nsGetApplicationControlData(u8 flag, u64 titleID, NsApplicationControlData* buffer, size_t size, u64* actual_size) { + const struct { u8 flag; u64 titleID; - } *raw; + } in = { flag, titleID }; - raw = ipcPrepareHeader(&c, sizeof(*raw)); - - raw->magic = SFCI_MAGIC; - raw->cmd_id = 400; - raw->flag = flag; - raw->titleID = titleID; - - Result rc = serviceIpcDispatch(&g_nsAppManSrv); - - if (R_SUCCEEDED(rc)) { - IpcParsedCommand r; - ipcParse(&r); - - struct { - u64 magic; - u64 result; - u64 actual_size; - } *resp = r.Raw; - - rc = resp->result; - - if (R_SUCCEEDED(rc) && actual_size) *actual_size = resp->actual_size; - } - - return rc; + return serviceDispatchInOut(&g_nsAppManSrv, 400, in, *actual_size, + .buffer_attrs = { SfBufferAttr_HipcMapAlias | SfBufferAttr_Out }, + .buffers = { { buffer, size } }, + ); } -Result nsGetTotalSpaceSize(FsStorageId storage_id, u64 *size) -{ - IpcCommand c; - ipcInitialize(&c); - - struct { - u64 magic; - u64 cmd_id; - u64 storage_id; - } *raw; - - raw = ipcPrepareHeader(&c, sizeof(*raw)); - - raw->magic = SFCI_MAGIC; - raw->cmd_id = 47; - raw->storage_id = storage_id; - - Result rc = serviceIpcDispatch(&g_nsAppManSrv); - - 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) *size = resp->size; - } - - return rc; +Result nsGetTotalSpaceSize(FsStorageId storage_id, u64 *size) { + return _nsCmdInU64OutU64(&g_nsAppManSrv, 47, storage_id, size); } -Result nsGetFreeSpaceSize(FsStorageId storage_id, u64 *size) -{ - IpcCommand c; - ipcInitialize(&c); - - struct { - u64 magic; - u64 cmd_id; - u64 storage_id; - } *raw; - - raw = ipcPrepareHeader(&c, sizeof(*raw)); - - raw->magic = SFCI_MAGIC; - raw->cmd_id = 48; - raw->storage_id = storage_id; - - Result rc = serviceIpcDispatch(&g_nsAppManSrv); - - 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) *size = resp->size; - } - - return rc; +Result nsGetFreeSpaceSize(FsStorageId storage_id, u64 *size) { + return _nsCmdInU64OutU64(&g_nsAppManSrv, 48, storage_id, size); } -Result nsvmInitialize(void) +NX_GENERATE_SERVICE_GUARD(nsvm); + +Result _nsvmInitialize(void) { if (hosversionBefore(3,0,0)) return 0; - atomicIncrement64(&g_nsvmRefCnt); - - if (serviceIsActive(&g_nsvmSrv)) - return 0; - return smGetService(&g_nsvmSrv, "ns:vm"); } -void nsvmExit(void) +void _nsvmCleanup(void) { if (hosversionBefore(3,0,0)) return; - if (atomicDecrement64(&g_nsvmRefCnt) == 0) { - serviceClose(&g_nsvmSrv); - } + serviceClose(&g_nsvmSrv); } Result nsvmNeedsUpdateVulnerability(bool *out) { - IpcCommand c; - ipcInitialize(&c); + Service *srv = &g_nsAppManSrv; + if (hosversionAtLeast(3,0,0)) srv = &g_nsvmSrv; - struct { - u64 magic; - u64 cmd_id; - } *raw; - - raw = ipcPrepareHeader(&c, sizeof(*raw)); - - raw->magic = SFCI_MAGIC; - raw->cmd_id = 1200; - - Result rc; - - if (hosversionAtLeast(3,0,0)) - 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; + return _nsCmdNoInOutBool(srv, 1200, out); } -Result nsvmGetSafeSystemVersion(u16 *out) -{ +Result nsvmGetSafeSystemVersion(u16 *out) { if (hosversionBefore(3,0,0)) return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); - IpcCommand c; - ipcInitialize(&c); + return serviceDispatchOut(&g_nsvmSrv, 1202, out); +} - struct { - u64 magic; - u64 cmd_id; - } *raw; +NX_GENERATE_SERVICE_GUARD(nsdev); - raw = ipcPrepareHeader(&c, sizeof(*raw)); +Result _nsdevInitialize(void) { + return smGetService(&g_nsdevSrv, "ns:dev"); +} - 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; +void _nsdevCleanup(void) { + serviceClose(&g_nsdevSrv); } Result nsdevLaunchProgram(u64* out_pid, const NsLaunchProperties* properties, u32 flags) { - IpcCommand c; - ipcInitialize(&c); - - struct { - u64 magic; - u64 cmd_id; + const struct { u32 flags; - u32 pad; NsLaunchProperties properties; - } *raw; + } in = { flags, *properties}; - 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; + return serviceDispatchInOut(&g_nsdevSrv, 0, in, *out_pid); } Result nsdevTerminateProcess(u64 pid) { - IpcCommand c; - ipcInitialize(&c); - - struct { - u64 magic; - u64 cmd_id; - u64 pid; - } *raw; - - raw = serviceIpcPrepareHeader(&g_nsdevSrv, &c, sizeof(*raw)); - - raw->magic = SFCI_MAGIC; - raw->cmd_id = 1; - raw->pid = pid; - - 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; + return _nsCmdInU64(&g_nsdevSrv, 1, pid); } Result nsdevTerminateProgram(u64 tid) { - IpcCommand c; - ipcInitialize(&c); - - struct { - u64 magic; - u64 cmd_id; - u64 tid; - } *raw; - - raw = serviceIpcPrepareHeader(&g_nsdevSrv, &c, sizeof(*raw)); - - raw->magic = SFCI_MAGIC; - raw->cmd_id = 2; - raw->tid = tid; - - 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; + return _nsCmdInU64(&g_nsdevSrv, 2, tid); } -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 nsdevGetShellEvent(Event* out_event) { + return _appletGetEvent(&g_nsdevSrv, 4, out_event, true); } Result nsdevGetShellEventInfo(NsShellEventInfo* out) { - IpcCommand c; - ipcInitialize(&c); - struct { - u64 magic; - u64 cmd_id; - } *raw; + u32 event; + u64 process_id; + } tmpout; - 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; - } - } + Result rc = serviceDispatchOut(&g_nsdevSrv, 5, tmpout); + if (R_SUCCEEDED(rc) && out) { + out->event = (NsShellEvent)tmpout.event; + out->process_id = tmpout.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; + return _nsCmdNoIO(&g_nsdevSrv, 6); } 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; + return serviceDispatchOut(&g_nsdevSrv, 7, out, + .buffer_attrs = { SfBufferAttr_HipcMapAlias | SfBufferAttr_In }, + .buffers = { { path, path_len } }, + ); } Result nsdevLaunchApplicationForDevelop(u64* out_pid, u64 app_title_id, u32 flags) { - IpcCommand c; - ipcInitialize(&c); - - struct { - u64 magic; - u64 cmd_id; + const struct { u32 flags; - u32 pad; u64 app_title_id; - } *raw; + } in = { .flags = flags, .app_title_id = app_title_id}; - 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; + return serviceDispatchInOut(&g_nsdevSrv, 8, in, *out_pid); } Result nsdevLaunchApplicationWithStorageIdForDevelop(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; + const struct { u8 app_storage_id; u8 patch_storage_id; - u16 pad; u32 flags; u64 app_title_id; - } *raw; + } in = { .app_storage_id = app_storage_id, .patch_storage_id = patch_storage_id, .flags = flags, .app_title_id = app_title_id}; - 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; + return serviceDispatchInOut(&g_nsdevSrv, 9, in, *out_pid); } Result nsdevIsSystemMemoryResourceLimitBoosted(bool* out) { if (hosversionBefore(6,0,0) || hosversionAtLeast(9,0,0)) 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; + return _nsCmdNoInOutBool(&g_nsdevSrv, 10, out); } Result nsdevGetRunningApplicationProcessIdForDevelop(u64* out_pid) { if (hosversionBefore(6,0,0)) 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; + return _nsCmdNoInOutU64(&g_nsdevSrv, 11, out_pid); } Result nsdevSetCurrentApplicationRightsEnvironmentCanBeActiveForDevelop(bool can_be_active) { if (hosversionBefore(6,0,0)) 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; - } - - return rc; + return _nsCmdInBool(&g_nsdevSrv, 12, can_be_active); }