From 78b94b4eeac38f273f6e54ef86e038725086b65a Mon Sep 17 00:00:00 2001 From: Dave Murphy Date: Thu, 25 Dec 2014 23:27:36 +0000 Subject: [PATCH] auto initialise commonly used services, prevent double initialisation --- libctru/source/sdmc_dev.c | 11 +++++++++-- libctru/source/services/apt.c | 8 ++++++++ libctru/source/services/fs.c | 13 ++++++++++++- libctru/source/services/hid.c | 7 ++++++- libctru/source/srv.c | 3 +++ libctru/source/system/appExit.c | 17 +++++++++++++++++ libctru/source/system/appInit.c | 17 +++++++++++++++++ libctru/source/system/ctru_exit.c | 3 ++- libctru/source/system/initSystem.c | 3 ++- 9 files changed, 76 insertions(+), 6 deletions(-) create mode 100644 libctru/source/system/appExit.c create mode 100644 libctru/source/system/appInit.c diff --git a/libctru/source/sdmc_dev.c b/libctru/source/sdmc_dev.c index c21b224..d9604b0 100644 --- a/libctru/source/sdmc_dev.c +++ b/libctru/source/sdmc_dev.c @@ -130,11 +130,14 @@ static const char *sdmc_fixpath(const char *path) extern int __system_argc; extern char** __system_argv; +static bool sdmcInitialised = false; + /*! Initialize SDMC device */ Result sdmcInit(void) { - Result rc; + Result rc = 0; + if (sdmcInitialised) return rc; rc = FSUSER_OpenArchive(NULL, &sdmcArchive); @@ -161,13 +164,17 @@ Result sdmcInit(void) } } + sdmcInitialised = true; + return rc; } /*! Clean up SDMC device */ Result sdmcExit(void) { - Result rc; + Result rc = 0; + + if (!sdmcInitialised) return rc; rc = FSUSER_CloseArchive(NULL, &sdmcArchive); if(rc == 0) diff --git a/libctru/source/services/apt.c b/libctru/source/services/apt.c index c6ea5f0..d4bdd1c 100644 --- a/libctru/source/services/apt.c +++ b/libctru/source/services/apt.c @@ -410,10 +410,14 @@ void aptEventHandler(u32 arg) svcExitThread(); } +static bool aptInitialised = false; + Result aptInit(void) { Result ret=0; + if (aptInitialised) return ret; + // Initialize APT stuff, escape load screen. ret = __apt_initservicehandle(); if(ret!=0)return ret; @@ -445,11 +449,15 @@ Result aptInit(void) } else aptAppStarted(); + aptInitialised = true; + return 0; } void aptExit() { + if (!aptInitialised) return; + if(!(__system_runflags&RUNFLAG_APTWORKAROUND))aptAppletUtility_Exit_RetToApp(0); // This is only executed when application-termination was triggered via the home-menu power-off screen. diff --git a/libctru/source/services/fs.c b/libctru/source/services/fs.c index cec30d1..d7fe22e 100644 --- a/libctru/source/services/fs.c +++ b/libctru/source/services/fs.c @@ -37,12 +37,21 @@ FS_makePath(FS_pathType type, * * @returns error */ + +static bool fsInitialised = false; + Result fsInit(void) { - Result ret; + Result ret = 0; + + if (fsInitialised) return ret; + if((ret=srvGetServiceHandle(&fsuHandle, "fs:USER"))!=0)return ret; if(__get_handle_from_list("fs:USER")==0)ret=FSUSER_Initialize(NULL); + + fsInitialised = true; + return ret; } @@ -53,6 +62,8 @@ fsInit(void) Result fsExit(void) { + if (!fsInitialised) return 0; + return svcCloseHandle(fsuHandle); } diff --git a/libctru/source/services/hid.c b/libctru/source/services/hid.c index a66a4fd..54657da 100644 --- a/libctru/source/services/hid.c +++ b/libctru/source/services/hid.c @@ -23,13 +23,16 @@ static circlePosition cPos; static accelVector aVec; static angularRate gRate; +static bool hidInitialised; Result hidInit(u32* sharedMem) { u8 val=0; + Result ret=0; + + if(hidInitialised) return ret; if(!sharedMem)sharedMem=(u32*)HID_SHAREDMEM_DEFAULT; - Result ret=0; // Request service. if((ret=srvGetServiceHandle(&hidHandle, "hid:USER")))return ret; @@ -61,6 +64,8 @@ cleanup1: void hidExit() { + if(!hidInitialised) return; + // Unmap HID sharedmem and close handles. u8 val=0; int i; for(i=0; i<5; i++)svcCloseHandle(hidEvents[i]); diff --git a/libctru/source/srv.c b/libctru/source/srv.c index 8f9d524..366eca6 100644 --- a/libctru/source/srv.c +++ b/libctru/source/srv.c @@ -72,10 +72,13 @@ void __destroy_handle_list(void) { __service_ptr->num = 0; } + Result srvInit() { Result rc = 0; + if(g_srv_handle != 0) return rc; + if((rc = svcConnectToPort(&g_srv_handle, "srv:")))return rc; if((rc = srvRegisterClient())) { diff --git a/libctru/source/system/appExit.c b/libctru/source/system/appExit.c new file mode 100644 index 0000000..d2e9d48 --- /dev/null +++ b/libctru/source/system/appExit.c @@ -0,0 +1,17 @@ +#include <3ds/types.h> +#include <3ds/srv.h> +#include <3ds/gfx.h> +#include <3ds/sdmc.h> +#include <3ds/services/apt.h> +#include <3ds/services/fs.h> +#include <3ds/services/hid.h> + +void __attribute__((weak)) __appExit() { + // Exit services + sdmcExit(); + fsExit(); + + hidExit(); + aptExit(); + srvExit(); +} diff --git a/libctru/source/system/appInit.c b/libctru/source/system/appInit.c new file mode 100644 index 0000000..ac90ae6 --- /dev/null +++ b/libctru/source/system/appInit.c @@ -0,0 +1,17 @@ +#include <3ds/types.h> +#include <3ds/srv.h> +#include <3ds/gfx.h> +#include <3ds/sdmc.h> +#include <3ds/services/apt.h> +#include <3ds/services/fs.h> +#include <3ds/services/hid.h> + +void __attribute__((weak)) __appInit() { + // Initialize services + srvInit(); + aptInit(); + hidInit(NULL); + + fsInit(); + sdmcInit(); +} diff --git a/libctru/source/system/ctru_exit.c b/libctru/source/system/ctru_exit.c index 9a86609..058ea7c 100644 --- a/libctru/source/system/ctru_exit.c +++ b/libctru/source/system/ctru_exit.c @@ -7,6 +7,7 @@ extern u32 __heap_size, __linear_heap_size; extern void (*__system_retAddr)(void); void __destroy_handle_list(void); +void __appExit(); void __libc_fini_array(void); @@ -17,7 +18,7 @@ void __attribute__((weak)) __attribute__((noreturn)) __ctru_exit(int rc) // Run the global destructors __libc_fini_array(); - // TODO: APT exit goes here + __appExit(); // Unmap the linear heap svcControlMemory(&tmp, __linear_heap, 0x0, __linear_heap_size, MEMOP_FREE, 0x0); diff --git a/libctru/source/system/initSystem.c b/libctru/source/system/initSystem.c index be5c118..080d125 100644 --- a/libctru/source/system/initSystem.c +++ b/libctru/source/system/initSystem.c @@ -10,6 +10,7 @@ extern void* __service_ptr; // used to detect if we're run from a homebrew launc void __system_allocateHeaps(); void __system_initArgv(); +void __appInit(); // newlib definitions we need void __libc_init_array(void); @@ -29,7 +30,7 @@ void __attribute__((weak)) initSystem(void (*retAddr)(void)) // Build argc/argv if present __system_initArgv(); - // TODO: APT init goes here + __appInit(); // Run the global constructors __libc_init_array(); -- 2.39.5