diff --git a/src/Utils/FileWatcher.h b/src/Utils/FileWatcher.h index e4ee75a..488511b 100644 --- a/src/Utils/FileWatcher.h +++ b/src/Utils/FileWatcher.h @@ -4,7 +4,7 @@ #include #include -namespace FileWatcher { - void Start(const std::vector& directories); - void Stop(); -} \ No newline at end of file +namespace FileWatcher { + void Start(const std::vector& directories); + void Stop(); +} diff --git a/src/dllmain.cpp b/src/dllmain.cpp index a887468..4562cc3 100644 --- a/src/dllmain.cpp +++ b/src/dllmain.cpp @@ -74,22 +74,30 @@ static DWORD WINAPI InitThread(LPVOID param) { return 0; } -BOOL APIENTRY DllMain(HMODULE hModule, DWORD dwReason, PVOID pvReserved) -{ - if (dwReason == DLL_PROCESS_ATTACH) - { - DisableThreadLibraryCalls(hModule); - // Hand off all real work to a worker thread to avoid running file I/O, - // LoadLibrary, and detour transactions under the loader lock. - HANDLE h = CreateThread(nullptr, 0, InitThread, hModule, 0, nullptr); - if (h) CloseHandle(h); - } - else if (dwReason == DLL_PROCESS_DETACH) - { - FileWatcher::Stop(); - SteamUI::CoreUnhook(); - SteamClient::CoreUnhook(); - } - - return TRUE; -} +BOOL APIENTRY DllMain(HMODULE hModule, DWORD dwReason, PVOID pvReserved) +{ + if (dwReason == DLL_PROCESS_ATTACH) + { + DisableThreadLibraryCalls(hModule); + // Keep this module pinned so explicit FreeLibrary cannot unload code + // while hooks and worker threads may still reference it. + HMODULE pinnedModule = nullptr; + GetModuleHandleExA( + GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_PIN, + reinterpret_cast(&DllMain), &pinnedModule); + // Hand off all real work to a worker thread to avoid running file I/O, + // LoadLibrary, and detour transactions under the loader lock. + HANDLE h = CreateThread(nullptr, 0, InitThread, hModule, 0, nullptr); + if (h) CloseHandle(h); + } + else if (dwReason == DLL_PROCESS_DETACH) + { + // During process termination, join watcher thread object so CRT static + // teardown does not hit std::thread's joinable-guard terminate. + if (pvReserved != nullptr) { + FileWatcher::Stop(); + } + } + + return TRUE; +}