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