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<IDirect3D2, IDirect3D7> : std::false_type {};
|
||||
template<> struct IsConvertible<IDirect3D3, IDirect3D7> : std::false_type {};
|
||||
@ -61,6 +64,8 @@ namespace Compat
|
||||
#define DEFINE_INTF_ID(Intf) \
|
||||
template<> inline const IID& getIntfId<Intf>() { 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 <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>
|
||||
std::enable_if_t<IsConvertible<OrigIntf, NewIntf>::value>
|
||||
queryInterface(OrigIntf& origIntf, NewIntf*& newIntf)
|
||||
|
@ -15,6 +15,11 @@ const Vtable<Interface>& getOrigVtable(Interface* /*This*/)
|
||||
return CompatVtable<Vtable<Interface>>::s_origVtable;
|
||||
}
|
||||
|
||||
inline const IUnknownVtbl& getOrigVtable(IUnknown* This)
|
||||
{
|
||||
return *This->lpVtbl;
|
||||
}
|
||||
|
||||
template <typename Vtable>
|
||||
class CompatVtable
|
||||
{
|
||||
|
@ -1,6 +1,5 @@
|
||||
#undef CINTERFACE
|
||||
|
||||
#include <filesystem>
|
||||
#include <list>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
@ -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<unsigned>(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<int*>(targetFunc + 1);
|
||||
instructionSize = 5;
|
||||
targetFunc += instructionSize + *reinterpret_cast<int*>(targetFunc + 1);
|
||||
}
|
||||
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])
|
||||
{
|
||||
instructionSize = 6;
|
||||
targetFunc = **reinterpret_cast<BYTE***>(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<BYTE*>(
|
||||
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<DWORD>(funcPtr) - reinterpret_cast<DWORD>(module);
|
||||
}
|
||||
else
|
||||
|
@ -292,7 +292,7 @@ namespace D3dDdi
|
||||
CompatPtr<IDirectDraw7> dd7(ddUnk);
|
||||
|
||||
DDDEVICEIDENTIFIER2 di = {};
|
||||
dd7->GetDeviceIdentifier(dd7, &di, 0);
|
||||
dd7.get()->lpVtbl->GetDeviceIdentifier(dd7, &di, 0);
|
||||
}
|
||||
|
||||
return g_lastOpenAdapterInfo.monitorRect;
|
||||
|
Loading…
x
Reference in New Issue
Block a user