mirror of
https://github.com/narzoul/DDrawCompat
synced 2024-12-30 08:55:36 +01:00
Hooked Direct3D display driver interfaces
This commit is contained in:
parent
1adb27ead4
commit
12ad482d29
5
DDrawCompat/CompatD3dDdiAdapterCallbacks.cpp
Normal file
5
DDrawCompat/CompatD3dDdiAdapterCallbacks.cpp
Normal file
@ -0,0 +1,5 @@
|
||||
#include "CompatD3dDdiAdapterCallbacks.h"
|
||||
|
||||
void CompatD3dDdiAdapterCallbacks::setCompatVtable(D3DDDI_ADAPTERCALLBACKS& /*vtable*/)
|
||||
{
|
||||
}
|
11
DDrawCompat/CompatD3dDdiAdapterCallbacks.h
Normal file
11
DDrawCompat/CompatD3dDdiAdapterCallbacks.h
Normal file
@ -0,0 +1,11 @@
|
||||
#pragma once
|
||||
|
||||
#include "CompatVtable.h"
|
||||
#include "D3dDdiAdapterCallbacksVisitor.h"
|
||||
|
||||
class CompatD3dDdiAdapterCallbacks :
|
||||
public CompatVtable<CompatD3dDdiAdapterCallbacks, D3dDdiAdapterCallbacksIntf>
|
||||
{
|
||||
public:
|
||||
static void setCompatVtable(D3DDDI_ADAPTERCALLBACKS& vtable);
|
||||
};
|
22
DDrawCompat/CompatD3dDdiAdapterFuncs.cpp
Normal file
22
DDrawCompat/CompatD3dDdiAdapterFuncs.cpp
Normal file
@ -0,0 +1,22 @@
|
||||
#include "CompatD3dDdiAdapterFuncs.h"
|
||||
#include "CompatD3dDdiDeviceCallbacks.h"
|
||||
#include "CompatD3dDdiDeviceFuncs.h"
|
||||
|
||||
namespace
|
||||
{
|
||||
HRESULT APIENTRY createDevice(HANDLE hAdapter, D3DDDIARG_CREATEDEVICE* pCreateData)
|
||||
{
|
||||
CompatD3dDdiDeviceCallbacks::hookVtable(pCreateData->pCallbacks);
|
||||
HRESULT result = CompatD3dDdiAdapterFuncs::s_origVtable.pfnCreateDevice(hAdapter, pCreateData);
|
||||
if (SUCCEEDED(result))
|
||||
{
|
||||
CompatD3dDdiDeviceFuncs::hookVtable(pCreateData->pDeviceFuncs);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
void CompatD3dDdiAdapterFuncs::setCompatVtable(D3DDDI_ADAPTERFUNCS& vtable)
|
||||
{
|
||||
vtable.pfnCreateDevice = &createDevice;
|
||||
}
|
10
DDrawCompat/CompatD3dDdiAdapterFuncs.h
Normal file
10
DDrawCompat/CompatD3dDdiAdapterFuncs.h
Normal file
@ -0,0 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
#include "CompatVtable.h"
|
||||
#include "D3dDdiAdapterFuncsVisitor.h"
|
||||
|
||||
class CompatD3dDdiAdapterFuncs : public CompatVtable<CompatD3dDdiAdapterFuncs, D3dDdiAdapterFuncsIntf>
|
||||
{
|
||||
public:
|
||||
static void setCompatVtable(D3DDDI_ADAPTERFUNCS& vtable);
|
||||
};
|
5
DDrawCompat/CompatD3dDdiDeviceCallbacks.cpp
Normal file
5
DDrawCompat/CompatD3dDdiDeviceCallbacks.cpp
Normal file
@ -0,0 +1,5 @@
|
||||
#include "CompatD3dDdiDeviceCallbacks.h"
|
||||
|
||||
void CompatD3dDdiDeviceCallbacks::setCompatVtable(D3DDDI_DEVICECALLBACKS& /*vtable*/)
|
||||
{
|
||||
}
|
10
DDrawCompat/CompatD3dDdiDeviceCallbacks.h
Normal file
10
DDrawCompat/CompatD3dDdiDeviceCallbacks.h
Normal file
@ -0,0 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
#include "CompatVtable.h"
|
||||
#include "D3dDdiDeviceCallbacksVisitor.h"
|
||||
|
||||
class CompatD3dDdiDeviceCallbacks : public CompatVtable<CompatD3dDdiDeviceCallbacks, D3dDdiDeviceCallbacksIntf>
|
||||
{
|
||||
public:
|
||||
static void setCompatVtable(D3DDDI_DEVICECALLBACKS& vtable);
|
||||
};
|
5
DDrawCompat/CompatD3dDdiDeviceFuncs.cpp
Normal file
5
DDrawCompat/CompatD3dDdiDeviceFuncs.cpp
Normal file
@ -0,0 +1,5 @@
|
||||
#include "CompatD3dDdiDeviceFuncs.h"
|
||||
|
||||
void CompatD3dDdiDeviceFuncs::setCompatVtable(D3DDDI_DEVICEFUNCS& /*vtable*/)
|
||||
{
|
||||
}
|
10
DDrawCompat/CompatD3dDdiDeviceFuncs.h
Normal file
10
DDrawCompat/CompatD3dDdiDeviceFuncs.h
Normal file
@ -0,0 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
#include "CompatVtable.h"
|
||||
#include "D3dDdiDeviceFuncsVisitor.h"
|
||||
|
||||
class CompatD3dDdiDeviceFuncs : public CompatVtable<CompatD3dDdiDeviceFuncs, D3dDdiDeviceFuncsIntf>
|
||||
{
|
||||
public:
|
||||
static void setCompatVtable(D3DDDI_DEVICEFUNCS& vtable);
|
||||
};
|
@ -5,6 +5,7 @@
|
||||
#include <vector>
|
||||
|
||||
#include "DDrawLog.h"
|
||||
#include "DDrawProcs.h"
|
||||
#include "DDrawVtableVisitor.h"
|
||||
#include "Hook.h"
|
||||
|
||||
@ -29,17 +30,14 @@ template <typename CompatInterface, typename Interface>
|
||||
class CompatVtable : public CompatVtableBase<Interface>
|
||||
{
|
||||
public:
|
||||
static void hookVtable(Interface& intf)
|
||||
static void hookVtable(const Vtable<Interface>* vtable)
|
||||
{
|
||||
static bool isInitialized = false;
|
||||
if (!isInitialized)
|
||||
if (!isInitialized && vtable)
|
||||
{
|
||||
isInitialized = true;
|
||||
|
||||
s_vtablePtr = intf.lpVtbl;
|
||||
s_origVtable = *intf.lpVtbl;
|
||||
|
||||
InitVisitor visitor;
|
||||
InitVisitor visitor(*vtable);
|
||||
forEach<Vtable<Interface>>(visitor);
|
||||
}
|
||||
}
|
||||
@ -48,9 +46,13 @@ private:
|
||||
class InitVisitor
|
||||
{
|
||||
public:
|
||||
InitVisitor(const Vtable<Interface>& origVtable) : m_origVtable(origVtable) {}
|
||||
|
||||
template <typename MemberDataPtr, MemberDataPtr ptr>
|
||||
void visit()
|
||||
{
|
||||
s_origVtable.*ptr = m_origVtable.*ptr;
|
||||
|
||||
if (!(s_compatVtable.*ptr))
|
||||
{
|
||||
s_threadSafeVtable.*ptr = s_origVtable.*ptr;
|
||||
@ -66,8 +68,11 @@ private:
|
||||
template <typename MemberDataPtr, MemberDataPtr ptr>
|
||||
void visitDebug(const std::string& vtableTypeName, const std::string& funcName)
|
||||
{
|
||||
Compat::Log() << "Hooking function: " << vtableTypeName << "::" << funcName;
|
||||
s_funcNames[getKey<MemberDataPtr, ptr>()] = vtableTypeName + "::" + funcName;
|
||||
|
||||
s_origVtable.*ptr = m_origVtable.*ptr;
|
||||
|
||||
s_threadSafeVtable.*ptr = getThreadSafeFuncPtr<MemberDataPtr, ptr>(s_compatVtable.*ptr);
|
||||
Compat::hookFunction(reinterpret_cast<void*&>(s_origVtable.*ptr), s_threadSafeVtable.*ptr);
|
||||
|
||||
@ -95,22 +100,46 @@ private:
|
||||
return &threadSafeFunc<MemberDataPtr, ptr, Result, Params...>;
|
||||
}
|
||||
|
||||
template <typename MemberDataPtr, MemberDataPtr ptr, typename Result, typename IntfPtr, typename... Params>
|
||||
static Result STDMETHODCALLTYPE threadSafeFunc(IntfPtr This, Params... params)
|
||||
template <typename MemberDataPtr, MemberDataPtr ptr, typename... Params>
|
||||
static FuncPtr<void, Params...> getThreadSafeFuncPtr(FuncPtr<void, Params...>)
|
||||
{
|
||||
return &threadSafeFunc<MemberDataPtr, ptr, Params...>;
|
||||
}
|
||||
|
||||
template <typename MemberDataPtr, MemberDataPtr ptr, typename Result, typename... Params>
|
||||
static Result STDMETHODCALLTYPE threadSafeFunc(Params... params)
|
||||
{
|
||||
Compat::origProcs.AcquireDDThreadLock();
|
||||
#ifdef _DEBUG
|
||||
Compat::LogEnter(s_funcNames[getKey<MemberDataPtr, ptr>()].c_str(), This, params...);
|
||||
Compat::LogEnter(s_funcNames[getKey<MemberDataPtr, ptr>()].c_str(), params...);
|
||||
#endif
|
||||
|
||||
Result result = (s_compatVtable.*ptr)(This, params...);
|
||||
Result result = (s_compatVtable.*ptr)(params...);
|
||||
|
||||
#ifdef _DEBUG
|
||||
Compat::LogLeave(s_funcNames[getKey<MemberDataPtr, ptr>()].c_str(), This, params...) << result;
|
||||
Compat::LogLeave(s_funcNames[getKey<MemberDataPtr, ptr>()].c_str(), params...) << result;
|
||||
#endif
|
||||
Compat::origProcs.ReleaseDDThreadLock();
|
||||
return result;
|
||||
}
|
||||
|
||||
template <typename MemberDataPtr, MemberDataPtr ptr, typename... Params>
|
||||
static void STDMETHODCALLTYPE threadSafeFunc(Params... params)
|
||||
{
|
||||
Compat::origProcs.AcquireDDThreadLock();
|
||||
#ifdef _DEBUG
|
||||
Compat::LogEnter(s_funcNames[getKey<MemberDataPtr, ptr>()].c_str(), params...);
|
||||
#endif
|
||||
|
||||
(s_compatVtable.*ptr)(params...);
|
||||
|
||||
#ifdef _DEBUG
|
||||
Compat::LogLeave(s_funcNames[getKey<MemberDataPtr, ptr>()].c_str(), params...);
|
||||
#endif
|
||||
Compat::origProcs.ReleaseDDThreadLock();
|
||||
}
|
||||
|
||||
const Vtable<Interface>& m_origVtable;
|
||||
};
|
||||
|
||||
static Vtable<Interface> createCompatVtable()
|
||||
@ -126,7 +155,6 @@ private:
|
||||
return vtable;
|
||||
}
|
||||
|
||||
static Vtable<Interface>* s_vtablePtr;
|
||||
static Vtable<Interface> s_compatVtable;
|
||||
static Vtable<Interface> s_threadSafeVtable;
|
||||
static std::map<std::vector<unsigned char>, std::string> s_funcNames;
|
||||
@ -136,10 +164,7 @@ template <typename Interface>
|
||||
Vtable<Interface> CompatVtableBase<Interface>::s_origVtable = {};
|
||||
|
||||
template <typename CompatInterface, typename Interface>
|
||||
Vtable<Interface>* CompatVtable<CompatInterface, Interface>::s_vtablePtr = nullptr;
|
||||
|
||||
template <typename CompatInterface, typename Interface>
|
||||
Vtable<Interface> CompatVtable<CompatInterface, Interface>::s_compatVtable(CompatInterface::getCompatVtable());
|
||||
Vtable<Interface> CompatVtable<CompatInterface, Interface>::s_compatVtable(getCompatVtable());
|
||||
|
||||
template <typename CompatInterface, typename Interface>
|
||||
Vtable<Interface> CompatVtable<CompatInterface, Interface>::s_threadSafeVtable = {};
|
||||
|
24
DDrawCompat/D3dDdiAdapterCallbacksVisitor.h
Normal file
24
DDrawCompat/D3dDdiAdapterCallbacksVisitor.h
Normal file
@ -0,0 +1,24 @@
|
||||
#pragma once
|
||||
|
||||
#define CINTERFACE
|
||||
|
||||
#include <d3d.h>
|
||||
#include <d3dumddi.h>
|
||||
|
||||
#include "DDrawVtableVisitor.h"
|
||||
|
||||
struct D3dDdiAdapterCallbacksIntf
|
||||
{
|
||||
D3DDDI_ADAPTERCALLBACKS* lpVtbl;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct DDrawVtableForEach<D3DDDI_ADAPTERCALLBACKS>
|
||||
{
|
||||
template <typename Vtable, typename Visitor>
|
||||
static void forEach(Visitor& visitor)
|
||||
{
|
||||
DD_VISIT(pfnQueryAdapterInfoCb);
|
||||
// DD_VISIT(pfnGetMultisampleMethodListCb); -- not set by ddraw, potentially garbage
|
||||
}
|
||||
};
|
25
DDrawCompat/D3dDdiAdapterFuncsVisitor.h
Normal file
25
DDrawCompat/D3dDdiAdapterFuncsVisitor.h
Normal file
@ -0,0 +1,25 @@
|
||||
#pragma once
|
||||
|
||||
#define CINTERFACE
|
||||
|
||||
#include <d3d.h>
|
||||
#include <d3dumddi.h>
|
||||
|
||||
#include "DDrawVtableVisitor.h"
|
||||
|
||||
struct D3dDdiAdapterFuncsIntf
|
||||
{
|
||||
D3DDDI_ADAPTERFUNCS* lpVtbl;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct DDrawVtableForEach<D3DDDI_ADAPTERFUNCS>
|
||||
{
|
||||
template <typename Vtable, typename Visitor>
|
||||
static void forEach(Visitor& visitor)
|
||||
{
|
||||
DD_VISIT(pfnGetCaps);
|
||||
DD_VISIT(pfnCreateDevice);
|
||||
DD_VISIT(pfnCloseAdapter);
|
||||
}
|
||||
};
|
85
DDrawCompat/D3dDdiDeviceCallbacksVisitor.h
Normal file
85
DDrawCompat/D3dDdiDeviceCallbacksVisitor.h
Normal file
@ -0,0 +1,85 @@
|
||||
#pragma once
|
||||
|
||||
#define CINTERFACE
|
||||
|
||||
#include <d3d.h>
|
||||
#include <d3dumddi.h>
|
||||
|
||||
#include "D3dDdiHooks.h"
|
||||
#include "DDrawVtableVisitor.h"
|
||||
|
||||
struct D3dDdiDeviceCallbacksIntf
|
||||
{
|
||||
D3DDDI_DEVICECALLBACKS* lpVtbl;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct DDrawVtableForEach<D3DDDI_DEVICECALLBACKS>
|
||||
{
|
||||
template <typename Vtable, typename Visitor>
|
||||
static void forEach(Visitor& visitor)
|
||||
{
|
||||
DD_VISIT(pfnAllocateCb);
|
||||
DD_VISIT(pfnDeallocateCb);
|
||||
DD_VISIT(pfnSetPriorityCb);
|
||||
DD_VISIT(pfnQueryResidencyCb);
|
||||
// DD_VISIT(pfnSetDisplayModeCb); -- not set by ddraw
|
||||
DD_VISIT(pfnPresentCb);
|
||||
DD_VISIT(pfnRenderCb);
|
||||
DD_VISIT(pfnLockCb);
|
||||
DD_VISIT(pfnUnlockCb);
|
||||
DD_VISIT(pfnEscapeCb);
|
||||
DD_VISIT(pfnCreateOverlayCb);
|
||||
DD_VISIT(pfnUpdateOverlayCb);
|
||||
DD_VISIT(pfnFlipOverlayCb);
|
||||
DD_VISIT(pfnDestroyOverlayCb);
|
||||
DD_VISIT(pfnCreateContextCb);
|
||||
DD_VISIT(pfnDestroyContextCb);
|
||||
DD_VISIT(pfnCreateSynchronizationObjectCb);
|
||||
DD_VISIT(pfnDestroySynchronizationObjectCb);
|
||||
DD_VISIT(pfnWaitForSynchronizationObjectCb);
|
||||
DD_VISIT(pfnSignalSynchronizationObjectCb);
|
||||
// DD_VISIT(pfnSetAsyncCallbacksCb); -- not set by ddraw
|
||||
DD_VISIT(pfnSetDisplayPrivateDriverFormatCb);
|
||||
|
||||
if (D3dDdiHooks::getDdiVersion() >= D3D_UMD_INTERFACE_VERSION_WIN8)
|
||||
{
|
||||
DD_VISIT(pfnOfferAllocationsCb);
|
||||
DD_VISIT(pfnReclaimAllocationsCb);
|
||||
DD_VISIT(pfnCreateSynchronizationObject2Cb);
|
||||
DD_VISIT(pfnWaitForSynchronizationObject2Cb);
|
||||
DD_VISIT(pfnSignalSynchronizationObject2Cb);
|
||||
// DD_VISIT(pfnPresentMultiPlaneOverlayCb); -- not set by ddraw
|
||||
}
|
||||
|
||||
if (D3dDdiHooks::getDdiVersion() >= D3D_UMD_INTERFACE_VERSION_WDDM1_3)
|
||||
{
|
||||
// DD_VISIT(pfnLogUMDMarkerCb); -- not set by ddraw
|
||||
}
|
||||
|
||||
if (D3dDdiHooks::getDdiVersion() >= D3D_UMD_INTERFACE_VERSION_WDDM2_0)
|
||||
{
|
||||
DD_VISIT(pfnMakeResidentCb);
|
||||
DD_VISIT(pfnEvictCb);
|
||||
DD_VISIT(pfnWaitForSynchronizationObjectFromCpuCb);
|
||||
DD_VISIT(pfnSignalSynchronizationObjectFromCpuCb);
|
||||
DD_VISIT(pfnWaitForSynchronizationObjectFromGpuCb);
|
||||
DD_VISIT(pfnSignalSynchronizationObjectFromGpuCb);
|
||||
DD_VISIT(pfnCreatePagingQueueCb);
|
||||
DD_VISIT(pfnDestroyPagingQueueCb);
|
||||
DD_VISIT(pfnLock2Cb);
|
||||
DD_VISIT(pfnUnlock2Cb);
|
||||
DD_VISIT(pfnInvalidateCacheCb);
|
||||
DD_VISIT(pfnReserveGpuVirtualAddressCb);
|
||||
DD_VISIT(pfnMapGpuVirtualAddressCb);
|
||||
DD_VISIT(pfnFreeGpuVirtualAddressCb);
|
||||
DD_VISIT(pfnUpdateGpuVirtualAddressCb);
|
||||
DD_VISIT(pfnCreateContextVirtualCb);
|
||||
DD_VISIT(pfnSubmitCommandCb);
|
||||
DD_VISIT(pfnDeallocate2Cb);
|
||||
DD_VISIT(pfnSignalSynchronizationObjectFromGpu2Cb);
|
||||
DD_VISIT(pfnReclaimAllocations2Cb);
|
||||
DD_VISIT(pfnGetResourcePresentPrivateDriverDataCb);
|
||||
}
|
||||
}
|
||||
};
|
181
DDrawCompat/D3dDdiDeviceFuncsVisitor.h
Normal file
181
DDrawCompat/D3dDdiDeviceFuncsVisitor.h
Normal file
@ -0,0 +1,181 @@
|
||||
#pragma once
|
||||
|
||||
#define CINTERFACE
|
||||
|
||||
#include <d3d.h>
|
||||
#include <d3dumddi.h>
|
||||
|
||||
#include "D3dDdiHooks.h"
|
||||
#include "DDrawVtableVisitor.h"
|
||||
|
||||
struct D3dDdiDeviceFuncsIntf
|
||||
{
|
||||
D3DDDI_DEVICEFUNCS* lpVtbl;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct DDrawVtableForEach<D3DDDI_DEVICEFUNCS>
|
||||
{
|
||||
template <typename Vtable, typename Visitor>
|
||||
static void forEach(Visitor& visitor)
|
||||
{
|
||||
DD_VISIT(pfnSetRenderState);
|
||||
DD_VISIT(pfnUpdateWInfo);
|
||||
DD_VISIT(pfnValidateDevice);
|
||||
DD_VISIT(pfnSetTextureStageState);
|
||||
DD_VISIT(pfnSetTexture);
|
||||
DD_VISIT(pfnSetPixelShader);
|
||||
DD_VISIT(pfnSetPixelShaderConst);
|
||||
DD_VISIT(pfnSetStreamSourceUm);
|
||||
DD_VISIT(pfnSetIndices);
|
||||
DD_VISIT(pfnSetIndicesUm);
|
||||
DD_VISIT(pfnDrawPrimitive);
|
||||
DD_VISIT(pfnDrawIndexedPrimitive);
|
||||
DD_VISIT(pfnDrawRectPatch);
|
||||
DD_VISIT(pfnDrawTriPatch);
|
||||
DD_VISIT(pfnDrawPrimitive2);
|
||||
DD_VISIT(pfnDrawIndexedPrimitive2);
|
||||
DD_VISIT(pfnVolBlt);
|
||||
DD_VISIT(pfnBufBlt);
|
||||
DD_VISIT(pfnTexBlt);
|
||||
DD_VISIT(pfnStateSet);
|
||||
DD_VISIT(pfnSetPriority);
|
||||
DD_VISIT(pfnClear);
|
||||
DD_VISIT(pfnUpdatePalette);
|
||||
DD_VISIT(pfnSetPalette);
|
||||
DD_VISIT(pfnSetVertexShaderConst);
|
||||
DD_VISIT(pfnMultiplyTransform);
|
||||
DD_VISIT(pfnSetTransform);
|
||||
DD_VISIT(pfnSetViewport);
|
||||
DD_VISIT(pfnSetZRange);
|
||||
DD_VISIT(pfnSetMaterial);
|
||||
DD_VISIT(pfnSetLight);
|
||||
DD_VISIT(pfnCreateLight);
|
||||
DD_VISIT(pfnDestroyLight);
|
||||
DD_VISIT(pfnSetClipPlane);
|
||||
DD_VISIT(pfnGetInfo);
|
||||
DD_VISIT(pfnLock);
|
||||
DD_VISIT(pfnUnlock);
|
||||
DD_VISIT(pfnCreateResource);
|
||||
DD_VISIT(pfnDestroyResource);
|
||||
DD_VISIT(pfnSetDisplayMode);
|
||||
DD_VISIT(pfnPresent);
|
||||
DD_VISIT(pfnFlush);
|
||||
DD_VISIT(pfnCreateVertexShaderFunc);
|
||||
DD_VISIT(pfnDeleteVertexShaderFunc);
|
||||
DD_VISIT(pfnSetVertexShaderFunc);
|
||||
DD_VISIT(pfnCreateVertexShaderDecl);
|
||||
DD_VISIT(pfnDeleteVertexShaderDecl);
|
||||
DD_VISIT(pfnSetVertexShaderDecl);
|
||||
DD_VISIT(pfnSetVertexShaderConstI);
|
||||
DD_VISIT(pfnSetVertexShaderConstB);
|
||||
DD_VISIT(pfnSetScissorRect);
|
||||
DD_VISIT(pfnSetStreamSource);
|
||||
DD_VISIT(pfnSetStreamSourceFreq);
|
||||
DD_VISIT(pfnSetConvolutionKernelMono);
|
||||
DD_VISIT(pfnComposeRects);
|
||||
DD_VISIT(pfnBlt);
|
||||
DD_VISIT(pfnColorFill);
|
||||
DD_VISIT(pfnDepthFill);
|
||||
DD_VISIT(pfnCreateQuery);
|
||||
DD_VISIT(pfnDestroyQuery);
|
||||
DD_VISIT(pfnIssueQuery);
|
||||
DD_VISIT(pfnGetQueryData);
|
||||
DD_VISIT(pfnSetRenderTarget);
|
||||
DD_VISIT(pfnSetDepthStencil);
|
||||
DD_VISIT(pfnGenerateMipSubLevels);
|
||||
DD_VISIT(pfnSetPixelShaderConstI);
|
||||
DD_VISIT(pfnSetPixelShaderConstB);
|
||||
DD_VISIT(pfnCreatePixelShader);
|
||||
DD_VISIT(pfnDeletePixelShader);
|
||||
DD_VISIT(pfnCreateDecodeDevice);
|
||||
DD_VISIT(pfnDestroyDecodeDevice);
|
||||
DD_VISIT(pfnSetDecodeRenderTarget);
|
||||
DD_VISIT(pfnDecodeBeginFrame);
|
||||
DD_VISIT(pfnDecodeEndFrame);
|
||||
DD_VISIT(pfnDecodeExecute);
|
||||
DD_VISIT(pfnDecodeExtensionExecute);
|
||||
DD_VISIT(pfnCreateVideoProcessDevice);
|
||||
DD_VISIT(pfnDestroyVideoProcessDevice);
|
||||
DD_VISIT(pfnVideoProcessBeginFrame);
|
||||
DD_VISIT(pfnVideoProcessEndFrame);
|
||||
DD_VISIT(pfnSetVideoProcessRenderTarget);
|
||||
DD_VISIT(pfnVideoProcessBlt);
|
||||
DD_VISIT(pfnCreateExtensionDevice);
|
||||
DD_VISIT(pfnDestroyExtensionDevice);
|
||||
DD_VISIT(pfnExtensionExecute);
|
||||
DD_VISIT(pfnCreateOverlay);
|
||||
DD_VISIT(pfnUpdateOverlay);
|
||||
DD_VISIT(pfnFlipOverlay);
|
||||
DD_VISIT(pfnGetOverlayColorControls);
|
||||
DD_VISIT(pfnSetOverlayColorControls);
|
||||
DD_VISIT(pfnDestroyOverlay);
|
||||
DD_VISIT(pfnDestroyDevice);
|
||||
DD_VISIT(pfnQueryResourceResidency);
|
||||
DD_VISIT(pfnOpenResource);
|
||||
DD_VISIT(pfnGetCaptureAllocationHandle);
|
||||
DD_VISIT(pfnCaptureToSysMem);
|
||||
DD_VISIT(pfnLockAsync);
|
||||
DD_VISIT(pfnUnlockAsync);
|
||||
DD_VISIT(pfnRename);
|
||||
|
||||
if (D3dDdiHooks::getDdiVersion() >= D3D_UMD_INTERFACE_VERSION_WIN7)
|
||||
{
|
||||
DD_VISIT(pfnCreateVideoProcessor);
|
||||
DD_VISIT(pfnSetVideoProcessBltState);
|
||||
DD_VISIT(pfnGetVideoProcessBltStatePrivate);
|
||||
DD_VISIT(pfnSetVideoProcessStreamState);
|
||||
DD_VISIT(pfnGetVideoProcessStreamStatePrivate);
|
||||
DD_VISIT(pfnVideoProcessBltHD);
|
||||
DD_VISIT(pfnDestroyVideoProcessor);
|
||||
DD_VISIT(pfnCreateAuthenticatedChannel);
|
||||
DD_VISIT(pfnAuthenticatedChannelKeyExchange);
|
||||
DD_VISIT(pfnQueryAuthenticatedChannel);
|
||||
DD_VISIT(pfnConfigureAuthenticatedChannel);
|
||||
DD_VISIT(pfnDestroyAuthenticatedChannel);
|
||||
DD_VISIT(pfnCreateCryptoSession);
|
||||
DD_VISIT(pfnCryptoSessionKeyExchange);
|
||||
DD_VISIT(pfnDestroyCryptoSession);
|
||||
DD_VISIT(pfnEncryptionBlt);
|
||||
DD_VISIT(pfnGetPitch);
|
||||
DD_VISIT(pfnStartSessionKeyRefresh);
|
||||
DD_VISIT(pfnFinishSessionKeyRefresh);
|
||||
DD_VISIT(pfnGetEncryptionBltKey);
|
||||
DD_VISIT(pfnDecryptionBlt);
|
||||
DD_VISIT(pfnResolveSharedResource);
|
||||
}
|
||||
|
||||
if (D3dDdiHooks::getDdiVersion() >= D3D_UMD_INTERFACE_VERSION_WIN8)
|
||||
{
|
||||
DD_VISIT(pfnVolBlt1);
|
||||
DD_VISIT(pfnBufBlt1);
|
||||
DD_VISIT(pfnTexBlt1);
|
||||
DD_VISIT(pfnDiscard);
|
||||
DD_VISIT(pfnOfferResources);
|
||||
DD_VISIT(pfnReclaimResources);
|
||||
DD_VISIT(pfnCheckDirectFlipSupport);
|
||||
DD_VISIT(pfnCreateResource2);
|
||||
DD_VISIT(pfnCheckMultiPlaneOverlaySupport);
|
||||
DD_VISIT(pfnPresentMultiPlaneOverlay);
|
||||
}
|
||||
|
||||
if (D3dDdiHooks::getDdiVersion() >= D3D_UMD_INTERFACE_VERSION_WDDM1_3)
|
||||
{
|
||||
// DD_VISIT(pfnReserved1); -- unused
|
||||
DD_VISIT(pfnFlush1);
|
||||
DD_VISIT(pfnCheckCounterInfo);
|
||||
DD_VISIT(pfnCheckCounter);
|
||||
DD_VISIT(pfnUpdateSubresourceUP);
|
||||
DD_VISIT(pfnPresent1);
|
||||
DD_VISIT(pfnCheckPresentDurationSupport);
|
||||
|
||||
DD_VISIT(pfnSetMarker);
|
||||
DD_VISIT(pfnSetMarkerMode);
|
||||
}
|
||||
|
||||
if (D3dDdiHooks::getDdiVersion() >= D3D_UMD_INTERFACE_VERSION_WDDM2_0)
|
||||
{
|
||||
DD_VISIT(pfnTrimResidencySet);
|
||||
}
|
||||
}
|
||||
};
|
160
DDrawCompat/D3dDdiHooks.cpp
Normal file
160
DDrawCompat/D3dDdiHooks.cpp
Normal file
@ -0,0 +1,160 @@
|
||||
#define CINTERFACE
|
||||
|
||||
#include <Windows.h>
|
||||
#include <d3d.h>
|
||||
#include <d3dumddi.h>
|
||||
#include <..\km\d3dkmthk.h>
|
||||
|
||||
#include "CompatD3dDdiAdapterCallbacks.h"
|
||||
#include "CompatD3dDdiAdapterFuncs.h"
|
||||
#include "DDrawLog.h"
|
||||
#include "Hook.h"
|
||||
|
||||
HRESULT APIENTRY OpenAdapter(D3DDDIARG_OPENADAPTER*) { return 0; }
|
||||
|
||||
namespace
|
||||
{
|
||||
UINT g_ddiVersion = 0;
|
||||
HMODULE g_umd = nullptr;
|
||||
|
||||
D3DKMT_HANDLE openAdapterFromHdc(HDC hdc);
|
||||
|
||||
void closeAdapter(D3DKMT_HANDLE adapter)
|
||||
{
|
||||
D3DKMT_CLOSEADAPTER closeAdapterData = {};
|
||||
closeAdapterData.hAdapter = adapter;
|
||||
D3DKMTCloseAdapter(&closeAdapterData);
|
||||
}
|
||||
|
||||
DISPLAY_DEVICE getPrimaryDisplayDevice()
|
||||
{
|
||||
DISPLAY_DEVICE dd = {};
|
||||
dd.cb = sizeof(dd);
|
||||
for (DWORD i = 0;
|
||||
EnumDisplayDevices(nullptr, i, &dd, 0) && !(dd.StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE);
|
||||
++i)
|
||||
{
|
||||
}
|
||||
|
||||
if (!(dd.StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE))
|
||||
{
|
||||
Compat::Log() << "Failed to find the primary display device";
|
||||
ZeroMemory(&dd, sizeof(dd));
|
||||
}
|
||||
|
||||
return dd;
|
||||
}
|
||||
|
||||
D3DKMT_UMDFILENAMEINFO getUmdDriverName(D3DKMT_HANDLE adapter)
|
||||
{
|
||||
D3DKMT_UMDFILENAMEINFO umdFileNameInfo = {};
|
||||
umdFileNameInfo.Version = KMTUMDVERSION_DX9;
|
||||
|
||||
D3DKMT_QUERYADAPTERINFO queryAdapterInfo = {};
|
||||
queryAdapterInfo.hAdapter = adapter;
|
||||
queryAdapterInfo.Type = KMTQAITYPE_UMDRIVERNAME;
|
||||
queryAdapterInfo.pPrivateDriverData = &umdFileNameInfo;
|
||||
queryAdapterInfo.PrivateDriverDataSize = sizeof(umdFileNameInfo);
|
||||
NTSTATUS result = D3DKMTQueryAdapterInfo(&queryAdapterInfo);
|
||||
if (FAILED(result))
|
||||
{
|
||||
Compat::Log() << "Failed to query the display driver name: " << result;
|
||||
ZeroMemory(&umdFileNameInfo, sizeof(umdFileNameInfo));
|
||||
}
|
||||
|
||||
return umdFileNameInfo;
|
||||
}
|
||||
|
||||
D3DKMT_UMDFILENAMEINFO getPrimaryUmdDriverName()
|
||||
{
|
||||
D3DKMT_UMDFILENAMEINFO umdFileNameInfo = {};
|
||||
|
||||
DISPLAY_DEVICE dd = getPrimaryDisplayDevice();
|
||||
if (!dd.DeviceName)
|
||||
{
|
||||
return umdFileNameInfo;
|
||||
}
|
||||
|
||||
HDC dc = CreateDC(nullptr, dd.DeviceName, nullptr, nullptr);
|
||||
if (!dc)
|
||||
{
|
||||
Compat::Log() << "Failed to create a DC for the primary display device";
|
||||
return umdFileNameInfo;
|
||||
}
|
||||
|
||||
D3DKMT_HANDLE adapter = openAdapterFromHdc(dc);
|
||||
DeleteDC(dc);
|
||||
if (!adapter)
|
||||
{
|
||||
return umdFileNameInfo;
|
||||
}
|
||||
|
||||
umdFileNameInfo = getUmdDriverName(adapter);
|
||||
closeAdapter(adapter);
|
||||
if (0 == umdFileNameInfo.UmdFileName[0])
|
||||
{
|
||||
return umdFileNameInfo;
|
||||
}
|
||||
|
||||
Compat::Log() << "Primary display adapter driver: " << umdFileNameInfo.UmdFileName;
|
||||
return umdFileNameInfo;
|
||||
}
|
||||
|
||||
HRESULT APIENTRY openAdapter(D3DDDIARG_OPENADAPTER* pOpenData)
|
||||
{
|
||||
Compat::LogEnter("openAdapter", pOpenData);
|
||||
CompatD3dDdiAdapterCallbacks::hookVtable(pOpenData->pAdapterCallbacks);
|
||||
HRESULT result = CALL_ORIG_FUNC(OpenAdapter)(pOpenData);
|
||||
if (SUCCEEDED(result))
|
||||
{
|
||||
g_ddiVersion = min(pOpenData->Version, pOpenData->DriverVersion);
|
||||
CompatD3dDdiAdapterFuncs::hookVtable(pOpenData->pAdapterFuncs);
|
||||
}
|
||||
Compat::LogLeave("openAdapter", pOpenData) << result;
|
||||
return result;
|
||||
}
|
||||
|
||||
D3DKMT_HANDLE openAdapterFromHdc(HDC hdc)
|
||||
{
|
||||
D3DKMT_OPENADAPTERFROMHDC openAdapterData = {};
|
||||
openAdapterData.hDc = hdc;
|
||||
NTSTATUS result = D3DKMTOpenAdapterFromHdc(&openAdapterData);
|
||||
if (FAILED(result))
|
||||
{
|
||||
Compat::Log() << "Failed to open the primary display adapter: " << result;
|
||||
return 0;
|
||||
}
|
||||
return openAdapterData.hAdapter;
|
||||
}
|
||||
}
|
||||
|
||||
namespace D3dDdiHooks
|
||||
{
|
||||
UINT getDdiVersion()
|
||||
{
|
||||
return g_ddiVersion;
|
||||
}
|
||||
|
||||
void installHooks()
|
||||
{
|
||||
D3DKMT_UMDFILENAMEINFO primaryUmd = getPrimaryUmdDriverName();
|
||||
g_umd = LoadLibraryW(primaryUmd.UmdFileName);
|
||||
if (!g_umd)
|
||||
{
|
||||
Compat::Log() << "Failed to load the primary display driver library";
|
||||
}
|
||||
|
||||
char umdFileName[MAX_PATH] = {};
|
||||
wcstombs_s(nullptr, umdFileName, primaryUmd.UmdFileName, _TRUNCATE);
|
||||
Compat::hookFunction<decltype(&OpenAdapter), &OpenAdapter>(
|
||||
umdFileName, "OpenAdapter", &openAdapter);
|
||||
}
|
||||
|
||||
void uninstallHooks()
|
||||
{
|
||||
if (g_umd)
|
||||
{
|
||||
FreeLibrary(g_umd);
|
||||
}
|
||||
}
|
||||
}
|
8
DDrawCompat/D3dDdiHooks.h
Normal file
8
DDrawCompat/D3dDdiHooks.h
Normal file
@ -0,0 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
namespace D3dDdiHooks
|
||||
{
|
||||
UINT getDdiVersion();
|
||||
void installHooks();
|
||||
void uninstallHooks();
|
||||
}
|
@ -148,6 +148,10 @@
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="CompatActivateAppHandler.h" />
|
||||
<ClInclude Include="CompatD3dDdiAdapterCallbacks.h" />
|
||||
<ClInclude Include="CompatD3dDdiAdapterFuncs.h" />
|
||||
<ClInclude Include="CompatD3dDdiDeviceCallbacks.h" />
|
||||
<ClInclude Include="CompatD3dDdiDeviceFuncs.h" />
|
||||
<ClInclude Include="CompatDepthBuffer.h" />
|
||||
<ClInclude Include="CompatDirect3d.h" />
|
||||
<ClInclude Include="CompatDirect3dDevice.h" />
|
||||
@ -172,6 +176,11 @@
|
||||
<ClInclude Include="CompatRegistry.h" />
|
||||
<ClInclude Include="CompatWeakPtr.h" />
|
||||
<ClInclude Include="Config.h" />
|
||||
<ClInclude Include="D3dDdiAdapterCallbacksVisitor.h" />
|
||||
<ClInclude Include="D3dDdiAdapterFuncsVisitor.h" />
|
||||
<ClInclude Include="D3dDdiDeviceCallbacksVisitor.h" />
|
||||
<ClInclude Include="D3dDdiDeviceFuncsVisitor.h" />
|
||||
<ClInclude Include="D3dDdiHooks.h" />
|
||||
<ClInclude Include="DDrawHooks.h" />
|
||||
<ClInclude Include="DDrawProcs.h" />
|
||||
<ClInclude Include="CompatDirectDraw.h" />
|
||||
@ -197,6 +206,10 @@
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="CompatActivateAppHandler.cpp" />
|
||||
<ClCompile Include="CompatD3dDdiAdapterCallbacks.cpp" />
|
||||
<ClCompile Include="CompatD3dDdiAdapterFuncs.cpp" />
|
||||
<ClCompile Include="CompatD3dDdiDeviceCallbacks.cpp" />
|
||||
<ClCompile Include="CompatD3dDdiDeviceFuncs.cpp" />
|
||||
<ClCompile Include="CompatDepthBuffer.cpp" />
|
||||
<ClCompile Include="CompatDirect3d.cpp" />
|
||||
<ClCompile Include="CompatDirect3dDevice.cpp" />
|
||||
@ -217,6 +230,7 @@
|
||||
<ClCompile Include="CompatHooks.cpp" />
|
||||
<ClCompile Include="CompatPaletteConverter.cpp" />
|
||||
<ClCompile Include="CompatRegistry.cpp" />
|
||||
<ClCompile Include="D3dDdiHooks.cpp" />
|
||||
<ClCompile Include="DDrawHooks.cpp" />
|
||||
<ClCompile Include="DDrawLog.cpp" />
|
||||
<ClCompile Include="DllMain.cpp" />
|
||||
|
@ -156,6 +156,33 @@
|
||||
<ClInclude Include="CompatDepthBuffer.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="D3dDdiAdapterCallbacksVisitor.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="D3dDdiAdapterFuncsVisitor.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="D3dDdiDeviceCallbacksVisitor.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="D3dDdiDeviceFuncsVisitor.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="CompatD3dDdiDeviceFuncs.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="CompatD3dDdiDeviceCallbacks.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="CompatD3dDdiAdapterFuncs.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="CompatD3dDdiAdapterCallbacks.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="D3dDdiHooks.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="DllMain.cpp">
|
||||
@ -257,6 +284,21 @@
|
||||
<ClCompile Include="CompatDepthBuffer.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="CompatD3dDdiDeviceFuncs.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="CompatD3dDdiDeviceCallbacks.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="CompatD3dDdiAdapterFuncs.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="CompatD3dDdiAdapterCallbacks.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="D3dDdiHooks.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="DDrawCompat.def">
|
||||
|
@ -135,7 +135,7 @@ namespace
|
||||
DDPCAPS_1BIT, paletteEntries, &palette.getRef(), nullptr);
|
||||
if (SUCCEEDED(result))
|
||||
{
|
||||
CompatDirectDrawPalette::hookVtable(*palette);
|
||||
CompatDirectDrawPalette::hookVtable(palette.get()->lpVtbl);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -172,7 +172,7 @@ namespace
|
||||
template <typename CompatInterface>
|
||||
void hookVtable(const CompatPtr<typename CompatInterface::Interface>& intf)
|
||||
{
|
||||
CompatInterface::hookVtable(*intf);
|
||||
CompatInterface::hookVtable(intf.get()->lpVtbl);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include "CompatGdi.h"
|
||||
#include "CompatHooks.h"
|
||||
#include "CompatRegistry.h"
|
||||
#include "D3dDdiHooks.h"
|
||||
#include "DDrawHooks.h"
|
||||
#include "DDrawProcs.h"
|
||||
#include "Time.h"
|
||||
@ -26,6 +27,8 @@ namespace
|
||||
static bool isAlreadyInstalled = false;
|
||||
if (!isAlreadyInstalled)
|
||||
{
|
||||
Compat::Log() << "Installing Direct3D driver hooks";
|
||||
D3dDdiHooks::installHooks();
|
||||
Compat::Log() << "Installing DirectDraw hooks";
|
||||
DDrawHooks::installHooks();
|
||||
Compat::Log() << "Installing GDI hooks";
|
||||
@ -133,6 +136,7 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID /*lpvReserved*/)
|
||||
{
|
||||
Compat::Log() << "Detaching DDrawCompat";
|
||||
DDrawHooks::uninstallHooks();
|
||||
D3dDdiHooks::uninstallHooks();
|
||||
CompatGdi::uninstallHooks();
|
||||
Compat::unhookAllFunctions();
|
||||
FreeLibrary(g_origDInputModule);
|
||||
|
Loading…
x
Reference in New Issue
Block a user