Make results, account, service compile

This commit is contained in:
Joey Yakimowich-Payne 2022-12-09 20:58:14 -07:00
commit f11006b4dd
No known key found for this signature in database
GPG key ID: 6BFE655FA5ABD1E1
6 changed files with 132 additions and 155 deletions

4
.gitignore vendored
View file

@ -1,3 +1,7 @@
*
!*/
!*.*
nimcache/ nimcache/
# Swap # Swap
[._]*.s[a-v][a-z] [._]*.s[a-v][a-z]

View file

@ -1,7 +1,7 @@
import strutils import strutils
import libnx/wrapper/acc import libnx/wrapper/switch/services/acc
import libnx/results import libnx/results
import libnx/wrapper/types import libnx/wrapper/switch/types
import libnx/ext/integer128 import libnx/ext/integer128
import libnx/service import libnx/service
import libnx/utils import libnx/utils
@ -19,7 +19,7 @@ type
AccountImageLoadError* = object of AccountError AccountImageLoadError* = object of AccountError
User* = ref object User* = ref object
id*: u128 id*: AccountUid
selected*: bool selected*: bool
username*: string username*: string
lastEdited*: uint64 lastEdited*: uint64
@ -32,24 +32,28 @@ type
AccountImage* = ref object AccountImage* = ref object
data: seq[uint8] data: seq[uint8]
imageSize: int imageSize: U32
export AccountUid
export AccountServiceType
var enabled = false var enabled = false
proc getService*(): Service = proc getService*(): Service =
let serv = accountGetService()[] let serv = accountGetServiceSession()[]
result = newService(serv) result = newService(serv)
proc init() = proc init(ty: AccountServiceType) =
## Initializes the account service. Should not ## Initializes the account service. Should not
## be used in client code ## be used in client code
let service = getService() let service = getService()
if service.isActive: if service.isActive:
return return
let code = accountInitialize().newResult let code = accountInitialize(ty).newResult
if code.failed: if code.failed:
raiseEx( raiseEx(
AccountInitError, AccountInitError,
@ -84,7 +88,7 @@ proc ensureEnabled() =
proc getImageSize*(profile: AccountProfile): int = proc getImageSize*(profile: AccountProfile): int =
ensureEnabled() ensureEnabled()
var res = 0.csize var res = 0.U32
result = 0 result = 0
let code = accountProfileGetImageSize(profile.unsafeAddr, res.addr).newResult let code = accountProfileGetImageSize(profile.unsafeAddr, res.addr).newResult
if code.failed: if code.failed:
@ -92,19 +96,19 @@ proc getImageSize*(profile: AccountProfile): int =
result = res.int result = res.int
proc imageSize*(user: User): int = proc imageSize*(user: User): csize_t =
ensureEnabled() ensureEnabled()
var prof: AccountProfile var prof: AccountProfile
var size: csize var size: U32
let res = accountProfileGetImageSize(prof.addr, size.addr).newResult let res = accountProfileGetImageSize(prof.addr, size.addr).newResult
if res.failed: if res.failed:
raiseEx(AccountImageSizeError, "Error, could not get image size", res) raiseEx(AccountImageSizeError, "Error, could not get image size", res)
result = size.int result = size.csize_t
proc getProfileHelper(userID: u128): AccountProfile = proc getProfileHelper(userID: AccountUid): AccountProfile =
let res = accountGetProfile(result.addr, userID).newResult let res = accountGetProfile(result.addr, userID).newResult
if res.failed: if res.failed:
@ -115,7 +119,6 @@ proc loadImage*(user: User): AccountImage =
ensureEnabled() ensureEnabled()
result = new(AccountImage) result = new(AccountImage)
let imSize = user.imageSize() let imSize = user.imageSize()
var size: csize
var prof = getProfileHelper(user.id) var prof = getProfileHelper(user.id)
@ -137,7 +140,7 @@ proc userID*(user: User): string =
$user.id $user.id
proc getUser*(userID: u128): User = proc getUser*(userID: AccountUid): User =
ensureEnabled() ensureEnabled()
result = new(User) result = new(User)
@ -154,7 +157,7 @@ proc getUser*(userID: u128): User =
if res.failed: if res.failed:
raiseEx(AccountUserDataError, "Error, could not get user data", res) raiseEx(AccountUserDataError, "Error, could not get user data", res)
result.username = profBase.username.join("") result.username = profBase.nickname.join("")
result.lastEdited = profBase.lastEditTimestamp result.lastEdited = profBase.lastEditTimestamp
result.iconID = userData.iconID result.iconID = userData.iconID
result.iconBgColorID = userData.iconBackgroundColorID result.iconBgColorID = userData.iconBackgroundColorID
@ -167,19 +170,15 @@ proc getActiveUser*(): User =
ensureEnabled() ensureEnabled()
result = new(User) result = new(User)
var var
userID: u128 = newUInt128(0,0) userID: AccountUid
selected: bool
var res = accountGetActiveUser(userID.addr, selected.addr).newResult var res = accountGetPreselectedUser(userID.addr).newResult
if res.failed: if res.failed:
raiseEx(AccountActiveUserError, "Error, could not get active user ID", res) raiseEx(AccountActiveUserError, "Error, could not get active user ID", res)
if not selected:
raiseEx(AccountUserNotSelectedError, "No user currently selected!")
result.id = userID result.id = userID
result.selected = selected result.selected = true
var var
prof: AccountProfile = getProfileHelper(userID) prof: AccountProfile = getProfileHelper(userID)
@ -191,7 +190,7 @@ proc getActiveUser*(): User =
if res.failed: if res.failed:
raiseEx(AccountUserDataError, "Error, could not get user data", res) raiseEx(AccountUserDataError, "Error, could not get user data", res)
result.username = profBase.username.join("") result.username = profBase.nickname.join("")
result.lastEdited = profBase.lastEditTimestamp result.lastEdited = profBase.lastEditTimestamp
result.iconID = userData.iconID result.iconID = userData.iconID
result.iconBgColorID = userData.iconBackgroundColorID result.iconBgColorID = userData.iconBackgroundColorID
@ -235,8 +234,8 @@ proc listAllUsers*(): seq[User] =
result = @[] result = @[]
var var
userIDs: array[ACC_USER_LIST_SIZE, u128] userIDs: array[ACC_USER_LIST_SIZE, AccountUid]
usersReturned: csize usersReturned: S32
let res = accountListAllUsers( let res = accountListAllUsers(
userIDs[0].addr, userIDs[0].addr,

View file

@ -1,7 +1,6 @@
import strutils import strutils
import import
libnx/wrapper/result, libnx/wrapper/switch/result
libnx/wrapper/types
type type
@ -83,8 +82,8 @@ type
IoctlFailed #///< Maps to Nvidia: 0x3000F IoctlFailed #///< Maps to Nvidia: 0x3000F
proc succeeded*(res: Result): bool = res.code.R_SUCCEEDED proc succeeded*(res: Result): bool {.inline.} = res.code.r_SUCCEEDED
proc failed*(res: Result): bool = res.code.R_FAILED proc failed*(res: Result): bool {.inline.} = res.code.r_FAILED
proc newResult*(code: uint32): Result = proc newResult*(code: uint32): Result =
## Create a result from a libnx error code for friendlier syntax. ## Create a result from a libnx error code for friendlier syntax.
@ -92,12 +91,12 @@ proc newResult*(code: uint32): Result =
result.code = code result.code = code
let moduleCode = code.R_MODULE let moduleCode = code.r_MODULE
let module = Module(moduleCode) let module = Module(moduleCode)
result.kind = module result.kind = module
let descCode = code.R_DESCRIPTION let descCode = code.r_DESCRIPTION
var error = "Unknown error: module: $# description: $#" % var error = "Unknown error: module: $# description: $#" %
[$moduleCode, $descCode] [$moduleCode, $descCode]

View file

@ -1,17 +1,18 @@
import import
libnx/results, libnx/results,
libnx/wrapper/sm libnx/wrapper/switch/services/sm,
libnx/wrapper/switch/sf/service,
libnx/wrapper/switch/types
from libnx/wrapper/types import Handle
type type
Service* = ref object Service* = ref object
serv: sm.Service serv: service.Service
proc getSmService*(serv: Service): sm.Service = proc getSmService*(serv: Service): service.Service =
serv.serv serv.serv
proc newService*(serv: sm.Service): Service = proc newService*(serv: service.Service): Service =
result = Service(serv: serv) result = Service(serv: serv)
proc isOverride*(service: Service): bool = proc isOverride*(service: Service): bool =
@ -54,24 +55,6 @@ proc objectId*(service: Service): uint32 =
## ##
serviceGetObjectId(service.serv.addr) serviceGetObjectId(service.serv.addr)
proc close*(service: Service; objectId: uint32): Result =
## *
## @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.
##
serviceCloseObjectById(service.serv.addr, objectId).newResult
proc ipcDispatch*(service: Service): Result =
## *
## @brief Dispatches an IPC request to a service.
## @param[in] s Service object.
## @return Result code.
##
serviceIpcDispatch(service.serv.addr).newResult
proc createService*(handle: Handle): Service = proc createService*(handle: Handle): Service =
## * ## *
## @brief Creates a service object from an IPC session handle. ## @brief Creates a service object from an IPC session handle.
@ -91,7 +74,7 @@ proc createDomainSubservice*(parent: Service; objectId: uint32): Service =
result = new(Service) result = new(Service)
serviceCreateDomainSubservice(result.serv.addr, parent.serv.addr, objectId) serviceCreateDomainSubservice(result.serv.addr, parent.serv.addr, objectId)
proc convertToDomain*(service: Service): Result = proc convertToDomain*(service: Service): results.Result =
## * ## *
## @brief Converts a regular service to a domain. ## @brief Converts a regular service to a domain.
## @param[in] s Service object. ## @param[in] s Service object.

View file

@ -59,22 +59,23 @@ type
AccountNetworkServiceAccountId* {.bycopy.} = object AccountNetworkServiceAccountId* {.bycopy.} = object
id*: U64 ## /< Id. id*: U64 ## /< Id.
## / Initialize account.
proc accountInitialize*(serviceType: AccountServiceType): Result {.cdecl, proc accountInitialize*(serviceType: AccountServiceType): Result {.cdecl,
importc: "accountInitialize".} importc: "accountInitialize".}
## / Exit account. ## / Initialize account.
proc accountExit*() {.cdecl, importc: "accountExit".} proc accountExit*() {.cdecl, importc: "accountExit".}
## / Gets the Service object for the actual account service session. ## / Exit account.
proc accountGetServiceSession*(): ptr Service {.cdecl, proc accountGetServiceSession*(): ptr Service {.cdecl,
importc: "accountGetServiceSession".} importc: "accountGetServiceSession".}
## / Get the total number of user profiles. ## / Gets the Service object for the actual account service session.
proc accountGetUserCount*(userCount: ptr S32): Result {.cdecl, proc accountGetUserCount*(userCount: ptr S32): Result {.cdecl,
importc: "accountGetUserCount".} importc: "accountGetUserCount".}
## / Get the total number of user profiles.
proc accountListAllUsers*(uids: ptr AccountUid; maxUids: S32; actualTotal: ptr S32): Result {.
cdecl, importc: "accountListAllUsers".}
## * ## *
## @brief Get a list of all userIds. The returned list will never be larger than ACC_USER_LIST_SIZE. ## @brief Get a list of all userIds. The returned list will never be larger than ACC_USER_LIST_SIZE.
## @param uids Pointer to array of userIds. ## @param uids Pointer to array of userIds.
@ -82,52 +83,50 @@ proc accountGetUserCount*(userCount: ptr S32): Result {.cdecl,
## @param actual_total The actual total number of userIds found. ## @param actual_total The actual total number of userIds found.
## ##
proc accountListAllUsers*(uids: ptr AccountUid; maxUids: S32; actualTotal: ptr S32): Result {.
cdecl, importc: "accountListAllUsers".}
## / Get the userId for the last opened user.
proc accountGetLastOpenedUser*(uid: ptr AccountUid): Result {.cdecl, proc accountGetLastOpenedUser*(uid: ptr AccountUid): Result {.cdecl,
importc: "accountGetLastOpenedUser".} importc: "accountGetLastOpenedUser".}
## / Get an AccountProfile for the specified userId. ## / Get the userId for the last opened user.
proc accountGetProfile*(`out`: ptr AccountProfile; uid: AccountUid): Result {.cdecl, proc accountGetProfile*(`out`: ptr AccountProfile; uid: AccountUid): Result {.cdecl,
importc: "accountGetProfile".} importc: "accountGetProfile".}
## / IsUserRegistrationRequestPermitted ## / Get an AccountProfile for the specified userId.
proc accountIsUserRegistrationRequestPermitted*(`out`: ptr bool): Result {.cdecl, proc accountIsUserRegistrationRequestPermitted*(`out`: ptr bool): Result {.cdecl,
importc: "accountIsUserRegistrationRequestPermitted".} importc: "accountIsUserRegistrationRequestPermitted".}
## / TrySelectUserWithoutInteraction ## / IsUserRegistrationRequestPermitted
proc accountTrySelectUserWithoutInteraction*(uid: ptr AccountUid; proc accountTrySelectUserWithoutInteraction*(uid: ptr AccountUid;
isNetworkServiceAccountRequired: bool): Result {.cdecl, isNetworkServiceAccountRequired: bool): Result {.cdecl,
importc: "accountTrySelectUserWithoutInteraction".} importc: "accountTrySelectUserWithoutInteraction".}
## / Close the AccountProfile. ## / TrySelectUserWithoutInteraction
proc accountProfileClose*(profile: ptr AccountProfile) {.cdecl, proc accountProfileClose*(profile: ptr AccountProfile) {.cdecl,
importc: "accountProfileClose".} importc: "accountProfileClose".}
## / Get \ref AccountUserData and \ref AccountProfileBase for the specified profile, userdata is optional (can be NULL). ## / Close the AccountProfile.
proc accountProfileGet*(profile: ptr AccountProfile; userdata: ptr AccountUserData; proc accountProfileGet*(profile: ptr AccountProfile; userdata: ptr AccountUserData;
profilebase: ptr AccountProfileBase): Result {.cdecl, profilebase: ptr AccountProfileBase): Result {.cdecl,
importc: "accountProfileGet".} importc: "accountProfileGet".}
## / Get the icon image size. ## / Get \ref AccountUserData and \ref AccountProfileBase for the specified profile, userdata is optional (can be NULL).
proc accountProfileGetImageSize*(profile: ptr AccountProfile; imageSize: ptr U32): Result {. proc accountProfileGetImageSize*(profile: ptr AccountProfile; imageSize: ptr U32): Result {.
cdecl, importc: "accountProfileGetImageSize".} cdecl, importc: "accountProfileGetImageSize".}
## / Load the JPEG profile icon, valid for both Miis and character icons. The output image_size is the same as the one from \ref accountProfileGetImageSize. ## / Get the icon image size.
proc accountProfileLoadImage*(profile: ptr AccountProfile; buf: pointer; len: csize_t; proc accountProfileLoadImage*(profile: ptr AccountProfile; buf: pointer; len: csize_t;
imageSize: ptr U32): Result {.cdecl, imageSize: ptr U32): Result {.cdecl,
importc: "accountProfileLoadImage".} importc: "accountProfileLoadImage".}
## / Gets the userId which was selected by the profile-selector applet (if any), prior to launching the currently running Application. ## / Load the JPEG profile icon, valid for both Miis and character icons. The output image_size is the same as the one from \ref accountProfileGetImageSize.
## / This gets the cached PreselectedUser loaded during accountInitialize, when PreselectedUser is available.
proc accountGetPreselectedUser*(uid: ptr AccountUid): Result {.cdecl, proc accountGetPreselectedUser*(uid: ptr AccountUid): Result {.cdecl,
importc: "accountGetPreselectedUser".} importc: "accountGetPreselectedUser".}
## * ## / Gets the userId which was selected by the profile-selector applet (if any), prior to launching the currently running Application.
## @brief Checks whether the specified \ref AccountUid is valid/set (non-zero). ## / This gets the cached PreselectedUser loaded during accountInitialize, when PreselectedUser is available.
## @param[in] Uid \ref AccountUid
##
proc accountUidIsValid*(uid: ptr AccountUid): bool {.inline, cdecl.} = proc accountUidIsValid*(uid: ptr AccountUid): bool {.inline, cdecl.} =
## *
## @brief Checks whether the specified \ref AccountUid is valid/set (non-zero).
## @param[in] Uid \ref AccountUid
##
return uid.uid[0] != 0 or uid.uid[1] != 0 return uid.uid[0] != 0 or uid.uid[1] != 0

View file

@ -72,74 +72,68 @@ type
outHandles*: ptr Handle outHandles*: ptr Handle
## *
## @brief Returns whether a service has been initialized.
## @param[in] s Service object.
## @return true if initialized.
##
proc serviceIsActive*(s: ptr Service): bool {.inline, cdecl.} = proc serviceIsActive*(s: ptr Service): bool {.inline, cdecl.} =
## *
## @brief Returns whether a service has been initialized.
## @param[in] s Service object.
## @return true if initialized.
##
return s.session != Invalid_Handle return s.session != Invalid_Handle
## *
## @brief Returns whether a service is overriden in the homebrew environment.
## @param[in] s Service object.
## @return true if overriden.
##
proc serviceIsOverride*(s: ptr Service): bool {.inline, cdecl.} = proc serviceIsOverride*(s: ptr Service): bool {.inline, cdecl.} =
## *
## @brief Returns whether a service is overriden in the homebrew environment.
## @param[in] s Service object.
## @return true if overriden.
##
return serviceIsActive(s) and not s.ownHandle.bool and not s.objectId.bool return serviceIsActive(s) and not s.ownHandle.bool and not s.objectId.bool
## *
## @brief Returns whether a service is a domain.
## @param[in] s Service object.
## @return true if a domain.
##
proc serviceIsDomain*(s: ptr Service): bool {.inline, cdecl.} = proc serviceIsDomain*(s: ptr Service): bool {.inline, cdecl.} =
## *
## @brief Returns whether a service is a domain.
## @param[in] s Service object.
## @return true if a domain.
##
return serviceIsActive(s) and s.ownHandle.bool and s.objectId.bool return serviceIsActive(s) and s.ownHandle.bool and s.objectId.bool
## *
## @brief Returns whether a service is a domain subservice.
## @param[in] s Service object.
## @return true if a domain subservice.
##
proc serviceIsDomainSubservice*(s: ptr Service): bool {.inline, cdecl.} = proc serviceIsDomainSubservice*(s: ptr Service): bool {.inline, cdecl.} =
## *
## @brief Returns whether a service is a domain subservice.
## @param[in] s Service object.
## @return true if a domain subservice.
##
return serviceIsActive(s) and not s.ownHandle.bool and s.objectId.bool return serviceIsActive(s) and not s.ownHandle.bool and s.objectId.bool
## *
## @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.
##
proc serviceGetObjectId*(s: ptr Service): U32 {.inline, cdecl.} = proc serviceGetObjectId*(s: ptr Service): U32 {.inline, cdecl.} =
## *
## @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.
##
return s.objectId return s.objectId
## *
## @brief Creates a service object from an IPC session handle.
## @param[out] s Service object.
## @param[in] h IPC session handle.
##
proc serviceCreate*(s: ptr Service; h: Handle) {.inline, cdecl.} = proc serviceCreate*(s: ptr Service; h: Handle) {.inline, cdecl.} =
## *
## @brief Creates a service object from an IPC session handle.
## @param[out] s Service object.
## @param[in] h IPC session handle.
##
s.session = h s.session = h
s.ownHandle = 1 s.ownHandle = 1
s.objectId = 0 s.objectId = 0
s.pointerBufferSize = 0 s.pointerBufferSize = 0
discard cmifQueryPointerBufferSize(h, addr(s.pointerBufferSize)) discard cmifQueryPointerBufferSize(h, addr(s.pointerBufferSize))
## *
## @brief Creates a non-domain subservice object from a parent service.
## @param[out] s Service object.
## @param[in] parent Parent service.
## @param[in] h IPC session handle for this subservice.
##
proc serviceCreateNonDomainSubservice*(s: ptr Service; parent: ptr Service; h: Handle) {. proc serviceCreateNonDomainSubservice*(s: ptr Service; parent: ptr Service; h: Handle) {.
inline, cdecl.} = inline, cdecl.} =
## *
## @brief Creates a non-domain subservice object from a parent service.
## @param[out] s Service object.
## @param[in] parent Parent service.
## @param[in] h IPC session handle for this subservice.
##
if h != Invalid_Handle: if h != Invalid_Handle:
s.session = h s.session = h
s.ownHandle = 1 s.ownHandle = 1
@ -148,15 +142,15 @@ proc serviceCreateNonDomainSubservice*(s: ptr Service; parent: ptr Service; h: H
else: else:
s[] = Service() s[] = Service()
## *
## @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.
##
proc serviceCreateDomainSubservice*(s: ptr Service; parent: ptr Service; objectId: U32) {. proc serviceCreateDomainSubservice*(s: ptr Service; parent: ptr Service; objectId: U32) {.
inline, cdecl.} = inline, cdecl.} =
## *
## @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.
##
if objectId != 0: if objectId != 0:
s.session = parent.session s.session = parent.session
s.ownHandle = 0 s.ownHandle = 0
@ -165,24 +159,24 @@ proc serviceCreateDomainSubservice*(s: ptr Service; parent: ptr Service; objectI
else: else:
s[] = Service() s[] = Service()
## *
## @brief Hints the compiler that a service will always contain a domain object.
## @param[in] _s Service object.
##
template serviceAssumeDomain*(s: untyped): void = template serviceAssumeDomain*(s: untyped): void =
## *
## @brief Hints the compiler that a service will always contain a domain object.
## @param[in] _s Service object.
##
while true: while true:
if not (s).objectId.bool: if not (s).objectId.bool:
builtinUnreachable() builtinUnreachable()
if not 0: if not 0:
break break
## *
## @brief Closes a service.
## @param[in] s Service object.
##
proc serviceClose*(s: ptr Service) {.inline, cdecl.} = proc serviceClose*(s: ptr Service) {.inline, cdecl.} =
## *
## @brief Closes a service.
## @param[in] s Service object.
##
{.emit: "#if defined(NX_SERVICE_ASSUME_NON_DOMAIN)".} {.emit: "#if defined(NX_SERVICE_ASSUME_NON_DOMAIN)".}
{.emit: " if (`s`->object_id)".} {.emit: " if (`s`->object_id)".}
{.emit: " __builtin_unreachable();".} {.emit: " __builtin_unreachable();".}
@ -195,13 +189,12 @@ proc serviceClose*(s: ptr Service) {.inline, cdecl.} =
{.emit: " }".} {.emit: " }".}
{.emit: " *`s` = (Service){};".} {.emit: " *`s` = (Service){};".}
## *
## @brief Clones a service.
## @param[in] s Service object.
## @param[out] out_s Output service object.
##
proc serviceClone*(s: ptr Service; outS: ptr Service): Result {.inline, cdecl.} = proc serviceClone*(s: ptr Service; outS: ptr Service): Result {.inline, cdecl.} =
## *
## @brief Clones a service.
## @param[in] s Service object.
## @param[out] out_s Output service object.
##
{.emit: "#if defined(NX_SERVICE_ASSUME_NON_DOMAIN)".} {.emit: "#if defined(NX_SERVICE_ASSUME_NON_DOMAIN)".}
{.emit: " if (`s`->object_id)".} {.emit: " if (`s`->object_id)".}
{.emit: " __builtin_unreachable();".} {.emit: " __builtin_unreachable();".}
@ -212,14 +205,14 @@ proc serviceClone*(s: ptr Service; outS: ptr Service): Result {.inline, cdecl.}
{.emit: " `outS`->pointer_buffer_size = `s`->pointer_buffer_size;".} {.emit: " `outS`->pointer_buffer_size = `s`->pointer_buffer_size;".}
{.emit: " `result` = cmifCloneCurrentObject(`s`->session, &`outS`->session);".} {.emit: " `result` = cmifCloneCurrentObject(`s`->session, &`outS`->session);".}
## *
## @brief Clones a service with a session manager tag.
## @param[in] s Service object.
## @param[in] tag Session manager tag (unused in current official server code)
## @param[out] out_s Output service object.
##
proc serviceCloneEx*(s: ptr Service; tag: U32; outS: ptr Service): Result {.inline, cdecl.} = proc serviceCloneEx*(s: ptr Service; tag: U32; outS: ptr Service): Result {.inline, cdecl.} =
## *
## @brief Clones a service with a session manager tag.
## @param[in] s Service object.
## @param[in] tag Session manager tag (unused in current official server code)
## @param[out] out_s Output service object.
##
{.emit: "#if defined(NX_SERVICE_ASSUME_NON_DOMAIN)".} {.emit: "#if defined(NX_SERVICE_ASSUME_NON_DOMAIN)".}
{.emit: " if (`s`->object_id)".} {.emit: " if (`s`->object_id)".}
{.emit: " __builtin_unreachable();".} {.emit: " __builtin_unreachable();".}
@ -230,13 +223,13 @@ proc serviceCloneEx*(s: ptr Service; tag: U32; outS: ptr Service): Result {.inli
{.emit: " `outS`->pointer_buffer_size = `s`->pointer_buffer_size;".} {.emit: " `outS`->pointer_buffer_size = `s`->pointer_buffer_size;".}
{.emit: " `result` = cmifCloneCurrentObjectEx(`s`->session, `tag`, &`outS`->session);".} {.emit: " `result` = cmifCloneCurrentObjectEx(`s`->session, `tag`, &`outS`->session);".}
## *
## @brief Converts a regular service to a domain.
## @param[in] s Service object.
## @return Result code.
##
proc serviceConvertToDomain*(s: ptr Service): Result {.inline, cdecl.} = proc serviceConvertToDomain*(s: ptr Service): Result {.inline, cdecl.} =
## *
## @brief Converts a regular service to a domain.
## @param[in] s Service object.
## @return Result code.
##
if not s.ownHandle.bool: if not s.ownHandle.bool:
## For overridden services, create a clone first. ## For overridden services, create a clone first.
var rc: Result = cmifCloneCurrentObjectEx(s.session, 0, addr(s.session)) var rc: Result = cmifCloneCurrentObjectEx(s.session, 0, addr(s.session))