From a622ae559327fbc62919fec43ed5d67b72fe303c Mon Sep 17 00:00:00 2001 From: TuxSH Date: Thu, 15 Feb 2018 16:33:48 +0100 Subject: [PATCH] Add domain handling to sm.h --- nx/include/switch/services/sm.h | 80 ++++++++++++++++++++++++++++++--- 1 file changed, 75 insertions(+), 5 deletions(-) diff --git a/nx/include/switch/services/sm.h b/nx/include/switch/services/sm.h index 1208e541..6fcecdd7 100644 --- a/nx/include/switch/services/sm.h +++ b/nx/include/switch/services/sm.h @@ -12,14 +12,17 @@ /// Service type. typedef enum { - ServiceType_Uninitialized, ///< Uninitialized service. - ServiceType_Normal, ///< Normal service. - ServiceType_Override ///< Service overriden in the homebrew environment. + ServiceType_Uninitialized, ///< Uninitialized service. + ServiceType_Normal, ///< Normal service. + ServiceType_Domain, ///< Domain. + ServiceType_DomainSubservice, ///< Domain subservice; + ServiceType_Override ///< Service overriden in the homebrew environment. } ServiceType; /// Service object structure. typedef struct { Handle handle; + u32 object_id; ServiceType type; } Service; @@ -41,10 +44,47 @@ static inline bool serviceIsActive(Service* s) { return s->type != ServiceType_Uninitialized; } +/** + * @brief Returns whether a service is a domain. + * @param[in] s Service object. + * @return true if a domain. + */ +static inline bool serviceIsDomain(Service* s) { + return s->type == ServiceType_Domain; +} + +/** + * @brief Returns whether a service is a domain subservice. + * @param[in] s Service object. + * @return true if a domain subservice. + */ +static inline bool serviceIsDomainSubservice(Service* s) { + return s->type == ServiceType_DomainSubservice; +} + +/** + * @brief For a domain/domain subservice, return the associated object ID. + * @param[in] s Service object, necessarily a domain or domain subservice. + * @return The object ID. + */ +static inline u32 serviceGetObjectId(Service* s) { + return s->object_id; +} + +/** + * @brief Closes a domain object by ID. + * @param[in] s Service object, necessarily a domain or domain subservice. + * @param object_id ID of the object to close. + * @return Result code. + */ +static inline Result serviceCloseObjectById(Service* s, u32 object_id) { + return ipcCloseObjectById(s->handle, object_id); +} + /** * @brief Dispatches an IPC request to a service. * @param[in] s Service object. - * @return Result code + * @return Result code. */ static inline Result serviceIpcDispatch(Service* s) { return ipcDispatch(s->handle); @@ -52,12 +92,37 @@ static inline Result serviceIpcDispatch(Service* s) { /** * @brief Creates a service object from an IPC session handle. - * @param[in] s Service object. + * @param[out] s Service object. * @param[in] h IPC session handle. */ static inline void serviceCreate(Service* s, Handle h) { s->handle = h; s->type = ServiceType_Normal; + s->object_id = IPC_INVALID_OBJECT_ID; +} + +/** + * @brief Creates a domain subservice object from a parent service. + * @param[out] s Service object. + * @param[in] parent Parent service, necessarily a domain or domain subservice. + * @param[in] object_id Object ID for this subservice. + */ +static inline void serviceCreateDomainSubservice(Service* s, Service* parent, u32 object_id) { + s->handle = parent->handle; + s->type = ServiceType_DomainSubservice; + s->object_id = object_id; +} + +/** + * @brief Converts a regular service to a domain. + * @param[in] s Service object. + * @return Result code. + */ +static inline Result serviceConvertToDomain(Service* s) { + Result rc = ipcConvertSessionToDomain(s->handle, &s->object_id); + if(R_SUCCEEDED(rc)) + s->type = ServiceType_Domain; + return rc; } /** @@ -68,9 +133,14 @@ static inline void serviceClose(Service* s) { switch (s->type) { case ServiceType_Normal: + case ServiceType_Domain: svcCloseHandle(s->handle); break; + case ServiceType_DomainSubservice: + serviceCloseObjectById(s, s->object_id); + break; + case ServiceType_Override: // Don't close because we don't own the overridden handle. break;