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:
parent
0d91170fb5
commit
35e66bd3cf
@ -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);
|
||||
|
@ -39,6 +39,5 @@ namespace Compat
|
||||
}
|
||||
|
||||
void removeShim(HMODULE module, const char* funcName);
|
||||
void unhookAllFunctions();
|
||||
void unhookFunction(void* origFunc);
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
@ -7,5 +7,4 @@ namespace D3dDdi
|
||||
UINT getDdiVersion();
|
||||
void installHooks(HMODULE origDDrawModule);
|
||||
void onUmdFileNameQueried(const std::wstring& umdFileName);
|
||||
void uninstallHooks();
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -105,9 +105,4 @@ namespace DDraw
|
||||
hookDirectDrawPalette(*dd7);
|
||||
hookDirectDrawSurface(*dd7);
|
||||
}
|
||||
|
||||
void uninstallHooks()
|
||||
{
|
||||
RealPrimarySurface::removeUpdateThread();
|
||||
}
|
||||
}
|
||||
|
@ -7,5 +7,4 @@
|
||||
namespace DDraw
|
||||
{
|
||||
void installHooks(CompatPtr<IDirectDraw7> dd7);
|
||||
void uninstallHooks();
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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) \
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -6,6 +6,5 @@ namespace Gdi
|
||||
{
|
||||
void blink();
|
||||
void installHooks();
|
||||
void uninstallHooks();
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -6,7 +6,6 @@ namespace Gdi
|
||||
{
|
||||
namespace Dc
|
||||
{
|
||||
void dllProcessDetach();
|
||||
void dllThreadDetach();
|
||||
HDC getDc(HDC origDc);
|
||||
HDC getOrigDc(HDC dc);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
};
|
||||
|
@ -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";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -13,6 +13,5 @@ namespace Gdi
|
||||
void setWindowRgn(HWND hwnd, HRGN rgn);
|
||||
|
||||
void installHooks();
|
||||
void uninstallHooks();
|
||||
}
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -10,6 +10,5 @@ namespace Gdi
|
||||
void installHooks();
|
||||
void onCreateWindow(HWND hwnd);
|
||||
void watchWindowPosChanges(WindowPosChangeNotifyFunc notifyFunc);
|
||||
void uninstallHooks();
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user