diff --git a/tools/steamclient_loader/win/extra_protection/dllmain.cpp b/tools/steamclient_loader/win/extra_protection/dllmain.cpp index 1441098a..677771a5 100644 --- a/tools/steamclient_loader/win/extra_protection/dllmain.cpp +++ b/tools/steamclient_loader/win/extra_protection/dllmain.cpp @@ -8,6 +8,9 @@ #include #include +#if defined(DEBUG) || defined(_DEBUG) + #define STUB_EXTRA_DEBUG +#endif static std::mutex dll_unload_mtx{}; static std::condition_variable dll_unload_cv{}; @@ -29,7 +32,7 @@ static void send_unload_signal() DWORD WINAPI self_unload(LPVOID lpParameter) { constexpr const auto UNLOAD_TIMEOUT = -#ifdef _DEBUG +#ifdef STUB_EXTRA_DEBUG std::chrono::minutes(5) #else std::chrono::seconds(5) @@ -37,8 +40,21 @@ DWORD WINAPI self_unload(LPVOID lpParameter) ; { +#ifdef STUB_EXTRA_DEBUG + auto t1 = std::chrono::high_resolution_clock::now(); +#endif + std::unique_lock lock(dll_unload_mtx); - dll_unload_cv.wait_for(lock, UNLOAD_TIMEOUT, [](){ return unload_dll; }); + dll_unload_cv.wait_for(lock, UNLOAD_TIMEOUT, []{ return unload_dll; }); + +#ifdef STUB_EXTRA_DEBUG + if (!unload_dll) { // flag was not raised, means we timed out + auto t2 = std::chrono::high_resolution_clock::now(); + auto dd = std::chrono::duration_cast(t2 - t1); + std::string msg = "Unloading after " + std::to_string(dd.count()) + " seconds, due to timeout"; + MessageBoxA(nullptr, msg.c_str(), "Self-unload thread", MB_OK | MB_ICONERROR); + } +#endif } unload_thread_handle = INVALID_HANDLE_VALUE; FreeLibraryAndExitThread(my_hModule, 0); @@ -52,19 +68,27 @@ BOOL APIENTRY DllMain( switch (reason) { case DLL_PROCESS_ATTACH: + stubdrm::set_cleanup_cb(send_unload_signal); + my_hModule = hModule; if (!stubdrm::patch()) { +#ifdef STUB_EXTRA_DEBUG + MessageBoxA(nullptr, "Failed to detect .bind", "Main", MB_OK | MB_ICONERROR); +#endif + // https://learn.microsoft.com/en-us/windows/win32/dlls/dllmain // "The system immediately calls your entry-point function with DLL_PROCESS_DETACH and unloads the DLL" unload_dll = true; return FALSE; } - my_hModule = hModule; - stubdrm::set_cleanup_cb(send_unload_signal); unload_thread_handle = CreateThread(nullptr, 0, self_unload, nullptr, 0, nullptr); break; case DLL_PROCESS_DETACH: if (!unload_dll) { // not unloaded yet, just an early exit, or thread timed out +#ifdef STUB_EXTRA_DEBUG + MessageBoxA(nullptr, "Unclean exit", "Main", MB_OK | MB_ICONERROR); +#endif + stubdrm::restore(); if (unload_thread_handle != INVALID_HANDLE_VALUE && unload_thread_handle != NULL) { TerminateThread(unload_thread_handle, 0);