mirror of
https://github.com/narzoul/DDrawCompat
synced 2024-12-30 08:55:36 +01:00
Fixed/simplified hooking logic for COM methods
This commit is contained in:
parent
e4b67be7ec
commit
f7f5348a87
@ -236,8 +236,12 @@ HRESULT CompatDirectDrawSurface<TSurface>::createCompatPrimarySurface(
|
||||
return result;
|
||||
}
|
||||
|
||||
s_compatPrimarySurface = compatSurface;
|
||||
initCompatPrimarySurface();
|
||||
IDirectDrawSurface7* compatSurface7 = nullptr;
|
||||
s_origVtable.QueryInterface(compatSurface, IID_IDirectDrawSurface7,
|
||||
reinterpret_cast<void**>(&compatSurface7));
|
||||
CompatPrimarySurface::setPrimary(compatSurface7);
|
||||
CompatDirectDrawSurface<IDirectDrawSurface7>::s_origVtable.Release(compatSurface7);
|
||||
|
||||
return DD_OK;
|
||||
}
|
||||
|
||||
@ -250,22 +254,6 @@ void CompatDirectDrawSurface<TSurface>::fixSurfacePtrs(TSurface& surface)
|
||||
surface7->lpVtbl->Release(surface7);
|
||||
}
|
||||
|
||||
template <typename TSurface>
|
||||
void CompatDirectDrawSurface<TSurface>::initPrimarySurfacePtr(const GUID& guid, IUnknown& surface)
|
||||
{
|
||||
if (SUCCEEDED(surface.lpVtbl->QueryInterface(
|
||||
&surface, guid, reinterpret_cast<LPVOID*>(&s_compatPrimarySurface))))
|
||||
{
|
||||
s_compatPrimarySurface->lpVtbl->Release(s_compatPrimarySurface);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename TSurface>
|
||||
void CompatDirectDrawSurface<TSurface>::resetPrimarySurfacePtr()
|
||||
{
|
||||
s_compatPrimarySurface = nullptr;
|
||||
}
|
||||
|
||||
template <typename TSurface>
|
||||
HRESULT STDMETHODCALLTYPE CompatDirectDrawSurface<TSurface>::Blt(
|
||||
TSurface* This,
|
||||
@ -275,7 +263,8 @@ HRESULT STDMETHODCALLTYPE CompatDirectDrawSurface<TSurface>::Blt(
|
||||
DWORD dwFlags,
|
||||
LPDDBLTFX lpDDBltFx)
|
||||
{
|
||||
if ((This == s_compatPrimarySurface || lpDDSrcSurface == s_compatPrimarySurface) &&
|
||||
const bool isPrimaryDest = CompatPrimarySurface::isPrimary(This);
|
||||
if ((isPrimaryDest || CompatPrimarySurface::isPrimary(lpDDSrcSurface)) &&
|
||||
RealPrimarySurface::isLost())
|
||||
{
|
||||
return DDERR_SURFACELOST;
|
||||
@ -327,7 +316,7 @@ HRESULT STDMETHODCALLTYPE CompatDirectDrawSurface<TSurface>::Blt(
|
||||
result = s_origVtable.Blt(This, lpDestRect, lpDDSrcSurface, lpSrcRect, dwFlags, lpDDBltFx);
|
||||
}
|
||||
|
||||
if (This == s_compatPrimarySurface && SUCCEEDED(result))
|
||||
if (isPrimaryDest && SUCCEEDED(result))
|
||||
{
|
||||
RealPrimarySurface::invalidate(lpDestRect);
|
||||
RealPrimarySurface::update();
|
||||
@ -345,14 +334,15 @@ HRESULT STDMETHODCALLTYPE CompatDirectDrawSurface<TSurface>::BltFast(
|
||||
LPRECT lpSrcRect,
|
||||
DWORD dwTrans)
|
||||
{
|
||||
if ((This == s_compatPrimarySurface || lpDDSrcSurface == s_compatPrimarySurface) &&
|
||||
const bool isPrimaryDest = CompatPrimarySurface::isPrimary(This);
|
||||
if ((isPrimaryDest || CompatPrimarySurface::isPrimary(lpDDSrcSurface)) &&
|
||||
RealPrimarySurface::isLost())
|
||||
{
|
||||
return DDERR_SURFACELOST;
|
||||
}
|
||||
|
||||
HRESULT result = s_origVtable.BltFast(This, dwX, dwY, lpDDSrcSurface, lpSrcRect, dwTrans);
|
||||
if (This == s_compatPrimarySurface && SUCCEEDED(result))
|
||||
if (isPrimaryDest && SUCCEEDED(result))
|
||||
{
|
||||
const LONG x = dwX;
|
||||
const LONG y = dwY;
|
||||
@ -383,7 +373,7 @@ HRESULT STDMETHODCALLTYPE CompatDirectDrawSurface<TSurface>::Flip(
|
||||
DWORD dwFlags)
|
||||
{
|
||||
HRESULT result = s_origVtable.Flip(This, lpDDSurfaceTargetOverride, dwFlags);
|
||||
if (This == s_compatPrimarySurface && SUCCEEDED(result))
|
||||
if (SUCCEEDED(result) && CompatPrimarySurface::isPrimary(This))
|
||||
{
|
||||
result = RealPrimarySurface::flip(dwFlags);
|
||||
}
|
||||
@ -396,7 +386,7 @@ HRESULT STDMETHODCALLTYPE CompatDirectDrawSurface<TSurface>::GetCaps(
|
||||
TDdsCaps* lpDDSCaps)
|
||||
{
|
||||
HRESULT result = s_origVtable.GetCaps(This, lpDDSCaps);
|
||||
if (This == s_compatPrimarySurface && SUCCEEDED(result))
|
||||
if (SUCCEEDED(result) && CompatPrimarySurface::isPrimary(This))
|
||||
{
|
||||
restorePrimaryCaps(*lpDDSCaps);
|
||||
}
|
||||
@ -409,7 +399,7 @@ HRESULT STDMETHODCALLTYPE CompatDirectDrawSurface<TSurface>::GetSurfaceDesc(
|
||||
TSurfaceDesc* lpDDSurfaceDesc)
|
||||
{
|
||||
HRESULT result = s_origVtable.GetSurfaceDesc(This, lpDDSurfaceDesc);
|
||||
if (This == s_compatPrimarySurface && SUCCEEDED(result) && !g_lockingPrimary)
|
||||
if (SUCCEEDED(result) && !g_lockingPrimary && CompatPrimarySurface::isPrimary(This))
|
||||
{
|
||||
restorePrimaryCaps(lpDDSurfaceDesc->ddsCaps);
|
||||
}
|
||||
@ -420,7 +410,7 @@ template <typename TSurface>
|
||||
HRESULT STDMETHODCALLTYPE CompatDirectDrawSurface<TSurface>::IsLost(TSurface* This)
|
||||
{
|
||||
HRESULT result = s_origVtable.IsLost(This);
|
||||
if (This == s_compatPrimarySurface && SUCCEEDED(result))
|
||||
if (SUCCEEDED(result) && CompatPrimarySurface::isPrimary(This))
|
||||
{
|
||||
result = RealPrimarySurface::isLost() ? DDERR_SURFACELOST : DD_OK;
|
||||
}
|
||||
@ -435,7 +425,7 @@ HRESULT STDMETHODCALLTYPE CompatDirectDrawSurface<TSurface>::Lock(
|
||||
DWORD dwFlags,
|
||||
HANDLE hEvent)
|
||||
{
|
||||
if (This == s_compatPrimarySurface)
|
||||
if (CompatPrimarySurface::isPrimary(This))
|
||||
{
|
||||
if (RealPrimarySurface::isLost())
|
||||
{
|
||||
@ -472,7 +462,7 @@ HRESULT STDMETHODCALLTYPE CompatDirectDrawSurface<TSurface>::QueryInterface(
|
||||
REFIID riid,
|
||||
LPVOID* obp)
|
||||
{
|
||||
if (This == s_compatPrimarySurface && riid == IID_IDirectDrawGammaControl)
|
||||
if (riid == IID_IDirectDrawGammaControl && CompatPrimarySurface::isPrimary(This))
|
||||
{
|
||||
return RealPrimarySurface::getSurface()->lpVtbl->QueryInterface(
|
||||
RealPrimarySurface::getSurface(), riid, obp);
|
||||
@ -483,13 +473,14 @@ HRESULT STDMETHODCALLTYPE CompatDirectDrawSurface<TSurface>::QueryInterface(
|
||||
template <typename TSurface>
|
||||
HRESULT STDMETHODCALLTYPE CompatDirectDrawSurface<TSurface>::ReleaseDC(TSurface* This, HDC hDC)
|
||||
{
|
||||
if (This == s_compatPrimarySurface && RealPrimarySurface::isLost())
|
||||
const bool isPrimary = CompatPrimarySurface::isPrimary(This);
|
||||
if (isPrimary && RealPrimarySurface::isLost())
|
||||
{
|
||||
return DDERR_SURFACELOST;
|
||||
}
|
||||
|
||||
HRESULT result = s_origVtable.ReleaseDC(This, hDC);
|
||||
if (This == s_compatPrimarySurface && SUCCEEDED(result))
|
||||
if (isPrimary && SUCCEEDED(result))
|
||||
{
|
||||
RealPrimarySurface::invalidate(nullptr);
|
||||
RealPrimarySurface::update();
|
||||
@ -508,7 +499,7 @@ HRESULT STDMETHODCALLTYPE CompatDirectDrawSurface<TSurface>::Restore(TSurface* T
|
||||
{
|
||||
fixSurfacePtrs(*This);
|
||||
}
|
||||
if (This == s_compatPrimarySurface)
|
||||
if (CompatPrimarySurface::isPrimary(This))
|
||||
{
|
||||
result = RealPrimarySurface::restore();
|
||||
if (wasLost)
|
||||
@ -526,7 +517,7 @@ HRESULT STDMETHODCALLTYPE CompatDirectDrawSurface<TSurface>::SetClipper(
|
||||
LPDIRECTDRAWCLIPPER lpDDClipper)
|
||||
{
|
||||
HRESULT result = s_origVtable.SetClipper(This, lpDDClipper);
|
||||
if (This == s_compatPrimarySurface && SUCCEEDED(result))
|
||||
if (SUCCEEDED(result) && CompatPrimarySurface::isPrimary(This))
|
||||
{
|
||||
RealPrimarySurface::setClipper(lpDDClipper);
|
||||
}
|
||||
@ -538,7 +529,8 @@ HRESULT STDMETHODCALLTYPE CompatDirectDrawSurface<TSurface>::SetPalette(
|
||||
TSurface* This,
|
||||
LPDIRECTDRAWPALETTE lpDDPalette)
|
||||
{
|
||||
if (This == s_compatPrimarySurface)
|
||||
const bool isPrimary = CompatPrimarySurface::isPrimary(This);
|
||||
if (isPrimary)
|
||||
{
|
||||
if (lpDDPalette)
|
||||
{
|
||||
@ -551,7 +543,7 @@ HRESULT STDMETHODCALLTYPE CompatDirectDrawSurface<TSurface>::SetPalette(
|
||||
}
|
||||
|
||||
HRESULT result = s_origVtable.SetPalette(This, lpDDPalette);
|
||||
if (This == s_compatPrimarySurface && SUCCEEDED(result))
|
||||
if (isPrimary && SUCCEEDED(result))
|
||||
{
|
||||
CompatPrimarySurface::palette = lpDDPalette;
|
||||
RealPrimarySurface::setPalette();
|
||||
@ -563,39 +555,13 @@ template <typename TSurface>
|
||||
HRESULT STDMETHODCALLTYPE CompatDirectDrawSurface<TSurface>::Unlock(TSurface* This, TUnlockParam lpRect)
|
||||
{
|
||||
HRESULT result = s_origVtable.Unlock(This, lpRect);
|
||||
if (This == s_compatPrimarySurface && SUCCEEDED(result))
|
||||
if (SUCCEEDED(result) && CompatPrimarySurface::isPrimary(This))
|
||||
{
|
||||
RealPrimarySurface::update();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
template <typename TSurface>
|
||||
void CompatDirectDrawSurface<TSurface>::initCompatPrimarySurface()
|
||||
{
|
||||
Compat::LogEnter("CompatDirectDrawSurface::initCompatPrimarySurface");
|
||||
|
||||
IUnknown& unk = reinterpret_cast<IUnknown&>(*s_compatPrimarySurface);
|
||||
CompatDirectDrawSurface<IDirectDrawSurface>::initPrimarySurfacePtr(IID_IDirectDrawSurface, unk);
|
||||
CompatDirectDrawSurface<IDirectDrawSurface2>::initPrimarySurfacePtr(IID_IDirectDrawSurface2, unk);
|
||||
CompatDirectDrawSurface<IDirectDrawSurface3>::initPrimarySurfacePtr(IID_IDirectDrawSurface3, unk);
|
||||
CompatDirectDrawSurface<IDirectDrawSurface4>::initPrimarySurfacePtr(IID_IDirectDrawSurface4, unk);
|
||||
CompatDirectDrawSurface<IDirectDrawSurface7>::initPrimarySurfacePtr(IID_IDirectDrawSurface7, unk);
|
||||
|
||||
if (SUCCEEDED(s_origVtable.QueryInterface(
|
||||
s_compatPrimarySurface,
|
||||
IID_IDirectDrawSurface7,
|
||||
reinterpret_cast<LPVOID*>(&CompatPrimarySurface::surface))))
|
||||
{
|
||||
IReleaseNotifier* releaseNotifier = &CompatPrimarySurface::releaseNotifier;
|
||||
CompatPrimarySurface::surface->lpVtbl->SetPrivateData(CompatPrimarySurface::surface,
|
||||
IID_IReleaseNotifier, releaseNotifier, sizeof(releaseNotifier), DDSPD_IUNKNOWNPOINTER);
|
||||
CompatPrimarySurface::surface->lpVtbl->Release(CompatPrimarySurface::surface);
|
||||
}
|
||||
|
||||
Compat::LogLeave("CompatDirectDrawSurface::initCompatPrimarySurface");
|
||||
}
|
||||
|
||||
template <typename TSurface>
|
||||
void CompatDirectDrawSurface<TSurface>::restorePrimaryCaps(TDdsCaps& caps)
|
||||
{
|
||||
@ -603,9 +569,6 @@ void CompatDirectDrawSurface<TSurface>::restorePrimaryCaps(TDdsCaps& caps)
|
||||
caps.dwCaps |= DDSCAPS_PRIMARYSURFACE | DDSCAPS_VISIBLE;
|
||||
}
|
||||
|
||||
template <typename TSurface>
|
||||
TSurface* CompatDirectDrawSurface<TSurface>::s_compatPrimarySurface = nullptr;
|
||||
|
||||
template <> const IID& CompatDirectDrawSurface<IDirectDrawSurface>::s_iid = IID_IDirectDrawSurface;
|
||||
template <> const IID& CompatDirectDrawSurface<IDirectDrawSurface2>::s_iid = IID_IDirectDrawSurface2;
|
||||
template <> const IID& CompatDirectDrawSurface<IDirectDrawSurface3>::s_iid = IID_IDirectDrawSurface3;
|
||||
|
@ -21,8 +21,6 @@ public:
|
||||
TSurface*& compatSurface);
|
||||
|
||||
static void fixSurfacePtrs(TSurface& surface);
|
||||
static void initPrimarySurfacePtr(const GUID& guid, IUnknown& surface);
|
||||
static void resetPrimarySurfacePtr();
|
||||
|
||||
static HRESULT STDMETHODCALLTYPE Blt(
|
||||
TSurface* This,
|
||||
@ -66,7 +64,5 @@ public:
|
||||
static const IID& s_iid;
|
||||
|
||||
private:
|
||||
static void initCompatPrimarySurface();
|
||||
static void restorePrimaryCaps(TDdsCaps& caps);
|
||||
static TSurface* s_compatPrimarySurface;
|
||||
};
|
||||
|
@ -1,3 +1,6 @@
|
||||
#include <algorithm>
|
||||
#include <vector>
|
||||
|
||||
#include "CompatDirectDraw.h"
|
||||
#include "CompatDirectDrawSurface.h"
|
||||
#include "CompatPrimarySurface.h"
|
||||
@ -6,10 +9,22 @@
|
||||
|
||||
namespace
|
||||
{
|
||||
std::vector<void*> g_primarySurfacePtrs;
|
||||
|
||||
void addPrimary(IDirectDrawSurface7* surface, const IID& iid)
|
||||
{
|
||||
IUnknown* intf = nullptr;
|
||||
CompatDirectDrawSurface<IDirectDrawSurface7>::s_origVtable.QueryInterface(
|
||||
surface, iid, reinterpret_cast<void**>(&intf));
|
||||
g_primarySurfacePtrs.push_back(intf);
|
||||
intf->lpVtbl->Release(intf);
|
||||
}
|
||||
|
||||
void onRelease()
|
||||
{
|
||||
Compat::LogEnter("CompatPrimarySurface::onRelease");
|
||||
|
||||
g_primarySurfacePtrs.clear();
|
||||
CompatPrimarySurface::surface = nullptr;
|
||||
CompatPrimarySurface::palette = nullptr;
|
||||
CompatPrimarySurface::width = 0;
|
||||
@ -17,12 +32,6 @@ namespace
|
||||
ZeroMemory(&CompatPrimarySurface::paletteEntries, sizeof(CompatPrimarySurface::paletteEntries));
|
||||
ZeroMemory(&CompatPrimarySurface::pixelFormat, sizeof(CompatPrimarySurface::pixelFormat));
|
||||
|
||||
CompatDirectDrawSurface<IDirectDrawSurface>::resetPrimarySurfacePtr();
|
||||
CompatDirectDrawSurface<IDirectDrawSurface2>::resetPrimarySurfacePtr();
|
||||
CompatDirectDrawSurface<IDirectDrawSurface3>::resetPrimarySurfacePtr();
|
||||
CompatDirectDrawSurface<IDirectDrawSurface4>::resetPrimarySurfacePtr();
|
||||
CompatDirectDrawSurface<IDirectDrawSurface7>::resetPrimarySurfacePtr();
|
||||
|
||||
RealPrimarySurface::release();
|
||||
|
||||
Compat::LogLeave("CompatPrimarySurface::onRelease");
|
||||
@ -50,6 +59,29 @@ namespace CompatPrimarySurface
|
||||
template DisplayMode getDisplayMode(IDirectDraw4& dd);
|
||||
template DisplayMode getDisplayMode(IDirectDraw7& dd);
|
||||
|
||||
bool isPrimary(void* surfacePtr)
|
||||
{
|
||||
return g_primarySurfacePtrs.end() !=
|
||||
std::find(g_primarySurfacePtrs.begin(), g_primarySurfacePtrs.end(), surfacePtr);
|
||||
}
|
||||
|
||||
void setPrimary(IDirectDrawSurface7* surfacePtr)
|
||||
{
|
||||
surface = surfacePtr;
|
||||
|
||||
g_primarySurfacePtrs.clear();
|
||||
g_primarySurfacePtrs.push_back(surfacePtr);
|
||||
addPrimary(surfacePtr, IID_IDirectDrawSurface4);
|
||||
addPrimary(surfacePtr, IID_IDirectDrawSurface3);
|
||||
addPrimary(surfacePtr, IID_IDirectDrawSurface2);
|
||||
addPrimary(surfacePtr, IID_IDirectDrawSurface);
|
||||
|
||||
IReleaseNotifier* releaseNotifierPtr = &releaseNotifier;
|
||||
CompatDirectDrawSurface<IDirectDrawSurface7>::s_origVtable.SetPrivateData(
|
||||
surfacePtr, IID_IReleaseNotifier, releaseNotifierPtr, sizeof(releaseNotifierPtr),
|
||||
DDSPD_IUNKNOWNPOINTER);
|
||||
}
|
||||
|
||||
DisplayMode displayMode = {};
|
||||
bool isDisplayModeChanged = false;
|
||||
IDirectDrawSurface7* surface = nullptr;
|
||||
|
@ -19,6 +19,9 @@ namespace CompatPrimarySurface
|
||||
template <typename TDirectDraw>
|
||||
DisplayMode getDisplayMode(TDirectDraw& dd);
|
||||
|
||||
bool isPrimary(void* surfacePtr);
|
||||
void setPrimary(IDirectDrawSurface7* surfacePtr);
|
||||
|
||||
extern DisplayMode displayMode;
|
||||
extern bool isDisplayModeChanged;
|
||||
extern IDirectDrawSurface7* surface;
|
||||
|
@ -1,6 +0,0 @@
|
||||
#include "CompatVtable.h"
|
||||
|
||||
namespace Compat
|
||||
{
|
||||
std::map<void*, HookedMethodInfo> g_hookedMethods;
|
||||
}
|
@ -11,22 +11,6 @@
|
||||
template <typename Interface>
|
||||
using Vtable = typename std::remove_pointer<decltype(Interface::lpVtbl)>::type;
|
||||
|
||||
namespace Compat
|
||||
{
|
||||
struct HookedMethodInfo
|
||||
{
|
||||
HookedMethodInfo(void*& updatedOrigMethodPtr, std::map<void*, void*>& vtablePtrToCompatVtable)
|
||||
: updatedOrigMethodPtr(updatedOrigMethodPtr), vtablePtrToCompatVtable(vtablePtrToCompatVtable)
|
||||
{
|
||||
}
|
||||
|
||||
void*& updatedOrigMethodPtr;
|
||||
std::map<void*, void*>& vtablePtrToCompatVtable;
|
||||
};
|
||||
|
||||
extern std::map<void*, HookedMethodInfo> g_hookedMethods;
|
||||
}
|
||||
|
||||
template <typename CompatInterface, typename Interface>
|
||||
class CompatVtable
|
||||
{
|
||||
@ -65,7 +49,7 @@ private:
|
||||
else
|
||||
{
|
||||
s_threadSafeVtable.*ptr = getThreadSafeFuncPtr<MemberDataPtr, ptr>(s_compatVtable.*ptr);
|
||||
hookMethod(reinterpret_cast<void*&>(s_origVtable.*ptr), s_threadSafeVtable.*ptr);
|
||||
Compat::hookFunction(reinterpret_cast<void*&>(s_origVtable.*ptr), s_threadSafeVtable.*ptr);
|
||||
}
|
||||
}
|
||||
|
||||
@ -75,7 +59,7 @@ private:
|
||||
s_funcNames[getKey<MemberDataPtr, ptr>()] = vtableTypeName + "::" + funcName;
|
||||
|
||||
s_threadSafeVtable.*ptr = getThreadSafeFuncPtr<MemberDataPtr, ptr>(s_compatVtable.*ptr);
|
||||
hookMethod(reinterpret_cast<void*&>(s_origVtable.*ptr), s_threadSafeVtable.*ptr);
|
||||
Compat::hookFunction(reinterpret_cast<void*&>(s_origVtable.*ptr), s_threadSafeVtable.*ptr);
|
||||
|
||||
if (!(s_compatVtable.*ptr))
|
||||
{
|
||||
@ -101,23 +85,6 @@ private:
|
||||
return &threadSafeFunc<MemberDataPtr, ptr, Result, Params...>;
|
||||
}
|
||||
|
||||
void hookMethod(void*& origMethodPtr, void* newMethodPtr)
|
||||
{
|
||||
auto it = Compat::g_hookedMethods.find(origMethodPtr);
|
||||
if (it != Compat::g_hookedMethods.end())
|
||||
{
|
||||
origMethodPtr = it->second.updatedOrigMethodPtr;
|
||||
it->second.vtablePtrToCompatVtable[s_vtablePtr] = &s_compatVtable;
|
||||
}
|
||||
else
|
||||
{
|
||||
s_vtablePtrToCompatVtable[s_vtablePtr] = &s_compatVtable;
|
||||
Compat::g_hookedMethods.emplace(origMethodPtr,
|
||||
Compat::HookedMethodInfo(origMethodPtr, s_vtablePtrToCompatVtable));
|
||||
Compat::hookFunction(origMethodPtr, newMethodPtr);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename MemberDataPtr, MemberDataPtr ptr, typename Result, typename IntfPtr, typename... Params>
|
||||
static Result STDMETHODCALLTYPE threadSafeFunc(IntfPtr This, Params... params)
|
||||
{
|
||||
@ -126,17 +93,7 @@ private:
|
||||
Compat::LogEnter(s_funcNames[getKey<MemberDataPtr, ptr>()].c_str(), This, params...);
|
||||
#endif
|
||||
|
||||
Result result;
|
||||
auto it = s_vtablePtrToCompatVtable.find(This->lpVtbl);
|
||||
if (it != s_vtablePtrToCompatVtable.end())
|
||||
{
|
||||
Vtable<Interface>& compatVtable = *static_cast<Vtable<Interface>*>(it->second);
|
||||
result = (compatVtable.*ptr)(This, params...);
|
||||
}
|
||||
else
|
||||
{
|
||||
result = (s_origVtable.*ptr)(This, params...);
|
||||
}
|
||||
Result result = (s_compatVtable.*ptr)(This, params...);
|
||||
|
||||
#ifdef _DEBUG
|
||||
Compat::LogLeave(s_funcNames[getKey<MemberDataPtr, ptr>()].c_str(), This, params...) << result;
|
||||
@ -162,7 +119,6 @@ private:
|
||||
static Vtable<Interface>* s_vtablePtr;
|
||||
static Vtable<Interface> s_compatVtable;
|
||||
static Vtable<Interface> s_threadSafeVtable;
|
||||
static std::map<void*, void*> s_vtablePtrToCompatVtable;
|
||||
static std::map<std::vector<unsigned char>, std::string> s_funcNames;
|
||||
};
|
||||
|
||||
@ -178,8 +134,5 @@ Vtable<Interface> CompatVtable<CompatInterface, Interface>::s_compatVtable(Compa
|
||||
template <typename CompatInterface, typename Interface>
|
||||
Vtable<Interface> CompatVtable<CompatInterface, Interface>::s_threadSafeVtable = {};
|
||||
|
||||
template <typename CompatInterface, typename Interface>
|
||||
std::map<void*, void*> CompatVtable<CompatInterface, Interface>::s_vtablePtrToCompatVtable;
|
||||
|
||||
template <typename CompatInterface, typename Interface>
|
||||
std::map<std::vector<unsigned char>, std::string> CompatVtable<CompatInterface, Interface>::s_funcNames;
|
||||
|
@ -194,7 +194,6 @@
|
||||
<ClCompile Include="CompatGdiWinProc.cpp" />
|
||||
<ClCompile Include="CompatPaletteConverter.cpp" />
|
||||
<ClCompile Include="CompatRegistry.cpp" />
|
||||
<ClCompile Include="CompatVtable.cpp" />
|
||||
<ClCompile Include="DDrawLog.cpp" />
|
||||
<ClCompile Include="DllMain.cpp" />
|
||||
<ClCompile Include="CompatPrimarySurface.cpp" />
|
||||
|
@ -137,9 +137,6 @@
|
||||
<ClCompile Include="IReleaseNotifier.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="CompatVtable.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="CompatDirectDraw.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
|
@ -1,7 +1,7 @@
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
|
||||
#include <map>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include <Windows.h>
|
||||
#include <detours.h>
|
||||
@ -11,7 +11,13 @@
|
||||
|
||||
namespace
|
||||
{
|
||||
std::vector<std::pair<void*, void*>> g_hookedFunctions;
|
||||
struct HookedFunctionInfo
|
||||
{
|
||||
void* trampoline;
|
||||
void* newFunction;
|
||||
};
|
||||
|
||||
std::map<void*, HookedFunctionInfo> g_hookedFunctions;
|
||||
|
||||
FARPROC getProcAddress(HMODULE module, const char* procName)
|
||||
{
|
||||
@ -53,6 +59,15 @@ namespace
|
||||
|
||||
void hookFunction(const char* funcName, void*& origFuncPtr, void* newFuncPtr)
|
||||
{
|
||||
const auto it = g_hookedFunctions.find(origFuncPtr);
|
||||
if (it != g_hookedFunctions.end())
|
||||
{
|
||||
origFuncPtr = it->second.trampoline;
|
||||
return;
|
||||
}
|
||||
|
||||
void* const hookedFuncPtr = origFuncPtr;
|
||||
|
||||
DetourTransactionBegin();
|
||||
const bool attachSuccessful = NO_ERROR == DetourAttach(&origFuncPtr, newFuncPtr);
|
||||
const bool commitSuccessful = NO_ERROR == DetourTransactionCommit();
|
||||
@ -69,7 +84,7 @@ namespace
|
||||
return;
|
||||
}
|
||||
|
||||
g_hookedFunctions.push_back(std::make_pair(origFuncPtr, newFuncPtr));
|
||||
g_hookedFunctions[hookedFuncPtr] = { origFuncPtr, newFuncPtr };
|
||||
}
|
||||
}
|
||||
|
||||
@ -79,7 +94,7 @@ namespace Compat
|
||||
{
|
||||
::hookFunction(nullptr, origFuncPtr, newFuncPtr);
|
||||
}
|
||||
|
||||
|
||||
void hookFunction(const char* moduleName, const char* funcName, void*& origFuncPtr, void* newFuncPtr)
|
||||
{
|
||||
FARPROC procAddr = getProcAddress(GetModuleHandle(moduleName), funcName);
|
||||
@ -98,7 +113,7 @@ namespace Compat
|
||||
for (auto& hookedFunc : g_hookedFunctions)
|
||||
{
|
||||
DetourTransactionBegin();
|
||||
DetourDetach(&hookedFunc.first, hookedFunc.second);
|
||||
DetourDetach(&hookedFunc.second.trampoline, hookedFunc.second.newFunction);
|
||||
DetourTransactionCommit();
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user