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

Use IAT hooks for D3DKMT* functions

Potential fix for issue #55.
This commit is contained in:
narzoul 2019-08-28 21:04:28 +02:00
parent d1cd6658c9
commit c7b94700d3
2 changed files with 22 additions and 54 deletions

View File

@ -59,13 +59,13 @@ namespace
{ {
g_lastOpenAdapterInfo = {}; g_lastOpenAdapterInfo = {};
} }
return CALL_ORIG_FUNC(D3DKMTCloseAdapter)(pData); return D3DKMTCloseAdapter(pData);
} }
NTSTATUS APIENTRY createContext(D3DKMT_CREATECONTEXT* pData) NTSTATUS APIENTRY createContext(D3DKMT_CREATECONTEXT* pData)
{ {
LOG_FUNC("D3DKMTCreateContext", pData); LOG_FUNC("D3DKMTCreateContext", pData);
NTSTATUS result = CALL_ORIG_FUNC(D3DKMTCreateContext)(pData); NTSTATUS result = D3DKMTCreateContext(pData);
if (SUCCEEDED(result)) if (SUCCEEDED(result))
{ {
g_contexts[pData->hContext].device = pData->hDevice; g_contexts[pData->hContext].device = pData->hDevice;
@ -76,7 +76,9 @@ namespace
NTSTATUS APIENTRY createContextVirtual(D3DKMT_CREATECONTEXTVIRTUAL* pData) NTSTATUS APIENTRY createContextVirtual(D3DKMT_CREATECONTEXTVIRTUAL* pData)
{ {
LOG_FUNC("D3DKMTCreateContextVirtual", pData); LOG_FUNC("D3DKMTCreateContextVirtual", pData);
NTSTATUS result = g_origD3dKmtCreateContextVirtual(pData); static auto d3dKmtCreateContextVirtual = reinterpret_cast<decltype(D3DKMTCreateContextVirtual)*>(
GetProcAddress(GetModuleHandle("gdi32"), "D3DKMTCreateContextVirtual"));
NTSTATUS result = d3dKmtCreateContextVirtual(pData);
if (SUCCEEDED(result)) if (SUCCEEDED(result))
{ {
g_contexts[pData->hContext].device = pData->hDevice; g_contexts[pData->hContext].device = pData->hDevice;
@ -135,38 +137,23 @@ namespace
} }
} }
auto result = CALL_ORIG_FUNC(D3DKMTCreateDCFromMemory)(pData); auto result = D3DKMTCreateDCFromMemory(pData);
pData->Format = origFormat; pData->Format = origFormat;
pData->pColorTable = origColorTable; pData->pColorTable = origColorTable;
return LOG_RESULT(result); return LOG_RESULT(result);
} }
NTSTATUS APIENTRY createDevice(D3DKMT_CREATEDEVICE* pData)
{
LOG_FUNC("D3DKMTCreateDevice", pData);
NTSTATUS result = CALL_ORIG_FUNC(D3DKMTCreateDevice)(pData);
if (SUCCEEDED(result))
{
D3DKMT_SETQUEUEDLIMIT limit = {};
limit.hDevice = pData->hDevice;
limit.Type = D3DKMT_SET_QUEUEDLIMIT_PRESENT;
limit.QueuedPresentLimit = 2;
CALL_ORIG_FUNC(D3DKMTSetQueuedLimit)(&limit);
}
return LOG_RESULT(result);
}
HDC WINAPI ddrawCreateDcA(LPCSTR pwszDriver, LPCSTR pwszDevice, LPCSTR pszPort, const DEVMODEA* pdm) HDC WINAPI ddrawCreateDcA(LPCSTR pwszDriver, LPCSTR pwszDevice, LPCSTR pszPort, const DEVMODEA* pdm)
{ {
LOG_FUNC("ddrawCreateDCA", pwszDriver, pwszDevice, pszPort, pdm); LOG_FUNC("ddrawCreateDCA", pwszDriver, pwszDevice, pszPort, pdm);
g_lastDDrawCreateDcDevice = pwszDevice ? pwszDevice : std::string(); g_lastDDrawCreateDcDevice = pwszDevice ? pwszDevice : std::string();
return LOG_RESULT(CALL_ORIG_FUNC(CreateDCA)(pwszDriver, pwszDevice, pszPort, pdm)); return LOG_RESULT(CreateDCA(pwszDriver, pwszDevice, pszPort, pdm));
} }
NTSTATUS APIENTRY destroyContext(const D3DKMT_DESTROYCONTEXT* pData) NTSTATUS APIENTRY destroyContext(const D3DKMT_DESTROYCONTEXT* pData)
{ {
LOG_FUNC("D3DKMTDestroyContext", pData); LOG_FUNC("D3DKMTDestroyContext", pData);
NTSTATUS result = CALL_ORIG_FUNC(D3DKMTDestroyContext)(pData); NTSTATUS result = D3DKMTDestroyContext(pData);
if (SUCCEEDED(result)) if (SUCCEEDED(result))
{ {
g_contexts.erase(pData->hContext); g_contexts.erase(pData->hContext);
@ -214,7 +201,7 @@ namespace
NTSTATUS APIENTRY openAdapterFromHdc(D3DKMT_OPENADAPTERFROMHDC* pData) NTSTATUS APIENTRY openAdapterFromHdc(D3DKMT_OPENADAPTERFROMHDC* pData)
{ {
LOG_FUNC("D3DKMTOpenAdapterFromHdc", pData); LOG_FUNC("D3DKMTOpenAdapterFromHdc", pData);
NTSTATUS result = CALL_ORIG_FUNC(D3DKMTOpenAdapterFromHdc)(pData); NTSTATUS result = D3DKMTOpenAdapterFromHdc(pData);
if (SUCCEEDED(result)) if (SUCCEEDED(result))
{ {
Compat::ScopedCriticalSection lock(g_vblankCs); Compat::ScopedCriticalSection lock(g_vblankCs);
@ -248,13 +235,13 @@ namespace
pData->FlipInterval = static_cast<D3DDDI_FLIPINTERVAL_TYPE>(g_flipIntervalOverride); pData->FlipInterval = static_cast<D3DDDI_FLIPINTERVAL_TYPE>(g_flipIntervalOverride);
} }
return LOG_RESULT(CALL_ORIG_FUNC(D3DKMTPresent)(pData)); return LOG_RESULT(D3DKMTPresent(pData));
} }
NTSTATUS APIENTRY queryAdapterInfo(const D3DKMT_QUERYADAPTERINFO* pData) NTSTATUS APIENTRY queryAdapterInfo(const D3DKMT_QUERYADAPTERINFO* pData)
{ {
LOG_FUNC("D3DKMTQueryAdapterInfo", pData); LOG_FUNC("D3DKMTQueryAdapterInfo", pData);
NTSTATUS result = CALL_ORIG_FUNC(D3DKMTQueryAdapterInfo)(pData); NTSTATUS result = D3DKMTQueryAdapterInfo(pData);
if (SUCCEEDED(result)) if (SUCCEEDED(result))
{ {
switch (pData->Type) switch (pData->Type)
@ -289,20 +276,6 @@ namespace
return LOG_RESULT(result); return LOG_RESULT(result);
} }
NTSTATUS APIENTRY setQueuedLimit(const D3DKMT_SETQUEUEDLIMIT* pData)
{
LOG_FUNC("D3DKMTSetQueuedLimit", pData);
if (D3DKMT_SET_QUEUEDLIMIT_PRESENT == pData->Type)
{
const UINT origLimit = pData->QueuedPresentLimit;
const_cast<D3DKMT_SETQUEUEDLIMIT*>(pData)->QueuedPresentLimit = 2;
NTSTATUS result = CALL_ORIG_FUNC(D3DKMTSetQueuedLimit)(pData);
const_cast<D3DKMT_SETQUEUEDLIMIT*>(pData)->QueuedPresentLimit = origLimit;
return LOG_RESULT(result);
}
return LOG_RESULT(CALL_ORIG_FUNC(D3DKMTSetQueuedLimit)(pData));
}
void updateGdiAdapterInfo() void updateGdiAdapterInfo()
{ {
static auto lastDisplaySettingsUniqueness = Win32::DisplayMode::queryDisplaySettingsUniqueness() - 1; static auto lastDisplaySettingsUniqueness = Win32::DisplayMode::queryDisplaySettingsUniqueness() - 1;
@ -313,7 +286,7 @@ namespace
{ {
D3DKMT_CLOSEADAPTER data = {}; D3DKMT_CLOSEADAPTER data = {};
data.hAdapter = g_gdiAdapterInfo.adapter; data.hAdapter = g_gdiAdapterInfo.adapter;
CALL_ORIG_FUNC(D3DKMTCloseAdapter)(&data); D3DKMTCloseAdapter(&data);
g_gdiAdapterInfo = {}; g_gdiAdapterInfo = {};
} }
@ -323,7 +296,7 @@ namespace
D3DKMT_OPENADAPTERFROMHDC data = {}; D3DKMT_OPENADAPTERFROMHDC data = {};
data.hDc = CreateDC(mi.szDevice, mi.szDevice, nullptr, nullptr); data.hDc = CreateDC(mi.szDevice, mi.szDevice, nullptr, nullptr);
if (SUCCEEDED(CALL_ORIG_FUNC(D3DKMTOpenAdapterFromHdc)(&data))) if (SUCCEEDED(D3DKMTOpenAdapterFromHdc(&data)))
{ {
g_gdiAdapterInfo = getAdapterInfo(data); g_gdiAdapterInfo = getAdapterInfo(data);
} }
@ -401,20 +374,15 @@ namespace D3dDdi
void installHooks(HMODULE origDDrawModule) void installHooks(HMODULE origDDrawModule)
{ {
HOOK_FUNCTION(gdi32, D3DKMTCloseAdapter, closeAdapter);
HOOK_FUNCTION(gdi32, D3DKMTCreateContext, createContext);
HOOK_FUNCTION(gdi32, D3DKMTCreateDevice, createDevice);
HOOK_FUNCTION(gdi32, D3DKMTCreateDCFromMemory, createDcFromMemory);
HOOK_FUNCTION(gdi32, D3DKMTDestroyContext, destroyContext);
HOOK_FUNCTION(gdi32, D3DKMTOpenAdapterFromHdc, openAdapterFromHdc);
HOOK_FUNCTION(gdi32, D3DKMTQueryAdapterInfo, queryAdapterInfo);
HOOK_FUNCTION(gdi32, D3DKMTPresent, present);
HOOK_FUNCTION(gdi32, D3DKMTSetQueuedLimit, setQueuedLimit);
Compat::hookIatFunction(origDDrawModule, "gdi32.dll", "CreateDCA", ddrawCreateDcA); Compat::hookIatFunction(origDDrawModule, "gdi32.dll", "CreateDCA", ddrawCreateDcA);
Compat::hookIatFunction(origDDrawModule, "gdi32.dll", "D3DKMTCloseAdapter", closeAdapter);
// Functions not available in Windows Vista Compat::hookIatFunction(origDDrawModule, "gdi32.dll", "D3DKMTCreateContext", createContext);
Compat::hookFunction("gdi32", "D3DKMTCreateContextVirtual", Compat::hookIatFunction(origDDrawModule, "gdi32.dll", "D3DKMTCreateContextVirtual", createContextVirtual);
reinterpret_cast<void*&>(g_origD3dKmtCreateContextVirtual), createContextVirtual); Compat::hookIatFunction(origDDrawModule, "gdi32.dll", "D3DKMTCreateDCFromMemory", createDcFromMemory);
Compat::hookIatFunction(origDDrawModule, "gdi32.dll", "D3DKMTDestroyContext", destroyContext);
Compat::hookIatFunction(origDDrawModule, "gdi32.dll", "D3DKMTOpenAdapterFromHdc", openAdapterFromHdc);
Compat::hookIatFunction(origDDrawModule, "gdi32.dll", "D3DKMTQueryAdapterInfo", queryAdapterInfo);
Compat::hookIatFunction(origDDrawModule, "gdi32.dll", "D3DKMTPresent", present);
} }
void setFlipIntervalOverride(UINT flipInterval) void setFlipIntervalOverride(UINT flipInterval)

View File

@ -166,7 +166,7 @@ namespace Win32
{ {
void installHooks() void installHooks()
{ {
HOOK_FUNCTION(KernelBase, RegGetValueW, regGetValueW); HOOK_SHIM_FUNCTION(RegGetValueW, regGetValueW);
HOOK_SHIM_FUNCTION(RegQueryValueExA, regQueryValueExA); HOOK_SHIM_FUNCTION(RegQueryValueExA, regQueryValueExA);
} }