1
0
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:
narzoul 2016-07-03 12:26:05 +02:00
parent 1adb27ead4
commit 12ad482d29
19 changed files with 664 additions and 18 deletions

View File

@ -0,0 +1,5 @@
#include "CompatD3dDdiAdapterCallbacks.h"
void CompatD3dDdiAdapterCallbacks::setCompatVtable(D3DDDI_ADAPTERCALLBACKS& /*vtable*/)
{
}

View 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);
};

View 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;
}

View 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);
};

View File

@ -0,0 +1,5 @@
#include "CompatD3dDdiDeviceCallbacks.h"
void CompatD3dDdiDeviceCallbacks::setCompatVtable(D3DDDI_DEVICECALLBACKS& /*vtable*/)
{
}

View 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);
};

View File

@ -0,0 +1,5 @@
#include "CompatD3dDdiDeviceFuncs.h"
void CompatD3dDdiDeviceFuncs::setCompatVtable(D3DDDI_DEVICEFUNCS& /*vtable*/)
{
}

View 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);
};

View File

@ -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 = {};

View 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
}
};

View 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);
}
};

View 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);
}
}
};

View 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
View 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);
}
}
}

View File

@ -0,0 +1,8 @@
#pragma once
namespace D3dDdiHooks
{
UINT getDdiVersion();
void installHooks();
void uninstallHooks();
}

View File

@ -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" />

View File

@ -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">

View File

@ -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);
}
}

View File

@ -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);