From 79de52cc4d37f27735b3e81e2bdc1bcf6b824bed Mon Sep 17 00:00:00 2001 From: chaoskagami Date: Fri, 14 Oct 2016 04:46:20 -0400 Subject: [PATCH] Add srvSysInit, srvSysExit - when the srv: port doesn't exist, strange things happen with the "normal" versions --- libctru/include/3ds/srv.h | 6 +++++ libctru/source/srv.c | 56 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 62 insertions(+) diff --git a/libctru/include/3ds/srv.h b/libctru/include/3ds/srv.h index d121cb1..b0a5860 100644 --- a/libctru/include/3ds/srv.h +++ b/libctru/include/3ds/srv.h @@ -4,6 +4,12 @@ */ #pragma once +/// Initializes the service API in a way that is safe during the boot process. +Result srvSysInit(void); + +/// Deinitializes the service API in a way that is safe from system modules. +Result srvSysExit(void); + /// Initializes the service API. Result srvInit(void); diff --git a/libctru/source/srv.c b/libctru/source/srv.c index e5b6652..0de2e86 100644 --- a/libctru/source/srv.c +++ b/libctru/source/srv.c @@ -13,6 +13,39 @@ static Handle srvHandle; static int srvRefCount; +static RecursiveLock initLock; +static int initLockinit = 0; + +Result srvSysInit(void) +{ + Result rc = 0; + + if (!initLockinit) { + RecursiveLock_Init(&initLock); + } + RecursiveLock_Lock(&initLock); + + if (srvRefCount > 0) { + RecursiveLock_Unlock(&initLock); + return MAKERESULT(RL_INFO, RS_NOP, 25, RD_ALREADY_INITIALIZED); + } + + while (1) { + rc = svcConnectToPort(&srvHandle, "srv:"); + if (R_LEVEL(rc) != RL_PERMANENT || R_SUMMARY(rc) != RS_NOTFOUND || R_DESCRIPTION(rc) != RD_NOT_FOUND) + break; + svcSleepThread(500000); + } + + if (R_SUCCEEDED(rc)) { + rc = srvRegisterClient(); + srvRefCount++; + } + + RecursiveLock_Unlock(&initLock); + + return rc; +} Result srvInit(void) { @@ -37,6 +70,29 @@ void srvExit(void) srvHandle = 0; } +Result srvSysExit() +{ + Result rc; + + RecursiveLock_Lock(&initLock); + if (srvRefCount > 1) { + srvRefCount--; + RecursiveLock_Unlock(&initLock); + return MAKERESULT(RL_INFO, RS_NOP, 25, RD_BUSY); + } + + if (srvHandle != 0) + svcCloseHandle(srvHandle); + else + svcBreak(USERBREAK_ASSERT); // This should never happen. + + srvHandle = 0; + srvRefCount--; + RecursiveLock_Unlock(&initLock); + + return rc; +} + Handle *srvGetSessionHandle(void) { return &srvHandle; -- 2.39.5