Pointer ElDorito::GetMainTls(size_t Offset) { static Pointer ThreadLocalStorage; if( !ThreadLocalStorage && GetMainThreadID() ) { size_t MainThreadID = GetMainThreadID(); HANDLE MainThreadHandle = OpenThread(THREAD_GET_CONTEXT | THREAD_SUSPEND_RESUME | THREAD_QUERY_INFORMATION, false, MainThreadID); // Get thread context CONTEXT MainThreadContext; MainThreadContext.ContextFlags = CONTEXT_FULL; if (MainThreadID != GetCurrentThreadId()) SuspendThread(MainThreadHandle); BOOL success = GetThreadContext(MainThreadHandle, &MainThreadContext); if( !success ) { OutputDebugString(std::string("Error getting thread context: ").append(std::to_string(GetLastError())).c_str()); std::exit(1); } ResumeThread(MainThreadHandle); // Get thread selector LDT_ENTRY MainThreadLdt; success = GetThreadSelectorEntry(MainThreadHandle, MainThreadContext.SegFs, &MainThreadLdt); if( !success ) { OutputDebugString(std::string("Error getting thread context: ").append(std::to_string(GetLastError())).c_str()); } size_t TlsPtrArrayAddress = (size_t)((size_t)(MainThreadLdt.HighWord.Bits.BaseHi << 24) | (MainThreadLdt.HighWord.Bits.BaseMid << 16) | MainThreadLdt.BaseLow) + 0x2C; size_t TlsPtrAddress = Pointer(TlsPtrArrayAddress).Read<uint32_t>(); // Index has been consistantly 0. Keep a look out. ThreadLocalStorage = Pointer(TlsPtrAddress)[0]; } return ThreadLocalStorage(Offset); }
void LSAPIInit::Initialize(LPCWSTR pwzLitestepPath, LPCWSTR pwzRcPath) { try { // Error if called again if (IsInitialized()) { throw LSAPIException(LSAPI_ERROR_RECURRENT); } // Do not allow any thread but the original to load us if (GetCurrentThreadId() != GetMainThreadID()) { throw LSAPIException(LSAPI_ERROR_INVALIDTHREAD); } // Copy over the strings if (FAILED(StringCchCopyW(m_wzLitestepPath, MAX_PATH, pwzLitestepPath))) { throw LSAPIException(LSAPI_ERROR_GENERAL); } if (FAILED(StringCchCopyW(m_wzRcPath, MAX_PATH, pwzRcPath))) { throw LSAPIException(LSAPI_ERROR_GENERAL); } // Create the Bang Manager m_bmBangManager = new BangManager; if (!m_bmBangManager) { throw LSAPIException(LSAPI_ERROR_GENERAL); } // Create the Settings Manager m_smSettingsManager = new SettingsManager(); if (!m_smSettingsManager) { throw LSAPIException(LSAPI_ERROR_GENERAL); } // Signal that we are initialized before continuing, so that // the LSAPI is available during setup m_bIsInitialized = true; // Initialize default variables setLitestepVars(); // Load the default RC config file m_smSettingsManager->ParseFile(m_wzRcPath); // Add our internal bang commands to the Bang Manager. SetupBangs(); } catch(LSAPIException& lse) { if (LSAPI_ERROR_RECURRENT != lse.Type()) { m_bIsInitialized = false; delete m_smSettingsManager; m_smSettingsManager = nullptr; delete m_bmBangManager; m_bmBangManager = nullptr; } throw; //rethrow } }