// Copyright 2018 plutoo #include static bool g_isNso = false; static Handle g_mainThreadHandle = INVALID_HANDLE; static void* g_loaderRetAddr = NULL; static void* g_overrideHeapAddr = NULL; static u64 g_overrideHeapSize = 0; typedef struct { u32 Key; u32 Flags; u64 Value[2]; } ConfigEntry; enum { EntryType_EndOfList=0, EntryType_MainThreadHandle=1, EntryType_LoaderReturnAddr=2, EntryType_OverrideHeap=3, EntryType_OverrideService=4, EntryType_Argv=5, EntryType_SyscallAvailableHint=6, EntryType_AppletType=7 }; void envParse(void* ctx, Handle main_thread) { if (main_thread != INVALID_HANDLE) { g_mainThreadHandle = main_thread; g_isNso = true; return; } ConfigEntry* ent = ctx; while (ent->Key != EntryType_EndOfList) { switch (ent->Key) { case EntryType_MainThreadHandle: g_mainThreadHandle = ent->Value[0]; break; case EntryType_LoaderReturnAddr: g_loaderRetAddr = (void*) ent->Value[0]; break; case EntryType_OverrideHeap: g_overrideHeapAddr = (void*) ent->Value[0]; g_overrideHeapSize = ent->Value[1]; break; case EntryType_OverrideService: // TODO break; case EntryType_Argv: // TODO break; case EntryType_SyscallAvailableHint: // TODO break; case EntryType_AppletType: // TODO break; default: // TODO break; } ent++; } } Handle envGetMainThreadHandle(void) { if (g_mainThreadHandle != INVALID_HANDLE) { return g_mainThreadHandle; } fatalSimple(MAKERESULT(MODULE_LIBNX, LIBNX_HANDLETOOEARLY)); } bool envIsNso(void) { return g_isNso; } bool envHasHeapOverride(void) { return g_overrideHeapAddr != NULL; } void* envGetHeapOverrideAddr(void) { return g_overrideHeapAddr; } u64 envGetHeapOverrideSize(void) { return g_overrideHeapSize; }