diff --git a/nx/include/switch/services/sm.h b/nx/include/switch/services/sm.h index a3bab05d..93324dcd 100644 --- a/nx/include/switch/services/sm.h +++ b/nx/include/switch/services/sm.h @@ -1,3 +1,5 @@ bool smHasInitialized(); Result smInitialize(); Result smGetService(Handle* handle_out, const char* name); +Result smRegisterService(Handle* handle_out, const char* name, bool is_light, int max_sessions); +Result smUnregisterService(const char* name); diff --git a/nx/source/services/sm.c b/nx/source/services/sm.c index 01af93ad..2e165a58 100644 --- a/nx/source/services/sm.c +++ b/nx/source/services/sm.c @@ -47,7 +47,7 @@ Result smInitialize() { return rc; } -Result smGetService(Handle* handle_out, const char* name) { +static u64 _EncodeName(const char* name) { u64 name_encoded = 0; size_t i; @@ -58,6 +58,10 @@ Result smGetService(Handle* handle_out, const char* name) { name_encoded |= ((u64) name[i]) << (8*i); } + return name_encoded; +} + +Result smGetService(Handle* handle_out, const char* name) { IpcCommand c; ipcInitialize(&c); @@ -72,7 +76,7 @@ Result smGetService(Handle* handle_out, const char* name) { raw->magic = SFCI_MAGIC; raw->cmd_id = 1; - raw->service_name = name_encoded; + raw->service_name = _EncodeName(name); Result rc = ipcDispatch(g_smHandle); @@ -94,3 +98,78 @@ Result smGetService(Handle* handle_out, const char* name) { return rc; } + +Result smRegisterService(Handle* handle_out, const char* name, bool is_light, int max_sessions) { + IpcCommand c; + ipcInitialize(&c); + + struct { + u64 magic; + u64 cmd_id; + u64 service_name; + u32 is_light; + u32 max_sessions; + } *raw; + + raw = ipcPrepareHeader(&c, sizeof(*raw)); + + raw->magic = SFCI_MAGIC; + raw->cmd_id = 2; + raw->service_name = _EncodeName(name); + raw->is_light = !!is_light; + raw->max_sessions = max_sessions; + + Result rc = ipcDispatch(g_smHandle); + + if (R_SUCCEEDED(rc)) { + IpcCommandResponse r; + ipcParseResponse(&r); + + struct { + u64 magic; + u64 result; + } *resp = r.Raw; + + rc = resp->result; + + if (R_SUCCEEDED(rc)) { + *handle_out = r.Handles[0]; + } + } + + return rc; +} + +Result smUnregisterService(const char* name) { + IpcCommand c; + ipcInitialize(&c); + + struct { + u64 magic; + u64 cmd_id; + u64 service_name; + u64 reserved; + } *raw; + + raw = ipcPrepareHeader(&c, sizeof(*raw)); + + raw->magic = SFCI_MAGIC; + raw->cmd_id = 3; + raw->service_name = _EncodeName(name); + + Result rc = ipcDispatch(g_smHandle); + + if (R_SUCCEEDED(rc)) { + IpcCommandResponse r; + ipcParseResponse(&r); + + struct { + u64 magic; + u64 result; + } *resp = r.Raw; + + rc = resp->result; + } + + return rc; +}