mirror of
https://github.com/narzoul/DDrawCompat
synced 2024-12-30 08:55:36 +01:00
172 lines
4.0 KiB
C++
172 lines
4.0 KiB
C++
#define CINTERFACE
|
|
|
|
#include <Windows.h>
|
|
#include <d3d.h>
|
|
#include <d3dumddi.h>
|
|
#include <..\km\d3dkmthk.h>
|
|
|
|
#include "D3dDdi/AdapterCallbacks.h"
|
|
#include "D3dDdi/AdapterFuncs.h"
|
|
#include "DDrawLog.h"
|
|
#include "Hook.h"
|
|
|
|
HRESULT APIENTRY OpenAdapter(D3DDDIARG_OPENADAPTER*) { return 0; }
|
|
|
|
std::ostream& operator<<(std::ostream& os, const D3DDDIARG_OPENADAPTER& data)
|
|
{
|
|
return Compat::LogStruct(os)
|
|
<< data.hAdapter
|
|
<< data.Interface
|
|
<< data.Version
|
|
<< data.pAdapterCallbacks
|
|
<< data.pAdapterFuncs
|
|
<< data.DriverVersion;
|
|
}
|
|
|
|
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);
|
|
D3dDdi::AdapterCallbacks::hookVtable(pOpenData->pAdapterCallbacks);
|
|
HRESULT result = CALL_ORIG_FUNC(OpenAdapter)(pOpenData);
|
|
if (SUCCEEDED(result))
|
|
{
|
|
g_ddiVersion = min(pOpenData->Version, pOpenData->DriverVersion);
|
|
D3dDdi::AdapterFuncs::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 D3dDdi
|
|
{
|
|
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);
|
|
}
|
|
}
|
|
}
|