From 35e66bd3cffe4147f986ac3880820d8ea2e601a7 Mon Sep 17 00:00:00 2001 From: narzoul Date: Mon, 1 Mar 2021 22:59:07 +0100 Subject: [PATCH] Leave cleanup to process termination --- DDrawCompat/Common/Hook.cpp | 16 ++-------------- DDrawCompat/Common/Hook.h | 1 - DDrawCompat/D3dDdi/Hooks.cpp | 9 +-------- DDrawCompat/D3dDdi/Hooks.h | 1 - DDrawCompat/D3dDdi/KernelModeThunks.cpp | 17 ++--------------- DDrawCompat/D3dDdi/KernelModeThunks.h | 1 - DDrawCompat/DDraw/Hooks.cpp | 5 ----- DDrawCompat/DDraw/Hooks.h | 1 - DDrawCompat/DDraw/RealPrimarySurface.cpp | 22 ++-------------------- DDrawCompat/DDraw/RealPrimarySurface.h | 1 - DDrawCompat/Dll/Dll.cpp | 12 ++++++++++++ DDrawCompat/Dll/Dll.h | 2 ++ DDrawCompat/Dll/DllMain.cpp | 13 ++----------- DDrawCompat/Gdi/Caret.cpp | 13 ++----------- DDrawCompat/Gdi/Caret.h | 1 - DDrawCompat/Gdi/Dc.cpp | 12 ------------ DDrawCompat/Gdi/Dc.h | 1 - DDrawCompat/Gdi/Gdi.cpp | 8 -------- DDrawCompat/Gdi/Gdi.h | 1 - DDrawCompat/Gdi/PresentationWindow.cpp | 14 -------------- DDrawCompat/Gdi/PresentationWindow.h | 1 - DDrawCompat/Gdi/WinProc.cpp | 24 ++++++------------------ DDrawCompat/Gdi/WinProc.h | 1 - 23 files changed, 31 insertions(+), 146 deletions(-) diff --git a/DDrawCompat/Common/Hook.cpp b/DDrawCompat/Common/Hook.cpp index 356c50a..f0c4e0c 100644 --- a/DDrawCompat/Common/Hook.cpp +++ b/DDrawCompat/Common/Hook.cpp @@ -158,7 +158,8 @@ namespace } HMODULE module = nullptr; - GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, static_cast(hookedFuncPtr), &module); + GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_PIN, + static_cast(hookedFuncPtr), &module); g_hookedFunctions.emplace( std::make_pair(hookedFuncPtr, HookedFunctionInfo{ module, origFuncPtr, newFuncPtr })); @@ -169,11 +170,6 @@ namespace DetourTransactionBegin(); DetourDetach(&hookedFunc->second.origFunction, hookedFunc->second.newFunction); DetourTransactionCommit(); - - if (hookedFunc->second.module) - { - FreeLibrary(hookedFunc->second.module); - } g_hookedFunctions.erase(hookedFunc); } } @@ -330,14 +326,6 @@ namespace Compat } } - void unhookAllFunctions() - { - while (!g_hookedFunctions.empty()) - { - ::unhookFunction(g_hookedFunctions.begin()); - } - } - void unhookFunction(void* origFunc) { auto it = findOrigFunc(origFunc); diff --git a/DDrawCompat/Common/Hook.h b/DDrawCompat/Common/Hook.h index b61bdaf..93b640c 100644 --- a/DDrawCompat/Common/Hook.h +++ b/DDrawCompat/Common/Hook.h @@ -39,6 +39,5 @@ namespace Compat } void removeShim(HMODULE module, const char* funcName); - void unhookAllFunctions(); void unhookFunction(void* origFunc); } diff --git a/DDrawCompat/D3dDdi/Hooks.cpp b/DDrawCompat/D3dDdi/Hooks.cpp index 366252e..843cad5 100644 --- a/DDrawCompat/D3dDdi/Hooks.cpp +++ b/DDrawCompat/D3dDdi/Hooks.cpp @@ -41,8 +41,7 @@ namespace { Compat::hookFunction(g_hookedUmdModule, "OpenAdapter", reinterpret_cast(g_origOpenAdapter), &openAdapter); - HMODULE module = nullptr; - GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_PIN, umdFileName.c_str(), &module); + Dll::pinModule(umdFileName.c_str()); } } @@ -97,10 +96,4 @@ namespace D3dDdi hookOpenAdapter(umdFileName); } } - - void uninstallHooks() - { - unhookOpenAdapter(); - KernelModeThunks::stopVsyncThread(); - } } diff --git a/DDrawCompat/D3dDdi/Hooks.h b/DDrawCompat/D3dDdi/Hooks.h index 7c59d82..77845bb 100644 --- a/DDrawCompat/D3dDdi/Hooks.h +++ b/DDrawCompat/D3dDdi/Hooks.h @@ -7,5 +7,4 @@ namespace D3dDdi UINT getDdiVersion(); void installHooks(HMODULE origDDrawModule); void onUmdFileNameQueried(const std::wstring& umdFileName); - void uninstallHooks(); } diff --git a/DDrawCompat/D3dDdi/KernelModeThunks.cpp b/DDrawCompat/D3dDdi/KernelModeThunks.cpp index b951faf..28ca2a6 100644 --- a/DDrawCompat/D3dDdi/KernelModeThunks.cpp +++ b/DDrawCompat/D3dDdi/KernelModeThunks.cpp @@ -32,8 +32,6 @@ namespace Compat::SrwLock g_lastOpenAdapterInfoSrwLock; std::string g_lastDDrawCreateDcDevice; - HANDLE g_vsyncThread = nullptr; - bool g_stopVsyncThread = false; UINT g_vsyncCounter = 0; CONDITION_VARIABLE g_vsyncCounterCv = CONDITION_VARIABLE_INIT; Compat::SrwLock g_vsyncCounterSrwLock; @@ -242,7 +240,7 @@ namespace unsigned WINAPI vsyncThreadProc(LPVOID /*lpParameter*/) { - while (!g_stopVsyncThread) + while (true) { waitForVerticalBlank(); @@ -323,7 +321,7 @@ namespace D3dDdi Compat::hookIatFunction(origDDrawModule, "gdi32.dll", "D3DKMTQueryAdapterInfo", queryAdapterInfo); Compat::hookIatFunction(origDDrawModule, "gdi32.dll", "D3DKMTSetGammaRamp", setGammaRamp); - g_vsyncThread = Dll::createThread(&vsyncThreadProc, nullptr, THREAD_PRIORITY_TIME_CRITICAL); + Dll::createThread(&vsyncThreadProc, nullptr, THREAD_PRIORITY_TIME_CRITICAL); } void setDcFormatOverride(UINT format) @@ -336,17 +334,6 @@ namespace D3dDdi g_dcPaletteOverride = enable; } - void stopVsyncThread() - { - g_stopVsyncThread = true; - if (WAIT_OBJECT_0 != WaitForSingleObject(g_vsyncThread, 100)) - { - TerminateThread(g_vsyncThread, 0); - Compat::Log() << "The vsync thread was terminated forcefully"; - } - g_vsyncThread = nullptr; - } - void waitForVsync() { waitForVsyncCounter(getVsyncCounter() + 1); diff --git a/DDrawCompat/D3dDdi/KernelModeThunks.h b/DDrawCompat/D3dDdi/KernelModeThunks.h index 88055a2..46a0f5f 100644 --- a/DDrawCompat/D3dDdi/KernelModeThunks.h +++ b/DDrawCompat/D3dDdi/KernelModeThunks.h @@ -11,7 +11,6 @@ namespace D3dDdi void installHooks(HMODULE origDDrawModule); void setDcFormatOverride(UINT format); void setDcPaletteOverride(bool enable); - void stopVsyncThread(); void waitForVsync(); bool waitForVsyncCounter(UINT counter); } diff --git a/DDrawCompat/DDraw/Hooks.cpp b/DDrawCompat/DDraw/Hooks.cpp index b092849..efe50ca 100644 --- a/DDrawCompat/DDraw/Hooks.cpp +++ b/DDrawCompat/DDraw/Hooks.cpp @@ -105,9 +105,4 @@ namespace DDraw hookDirectDrawPalette(*dd7); hookDirectDrawSurface(*dd7); } - - void uninstallHooks() - { - RealPrimarySurface::removeUpdateThread(); - } } diff --git a/DDrawCompat/DDraw/Hooks.h b/DDrawCompat/DDraw/Hooks.h index ccb82f9..d150921 100644 --- a/DDrawCompat/DDraw/Hooks.h +++ b/DDrawCompat/DDraw/Hooks.h @@ -7,5 +7,4 @@ namespace DDraw { void installHooks(CompatPtr dd7); - void uninstallHooks(); } diff --git a/DDrawCompat/DDraw/RealPrimarySurface.cpp b/DDrawCompat/DDraw/RealPrimarySurface.cpp index 3505fc6..0d81ac8 100644 --- a/DDrawCompat/DDraw/RealPrimarySurface.cpp +++ b/DDrawCompat/DDraw/RealPrimarySurface.cpp @@ -30,8 +30,6 @@ namespace DDSURFACEDESC2 g_surfaceDesc = {}; DDraw::IReleaseNotifier g_releaseNotifier(onRelease); - bool g_stopUpdateThread = false; - HANDLE g_updateThread = nullptr; bool g_isFullScreen = false; DDraw::Surface* g_lastFlipSurface = nullptr; @@ -217,7 +215,7 @@ namespace { bool skipWaitForVsync = false; - while (!g_stopUpdateThread) + while (true) { if (!skipWaitForVsync) { @@ -356,7 +354,7 @@ namespace DDraw void RealPrimarySurface::init() { - g_updateThread = Dll::createThread(&updateThreadProc, nullptr, THREAD_PRIORITY_TIME_CRITICAL); + Dll::createThread(&updateThreadProc, nullptr, THREAD_PRIORITY_TIME_CRITICAL); } bool RealPrimarySurface::isFullScreen() @@ -376,22 +374,6 @@ namespace DDraw g_frontBuffer.release(); } - void RealPrimarySurface::removeUpdateThread() - { - if (!g_updateThread) - { - return; - } - - g_stopUpdateThread = true; - if (WAIT_OBJECT_0 != WaitForSingleObject(g_updateThread, 1000)) - { - TerminateThread(g_updateThread, 0); - Compat::Log() << "The update thread was terminated forcefully"; - } - g_updateThread = nullptr; - } - HRESULT RealPrimarySurface::restore() { DDraw::ScopedThreadLock lock; diff --git a/DDrawCompat/DDraw/RealPrimarySurface.h b/DDrawCompat/DDraw/RealPrimarySurface.h index 7d3504e..6de7212 100644 --- a/DDrawCompat/DDraw/RealPrimarySurface.h +++ b/DDrawCompat/DDraw/RealPrimarySurface.h @@ -23,7 +23,6 @@ namespace DDraw static bool isFullScreen(); static bool isLost(); static void release(); - static void removeUpdateThread(); static HRESULT restore(); static void scheduleUpdate(); static HRESULT setGammaRamp(DDGAMMARAMP* rampData); diff --git a/DDrawCompat/Dll/Dll.cpp b/DDrawCompat/Dll/Dll.cpp index ba7e9fe..c177725 100644 --- a/DDrawCompat/Dll/Dll.cpp +++ b/DDrawCompat/Dll/Dll.cpp @@ -17,6 +17,18 @@ namespace Dll } return thread; } + + void pinModule(LPCSTR moduleName) + { + HMODULE module = nullptr; + GetModuleHandleExA(GET_MODULE_HANDLE_EX_FLAG_PIN, moduleName, &module); + } + + void pinModule(LPCWSTR moduleName) + { + HMODULE module = nullptr; + GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_PIN, moduleName, &module); + } } #define CREATE_PROC_STUB(procName) \ diff --git a/DDrawCompat/Dll/Dll.h b/DDrawCompat/Dll/Dll.h index b163af6..0fc0662 100644 --- a/DDrawCompat/Dll/Dll.h +++ b/DDrawCompat/Dll/Dll.h @@ -68,6 +68,8 @@ namespace Dll }; HANDLE createThread(unsigned(__stdcall* threadProc)(void*), unsigned int* threadId, int priority); + void pinModule(LPCSTR moduleName); + void pinModule(LPCWSTR moduleName); extern HMODULE g_currentModule; extern Procs g_origProcs; diff --git a/DDrawCompat/Dll/DllMain.cpp b/DDrawCompat/Dll/DllMain.cpp index a33612f..00059d2 100644 --- a/DDrawCompat/Dll/DllMain.cpp +++ b/DDrawCompat/Dll/DllMain.cpp @@ -252,6 +252,8 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) return FALSE; } + Dll::pinModule(systemDDrawDllPath.c_str()); + HMODULE origModule = g_origDDrawModule; VISIT_DDRAW_PROCS(LOAD_ORIG_PROC); @@ -285,17 +287,6 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) } else if (fdwReason == DLL_PROCESS_DETACH) { - Compat::Log() << "Detaching DDrawCompat due to " << (lpvReserved ? "process termination" : "FreeLibrary"); - if (!lpvReserved) - { - DDraw::uninstallHooks(); - D3dDdi::uninstallHooks(); - Gdi::uninstallHooks(); - Compat::unhookAllFunctions(); - FreeLibrary(g_origDciman32Module); - FreeLibrary(g_origDDrawModule); - } - timeEndPeriod(1); Compat::Log() << "DDrawCompat detached successfully"; } else if (fdwReason == DLL_THREAD_DETACH) diff --git a/DDrawCompat/Gdi/Caret.cpp b/DDrawCompat/Gdi/Caret.cpp index 96c9a54..4f2d9df 100644 --- a/DDrawCompat/Gdi/Caret.cpp +++ b/DDrawCompat/Gdi/Caret.cpp @@ -9,9 +9,6 @@ namespace { - HWINEVENTHOOK g_caretGeneralEventHook = nullptr; - HWINEVENTHOOK g_caretLocationChangeEventHook = nullptr; - struct CaretData { HWND hwnd; @@ -114,16 +111,10 @@ namespace Gdi void installHooks() { - g_caretGeneralEventHook = SetWinEventHook(EVENT_OBJECT_SHOW, EVENT_OBJECT_HIDE, + SetWinEventHook(EVENT_OBJECT_SHOW, EVENT_OBJECT_HIDE, Dll::g_currentModule, &caretEvent, GetCurrentProcessId(), 0, WINEVENT_INCONTEXT); - g_caretLocationChangeEventHook = SetWinEventHook(EVENT_OBJECT_LOCATIONCHANGE, EVENT_OBJECT_LOCATIONCHANGE, + SetWinEventHook(EVENT_OBJECT_LOCATIONCHANGE, EVENT_OBJECT_LOCATIONCHANGE, Dll::g_currentModule, &caretEvent, GetCurrentProcessId(), 0, WINEVENT_INCONTEXT); } - - void uninstallHooks() - { - UnhookWinEvent(g_caretLocationChangeEventHook); - UnhookWinEvent(g_caretGeneralEventHook); - } } } diff --git a/DDrawCompat/Gdi/Caret.h b/DDrawCompat/Gdi/Caret.h index 47d818f..d3431fd 100644 --- a/DDrawCompat/Gdi/Caret.h +++ b/DDrawCompat/Gdi/Caret.h @@ -6,6 +6,5 @@ namespace Gdi { void blink(); void installHooks(); - void uninstallHooks(); } } diff --git a/DDrawCompat/Gdi/Dc.cpp b/DDrawCompat/Gdi/Dc.cpp index d5cb73a..e8864e7 100644 --- a/DDrawCompat/Gdi/Dc.cpp +++ b/DDrawCompat/Gdi/Dc.cpp @@ -130,18 +130,6 @@ namespace Gdi { namespace Dc { - void dllProcessDetach() - { - Compat::ScopedCriticalSection lock(g_cs); - for (auto& origDcToCompatDc : g_origDcToCompatDc) - { - restoreDc(origDcToCompatDc.second); - Gdi::VirtualScreen::deleteDc(origDcToCompatDc.second.dc); - } - g_origDcToCompatDc.clear(); - g_threadIdToDcCache.clear(); - } - void dllThreadDetach() { Compat::ScopedCriticalSection lock(g_cs); diff --git a/DDrawCompat/Gdi/Dc.h b/DDrawCompat/Gdi/Dc.h index 67f1de7..359efdb 100644 --- a/DDrawCompat/Gdi/Dc.h +++ b/DDrawCompat/Gdi/Dc.h @@ -6,7 +6,6 @@ namespace Gdi { namespace Dc { - void dllProcessDetach(); void dllThreadDetach(); HDC getDc(HDC origDc); HDC getOrigDc(HDC dc); diff --git a/DDrawCompat/Gdi/Gdi.cpp b/DDrawCompat/Gdi/Gdi.cpp index 94959a0..047c61f 100644 --- a/DDrawCompat/Gdi/Gdi.cpp +++ b/DDrawCompat/Gdi/Gdi.cpp @@ -90,14 +90,6 @@ namespace Gdi DestroyWindow(hwnd); } - void uninstallHooks() - { - Caret::uninstallHooks(); - PresentationWindow::uninstallHooks(); - WinProc::uninstallHooks(); - Dc::dllProcessDetach(); - } - void watchWindowPosChanges(WindowPosChangeNotifyFunc notifyFunc) { WinProc::watchWindowPosChanges(notifyFunc); diff --git a/DDrawCompat/Gdi/Gdi.h b/DDrawCompat/Gdi/Gdi.h index 9e49d14..ad44b1a 100644 --- a/DDrawCompat/Gdi/Gdi.h +++ b/DDrawCompat/Gdi/Gdi.h @@ -16,6 +16,5 @@ namespace Gdi void redraw(HRGN rgn); void redrawWindow(HWND hwnd, HRGN rgn); void unhookWndProc(LPCSTR className, WNDPROC oldWndProc); - void uninstallHooks(); void watchWindowPosChanges(WindowPosChangeNotifyFunc notifyFunc); }; diff --git a/DDrawCompat/Gdi/PresentationWindow.cpp b/DDrawCompat/Gdi/PresentationWindow.cpp index e3a92d7..f7aa5d0 100644 --- a/DDrawCompat/Gdi/PresentationWindow.cpp +++ b/DDrawCompat/Gdi/PresentationWindow.cpp @@ -9,7 +9,6 @@ namespace const UINT WM_SETPRESENTATIONWINDOWPOS = WM_USER + 1; const UINT WM_SETPRESENTATIONWINDOWRGN = WM_USER + 2; - HANDLE g_presentationWindowThread = nullptr; unsigned g_presentationWindowThreadId = 0; HWND g_messageWindow = nullptr; @@ -165,18 +164,5 @@ namespace Gdi { sendMessageBlocking(hwnd, WM_SETPRESENTATIONWINDOWRGN, reinterpret_cast(rgn), 0); } - - void uninstallHooks() - { - if (g_presentationWindowThread) - { - sendMessageBlocking(g_messageWindow, WM_CLOSE, 0, 0); - if (WAIT_OBJECT_0 != WaitForSingleObject(g_presentationWindowThread, 1000)) - { - TerminateThread(g_presentationWindowThread, 0); - Compat::Log() << "The presentation window thread was terminated forcefully"; - } - } - } } } diff --git a/DDrawCompat/Gdi/PresentationWindow.h b/DDrawCompat/Gdi/PresentationWindow.h index 93102a4..52ffba6 100644 --- a/DDrawCompat/Gdi/PresentationWindow.h +++ b/DDrawCompat/Gdi/PresentationWindow.h @@ -13,6 +13,5 @@ namespace Gdi void setWindowRgn(HWND hwnd, HRGN rgn); void installHooks(); - void uninstallHooks(); } } diff --git a/DDrawCompat/Gdi/WinProc.cpp b/DDrawCompat/Gdi/WinProc.cpp index a837745..00eb6cc 100644 --- a/DDrawCompat/Gdi/WinProc.cpp +++ b/DDrawCompat/Gdi/WinProc.cpp @@ -25,8 +25,7 @@ namespace WNDPROC wndProcW; }; - HWINEVENTHOOK g_objectCreateEventHook = nullptr; - HWINEVENTHOOK g_objectStateChangeEventHook = nullptr; + bool g_isInitialized = false; std::set g_windowPosChangeNotifyFuncs; Compat::SrwLock g_windowProcSrwLock; @@ -461,18 +460,20 @@ namespace Gdi HOOK_FUNCTION(user32, UpdateLayeredWindowIndirect, updateLayeredWindowIndirect); CoInitialize(nullptr); - g_objectCreateEventHook = SetWinEventHook(EVENT_OBJECT_CREATE, EVENT_OBJECT_CREATE, + SetWinEventHook(EVENT_OBJECT_CREATE, EVENT_OBJECT_CREATE, Dll::g_currentModule, &objectCreateEvent, GetCurrentProcessId(), 0, WINEVENT_INCONTEXT); - g_objectStateChangeEventHook = SetWinEventHook(EVENT_OBJECT_STATECHANGE, EVENT_OBJECT_STATECHANGE, + SetWinEventHook(EVENT_OBJECT_STATECHANGE, EVENT_OBJECT_STATECHANGE, Dll::g_currentModule, &objectStateChangeEvent, GetCurrentProcessId(), 0, WINEVENT_INCONTEXT); + g_isInitialized = true; + EnumWindows(initTopLevelWindow, 0); Gdi::Window::updateAll(); } void onCreateWindow(HWND hwnd) { - if (g_objectCreateEventHook) + if (g_isInitialized) { ::onCreateWindow(hwnd); } @@ -482,18 +483,5 @@ namespace Gdi { g_windowPosChangeNotifyFuncs.insert(notifyFunc); } - - void uninstallHooks() - { - UnhookWinEvent(g_objectStateChangeEventHook); - UnhookWinEvent(g_objectCreateEventHook); - - Compat::ScopedSrwLockExclusive lock(g_windowProcSrwLock); - for (const auto& windowProc : g_windowProc) - { - setWindowProc(windowProc.first, windowProc.second.wndProcA, windowProc.second.wndProcW); - } - g_windowProc.clear(); - } } } diff --git a/DDrawCompat/Gdi/WinProc.h b/DDrawCompat/Gdi/WinProc.h index 3843ce4..c841cb7 100644 --- a/DDrawCompat/Gdi/WinProc.h +++ b/DDrawCompat/Gdi/WinProc.h @@ -10,6 +10,5 @@ namespace Gdi void installHooks(); void onCreateWindow(HWND hwnd); void watchWindowPosChanges(WindowPosChangeNotifyFunc notifyFunc); - void uninstallHooks(); } }