mirror of
https://github.com/switchbrew/libnx.git
synced 2025-08-06 00:19:22 +02:00
sm: update for 12.0.0, tipc
This commit is contained in:
parent
ebb54a1224
commit
7416b23ef9
@ -9,6 +9,7 @@
|
||||
#include "../types.h"
|
||||
#include "../kernel/svc.h"
|
||||
#include "../sf/service.h"
|
||||
#include "../sf/tipc.h"
|
||||
|
||||
/// Structure representing a service name (null terminated, remaining characters set to zero).
|
||||
typedef struct SmServiceName {
|
||||
@ -117,6 +118,12 @@ Handle smGetServiceOverride(SmServiceName name);
|
||||
*/
|
||||
Result smRegisterService(Handle* handle_out, SmServiceName name, bool is_light, s32 max_sessions);
|
||||
|
||||
/// Same as \ref smRegisterService, but always using cmif serialization.
|
||||
Result smRegisterServiceCmif(Handle* handle_out, SmServiceName name, bool is_light, s32 max_sessions);
|
||||
|
||||
/// Same as \ref smRegisterService, but always using cmif serialization.
|
||||
Result smRegisterServiceTipc(Handle* handle_out, SmServiceName name, bool is_light, s32 max_sessions);
|
||||
|
||||
/**
|
||||
* @brief Unregisters a previously registered service in SM.
|
||||
* @param[in] name Name of the service.
|
||||
@ -124,19 +131,38 @@ Result smRegisterService(Handle* handle_out, SmServiceName name, bool is_light,
|
||||
*/
|
||||
Result smUnregisterService(SmServiceName name);
|
||||
|
||||
/// Same as \ref smUnregisterService, but always using cmif serialization.
|
||||
Result smUnregisterServiceCmif(SmServiceName name);
|
||||
|
||||
/// Same as \ref smUnregisterService, but always using cmif serialization.
|
||||
Result smUnregisterServiceTipc(SmServiceName name);
|
||||
|
||||
/**
|
||||
* @brief Detaches the current SM session.
|
||||
* @note After this function is called, the rest of the SM API cannot be used.
|
||||
* @note Only available on [11.0.0+].
|
||||
* @note Only available on [11.0.0-11.0.1], or Atmosphère.
|
||||
*/
|
||||
Result smDetachClient(void);
|
||||
|
||||
/// Same as \ref smDetachClient, but always using cmif serialization.
|
||||
Result smDetachClientCmif(void);
|
||||
|
||||
/// Same as \ref smDetachClient, but always using tipc serialization.
|
||||
Result smDetachClientTipc(void);
|
||||
|
||||
/**
|
||||
* @brief Gets the Service session used to communicate with SM.
|
||||
* @return Pointer to service session used to communicate with SM.
|
||||
*/
|
||||
Service *smGetServiceSession(void);
|
||||
|
||||
/**
|
||||
* @brief Gets the TipcService session used to communicate with SM.
|
||||
* @return Pointer to tipc service session used to communicate with SM.
|
||||
* @note Only available on [12.0.0+], or Atmosphère.
|
||||
*/
|
||||
TipcService *smGetServiceSessionTipc(void);
|
||||
|
||||
/**
|
||||
* @brief Overrides a service with a custom IPC service handle.
|
||||
* @param[in] name Name of the service.
|
||||
|
@ -1,9 +1,13 @@
|
||||
#define NX_SERVICE_ASSUME_NON_DOMAIN
|
||||
#include "service_guard.h"
|
||||
#include "sf/tipc.h"
|
||||
#include "runtime/hosversion.h"
|
||||
#include "runtime/diag.h"
|
||||
|
||||
static Service g_smSrv;
|
||||
static union {
|
||||
Service cmif;
|
||||
TipcService tipc;
|
||||
} g_smSrv;
|
||||
|
||||
#define MAX_OVERRIDES 32
|
||||
|
||||
@ -14,6 +18,10 @@ static struct {
|
||||
|
||||
static size_t g_smOverridesNum = 0;
|
||||
|
||||
static bool _smShouldUseTipc(void) {
|
||||
return hosversionIsAtmosphere() || hosversionAtLeast(12,0,0);
|
||||
}
|
||||
|
||||
void smAddOverrideHandle(SmServiceName name, Handle handle) {
|
||||
if (g_smOverridesNum == MAX_OVERRIDES)
|
||||
diagAbortWithResult(MAKERESULT(Module_Libnx, LibnxError_TooManyOverrides));
|
||||
@ -36,9 +44,13 @@ Handle smGetServiceOverride(SmServiceName name) {
|
||||
|
||||
NX_GENERATE_SERVICE_GUARD(sm);
|
||||
|
||||
static Result _smCmdInPid(u32 cmd_id) {
|
||||
static Result _smCmifCmdInPid(u32 cmd_id) {
|
||||
u64 pid_placeholder = 0;
|
||||
return serviceDispatchIn(&g_smSrv, cmd_id, pid_placeholder, .in_send_pid = true);
|
||||
return serviceDispatchIn(&g_smSrv.cmif, cmd_id, pid_placeholder, .in_send_pid = true);
|
||||
}
|
||||
|
||||
static Result _smTipcCmdInPid(u32 cmd_id) {
|
||||
return tipcDispatch(&g_smSrv.tipc, cmd_id, .in_send_pid = true);
|
||||
}
|
||||
|
||||
Result _smInitialize(void) {
|
||||
@ -49,24 +61,26 @@ Result _smInitialize(void) {
|
||||
rc = svcConnectToNamedPort(&sm_handle, "sm:");
|
||||
}
|
||||
|
||||
// Call RegisterClient. This is unconditionally done through cmif,
|
||||
// see comment in smGetServiceOriginal for more details.
|
||||
if (R_SUCCEEDED(rc)) {
|
||||
serviceCreate(&g_smSrv, sm_handle);
|
||||
}
|
||||
|
||||
Handle tmp;
|
||||
if (R_SUCCEEDED(rc) && R_VALUE(smGetServiceOriginal(&tmp, (SmServiceName){})) == 0x415) {
|
||||
rc = _smCmdInPid(0);
|
||||
serviceCreate(&g_smSrv.cmif, sm_handle);
|
||||
rc = _smCmifCmdInPid(0); // RegisterClient
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
void _smCleanup(void) {
|
||||
serviceClose(&g_smSrv);
|
||||
serviceClose(&g_smSrv.cmif);
|
||||
}
|
||||
|
||||
Service *smGetServiceSession(void) {
|
||||
return &g_smSrv;
|
||||
return &g_smSrv.cmif;
|
||||
}
|
||||
|
||||
TipcService *smGetServiceSessionTipc(void) {
|
||||
return &g_smSrv.tipc;
|
||||
}
|
||||
|
||||
Result smGetServiceWrapper(Service* service_out, SmServiceName name) {
|
||||
@ -88,30 +102,75 @@ Result smGetServiceWrapper(Service* service_out, SmServiceName name) {
|
||||
}
|
||||
|
||||
Result smGetServiceOriginal(Handle* handle_out, SmServiceName name) {
|
||||
return serviceDispatchIn(&g_smSrv, 1, name,
|
||||
// Even though GetServiceHandle is also available through tipc, we choose to only
|
||||
// call this command through cmif, since that is available on all system versions.
|
||||
return serviceDispatchIn(&g_smSrv.cmif, 1, name,
|
||||
.out_handle_attrs = { SfOutHandleAttr_HipcMove },
|
||||
.out_handles = handle_out,
|
||||
);
|
||||
}
|
||||
|
||||
Result smRegisterService(Handle* handle_out, SmServiceName name, bool is_light, s32 max_sessions) {
|
||||
if (_smShouldUseTipc())
|
||||
return smRegisterServiceTipc(handle_out, name, is_light, max_sessions);
|
||||
else
|
||||
return smRegisterServiceCmif(handle_out, name, is_light, max_sessions);
|
||||
}
|
||||
|
||||
Result smRegisterServiceCmif(Handle* handle_out, SmServiceName name, bool is_light, s32 max_sessions) {
|
||||
const struct {
|
||||
SmServiceName service_name;
|
||||
u8 is_light;
|
||||
s32 max_sessions;
|
||||
} in = { name, is_light!=0, max_sessions };
|
||||
|
||||
return serviceDispatchIn(&g_smSrv, 2, in,
|
||||
return serviceDispatchIn(&g_smSrv.cmif, 2, in,
|
||||
.out_handle_attrs = { SfOutHandleAttr_HipcMove },
|
||||
.out_handles = handle_out,
|
||||
);
|
||||
}
|
||||
|
||||
Result smRegisterServiceTipc(Handle* handle_out, SmServiceName name, bool is_light, s32 max_sessions) {
|
||||
const struct {
|
||||
SmServiceName service_name;
|
||||
s32 max_sessions;
|
||||
u8 is_light;
|
||||
} in = { name, max_sessions, is_light!=0 };
|
||||
|
||||
return tipcDispatchIn(&g_smSrv.tipc, 2, in,
|
||||
.out_handle_attrs = { SfOutHandleAttr_HipcMove },
|
||||
.out_handles = handle_out,
|
||||
);
|
||||
}
|
||||
|
||||
Result smUnregisterService(SmServiceName name) {
|
||||
return serviceDispatchIn(&g_smSrv, 3, name);
|
||||
if (_smShouldUseTipc())
|
||||
return smUnregisterServiceTipc(name);
|
||||
else
|
||||
return smUnregisterServiceCmif(name);
|
||||
}
|
||||
|
||||
Result smUnregisterServiceCmif(SmServiceName name) {
|
||||
return serviceDispatchIn(&g_smSrv.cmif, 3, name);
|
||||
}
|
||||
|
||||
Result smUnregisterServiceTipc(SmServiceName name) {
|
||||
return tipcDispatchIn(&g_smSrv.tipc, 3, name);
|
||||
}
|
||||
|
||||
Result smDetachClient(void) {
|
||||
if (!hosversionIsAtmosphere() && hosversionBefore(11,0,0)) return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
|
||||
return _smCmdInPid(4);
|
||||
if (hosversionIsAtmosphere())
|
||||
return smDetachClientTipc();
|
||||
else if (hosversionBetween(11, 12))
|
||||
return smDetachClientCmif();
|
||||
else
|
||||
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
|
||||
}
|
||||
|
||||
Result smDetachClientCmif(void) {
|
||||
return _smCmifCmdInPid(4);
|
||||
}
|
||||
|
||||
Result smDetachClientTipc(void) {
|
||||
return _smTipcCmdInPid(4);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user