1
0
mirror of https://github.com/narzoul/DDrawCompat synced 2024-12-30 08:55:36 +01:00

Leave cleanup to process termination

This commit is contained in:
narzoul 2021-03-01 22:59:07 +01:00
parent 0d91170fb5
commit 35e66bd3cf
23 changed files with 31 additions and 146 deletions

View File

@ -158,7 +158,8 @@ namespace
}
HMODULE module = nullptr;
GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, static_cast<char*>(hookedFuncPtr), &module);
GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_PIN,
static_cast<char*>(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);

View File

@ -39,6 +39,5 @@ namespace Compat
}
void removeShim(HMODULE module, const char* funcName);
void unhookAllFunctions();
void unhookFunction(void* origFunc);
}

View File

@ -41,8 +41,7 @@ namespace
{
Compat::hookFunction(g_hookedUmdModule, "OpenAdapter",
reinterpret_cast<void*&>(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();
}
}

View File

@ -7,5 +7,4 @@ namespace D3dDdi
UINT getDdiVersion();
void installHooks(HMODULE origDDrawModule);
void onUmdFileNameQueried(const std::wstring& umdFileName);
void uninstallHooks();
}

View File

@ -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);

View File

@ -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);
}

View File

@ -105,9 +105,4 @@ namespace DDraw
hookDirectDrawPalette(*dd7);
hookDirectDrawSurface(*dd7);
}
void uninstallHooks()
{
RealPrimarySurface::removeUpdateThread();
}
}

View File

@ -7,5 +7,4 @@
namespace DDraw
{
void installHooks(CompatPtr<IDirectDraw7> dd7);
void uninstallHooks();
}

View File

@ -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;

View File

@ -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);

View File

@ -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) \

View File

@ -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;

View File

@ -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)

View File

@ -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);
}
}
}

View File

@ -6,6 +6,5 @@ namespace Gdi
{
void blink();
void installHooks();
void uninstallHooks();
}
}

View File

@ -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);

View File

@ -6,7 +6,6 @@ namespace Gdi
{
namespace Dc
{
void dllProcessDetach();
void dllThreadDetach();
HDC getDc(HDC origDc);
HDC getOrigDc(HDC dc);

View File

@ -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);

View File

@ -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);
};

View File

@ -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<WPARAM>(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";
}
}
}
}
}

View File

@ -13,6 +13,5 @@ namespace Gdi
void setWindowRgn(HWND hwnd, HRGN rgn);
void installHooks();
void uninstallHooks();
}
}

View File

@ -25,8 +25,7 @@ namespace
WNDPROC wndProcW;
};
HWINEVENTHOOK g_objectCreateEventHook = nullptr;
HWINEVENTHOOK g_objectStateChangeEventHook = nullptr;
bool g_isInitialized = false;
std::set<Gdi::WindowPosChangeNotifyFunc> 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();
}
}
}

View File

@ -10,6 +10,5 @@ namespace Gdi
void installHooks();
void onCreateWindow(HWND hwnd);
void watchWindowPosChanges(WindowPosChangeNotifyFunc notifyFunc);
void uninstallHooks();
}
}