From 148d7287e846afbe1bd32bf83c0083f39ec01cac Mon Sep 17 00:00:00 2001 From: narzoul Date: Fri, 2 Apr 2021 18:04:00 +0200 Subject: [PATCH] Fixed incompatibility with Steam overlay See issue #68. --- DDrawCompat/Common/CompatQueryInterface.h | 20 +++++------------ DDrawCompat/Common/CompatVtable.h | 5 +++++ DDrawCompat/Common/Hook.cpp | 27 ++++++++++++++--------- DDrawCompat/D3dDdi/KernelModeThunks.cpp | 2 +- 4 files changed, 27 insertions(+), 27 deletions(-) diff --git a/DDrawCompat/Common/CompatQueryInterface.h b/DDrawCompat/Common/CompatQueryInterface.h index 759c172..24a3548 100644 --- a/DDrawCompat/Common/CompatQueryInterface.h +++ b/DDrawCompat/Common/CompatQueryInterface.h @@ -20,6 +20,9 @@ namespace Compat { }; + template struct IsConvertible : std::true_type {}; + template struct IsConvertible : std::true_type {}; + template<> struct IsConvertible : std::false_type {}; template<> struct IsConvertible : std::false_type {}; template<> struct IsConvertible : std::false_type {}; @@ -61,6 +64,8 @@ namespace Compat #define DEFINE_INTF_ID(Intf) \ template<> inline const IID& getIntfId() { return IID_##Intf; } + DEFINE_INTF_ID(IUnknown); + DEFINE_INTF_ID(IDirectDraw); DEFINE_INTF_ID(IDirectDraw2); DEFINE_INTF_ID(IDirectDraw4); @@ -94,21 +99,6 @@ namespace Compat #undef DEFINE_INTF_ID - template - void queryInterface(IUnknown& origIntf, NewIntf*& newIntf) - { - getOrigVtable(newIntf).QueryInterface( - reinterpret_cast(&origIntf), - getIntfId(), - reinterpret_cast(&newIntf)); - } - - template - void queryInterface(OrigIntf& origIntf, IUnknown*& newIntf) - { - getOrigVtable(&origIntf).QueryInterface(&origIntf, IID_IUnknown, reinterpret_cast(&newIntf)); - } - template std::enable_if_t::value> queryInterface(OrigIntf& origIntf, NewIntf*& newIntf) diff --git a/DDrawCompat/Common/CompatVtable.h b/DDrawCompat/Common/CompatVtable.h index abcfdd7..9f6d9f6 100644 --- a/DDrawCompat/Common/CompatVtable.h +++ b/DDrawCompat/Common/CompatVtable.h @@ -15,6 +15,11 @@ const Vtable& getOrigVtable(Interface* /*This*/) return CompatVtable>::s_origVtable; } +inline const IUnknownVtbl& getOrigVtable(IUnknown* This) +{ + return *This->lpVtbl; +} + template class CompatVtable { diff --git a/DDrawCompat/Common/Hook.cpp b/DDrawCompat/Common/Hook.cpp index 4be47ba..5c614a0 100644 --- a/DDrawCompat/Common/Hook.cpp +++ b/DDrawCompat/Common/Hook.cpp @@ -1,6 +1,5 @@ #undef CINTERFACE -#include #include #include #include @@ -23,7 +22,7 @@ namespace bool g_isDbgEngInitialized = false; PIMAGE_NT_HEADERS getImageNtHeaders(HMODULE module); - std::filesystem::path getModulePath(HMODULE module); + std::string getModulePath(HMODULE module); bool initDbgEng(); FARPROC* findProcAddressInIat(HMODULE module, const char* procName) @@ -107,7 +106,7 @@ namespace return static_cast(endOffset - g_debugBase); } - std::filesystem::path getModulePath(HMODULE module) + std::string getModulePath(HMODULE module) { char path[MAX_PATH] = {}; GetModuleFileName(module, path, sizeof(path)); @@ -120,7 +119,7 @@ namespace std::ostringstream oss; #ifdef DEBUGLOGS - oss << Compat::funcPtrToStr(targetFunc); + oss << Compat::funcPtrToStr(targetFunc) << ' '; char origFuncPtrStr[20] = {}; if (!funcName) @@ -128,20 +127,26 @@ namespace sprintf_s(origFuncPtrStr, "%p", origFuncPtr); funcName = origFuncPtrStr; } + + auto prevTargetFunc = targetFunc; #endif while (true) { + unsigned instructionSize = 0; if (0xE9 == targetFunc[0]) { - targetFunc += 1 + *reinterpret_cast(targetFunc + 1); + instructionSize = 5; + targetFunc += instructionSize + *reinterpret_cast(targetFunc + 1); } else if (0xEB == targetFunc[0]) { - targetFunc += 1 + static_cast(targetFunc[1]); + instructionSize = 2; + targetFunc += instructionSize + *reinterpret_cast(targetFunc + 1); } else if (0xFF == targetFunc[0] && 0x25 == targetFunc[1]) { + instructionSize = 6; targetFunc = **reinterpret_cast(targetFunc + 2); } else @@ -149,12 +154,11 @@ namespace break; } #ifdef DEBUGLOGS - oss << " -> " << Compat::funcPtrToStr(targetFunc); + oss << Compat::hexDump(prevTargetFunc, instructionSize) << " -> " << Compat::funcPtrToStr(targetFunc) << ' '; + prevTargetFunc = targetFunc; #endif } - LOG_DEBUG << "Hooking function: " << funcName << " (" << oss.str() << ')'; - if (Compat::getModuleHandleFromAddress(targetFunc) == Dll::g_currentModule) { Compat::Log() << "ERROR: Target function is already hooked: " << funcName; @@ -177,7 +181,8 @@ namespace totalInstructionSize += instructionSize; } - LOG_DEBUG << "Decoded instructions: " << Compat::hexDump(targetFunc, totalInstructionSize); + LOG_DEBUG << "Hooking function: " << funcName + << " (" << oss.str() << Compat::hexDump(targetFunc, totalInstructionSize) << ')'; BYTE* trampoline = static_cast( VirtualAlloc(nullptr, totalInstructionSize + 5, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE)); @@ -299,7 +304,7 @@ namespace Compat HMODULE module = Compat::getModuleHandleFromAddress(funcPtr); if (module) { - oss << getModulePath(module).string() << "+0x" << std::hex << + oss << getModulePath(module) << "+0x" << std::hex << reinterpret_cast(funcPtr) - reinterpret_cast(module); } else diff --git a/DDrawCompat/D3dDdi/KernelModeThunks.cpp b/DDrawCompat/D3dDdi/KernelModeThunks.cpp index d8fd9a0..7dffd28 100644 --- a/DDrawCompat/D3dDdi/KernelModeThunks.cpp +++ b/DDrawCompat/D3dDdi/KernelModeThunks.cpp @@ -292,7 +292,7 @@ namespace D3dDdi CompatPtr dd7(ddUnk); DDDEVICEIDENTIFIER2 di = {}; - dd7->GetDeviceIdentifier(dd7, &di, 0); + dd7.get()->lpVtbl->GetDeviceIdentifier(dd7, &di, 0); } return g_lastOpenAdapterInfo.monitorRect;