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

Removed dependency on context handle for driver hooks

Potential fix for issue #55.
This commit is contained in:
narzoul 2019-09-02 22:29:39 +02:00
parent 81c2748027
commit 2a129c41c9
8 changed files with 27 additions and 18 deletions

View File

@ -14,8 +14,15 @@
} \ } \
} }
template <typename Vtable, int instanceId = 0> template <typename Vtable>
class CompatVtableInstance class CompatVtableInstanceBase
{
public:
static Vtable* s_origVtablePtr;
};
template <typename Vtable, int instanceId = -1>
class CompatVtableInstance : public CompatVtableInstanceBase<Vtable>
{ {
public: public:
static void hookVtable(const Vtable& origVtable, Vtable compatVtable) static void hookVtable(const Vtable& origVtable, Vtable compatVtable)
@ -33,10 +40,15 @@ public:
origVtable, s_origVtable, LogWrapperVisitor<Vtable, instanceId>::s_compatVtable); origVtable, s_origVtable, LogWrapperVisitor<Vtable, instanceId>::s_compatVtable);
forEach<Vtable>(vtableUpdateVisitor); forEach<Vtable>(vtableUpdateVisitor);
#endif #endif
s_origVtablePtr = &s_origVtable;
} }
static Vtable s_origVtable; static Vtable s_origVtable;
}; };
template <typename Vtable>
Vtable* CompatVtableInstanceBase<Vtable>::s_origVtablePtr = nullptr;
template <typename Vtable, int instanceId> template <typename Vtable, int instanceId>
Vtable CompatVtableInstance<Vtable, instanceId>::s_origVtable = {}; Vtable CompatVtableInstance<Vtable, instanceId>::s_origVtable = {};

View File

@ -62,6 +62,7 @@ private:
static Result STDMETHODCALLTYPE threadSafeFunc(Params... params) static Result STDMETHODCALLTYPE threadSafeFunc(Params... params)
{ {
ScopedVtableFuncLock<Vtable> lock; ScopedVtableFuncLock<Vtable> lock;
CompatVtableInstanceBase<Vtable>::s_origVtablePtr = &CompatVtableInstance<Vtable, instanceId>::s_origVtable;
return (s_compatVtable.*ptr)(params...); return (s_compatVtable.*ptr)(params...);
} }

View File

@ -14,7 +14,7 @@ namespace D3dDdi
getCaps.Type = D3DDDICAPS_GETD3D7CAPS; getCaps.Type = D3DDDICAPS_GETD3D7CAPS;
getCaps.pData = &m_d3dExtendedCaps; getCaps.pData = &m_d3dExtendedCaps;
getCaps.DataSize = sizeof(m_d3dExtendedCaps); getCaps.DataSize = sizeof(m_d3dExtendedCaps);
D3dDdi::AdapterFuncs::s_origVtables.at(adapter).pfnGetCaps(adapter, &getCaps); D3dDdi::AdapterFuncs::s_origVtablePtr->pfnGetCaps(adapter, &getCaps);
} }
} }

View File

