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

Fixed incompatibility with Steam overlay

See issue #68.
This commit is contained in:
narzoul 2021-04-02 18:04:00 +02:00
parent 4e00ce0447
commit 148d7287e8
4 changed files with 27 additions and 27 deletions

View File

@ -20,6 +20,9 @@ namespace Compat
{ {
}; };
template <typename SrcIntf> struct IsConvertible<SrcIntf, IUnknown> : std::true_type {};
template <typename DestIntf> struct IsConvertible<IUnknown, DestIntf> : std::true_type {};
template<> struct IsConvertible<IDirect3D, IDirect3D7> : std::false_type {}; template<> struct IsConvertible<IDirect3D, IDirect3D7> : std::false_type {};
template<> struct IsConvertible<IDirect3D2, IDirect3D7> : std::false_type {}; template<> struct IsConvertible<IDirect3D2, IDirect3D7> : std::false_type {};
template<> struct IsConvertible<IDirect3D3, IDirect3D7> : std::false_type {}; template<> struct IsConvertible<IDirect3D3, IDirect3D7> : std::false_type {};
@ -61,6 +64,8 @@ namespace Compat
#define DEFINE_INTF_ID(Intf) \ #define DEFINE_INTF_ID(Intf) \
template<> inline const IID& getIntfId<Intf>() { return IID_##Intf; } template<> inline const IID& getIntfId<Intf>() { return IID_##Intf; }
DEFINE_INTF_ID(IUnknown);
DEFINE_INTF_ID(IDirectDraw); DEFINE_INTF_ID(IDirectDraw);
DEFINE_INTF_ID(IDirectDraw2); DEFINE_INTF_ID(IDirectDraw2);
DEFINE_INTF_ID(IDirectDraw4); DEFINE_INTF_ID(IDirectDraw4);
@ -94,21 +99,6 @@ namespace Compat
#undef DEFINE_INTF_ID #undef DEFINE_INTF_ID
template <typename NewIntf>
void queryInterface(IUnknown& origIntf, NewIntf*& newIntf)
{
getOrigVtable(newIntf).QueryInterface(
reinterpret_cast<NewIntf*>(&origIntf),
getIntfId<NewIntf>(),
reinterpret_cast<void**>(&newIntf));
}
template <typename OrigIntf>
void queryInterface(OrigIntf& origIntf, IUnknown*& newIntf)
{
getOrigVtable(&origIntf).QueryInterface(&origIntf, IID_IUnknown, reinterpret_cast<void**>(&newIntf));
}
template <typename NewIntf, typename OrigIntf> template <typename NewIntf, typename OrigIntf>
std::enable_if_t<IsConvertible<OrigIntf, NewIntf>::value> std::enable_if_t<IsConvertible<OrigIntf, NewIntf>::value>
queryInterface(OrigIntf& origIntf, NewIntf*& newIntf) queryInterface(OrigIntf& origIntf, NewIntf*& newIntf)

View File

@ -15,6 +15,11 @@ const Vtable<Interface>& getOrigVtable(Interface* /*This*/)
return CompatVtable<Vtable<Interface>>::s_origVtable; return CompatVtable<Vtable<Interface>>::s_origVtable;
} }
inline const IUnknownVtbl& getOrigVtable(IUnknown* This)
{
return *This->lpVtbl;
}
template <typename Vtable> template <typename Vtable>
class CompatVtable class CompatVtable
{ {

View File

@ -1,6 +1,5 @@
#undef CINTERFACE #undef CINTERFACE
#include <filesystem>
#include <list> #include <list>
#include <sstream> #include <sstream>
#include <string> #include <string>
@ -23,7 +22,7 @@ namespace
bool g_isDbgEngInitialized = false; bool g_isDbgEngInitialized = false;
PIMAGE_NT_HEADERS getImageNtHeaders(HMODULE module); PIMAGE_NT_HEADERS getImageNtHeaders(HMODULE module);
std::filesystem::path getModulePath(HMODULE module); std::string getModulePath(HMODULE module);
bool initDbgEng(); bool initDbgEng();
FARPROC* findProcAddressInIat(HMODULE module, const char* procName) FARPROC* findProcAddressInIat(HMODULE module, const char* procName)
@ -107,7 +106,7 @@ namespace
return static_cast<unsigned>(endOffset - g_debugBase); return static_cast<unsigned>(endOffset - g_debugBase);
} }
std::filesystem::path getModulePath(HMODULE module) std::string getModulePath(HMODULE module)
{ {
char path[MAX_PATH] = {}; char path[MAX_PATH] = {};
GetModuleFileName(module, path, sizeof(path)); GetModuleFileName(module, path, sizeof(path));
@ -120,7 +119,7 @@ namespace
std::ostringstream oss; std::ostringstream oss;
#ifdef DEBUGLOGS #ifdef DEBUGLOGS
oss << Compat::funcPtrToStr(targetFunc); oss << Compat::funcPtrToStr(targetFunc) << ' ';
char origFuncPtrStr[20] = {}; char origFuncPtrStr[20] = {};
if (!funcName) if (!funcName)
@ -128,20 +127,26 @@ namespace
sprintf_s(origFuncPtrStr, "%p", origFuncPtr); sprintf_s(origFuncPtrStr, "%p", origFuncPtr);
funcName = origFuncPtrStr; funcName = origFuncPtrStr;
} }
auto prevTargetFunc = targetFunc;
#endif #endif
while (true) while (true)
{ {
unsigned instructionSize = 0;
if (0xE9 == targetFunc[0]) if (0xE9 == targetFunc[0])
{ {
targetFunc += 1 + *reinterpret_cast<int*>(targetFunc + 1); instructionSize = 5;
targetFunc += instructionSize + *reinterpret_cast<int*>(targetFunc + 1);
} }
else if (0xEB == targetFunc[0]) else if (0xEB == targetFunc[0])
{ {
targetFunc += 1 + static_cast<signed char>(targetFunc[1]); instructionSize = 2;
targetFunc += instructionSize + *reinterpret_cast<signed char*>(targetFunc + 1);
} }
else if (0xFF == targetFunc[0] && 0x25 == targetFunc[1]) else if (0xFF == targetFunc[0] && 0x25 == targetFunc[1])
{ {
instructionSize = 6;
targetFunc = **reinterpret_cast<BYTE***>(targetFunc + 2); targetFunc = **reinterpret_cast<BYTE***>(targetFunc + 2);
} }
else else
@ -149,12 +154,11 @@ namespace
break; break;
} }
#ifdef DEBUGLOGS #ifdef DEBUGLOGS
oss << " -> " << Compat::funcPtrToStr(targetFunc); oss << Compat::hexDump(prevTargetFunc, instructionSize) << " -> " << Compat::funcPtrToStr(targetFunc) << ' ';
prevTargetFunc = targetFunc;
#endif #endif
} }
LOG_DEBUG << "Hooking function: " << funcName << " (" << oss.str() << ')';
if (Compat::getModuleHandleFromAddress(targetFunc) == Dll::g_currentModule) if (Compat::getModuleHandleFromAddress(targetFunc) == Dll::g_currentModule)
{ {
Compat::Log() << "ERROR: Target function is already hooked: " << funcName; Compat::Log() << "ERROR: Target function is already hooked: " << funcName;
@ -177,7 +181,8 @@ namespace
totalInstructionSize += instructionSize; 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<BYTE*>( BYTE* trampoline = static_cast<BYTE*>(
VirtualAlloc(nullptr, totalInstructionSize + 5, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE)); VirtualAlloc(nullptr, totalInstructionSize + 5, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE));
@ -299,7 +304,7 @@ namespace Compat
HMODULE module = Compat::getModuleHandleFromAddress(funcPtr); HMODULE module = Compat::getModuleHandleFromAddress(funcPtr);
if (module) if (module)
{ {
oss << getModulePath(module).string() << "+0x" << std::hex << oss << getModulePath(module) << "+0x" << std::hex <<
reinterpret_cast<DWORD>(funcPtr) - reinterpret_cast<DWORD>(module); reinterpret_cast<DWORD>(funcPtr) - reinterpret_cast<DWORD>(module);
} }
else else

View File

@ -292,7 +292,7 @@ namespace D3dDdi
CompatPtr<IDirectDraw7> dd7(ddUnk); CompatPtr<IDirectDraw7> dd7(ddUnk);
DDDEVICEIDENTIFIER2 di = {}; DDDEVICEIDENTIFIER2 di = {};
dd7->GetDeviceIdentifier(dd7, &di, 0); dd7.get()->lpVtbl->GetDeviceIdentifier(dd7, &di, 0);
} }
return g_lastOpenAdapterInfo.monitorRect; return g_lastOpenAdapterInfo.monitorRect;