diff --git a/libctru/include/3ds/os.h b/libctru/include/3ds/os.h index e6d04f9..23d698a 100644 --- a/libctru/include/3ds/os.h +++ b/libctru/include/3ds/os.h @@ -103,6 +103,18 @@ static inline u32 osGetKernelVersion(void) return (*(vu32*)0x1FF80000) & ~0xFF; } +/// Gets the system's "core version" (2 on NATIVE_FIRM, 3 on SAFE_FIRM, etc.) +static inline u32 osGetSystemCoreVersion(void) +{ + return *(vu32*)0x1FF80010; +} + +/// Gets the system's memory layout ID (0-5 on Old 3DS, 6-8 on New 3DS) +static inline u32 osGetApplicationMemType(void) +{ + return *(vu32*)0x1FF80030; +} + /** * @brief Gets the size of the specified memory region. * @param region Memory region to check. diff --git a/libctru/source/services/apt.c b/libctru/source/services/apt.c index 20d4c56..a07b94b 100644 --- a/libctru/source/services/apt.c +++ b/libctru/source/services/apt.c @@ -14,6 +14,7 @@ #include <3ds/ipc.h> #include <3ds/env.h> #include <3ds/thread.h> +#include <3ds/os.h> #define APT_HANDLER_STACKSIZE (0x1000) @@ -188,6 +189,8 @@ Result aptInit(void) if (AtomicPostIncrement(&aptRefCount)) return 0; + aptHomeAllowed = osGetSystemCoreVersion() == 2; + // Retrieve APT lock ret = APT_GetLockHandle(0x0, &aptLockHandle); if (R_FAILED(ret)) goto _fail; @@ -309,10 +312,22 @@ void aptExit(void) { if (!exited && aptIsChainload()) { - u8 param[0x300] = {0}; - u8 hmac[0x20] = {0}; - APT_PrepareToDoApplicationJump(0, aptChainloadTid, aptChainloadMediatype); - APT_DoApplicationJump(param, sizeof(param), hmac); + // Check if Home Menu exists and has been launched + bool hmRegistered; + if (R_SUCCEEDED(APT_IsRegistered(APPID_HOMEMENU, &hmRegistered)) && hmRegistered) + { + // Normal, sane chainload + u8 param[0x300] = {0}; + u8 hmac[0x20] = {0}; + APT_PrepareToDoApplicationJump(0, aptChainloadTid, aptChainloadMediatype); + APT_DoApplicationJump(param, sizeof(param), hmac); + } + else + { + // Dirty workaround w/ custom notification + APT_Finalize(envGetAptAppId()); + srvPublishToSubscriber(0x3000, 0); + } while (aptMainLoop()) svcSleepThread(25*1000*1000); }