@ -9,10 +9,9 @@ namespace
{ {
HRESULT APIENTRY closeAdapter(HANDLE hAdapter) HRESULT APIENTRY closeAdapter(HANDLE hAdapter)
{ {
HRESULT result = D3dDdi::AdapterFuncs::s_origVtables.at(hAdapter).pfnCloseAdapter(hAdapter); HRESULT result = D3dDdi::AdapterFuncs::s_origVtablePtr->pfnCloseAdapter(hAdapter);
if (SUCCEEDED(result)) if (SUCCEEDED(result))
{ {
D3dDdi::AdapterFuncs::s_origVtables.erase(hAdapter);
D3dDdi::Adapter::remove(hAdapter); D3dDdi::Adapter::remove(hAdapter);
} }
return result; return result;
@ -21,12 +20,11 @@ namespace
HRESULT APIENTRY createDevice(HANDLE hAdapter, D3DDDIARG_CREATEDEVICE* pCreateData) HRESULT APIENTRY createDevice(HANDLE hAdapter, D3DDDIARG_CREATEDEVICE* pCreateData)
{ {
D3dDdi::DeviceCallbacks::hookVtable(pCreateData->pCallbacks); D3dDdi::DeviceCallbacks::hookVtable(pCreateData->pCallbacks);
HRESULT result = D3dDdi::AdapterFuncs::s_origVtables.at(hAdapter).pfnCreateDevice( HRESULT result = D3dDdi::AdapterFuncs::s_origVtablePtr->pfnCreateDevice(hAdapter, pCreateData);
hAdapter, pCreateData);
if (SUCCEEDED(result)) if (SUCCEEDED(result))
{ {
D3dDdi::DeviceFuncs::hookVtable( D3dDdi::DeviceFuncs::hookVtable(
D3dDdi::Adapter::get(hAdapter).getModule(), pCreateData->hDevice, pCreateData->pDeviceFuncs); D3dDdi::Adapter::get(hAdapter).getModule(), pCreateData->pDeviceFuncs);
D3dDdi::DeviceFuncs::onCreateDevice(hAdapter, pCreateData->hDevice); D3dDdi::DeviceFuncs::onCreateDevice(hAdapter, pCreateData->hDevice);
} }
return result; return result;
@ -34,7 +32,7 @@ namespace
HRESULT APIENTRY getCaps(HANDLE hAdapter, const D3DDDIARG_GETCAPS* pData) HRESULT APIENTRY getCaps(HANDLE hAdapter, const D3DDDIARG_GETCAPS* pData)
{ {
HRESULT result = D3dDdi::AdapterFuncs::s_origVtables.at(hAdapter).pfnGetCaps(hAdapter, pData); HRESULT result = D3dDdi::AdapterFuncs::s_origVtablePtr->pfnGetCaps(hAdapter, pData);
if (SUCCEEDED(result) && D3DDDICAPS_DDRAW == pData->Type) if (SUCCEEDED(result) && D3DDDICAPS_DDRAW == pData->Type)
{ {
static_cast<DDRAW_CAPS*>(pData->pData)->FxCaps = static_cast<DDRAW_CAPS*>(pData->pData)->FxCaps =

View File

@ -13,7 +13,7 @@ namespace D3dDdi
class D3dDdiVtable class D3dDdiVtable
{ {
public: public:
static void hookVtable(HMODULE module, HANDLE context, const Vtable* vtable) static void hookVtable(HMODULE module, const Vtable* vtable)
{ {
if (!vtable) if (!vtable)
{ {
@ -25,12 +25,10 @@ namespace D3dDdi
{ {
it = s_origModuleVtables.emplace(module, hookVtableInstance(*vtable, InstanceId<0>())).first; it = s_origModuleVtables.emplace(module, hookVtableInstance(*vtable, InstanceId<0>())).first;
} }
s_origVtables.emplace(context, it->second);
} }
static std::map<HMODULE, const Vtable&> s_origModuleVtables; static std::map<HMODULE, const Vtable&> s_origModuleVtables;
static std::map<HANDLE, const Vtable&> s_origVtables; static Vtable*& s_origVtablePtr;
private: private:
template <int instanceId> struct InstanceId {}; template <int instanceId> struct InstanceId {};
@ -66,5 +64,5 @@ namespace D3dDdi
std::map<HMODULE, const Vtable&> D3dDdiVtable<Vtable>::s_origModuleVtables; std::map<HMODULE, const Vtable&> D3dDdiVtable<Vtable>::s_origModuleVtables;
template <typename Vtable> template <typename Vtable>
std::map<HANDLE, const Vtable&> D3dDdiVtable<Vtable>::s_origVtables; Vtable*& D3dDdiVtable<Vtable>::s_origVtablePtr = CompatVtableInstanceBase<Vtable>::s_origVtablePtr;
} }

View File

@ -17,7 +17,7 @@ namespace
namespace D3dDdi namespace D3dDdi
{ {
Device::Device(HANDLE adapter, HANDLE device) Device::Device(HANDLE adapter, HANDLE device)
: m_origVtable(DeviceFuncs::s_origVtables.at(device)) : m_origVtable(*DeviceFuncs::s_origVtablePtr)
, m_adapter(Adapter::get(adapter)) , m_adapter(Adapter::get(adapter))
, m_device(device) , m_device(device)
, m_renderTarget(nullptr) , m_renderTarget(nullptr)

View File

@ -11,10 +11,9 @@ namespace
HRESULT APIENTRY destroyDevice(HANDLE hDevice) HRESULT APIENTRY destroyDevice(HANDLE hDevice)
{ {
HRESULT result = D3dDdi::DeviceFuncs::s_origVtables.at(hDevice).pfnDestroyDevice(hDevice); HRESULT result = D3dDdi::DeviceFuncs::s_origVtablePtr->pfnDestroyDevice(hDevice);
if (SUCCEEDED(result)) if (SUCCEEDED(result))
{ {
D3dDdi::DeviceFuncs::s_origVtables.erase(hDevice);
D3dDdi::Device::remove(hDevice); D3dDdi::Device::remove(hDevice);
} }
return result; return result;

View File

@ -47,6 +47,7 @@ namespace
HRESULT APIENTRY openAdapter(D3DDDIARG_OPENADAPTER* pOpenData) HRESULT APIENTRY openAdapter(D3DDDIARG_OPENADAPTER* pOpenData)
{ {
D3dDdi::ScopedCriticalSection lock;
LOG_FUNC("openAdapter", pOpenData); LOG_FUNC("openAdapter", pOpenData);
D3dDdi::AdapterCallbacks::hookVtable(pOpenData->pAdapterCallbacks); D3dDdi::AdapterCallbacks::hookVtable(pOpenData->pAdapterCallbacks);
HRESULT result = g_origOpenAdapter(pOpenData); HRESULT result = g_origOpenAdapter(pOpenData);
@ -59,7 +60,7 @@ namespace
hookedUmdFileNames.insert(g_hookedUmdFileName); hookedUmdFileNames.insert(g_hookedUmdFileName);
} }
g_ddiVersion = min(pOpenData->Version, pOpenData->DriverVersion); g_ddiVersion = min(pOpenData->Version, pOpenData->DriverVersion);
D3dDdi::AdapterFuncs::hookVtable(g_hookedUmdModule, pOpenData->hAdapter, pOpenData->pAdapterFuncs); D3dDdi::AdapterFuncs::hookVtable(g_hookedUmdModule, pOpenData->pAdapterFuncs);
D3dDdi::AdapterFuncs::onOpenAdapter(pOpenData->hAdapter, g_hookedUmdModule); D3dDdi::AdapterFuncs::onOpenAdapter(pOpenData->hAdapter, g_hookedUmdModule);
} }
return LOG_RESULT(result); return LOG_RESULT(result);