mirror of
https://github.com/narzoul/DDrawCompat
synced 2024-12-30 08:55:36 +01:00
parent
4e00ce0447
commit
148d7287e8
@ -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)
|
||||||
|
@ -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
|
||||||
{
|
{
|
||||||
|
@ -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
|
||||||
|
@ -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;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user