mirror of
https://github.com/narzoul/DDrawCompat
synced 2024-12-30 08:55:36 +01:00
Use variable templates and auto template parameters
This commit is contained in:
parent
5882ef9f9c
commit
b2c92f31da
@ -4,26 +4,20 @@
|
||||
|
||||
#include <Windows.h>
|
||||
|
||||
#define CALL_ORIG_FUNC(func) Compat::getOrigFuncPtr<decltype(&func), &func>()
|
||||
#define CALL_ORIG_FUNC(func) Compat::g_origFuncPtr<&func>
|
||||
|
||||
#define HOOK_FUNCTION(module, func, newFunc) \
|
||||
Compat::hookFunction<decltype(&func), &func>(#module, #func, &newFunc)
|
||||
Compat::hookFunction<&func>(#module, #func, &newFunc)
|
||||
#define HOOK_SHIM_FUNCTION(func, newFunc) \
|
||||
Compat::hookFunction( \
|
||||
reinterpret_cast<void*&>(Compat::getOrigFuncPtr<decltype(&func), &func>()), newFunc, #func);
|
||||
|
||||
Compat::hookFunction(reinterpret_cast<void*&>(Compat::g_origFuncPtr<&func>), newFunc, #func)
|
||||
|
||||
namespace Compat
|
||||
{
|
||||
std::string funcPtrToStr(void* funcPtr);
|
||||
HMODULE getModuleHandleFromAddress(void* address);
|
||||
|
||||
template <typename OrigFuncPtr, OrigFuncPtr origFunc>
|
||||
OrigFuncPtr& getOrigFuncPtr()
|
||||
{
|
||||
static OrigFuncPtr origFuncPtr = origFunc;
|
||||
return origFuncPtr;
|
||||
}
|
||||
template <auto origFunc>
|
||||
decltype(origFunc) g_origFuncPtr = origFunc;
|
||||
|
||||
FARPROC getProcAddress(HMODULE module, const char* procName);
|
||||
void hookFunction(void*& origFuncPtr, void* newFuncPtr, const char* funcName);
|
||||
@ -31,11 +25,10 @@ namespace Compat
|
||||
void hookFunction(const char* moduleName, const char* funcName, void*& origFuncPtr, void* newFuncPtr);
|
||||
void hookIatFunction(HMODULE module, const char* funcName, void* newFuncPtr);
|
||||
|
||||
template <typename OrigFuncPtr, OrigFuncPtr origFunc>
|
||||
void hookFunction(const char* moduleName, const char* funcName, OrigFuncPtr newFuncPtr)
|
||||
template <auto origFunc>
|
||||
void hookFunction(const char* moduleName, const char* funcName, decltype(origFunc) newFuncPtr)
|
||||
{
|
||||
hookFunction(moduleName, funcName,
|
||||
reinterpret_cast<void*&>(getOrigFuncPtr<OrigFuncPtr, origFunc>()), newFuncPtr);
|
||||
hookFunction(moduleName, funcName, reinterpret_cast<void*&>(g_origFuncPtr<origFunc>), newFuncPtr);
|
||||
}
|
||||
|
||||
void removeShim(HMODULE module, const char* funcName);
|
||||
|
@ -57,8 +57,8 @@ public:
|
||||
if (m_vtable.*memberPtr)
|
||||
{
|
||||
#ifdef DEBUGLOGS
|
||||
getFuncName<memberPtr>() = s_vtableTypeName + "::" + funcName;
|
||||
Compat::Log() << "Hooking function: " << getFuncName<memberPtr>()
|
||||
s_funcName<memberPtr> = s_vtableTypeName + "::" + funcName;
|
||||
Compat::Log() << "Hooking function: " << s_funcName<memberPtr>
|
||||
<< " (" << Compat::funcPtrToStr(m_vtable.*memberPtr) << ')';
|
||||
#endif
|
||||
m_vtable.*memberPtr = &hookFunc<memberPtr>;
|
||||
@ -67,13 +67,6 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
template <auto memberPtr>
|
||||
static std::string& getFuncName()
|
||||
{
|
||||
static std::string funcName;
|
||||
return funcName;
|
||||
}
|
||||
|
||||
static std::string getVtableTypeName()
|
||||
{
|
||||
std::string name = typeid(Vtable).name();
|
||||
@ -87,10 +80,7 @@ private:
|
||||
template <auto memberPtr, typename Result, typename FirstParam, typename... Params>
|
||||
static Result STDMETHODCALLTYPE hookFunc(FirstParam firstParam, Params... params)
|
||||
{
|
||||
#ifdef DEBUGLOGS
|
||||
const char* funcName = getFuncName<memberPtr>().c_str();
|
||||
#endif
|
||||
LOG_FUNC(funcName, firstParam, params...);
|
||||
LOG_FUNC(s_funcName<memberPtr>.c_str(), firstParam, params...);
|
||||
[[maybe_unused]] Lock lock;
|
||||
constexpr auto compatFunc = getCompatFunc<memberPtr, Vtable>();
|
||||
if constexpr (std::is_void_v<Result>)
|
||||
@ -105,10 +95,17 @@ private:
|
||||
|
||||
Vtable& m_vtable;
|
||||
|
||||
template <auto memberPtr>
|
||||
static std::string s_funcName;
|
||||
|
||||
static std::string s_vtableTypeName;
|
||||
};
|
||||
|
||||
#ifdef DEBUGLOGS
|
||||
template <typename Vtable, typename Lock>
|
||||
template <auto memberPtr>
|
||||
std::string VtableHookVisitor<Vtable, Lock>::s_funcName;
|
||||
|
||||
template <typename Vtable, typename Lock>
|
||||
std::string VtableHookVisitor<Vtable, Lock>::s_vtableTypeName(getVtableTypeName());
|
||||
#endif
|
||||
|
@ -87,7 +87,7 @@
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>dxguid.lib;detours.lib;msimg32.lib;oleacc.lib;psapi.lib;uxtheme.lib;dwmapi.lib;winmm.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalDependencies>dxguid.lib;detours.lib;msimg32.lib;oleacc.lib;uxtheme.lib;dwmapi.lib;winmm.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<GenerateDebugInformation>DebugFull</GenerateDebugInformation>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
|
||||
@ -105,7 +105,7 @@
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>dxguid.lib;detours.lib;msimg32.lib;oleacc.lib;psapi.lib;uxtheme.lib;dwmapi.lib;winmm.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalDependencies>dxguid.lib;detours.lib;msimg32.lib;oleacc.lib;uxtheme.lib;dwmapi.lib;winmm.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<GenerateDebugInformation>DebugFull</GenerateDebugInformation>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
|
||||
@ -123,7 +123,7 @@
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>dxguid.lib;detours.lib;msimg32.lib;oleacc.lib;psapi.lib;uxtheme.lib;dwmapi.lib;winmm.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalDependencies>dxguid.lib;detours.lib;msimg32.lib;oleacc.lib;uxtheme.lib;dwmapi.lib;winmm.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<GenerateDebugInformation>DebugFull</GenerateDebugInformation>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
|
||||
@ -199,7 +199,6 @@
|
||||
<ClInclude Include="Direct3d\Direct3dViewport.h" />
|
||||
<ClInclude Include="Direct3d\Hooks.h" />
|
||||
<ClInclude Include="Direct3d\Log.h" />
|
||||
<ClInclude Include="Direct3d\Types.h" />
|
||||
<ClInclude Include="Direct3d\Visitors\Direct3dDeviceVtblVisitor.h" />
|
||||
<ClInclude Include="Direct3d\Visitors\Direct3dExecuteBufferVtblVisitor.h" />
|
||||
<ClInclude Include="Direct3d\Visitors\Direct3dLightVtblVisitor.h" />
|
||||
|
@ -135,9 +135,6 @@
|
||||
<ClInclude Include="Direct3d\Direct3dDevice.h">
|
||||
<Filter>Header Files\Direct3d</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Direct3d\Types.h">
|
||||
<Filter>Header Files\Direct3d</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Direct3d\Hooks.h">
|
||||
<Filter>Header Files\Direct3d</Filter>
|
||||
</ClInclude>
|
||||
|
@ -1,55 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <d3d.h>
|
||||
|
||||
namespace Direct3d
|
||||
{
|
||||
struct Types1
|
||||
{
|
||||
typedef IDirect3D TDirect3d;
|
||||
typedef IDirect3D3 TDirect3dHighest;
|
||||
typedef IDirect3DDevice TDirect3dDevice;
|
||||
typedef D3DDEVICEDESC TD3dDeviceDesc;
|
||||
typedef LPD3DENUMDEVICESCALLBACK TD3dEnumDevicesCallback;
|
||||
};
|
||||
|
||||
struct Types2
|
||||
{
|
||||
typedef IDirect3D2 TDirect3d;
|
||||
typedef IDirect3D3 TDirect3dHighest;
|
||||
typedef IDirect3DDevice2 TDirect3dDevice;
|
||||
typedef D3DDEVICEDESC TD3dDeviceDesc;
|
||||
typedef LPD3DENUMDEVICESCALLBACK TD3dEnumDevicesCallback;
|
||||
};
|
||||
|
||||
struct Types3
|
||||
{
|
||||
typedef IDirect3D3 TDirect3d;
|
||||
typedef IDirect3D3 TDirect3dHighest;
|
||||
typedef IDirect3DDevice3 TDirect3dDevice;
|
||||
typedef D3DDEVICEDESC TD3dDeviceDesc;
|
||||
typedef LPD3DENUMDEVICESCALLBACK TD3dEnumDevicesCallback;
|
||||
};
|
||||
|
||||
struct Types7
|
||||
{
|
||||
typedef IDirect3D7 TDirect3d;
|
||||
typedef IDirect3D7 TDirect3dHighest;
|
||||
typedef IDirect3DDevice7 TDirect3dDevice;
|
||||
typedef D3DDEVICEDESC7 TD3dDeviceDesc;
|
||||
typedef LPD3DENUMDEVICESCALLBACK7 TD3dEnumDevicesCallback;
|
||||
};
|
||||
|
||||
template <typename Interface>
|
||||
struct Types;
|
||||
|
||||
template <> struct Types<IDirect3D> : Types1 {};
|
||||
template <> struct Types<IDirect3D2> : Types2 {};
|
||||
template <> struct Types<IDirect3D3> : Types3 {};
|
||||
template <> struct Types<IDirect3D7> : Types7 {};
|
||||
|
||||
template <> struct Types<IDirect3DDevice> : Types1 {};
|
||||
template <> struct Types<IDirect3DDevice2> : Types2 {};
|
||||
template <> struct Types<IDirect3DDevice3> : Types3 {};
|
||||
template <> struct Types<IDirect3DDevice7> : Types7 {};
|
||||
}
|
@ -1,8 +1,6 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <Windows.h>
|
||||
#include <Psapi.h>
|
||||
#include <ShellScalingApi.h>
|
||||
#include <timeapi.h>
|
||||
#include <Uxtheme.h>
|
||||
@ -73,17 +71,6 @@ namespace
|
||||
return path;
|
||||
}
|
||||
|
||||
std::vector<HMODULE> getProcessModules(HANDLE process)
|
||||
{
|
||||
std::vector<HMODULE> modules(10000);
|
||||
DWORD bytesNeeded = 0;
|
||||
if (EnumProcessModules(process, modules.data(), modules.size(), &bytesNeeded))
|
||||
{
|
||||
modules.resize(bytesNeeded / sizeof(modules[0]));
|
||||
}
|
||||
return modules;
|
||||
}
|
||||
|
||||
std::string getSystemDirectory()
|
||||
{
|
||||
char path[MAX_PATH] = {};
|
||||
@ -140,28 +127,20 @@ namespace
|
||||
}
|
||||
}
|
||||
|
||||
bool isEqualPath(const std::string& p1, const std::string& p2)
|
||||
bool isEqual(const std::string& p1, const std::string& p2)
|
||||
{
|
||||
return 0 == _strcmpi(p1.c_str(), p2.c_str());
|
||||
return 0 == _stricmp(p1.c_str(), p2.c_str());
|
||||
}
|
||||
|
||||
bool isOtherDDrawWrapperLoaded()
|
||||
{
|
||||
auto currentDllPath = getModulePath(Dll::g_currentModule);
|
||||
auto systemDirectory = getSystemDirectory();
|
||||
auto processModules = getProcessModules(GetCurrentProcess());
|
||||
for (HMODULE module : processModules)
|
||||
{
|
||||
auto path = getModulePath(module);
|
||||
auto fileName = getFileName(path);
|
||||
if ((isEqualPath(fileName, "ddraw.dll") || isEqualPath(fileName, "dciman32.dll")) &&
|
||||
!isEqualPath(path, currentDllPath) &&
|
||||
!isEqualPath(getDirName(path), systemDirectory))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
const auto currentDllPath = getModulePath(Dll::g_currentModule);
|
||||
const auto currentDllDir = getDirName(currentDllPath);
|
||||
const auto ddrawDllPath = currentDllDir + "\\ddraw.dll";
|
||||
const auto dciman32DllPath = currentDllDir + "\\dciman32.dll";
|
||||
|
||||
return (!isEqual(currentDllPath, ddrawDllPath) && GetModuleHandle(ddrawDllPath.c_str())) ||
|
||||
(!isEqual(currentDllPath, dciman32DllPath) && GetModuleHandle(dciman32DllPath.c_str()));
|
||||
}
|
||||
|
||||
void printEnvironmentVariable(const char* var)
|
||||
@ -237,7 +216,7 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
|
||||
Compat::Log() << "Loading DDrawCompat " << (lpvReserved ? "statically" : "dynamically") << " from " << currentDllPath;
|
||||
|
||||
auto systemDirectory = getSystemDirectory();
|
||||
if (isEqualPath(getDirName(currentDllPath), systemDirectory))
|
||||
if (isEqual(getDirName(currentDllPath), systemDirectory))
|
||||
{
|
||||
Compat::Log() << "DDrawCompat cannot be installed in the Windows system directory";
|
||||
return FALSE;
|
||||
|
@ -1,5 +1,3 @@
|
||||
#include <unordered_map>
|
||||
|
||||
#include <Common/Hook.h>
|
||||
#include <Common/Log.h>
|
||||
#include <Gdi/CompatDc.h>
|
||||
@ -13,11 +11,13 @@
|
||||
|
||||
namespace
|
||||
{
|
||||
std::unordered_map<void*, const char*> g_funcNames;
|
||||
template <auto func>
|
||||
const char* g_funcName = nullptr;
|
||||
|
||||
thread_local UINT g_disableDibRedirection = 0;
|
||||
|
||||
#define CREATE_DC_FUNC_ATTRIBUTE(attribute) \
|
||||
template <typename OrigFuncPtr, OrigFuncPtr origFunc> \
|
||||
template <auto origFunc> \
|
||||
bool attribute() \
|
||||
{ \
|
||||
return false; \
|
||||
@ -25,7 +25,7 @@ namespace
|
||||
|
||||
#define SET_DC_FUNC_ATTRIBUTE(attribute, func) \
|
||||
template <> \
|
||||
bool attribute<decltype(&func), &func>() \
|
||||
bool attribute<&func>() \
|
||||
{ \
|
||||
return true; \
|
||||
}
|
||||
@ -53,9 +53,6 @@ namespace
|
||||
BOOL WINAPI GdiDrawStream(HDC, DWORD, DWORD) { return FALSE; }
|
||||
BOOL WINAPI PolyPatBlt(HDC, DWORD, DWORD, DWORD, DWORD) { return FALSE; }
|
||||
|
||||
template <typename Result, typename... Params>
|
||||
using FuncPtr = Result(WINAPI *)(Params...);
|
||||
|
||||
bool hasDisplayDcArg(HDC dc)
|
||||
{
|
||||
return Gdi::isDisplayDc(dc);
|
||||
@ -94,18 +91,16 @@ namespace
|
||||
return Gdi::CompatDc(dc);
|
||||
}
|
||||
|
||||
template <typename OrigFuncPtr, OrigFuncPtr origFunc, typename Result, typename... Params>
|
||||
template <auto origFunc, typename Result, typename... Params>
|
||||
Result WINAPI compatGdiDcFunc(HDC hdc, Params... params)
|
||||
{
|
||||
#ifdef DEBUGLOGS
|
||||
LOG_FUNC(g_funcNames[origFunc], hdc, params...);
|
||||
#endif
|
||||
LOG_FUNC(g_funcName<origFunc>, hdc, params...);
|
||||
|
||||
if (hasDisplayDcArg(hdc, params...))
|
||||
{
|
||||
Gdi::CompatDc compatDc(hdc, isReadOnly<OrigFuncPtr, origFunc>());
|
||||
Result result = Compat::getOrigFuncPtr<OrigFuncPtr, origFunc>()(compatDc, replaceDc(params)...);
|
||||
if (isPositionUpdated<OrigFuncPtr, origFunc>() && result)
|
||||
Gdi::CompatDc compatDc(hdc, isReadOnly<origFunc>());
|
||||
Result result = Compat::g_origFuncPtr<origFunc>(compatDc, replaceDc(params)...);
|
||||
if (isPositionUpdated<origFunc>() && result)
|
||||
{
|
||||
POINT currentPos = {};
|
||||
GetCurrentPositionEx(compatDc, ¤tPos);
|
||||
@ -114,11 +109,11 @@ namespace
|
||||
return LOG_RESULT(result);
|
||||
}
|
||||
|
||||
return LOG_RESULT(Compat::getOrigFuncPtr<OrigFuncPtr, origFunc>()(hdc, params...));
|
||||
return LOG_RESULT(Compat::g_origFuncPtr<origFunc>(hdc, params...));
|
||||
}
|
||||
|
||||
template <>
|
||||
BOOL WINAPI compatGdiDcFunc<decltype(&ExtTextOutW), &ExtTextOutW>(
|
||||
BOOL WINAPI compatGdiDcFunc<&ExtTextOutW>(
|
||||
HDC hdc, int x, int y, UINT options, const RECT* lprect, LPCWSTR lpString, UINT c, const INT* lpDx)
|
||||
{
|
||||
LOG_FUNC("ExtTextOutW", hdc, x, y, options, lprect, lpString, c, lpDx);
|
||||
@ -164,11 +159,11 @@ namespace
|
||||
return LOG_RESULT(TRUE);
|
||||
}
|
||||
|
||||
template <typename OrigFuncPtr, OrigFuncPtr origFunc, typename Result, typename... Params>
|
||||
template <auto origFunc, typename Result, typename... Params>
|
||||
Result WINAPI compatGdiTextDcFunc(HDC dc, Params... params)
|
||||
{
|
||||
Gdi::Font::Mapper fontMapper(dc);
|
||||
return compatGdiDcFunc<OrigFuncPtr, origFunc, Result>(dc, params...);
|
||||
return compatGdiDcFunc<origFunc, Result>(dc, params...);
|
||||
}
|
||||
|
||||
HBITMAP WINAPI createCompatibleBitmap(HDC hdc, int cx, int cy)
|
||||
@ -222,38 +217,24 @@ namespace
|
||||
return LOG_RESULT(CALL_ORIG_FUNC(DrawCaption)(hwnd, hdc, lprect, flags));
|
||||
}
|
||||
|
||||
template <typename OrigFuncPtr, OrigFuncPtr origFunc, typename Result, typename... Params>
|
||||
OrigFuncPtr getCompatGdiDcFuncPtr(FuncPtr<Result, HDC, Params...>)
|
||||
{
|
||||
return &compatGdiDcFunc<OrigFuncPtr, origFunc, Result, Params...>;
|
||||
}
|
||||
|
||||
template <typename OrigFuncPtr, OrigFuncPtr origFunc, typename Result, typename... Params>
|
||||
OrigFuncPtr getCompatGdiTextDcFuncPtr(FuncPtr<Result, HDC, Params...>)
|
||||
{
|
||||
return &compatGdiTextDcFunc<OrigFuncPtr, origFunc, Result, Params...>;
|
||||
}
|
||||
|
||||
template <typename OrigFuncPtr, OrigFuncPtr origFunc>
|
||||
template <auto origFunc>
|
||||
void hookGdiDcFunction(const char* moduleName, const char* funcName)
|
||||
{
|
||||
#ifdef DEBUGLOGS
|
||||
g_funcNames[origFunc] = funcName;
|
||||
g_funcName<origFunc> = funcName;
|
||||
#endif
|
||||
|
||||
Compat::hookFunction<OrigFuncPtr, origFunc>(
|
||||
moduleName, funcName, getCompatGdiDcFuncPtr<OrigFuncPtr, origFunc>(origFunc));
|
||||
Compat::hookFunction<origFunc>(moduleName, funcName, &compatGdiDcFunc<origFunc>);
|
||||
}
|
||||
|
||||
template <typename OrigFuncPtr, OrigFuncPtr origFunc>
|
||||
template <auto origFunc>
|
||||
void hookGdiTextDcFunction(const char* moduleName, const char* funcName)
|
||||
{
|
||||
#ifdef DEBUGLOGS
|
||||
g_funcNames[origFunc] = funcName;
|
||||
g_funcName<origFunc> = funcName;
|
||||
#endif
|
||||
|
||||
Compat::hookFunction<OrigFuncPtr, origFunc>(
|
||||
moduleName, funcName, getCompatGdiTextDcFuncPtr<OrigFuncPtr, origFunc>(origFunc));
|
||||
Compat::hookFunction<origFunc>(moduleName, funcName, &compatGdiTextDcFunc<origFunc>);
|
||||
}
|
||||
|
||||
HWND WINAPI windowFromDc(HDC dc)
|
||||
@ -263,11 +244,11 @@ namespace
|
||||
}
|
||||
|
||||
#define HOOK_GDI_DC_FUNCTION(module, func) \
|
||||
hookGdiDcFunction<decltype(&func), &func>(#module, #func)
|
||||
hookGdiDcFunction<&func>(#module, #func)
|
||||
|
||||
#define HOOK_GDI_TEXT_DC_FUNCTION(module, func) \
|
||||
HOOK_GDI_DC_FUNCTION(module, func##A); \
|
||||
HOOK_GDI_DC_FUNCTION(module, func##W)
|
||||
hookGdiTextDcFunction<&func##A>(#module, #func"A"); \
|
||||
hookGdiTextDcFunction<&func##W>(#module, #func"W")
|
||||
|
||||
namespace Gdi
|
||||
{
|
||||
|
@ -1,5 +1,3 @@
|
||||
#include <map>
|
||||
|
||||
#include <Common/Hook.h>
|
||||
#include <Common/Log.h>
|
||||
#include <Gdi/DcFunctions.h>
|
||||
@ -7,71 +5,57 @@
|
||||
|
||||
namespace
|
||||
{
|
||||
std::map<void*, const char*> g_funcNames;
|
||||
template <auto func>
|
||||
const char* g_funcName = nullptr;
|
||||
|
||||
template <typename Result, typename... Params>
|
||||
using FuncPtr = Result(WINAPI*)(Params...);
|
||||
|
||||
template <typename OrigFuncPtr, OrigFuncPtr origFunc, typename... Params>
|
||||
struct EnableDibRedirection
|
||||
template <auto origFunc, typename... Params>
|
||||
bool isDibRedirectionEnabled(Params...)
|
||||
{
|
||||
bool operator()(Params...) { return false; }
|
||||
};
|
||||
return false;
|
||||
}
|
||||
|
||||
template <typename... Params>
|
||||
struct EnableDibRedirection<decltype(&CopyImage), &CopyImage, Params...>
|
||||
template <>
|
||||
bool isDibRedirectionEnabled<&CopyImage>(HANDLE, UINT type, int, int, UINT)
|
||||
{
|
||||
bool operator()(HANDLE, UINT type, int, int, UINT)
|
||||
{
|
||||
return IMAGE_CURSOR != type && IMAGE_ICON != type;
|
||||
}
|
||||
};
|
||||
return IMAGE_CURSOR != type && IMAGE_ICON != type;
|
||||
}
|
||||
|
||||
struct EnableDibRedirectionLoadImage
|
||||
template <>
|
||||
bool isDibRedirectionEnabled<&LoadImageA>(HINSTANCE, LPCSTR, UINT type, int, int, UINT)
|
||||
{
|
||||
template <typename String>
|
||||
bool operator()(HINSTANCE, String, UINT type, int, int, UINT)
|
||||
{
|
||||
return IMAGE_CURSOR != type && IMAGE_ICON != type;
|
||||
}
|
||||
};
|
||||
return IMAGE_CURSOR != type && IMAGE_ICON != type;
|
||||
}
|
||||
|
||||
template <typename... Params>
|
||||
struct EnableDibRedirection<decltype(&LoadImageA), &LoadImageA, Params...> : EnableDibRedirectionLoadImage {};
|
||||
template <typename... Params>
|
||||
struct EnableDibRedirection<decltype(&LoadImageW), &LoadImageW, Params...> : EnableDibRedirectionLoadImage {};
|
||||
template <>
|
||||
bool isDibRedirectionEnabled<&LoadImageW>(HINSTANCE, LPCWSTR, UINT type, int, int, UINT)
|
||||
{
|
||||
return IMAGE_CURSOR != type && IMAGE_ICON != type;
|
||||
}
|
||||
|
||||
template <typename OrigFuncPtr, OrigFuncPtr origFunc, typename Result, typename... Params>
|
||||
template <auto origFunc, typename Result, typename... Params>
|
||||
Result WINAPI iconFunc(Params... params)
|
||||
{
|
||||
LOG_FUNC(g_funcNames[origFunc], params...);
|
||||
LOG_FUNC(g_funcName<origFunc>, params...);
|
||||
|
||||
if (EnableDibRedirection<OrigFuncPtr, origFunc, Params...>()(params...))
|
||||
if (isDibRedirectionEnabled<origFunc>(params...))
|
||||
{
|
||||
return LOG_RESULT(Compat::getOrigFuncPtr<OrigFuncPtr, origFunc>()(params...));
|
||||
return LOG_RESULT(Compat::g_origFuncPtr<origFunc>(params...));
|
||||
}
|
||||
|
||||
Gdi::DcFunctions::disableDibRedirection(true);
|
||||
Result result = Compat::getOrigFuncPtr<OrigFuncPtr, origFunc>()(params...);
|
||||
Result result = Compat::g_origFuncPtr<origFunc>(params...);
|
||||
Gdi::DcFunctions::disableDibRedirection(false);
|
||||
return LOG_RESULT(result);
|
||||
}
|
||||
|
||||
template <typename OrigFuncPtr, OrigFuncPtr origFunc, typename Result, typename... Params>
|
||||
OrigFuncPtr getIconFuncPtr(FuncPtr<Result, Params...>)
|
||||
{
|
||||
return &iconFunc<OrigFuncPtr, origFunc, Result, Params...>;
|
||||
}
|
||||
|
||||
template <typename OrigFuncPtr, OrigFuncPtr origFunc>
|
||||
template <auto origFunc>
|
||||
void hookIconFunc(const char* moduleName, const char* funcName)
|
||||
{
|
||||
#ifdef DEBUGLOGS
|
||||
g_funcNames[origFunc] = funcName;
|
||||
g_funcName<origFunc> = funcName;
|
||||
#endif
|
||||
|
||||
Compat::hookFunction<OrigFuncPtr, origFunc>(
|
||||
moduleName, funcName, getIconFuncPtr<OrigFuncPtr, origFunc>(origFunc));
|
||||
Compat::hookFunction<origFunc>(moduleName, funcName, &iconFunc<origFunc>);
|
||||
}
|
||||
|
||||
template <typename WndClass, typename WndClassEx>
|
||||
@ -130,7 +114,7 @@ namespace
|
||||
}
|
||||
}
|
||||
|
||||
#define HOOK_ICON_FUNCTION(module, func) hookIconFunc<decltype(&func), &func>(#module, #func)
|
||||
#define HOOK_ICON_FUNCTION(module, func) hookIconFunc<&func>(#module, #func)
|
||||
|
||||
namespace Gdi
|
||||
{
|
||||
|
@ -1,5 +1,3 @@
|
||||
#include <vector>
|
||||
|
||||
#include <D3dDdi/ScopedCriticalSection.h>
|
||||
#include <Gdi/CompatDc.h>
|
||||
#include <Gdi/ScrollBar.h>
|
||||
@ -40,6 +38,11 @@ namespace
|
||||
bool isUnicode;
|
||||
};
|
||||
|
||||
template <WndProcHook>
|
||||
User32WndProc g_user32WndProcA = {};
|
||||
template <WndProcHook>
|
||||
User32WndProc g_user32WndProcW = {};
|
||||
|
||||
LRESULT defPaintProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam, WNDPROC origWndProc);
|
||||
LRESULT defPaintProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam, WNDPROC origWndProc,
|
||||
const char* origWndProcName);
|
||||
@ -218,20 +221,6 @@ namespace
|
||||
return defPaintProc(hwnd, msg, wParam, lParam, origWndProc);
|
||||
}
|
||||
|
||||
template <WndProcHook>
|
||||
User32WndProc& getUser32WndProcA()
|
||||
{
|
||||
static User32WndProc user32WndProcA = {};
|
||||
return user32WndProcA;
|
||||
}
|
||||
|
||||
template <WndProcHook>
|
||||
User32WndProc& getUser32WndProcW()
|
||||
{
|
||||
static User32WndProc user32WndProcW = {};
|
||||
return user32WndProcW;
|
||||
}
|
||||
|
||||
void hookUser32WndProc(User32WndProc& user32WndProc, WNDPROC newWndProc,
|
||||
const std::string& procName, const std::string& className, bool isUnicode)
|
||||
{
|
||||
@ -270,14 +259,14 @@ namespace
|
||||
template <WndProcHook wndProcHook>
|
||||
void hookUser32WndProcA(const std::string& className, const std::string& procName)
|
||||
{
|
||||
hookUser32WndProc(getUser32WndProcA<wndProcHook>(), user32WndProcA<wndProcHook>,
|
||||
hookUser32WndProc(g_user32WndProcA<wndProcHook>, user32WndProcA<wndProcHook>,
|
||||
procName + 'A', className, false);
|
||||
}
|
||||
|
||||
template <WndProcHook wndProcHook>
|
||||
void hookUser32WndProcW(const std::string& className, const std::string& procName)
|
||||
{
|
||||
hookUser32WndProc(getUser32WndProcW<wndProcHook>(), user32WndProcW<wndProcHook>,
|
||||
hookUser32WndProc(g_user32WndProcW<wndProcHook>, user32WndProcW<wndProcHook>,
|
||||
procName + 'W', className, true);
|
||||
}
|
||||
|
||||
@ -465,14 +454,14 @@ namespace
|
||||
template <WndProcHook wndProcHook>
|
||||
LRESULT CALLBACK user32WndProcA(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
auto& wp = getUser32WndProcA<wndProcHook>();
|
||||
auto& wp = g_user32WndProcA<wndProcHook>;
|
||||
return user32WndProc(hwnd, uMsg, wParam, lParam, wp.procName, wndProcHook, wp.oldWndProcTrampoline);
|
||||
}
|
||||
|
||||
template <WndProcHook wndProcHook>
|
||||
LRESULT CALLBACK user32WndProcW(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
auto& wp = getUser32WndProcW<wndProcHook>();
|
||||
auto& wp = g_user32WndProcW<wndProcHook>;
|
||||
return user32WndProc(hwnd, uMsg, wParam, lParam, wp.procName, wndProcHook, wp.oldWndProcTrampoline);
|
||||
}
|
||||
}
|
||||
|
@ -19,16 +19,16 @@ namespace
|
||||
}
|
||||
}
|
||||
|
||||
template <typename FuncPtr, FuncPtr func, typename Result, typename... Params>
|
||||
template <auto func, typename Result, typename... Params>
|
||||
Result WINAPI mitigatedBusyWaitingFunc(Params... params)
|
||||
{
|
||||
mitigateBusyWaiting();
|
||||
return Compat::getOrigFuncPtr<FuncPtr, func>()(params...);
|
||||
return Compat::g_origFuncPtr<func>(params...);
|
||||
}
|
||||
}
|
||||
|
||||
#define MITIGATE_BUSY_WAITING(module, func) \
|
||||
Compat::hookFunction<decltype(&func), &func>(#module, #func, &mitigatedBusyWaitingFunc<decltype(&func), func>)
|
||||
Compat::hookFunction<&func>(#module, #func, &mitigatedBusyWaitingFunc<&func>)
|
||||
|
||||
namespace Win32
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user