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

Extracted function hooking to its own unit

This commit is contained in:
narzoul 2016-03-21 22:51:56 +01:00
parent 1a7319dbee
commit 68d3c75c95
15 changed files with 193 additions and 148 deletions

View File

@ -23,44 +23,6 @@ namespace
bool g_isPaletteUsed = false;
PALETTEENTRY g_usedPaletteEntries[256] = {};
FARPROC getProcAddress(HMODULE module, const char* procName)
{
if (!module || !procName)
{
return nullptr;
}
PIMAGE_DOS_HEADER dosHeader = reinterpret_cast<PIMAGE_DOS_HEADER>(module);
if (IMAGE_DOS_SIGNATURE != dosHeader->e_magic) {
return nullptr;
}
char* moduleBase = reinterpret_cast<char*>(module);
PIMAGE_NT_HEADERS ntHeader = reinterpret_cast<PIMAGE_NT_HEADERS>(
reinterpret_cast<char*>(dosHeader) + dosHeader->e_lfanew);
if (IMAGE_NT_SIGNATURE != ntHeader->Signature)
{
return nullptr;
}
PIMAGE_EXPORT_DIRECTORY exportDir = reinterpret_cast<PIMAGE_EXPORT_DIRECTORY>(
moduleBase + ntHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress);
DWORD* rvaOfNames = reinterpret_cast<DWORD*>(moduleBase + exportDir->AddressOfNames);
for (DWORD i = 0; i < exportDir->NumberOfNames; ++i)
{
if (0 == strcmp(procName, moduleBase + rvaOfNames[i]))
{
WORD* nameOrds = reinterpret_cast<WORD*>(moduleBase + exportDir->AddressOfNameOrdinals);
DWORD* rvaOfFunctions = reinterpret_cast<DWORD*>(moduleBase + exportDir->AddressOfFunctions);
return reinterpret_cast<FARPROC>(moduleBase + rvaOfFunctions[nameOrds[i]]);
}
}
return nullptr;
}
BOOL CALLBACK invalidateWindow(HWND hwnd, LPARAM lParam)
{
if (!IsWindowVisible(hwnd))
@ -157,7 +119,6 @@ namespace
namespace CompatGdi
{
CRITICAL_SECTION g_gdiCriticalSection;
std::unordered_map<void*, const char*> g_funcNames;
GdiScopedThreadLock::GdiScopedThreadLock() : m_isLocked(true)
{
@ -252,27 +213,6 @@ namespace CompatGdi
}
}
void hookGdiFunction(const char* moduleName, const char* funcName, void*& origFuncPtr, void* newFuncPtr)
{
#ifdef _DEBUG
g_funcNames[origFuncPtr] = funcName;
#endif
FARPROC procAddr = getProcAddress(GetModuleHandle(moduleName), funcName);
if (!procAddr)
{
Compat::Log() << "Failed to load the address of a GDI function: " << funcName;
return;
}
origFuncPtr = procAddr;
if (NO_ERROR != DetourAttach(&origFuncPtr, newFuncPtr))
{
Compat::Log() << "Failed to hook a GDI function: " << funcName;
return;
}
}
void hookWndProc(LPCSTR className, WNDPROC &oldWndProc, WNDPROC newWndProc)
{
HWND hwnd = CreateWindow(className, nullptr, 0, 0, 0, 0, 0, nullptr, nullptr, nullptr, 0);

View File

@ -2,17 +2,8 @@
#define WIN32_LEAN_AND_MEAN
#include <unordered_map>
#include <Windows.h>
#include "DDrawLog.h"
#define CALL_ORIG_GDI(func) CompatGdi::getOrigFuncPtr<decltype(&func), &func>()
#define HOOK_GDI_FUNCTION(module, func, newFunc) \
CompatGdi::hookGdiFunction<decltype(&func), &func>(#module, #func, &newFunc)
namespace CompatGdi
{
class GdiScopedThreadLock
@ -26,27 +17,10 @@ namespace CompatGdi
};
extern CRITICAL_SECTION g_gdiCriticalSection;
extern std::unordered_map<void*, const char*> g_funcNames;
bool beginGdiRendering();
void endGdiRendering();
template <typename OrigFuncPtr, OrigFuncPtr origFunc>
OrigFuncPtr& getOrigFuncPtr()
{
static OrigFuncPtr origFuncPtr = origFunc;
return origFuncPtr;
}
void hookGdiFunction(const char* moduleName, const char* funcName, void*& origFuncPtr, void* newFuncPtr);
template <typename OrigFuncPtr, OrigFuncPtr origFunc>
void hookGdiFunction(const char* moduleName, const char* funcName, OrigFuncPtr newFuncPtr)
{
hookGdiFunction(moduleName, funcName,
reinterpret_cast<void*&>(getOrigFuncPtr<OrigFuncPtr, origFunc>()), newFuncPtr);
}
void hookWndProc(LPCSTR className, WNDPROC &oldWndProc, WNDPROC newWndProc);
void installHooks();
void invalidate(const RECT* rect);

View File

@ -3,11 +3,11 @@
#include <oleacc.h>
#include <Windows.h>
#include <detours.h>
#include "CompatGdi.h"
#include "CompatGdiCaret.h"
#include "CompatGdiDc.h"
#include "Hook.h"
namespace
{
@ -144,7 +144,7 @@ namespace
BOOL WINAPI createCaret(HWND hWnd, HBITMAP hBitmap, int nWidth, int nHeight)
{
BOOL result = CALL_ORIG_GDI(CreateCaret)(hWnd, hBitmap, nWidth, nHeight);
BOOL result = CALL_ORIG_FUNC(CreateCaret)(hWnd, hBitmap, nWidth, nHeight);
if (result)
{
CaretScopedThreadLock caretLock;
@ -161,7 +161,7 @@ namespace
BOOL WINAPI hideCaret(HWND hWnd)
{
BOOL result = CALL_ORIG_GDI(HideCaret)(hWnd);
BOOL result = CALL_ORIG_FUNC(HideCaret)(hWnd);
if (result)
{
CaretScopedThreadLock caretLock;
@ -176,7 +176,7 @@ namespace
BOOL WINAPI showCaret(HWND hWnd)
{
if (!CALL_ORIG_GDI(ShowCaret)(hWnd))
if (!CALL_ORIG_FUNC(ShowCaret)(hWnd))
{
return FALSE;
}
@ -213,11 +213,11 @@ namespace CompatGdiCaret
{
InitializeCriticalSection(&g_caretCriticalSection);
DetourTransactionBegin();
HOOK_GDI_FUNCTION(user32, CreateCaret, createCaret);
HOOK_GDI_FUNCTION(user32, HideCaret, hideCaret);
HOOK_GDI_FUNCTION(user32, ShowCaret, showCaret);
DetourTransactionCommit();
Compat::beginHookTransaction();
HOOK_FUNCTION(user32, CreateCaret, createCaret);
HOOK_FUNCTION(user32, HideCaret, hideCaret);
HOOK_FUNCTION(user32, ShowCaret, showCaret);
Compat::endHookTransaction();
const DWORD threadId = GetCurrentThreadId();
SetWinEventHook(EVENT_OBJECT_DESTROY, EVENT_OBJECT_DESTROY,

View File

@ -1,13 +1,16 @@
#include <unordered_map>
#include "CompatGdi.h"
#include "CompatGdiDc.h"
#include "CompatGdiDcFunctions.h"
#include "DDrawLog.h"
#include "Hook.h"
#include "RealPrimarySurface.h"
#include <detours.h>
namespace
{
std::unordered_map<void*, const char*> g_funcNames;
BOOL WINAPI PolyPatBlt(HDC, DWORD, DWORD, DWORD, DWORD) { return FALSE; }
template <typename Result, typename... Params>
@ -61,12 +64,12 @@ namespace
Result WINAPI compatGdiDcFunc(Params... params)
{
#ifdef _DEBUG
Compat::LogEnter(CompatGdi::g_funcNames[origFunc], params...);
Compat::LogEnter(g_funcNames[origFunc], params...);
#endif
if (!hasDisplayDcArg(params...) || !CompatGdi::beginGdiRendering())
{
Result result = CompatGdi::getOrigFuncPtr<OrigFuncPtr, origFunc>()(params...);
Result result = Compat::getOrigFuncPtr<OrigFuncPtr, origFunc>()(params...);
#ifdef _DEBUG
if (!hasDisplayDcArg(params...))
@ -81,18 +84,18 @@ namespace
{
Compat::Log() << "Skipping redirection since the primary surface could not be locked";
}
Compat::LogLeave(CompatGdi::g_funcNames[origFunc], params...) << result;
Compat::LogLeave(g_funcNames[origFunc], params...) << result;
#endif
return result;
}
Result result = CompatGdi::getOrigFuncPtr<OrigFuncPtr, origFunc>()(replaceDc(params)...);
Result result = Compat::getOrigFuncPtr<OrigFuncPtr, origFunc>()(replaceDc(params)...);
releaseDc(params...);
CompatGdi::endGdiRendering();
#ifdef _DEBUG
Compat::LogLeave(CompatGdi::g_funcNames[origFunc], params...) << result;
Compat::LogLeave(g_funcNames[origFunc], params...) << result;
#endif
return result;
@ -104,15 +107,25 @@ namespace
return &compatGdiDcFunc<OrigFuncPtr, origFunc, Result, Params...>;
}
template <typename OrigFuncPtr, OrigFuncPtr origFunc>
void hookGdiDcFunction(const char* moduleName, const char* funcName)
{
#ifdef _DEBUG
g_funcNames[origFunc] = funcName;
#endif
Compat::hookFunction<OrigFuncPtr, origFunc>(
moduleName, funcName, getCompatGdiDcFuncPtr<OrigFuncPtr, origFunc>(origFunc));
}
HWND WINAPI windowFromDc(HDC dc)
{
return CALL_ORIG_GDI(WindowFromDC)(CompatGdiDc::getOrigDc(dc));
return CALL_ORIG_FUNC(WindowFromDC)(CompatGdiDc::getOrigDc(dc));
}
}
#define HOOK_GDI_DC_FUNCTION(module, func) \
CompatGdi::hookGdiFunction<decltype(&func), &func>( \
#module, #func, getCompatGdiDcFuncPtr<decltype(&func), &func>(&func))
hookGdiDcFunction<decltype(&func), &func>(#module, #func)
#define HOOK_GDI_TEXT_DC_FUNCTION(module, func) \
HOOK_GDI_DC_FUNCTION(module, func##A); \
@ -122,7 +135,7 @@ namespace CompatGdiDcFunctions
{
void installHooks()
{
DetourTransactionBegin();
Compat::beginHookTransaction();
// Bitmap functions
HOOK_GDI_DC_FUNCTION(msimg32, AlphaBlend);
@ -154,7 +167,7 @@ namespace CompatGdiDcFunctions
// Device context functions
HOOK_GDI_DC_FUNCTION(gdi32, CreateCompatibleDC);
HOOK_GDI_DC_FUNCTION(gdi32, DrawEscape);
HOOK_GDI_FUNCTION(user32, WindowFromDC, windowFromDc);
HOOK_FUNCTION(user32, WindowFromDC, windowFromDc);
// Filled shape functions
HOOK_GDI_DC_FUNCTION(gdi32, Chord);
@ -213,6 +226,6 @@ namespace CompatGdiDcFunctions
// Undocumented functions
HOOK_GDI_DC_FUNCTION(gdi32, PolyPatBlt);
DetourTransactionCommit();
Compat::endHookTransaction();
}
}

View File

@ -3,8 +3,8 @@
#include "CompatGdiPaintHandlers.h"
#include "CompatGdiScrollBar.h"
#include "CompatGdiTitleBar.h"
#include <detours.h>
#include "DDrawLog.h"
#include "Hook.h"
namespace
{
@ -25,12 +25,12 @@ namespace
LRESULT WINAPI defDlgProcA(HWND hdlg, UINT msg, WPARAM wParam, LPARAM lParam)
{
return defWindowProc(hdlg, msg, wParam, lParam, CALL_ORIG_GDI(DefDlgProcA), "defDlgProcA");
return defWindowProc(hdlg, msg, wParam, lParam, CALL_ORIG_FUNC(DefDlgProcA), "defDlgProcA");
}
LRESULT WINAPI defDlgProcW(HWND hdlg, UINT msg, WPARAM wParam, LPARAM lParam)
{
return defWindowProc(hdlg, msg, wParam, lParam, CALL_ORIG_GDI(DefDlgProcW), "defDlgProcW");
return defWindowProc(hdlg, msg, wParam, lParam, CALL_ORIG_FUNC(DefDlgProcW), "defDlgProcW");
}
LRESULT WINAPI defWindowProc(
@ -70,12 +70,12 @@ namespace
LRESULT WINAPI defWindowProcA(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
return defWindowProc(hwnd, msg, wParam, lParam, CALL_ORIG_GDI(DefWindowProcA), "defWindowProcA");
return defWindowProc(hwnd, msg, wParam, lParam, CALL_ORIG_FUNC(DefWindowProcA), "defWindowProcA");
}
LRESULT WINAPI defWindowProcW(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
return defWindowProc(hwnd, msg, wParam, lParam, CALL_ORIG_GDI(DefWindowProcW), "defWindowProcW");
return defWindowProc(hwnd, msg, wParam, lParam, CALL_ORIG_FUNC(DefWindowProcW), "defWindowProcW");
}
LRESULT WINAPI editWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
@ -294,11 +294,11 @@ namespace CompatGdiPaintHandlers
CompatGdi::hookWndProc("#32768", g_origMenuWndProc, &menuWndProc);
CompatGdi::hookWndProc("ScrollBar", g_origScrollBarWndProc, &scrollBarWndProc);
DetourTransactionBegin();
HOOK_GDI_FUNCTION(user32, DefWindowProcA, defWindowProcA);
HOOK_GDI_FUNCTION(user32, DefWindowProcW, defWindowProcW);
HOOK_GDI_FUNCTION(user32, DefDlgProcA, defDlgProcA);
HOOK_GDI_FUNCTION(user32, DefDlgProcW, defDlgProcW);
DetourTransactionCommit();
Compat::beginHookTransaction();
HOOK_FUNCTION(user32, DefWindowProcA, defWindowProcA);
HOOK_FUNCTION(user32, DefWindowProcW, defWindowProcW);
HOOK_FUNCTION(user32, DefDlgProcA, defDlgProcA);
HOOK_FUNCTION(user32, DefDlgProcW, defDlgProcW);
Compat::endHookTransaction();
}
}

View File

@ -1,5 +1,6 @@
#include "CompatGdi.h"
#include "CompatGdiScrollBar.h"
#include "Hook.h"
namespace
{
@ -72,7 +73,7 @@ namespace CompatGdi
}
RECT rect = sbci.rect;
CALL_ORIG_GDI(DrawFrameControl)(m_compatDc, &rect, DFC_SCROLL, dfcState | stateFlags);
CALL_ORIG_FUNC(DrawFrameControl)(m_compatDc, &rect, DFC_SCROLL, dfcState | stateFlags);
}
void ScrollBar::drawHorizArrows() const

View File

@ -1,7 +1,6 @@
#include "CompatGdi.h"
#include "CompatGdiScrollFunctions.h"
#include <detours.h>
#include "Hook.h"
namespace
{
@ -12,7 +11,7 @@ namespace
_In_ const RECT *lpRect,
_In_ const RECT *lpClipRect)
{
BOOL result = CALL_ORIG_GDI(ScrollWindow)(hWnd, XAmount, YAmount, lpRect, lpClipRect);
BOOL result = CALL_ORIG_FUNC(ScrollWindow)(hWnd, XAmount, YAmount, lpRect, lpClipRect);
CompatGdiScrollFunctions::updateScrolledWindow(hWnd);
return result;
}
@ -27,7 +26,7 @@ namespace
_Out_ LPRECT prcUpdate,
_In_ UINT flags)
{
int result = CALL_ORIG_GDI(ScrollWindowEx)(
int result = CALL_ORIG_FUNC(ScrollWindowEx)(
hWnd, dx, dy, prcScroll, prcClip, hrgnUpdate, prcUpdate, flags);
CompatGdiScrollFunctions::updateScrolledWindow(hWnd);
return result;
@ -38,10 +37,10 @@ namespace CompatGdiScrollFunctions
{
void installHooks()
{
DetourTransactionBegin();
HOOK_GDI_FUNCTION(user32, ScrollWindow, scrollWindow);
HOOK_GDI_FUNCTION(user32, ScrollWindowEx, scrollWindowEx);
DetourTransactionCommit();
Compat::beginHookTransaction();
HOOK_FUNCTION(user32, ScrollWindow, scrollWindow);
HOOK_FUNCTION(user32, ScrollWindowEx, scrollWindowEx);
Compat::endHookTransaction();
}
void updateScrolledWindow(HWND hwnd)

View File

@ -1,5 +1,6 @@
#include "CompatGdi.h"
#include "CompatGdiTitleBar.h"
#include "Hook.h"
namespace
{
@ -99,7 +100,7 @@ namespace CompatGdi
flags |= DC_SMALLCAP;
}
CALL_ORIG_GDI(DrawCaption)(m_hwnd, m_compatDc, &m_tbi.rcTitleBar, flags);
CALL_ORIG_FUNC(DrawCaption)(m_hwnd, m_compatDc, &m_tbi.rcTitleBar, flags);
}
void TitleBar::drawButton(std::size_t tbiIndex, UINT dfcState) const
@ -120,7 +121,7 @@ namespace CompatGdi
}
RECT rect = m_tbi.rgrect[tbiIndex];
CALL_ORIG_GDI(DrawFrameControl)(m_compatDc, &rect, DFC_CAPTION, dfcState | stateFlags);
CALL_ORIG_FUNC(DrawFrameControl)(m_compatDc, &rect, DFC_CAPTION, dfcState | stateFlags);
}
void TitleBar::excludeFromClipRegion() const

View File

@ -2,5 +2,5 @@
namespace Compat
{
std::map<void*, DetouredMethodInfo> detouredMethods;
std::map<void*, HookedMethodInfo> g_hookedMethods;
}

View File

@ -1,25 +1,21 @@
#pragma once
#define WIN32_LEAN_AND_MEAN
#include <map>
#include <string>
#include <vector>
#include <Windows.h>
#include <detours.h>
#include "DDrawLog.h"
#include "DDrawVtableVisitor.h"
#include "Hook.h"
template <typename Interface>
using Vtable = typename std::remove_pointer<decltype(Interface::lpVtbl)>::type;
namespace Compat
{
struct DetouredMethodInfo
struct HookedMethodInfo
{
DetouredMethodInfo(void*& updatedOrigMethodPtr, std::map<void*, void*>& vtablePtrToCompatVtable)
HookedMethodInfo(void*& updatedOrigMethodPtr, std::map<void*, void*>& vtablePtrToCompatVtable)
: updatedOrigMethodPtr(updatedOrigMethodPtr), vtablePtrToCompatVtable(vtablePtrToCompatVtable)
{
}
@ -28,7 +24,7 @@ namespace Compat
std::map<void*, void*>& vtablePtrToCompatVtable;
};
extern std::map<void*, DetouredMethodInfo> detouredMethods;
extern std::map<void*, HookedMethodInfo> g_hookedMethods;
}
template <typename CompatInterface, typename Interface>
@ -107,8 +103,8 @@ private:
void hookMethod(void*& origMethodPtr, void* newMethodPtr)
{
auto it = Compat::detouredMethods.find(origMethodPtr);
if (it != Compat::detouredMethods.end())
auto it = Compat::g_hookedMethods.find(origMethodPtr);
if (it != Compat::g_hookedMethods.end())
{
origMethodPtr = it->second.updatedOrigMethodPtr;
it->second.vtablePtrToCompatVtable[s_vtablePtr] = &s_compatVtable;
@ -116,11 +112,11 @@ private:
else
{
s_vtablePtrToCompatVtable[s_vtablePtr] = &s_compatVtable;
Compat::detouredMethods.emplace(origMethodPtr,
Compat::DetouredMethodInfo(origMethodPtr, s_vtablePtrToCompatVtable));
DetourTransactionBegin();
DetourAttach(&origMethodPtr, newMethodPtr);
DetourTransactionCommit();
Compat::g_hookedMethods.emplace(origMethodPtr,
Compat::HookedMethodInfo(origMethodPtr, s_vtablePtrToCompatVtable));
Compat::beginHookTransaction();
Compat::hookFunction(origMethodPtr, newMethodPtr);
Compat::endHookTransaction();
}
}

View File

@ -168,6 +168,7 @@
<ClInclude Include="DirectDrawSurfaceVtblVisitor.h" />
<ClInclude Include="DirectDrawVtblVisitor.h" />
<ClInclude Include="DDrawLog.h" />
<ClInclude Include="Hook.h" />
<ClInclude Include="IReleaseNotifier.h" />
<ClInclude Include="RealPrimarySurface.h" />
</ItemGroup>
@ -189,6 +190,7 @@
<ClCompile Include="DllMain.cpp" />
<ClCompile Include="CompatPrimarySurface.cpp" />
<ClCompile Include="DDrawProcs.cpp" />
<ClCompile Include="Hook.cpp" />
<ClCompile Include="IReleaseNotifier.cpp" />
<ClCompile Include="RealPrimarySurface.cpp" />
<ClCompile Include="CompatGdiDc.cpp" />

View File

@ -93,6 +93,9 @@
<ClInclude Include="CompatGdiPaintHandlers.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Hook.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="DllMain.cpp">
@ -158,6 +161,9 @@
<ClCompile Include="CompatGdiPaintHandlers.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Hook.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<None Include="DDrawCompat.def">

83
DDrawCompat/Hook.cpp Normal file
View File

@ -0,0 +1,83 @@
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
#include <detours.h>
#include "DDrawLog.h"
#include "Hook.h"
namespace
{
FARPROC getProcAddress(HMODULE module, const char* procName)
{
if (!module || !procName)
{
return nullptr;
}
PIMAGE_DOS_HEADER dosHeader = reinterpret_cast<PIMAGE_DOS_HEADER>(module);
if (IMAGE_DOS_SIGNATURE != dosHeader->e_magic) {
return nullptr;
}
char* moduleBase = reinterpret_cast<char*>(module);
PIMAGE_NT_HEADERS ntHeader = reinterpret_cast<PIMAGE_NT_HEADERS>(
reinterpret_cast<char*>(dosHeader) + dosHeader->e_lfanew);
if (IMAGE_NT_SIGNATURE != ntHeader->Signature)
{
return nullptr;
}
PIMAGE_EXPORT_DIRECTORY exportDir = reinterpret_cast<PIMAGE_EXPORT_DIRECTORY>(
moduleBase + ntHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress);
DWORD* rvaOfNames = reinterpret_cast<DWORD*>(moduleBase + exportDir->AddressOfNames);
for (DWORD i = 0; i < exportDir->NumberOfNames; ++i)
{
if (0 == strcmp(procName, moduleBase + rvaOfNames[i]))
{
WORD* nameOrds = reinterpret_cast<WORD*>(moduleBase + exportDir->AddressOfNameOrdinals);
DWORD* rvaOfFunctions = reinterpret_cast<DWORD*>(moduleBase + exportDir->AddressOfFunctions);
return reinterpret_cast<FARPROC>(moduleBase + rvaOfFunctions[nameOrds[i]]);
}
}
return nullptr;
}
}
namespace Compat
{
void beginHookTransaction()
{
DetourTransactionBegin();
}
void endHookTransaction()
{
DetourTransactionCommit();
}
void hookFunction(void*& origFuncPtr, void* newFuncPtr)
{
DetourAttach(&origFuncPtr, newFuncPtr);
}
void hookFunction(const char* moduleName, const char* funcName, void*& origFuncPtr, void* newFuncPtr)
{
FARPROC procAddr = getProcAddress(GetModuleHandle(moduleName), funcName);
if (!procAddr)
{
Compat::Log() << "Failed to load the address of a function: " << funcName;
return;
}
origFuncPtr = procAddr;
if (NO_ERROR != DetourAttach(&origFuncPtr, newFuncPtr))
{
Compat::Log() << "Failed to hook a function: " << funcName;
return;
}
}
}

29
DDrawCompat/Hook.h Normal file
View File

@ -0,0 +1,29 @@
#pragma once
#define CALL_ORIG_FUNC(func) Compat::getOrigFuncPtr<decltype(&func), &func>()
#define HOOK_FUNCTION(module, func, newFunc) \
Compat::hookFunction<decltype(&func), &func>(#module, #func, &newFunc)
namespace Compat
{
void beginHookTransaction();
void endHookTransaction();
template <typename OrigFuncPtr, OrigFuncPtr origFunc>
OrigFuncPtr& getOrigFuncPtr()
{
static OrigFuncPtr origFuncPtr = origFunc;
return origFuncPtr;
}
void hookFunction(void*& origFuncPtr, void* newFuncPtr);
void hookFunction(const char* moduleName, const char* funcName, void*& origFuncPtr, void* newFuncPtr);
template <typename OrigFuncPtr, OrigFuncPtr origFunc>
void hookFunction(const char* moduleName, const char* funcName, OrigFuncPtr newFuncPtr)
{
hookFunction(moduleName, funcName,
reinterpret_cast<void*&>(getOrigFuncPtr<OrigFuncPtr, origFunc>()), newFuncPtr);
}
}

View File

@ -7,6 +7,7 @@
#include "Config.h"
#include "DDrawProcs.h"
#include "DDrawTypes.h"
#include "Hook.h"
#include "IReleaseNotifier.h"
#include "RealPrimarySurface.h"
@ -55,7 +56,7 @@ namespace
HDC converterDc = nullptr;
origVtable.GetDC(g_paletteConverterSurface, &converterDc);
result = TRUE == CALL_ORIG_GDI(BitBlt)(destDc, 0, 0,
result = TRUE == CALL_ORIG_FUNC(BitBlt)(destDc, 0, 0,
RealPrimarySurface::s_surfaceDesc.dwWidth, RealPrimarySurface::s_surfaceDesc.dwHeight,
converterDc, 0, 0, SRCCOPY);