1
0
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:
narzoul 2021-03-20 16:16:39 +01:00
parent 5882ef9f9c
commit b2c92f31da
10 changed files with 94 additions and 230 deletions

View File

@ -4,26 +4,20 @@
#include <Windows.h> #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) \ #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) \ #define HOOK_SHIM_FUNCTION(func, newFunc) \
Compat::hookFunction( \ Compat::hookFunction(reinterpret_cast<void*&>(Compat::g_origFuncPtr<&func>), newFunc, #func)
reinterpret_cast<void*&>(Compat::getOrigFuncPtr<decltype(&func), &func>()), newFunc, #func);
namespace Compat namespace Compat
{ {
std::string funcPtrToStr(void* funcPtr); std::string funcPtrToStr(void* funcPtr);
HMODULE getModuleHandleFromAddress(void* address); HMODULE getModuleHandleFromAddress(void* address);
template <typename OrigFuncPtr, OrigFuncPtr origFunc> template <auto origFunc>
OrigFuncPtr& getOrigFuncPtr() decltype(origFunc) g_origFuncPtr = origFunc;
{
static OrigFuncPtr origFuncPtr = origFunc;
return origFuncPtr;
}
FARPROC getProcAddress(HMODULE module, const char* procName); FARPROC getProcAddress(HMODULE module, const char* procName);
void hookFunction(void*& origFuncPtr, void* newFuncPtr, const char* funcName); 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 hookFunction(const char* moduleName, const char* funcName, void*& origFuncPtr, void* newFuncPtr);
void hookIatFunction(HMODULE module, const char* funcName, void* newFuncPtr); void hookIatFunction(HMODULE module, const char* funcName, void* newFuncPtr);
template <typename OrigFuncPtr, OrigFuncPtr origFunc> template <auto origFunc>
void hookFunction(const char* moduleName, const char* funcName, OrigFuncPtr newFuncPtr) void hookFunction(const char* moduleName, const char* funcName, decltype(origFunc) newFuncPtr)
{ {
hookFunction(moduleName, funcName, hookFunction(moduleName, funcName, reinterpret_cast<void*&>(g_origFuncPtr<origFunc>), newFuncPtr);
reinterpret_cast<void*&>(getOrigFuncPtr<OrigFuncPtr, origFunc>()), newFuncPtr);
} }
void removeShim(HMODULE module, const char* funcName); void removeShim(HMODULE module, const char* funcName);

View File

@ -57,8 +57,8 @@ public:
if (m_vtable.*memberPtr) if (m_vtable.*memberPtr)
{ {
#ifdef DEBUGLOGS #ifdef DEBUGLOGS
getFuncName<memberPtr>() = s_vtableTypeName + "::" + funcName; s_funcName<memberPtr> = s_vtableTypeName + "::" + funcName;
Compat::Log() << "Hooking function: " << getFuncName<memberPtr>() Compat::Log() << "Hooking function: " << s_funcName<memberPtr>
<< " (" << Compat::funcPtrToStr(m_vtable.*memberPtr) << ')'; << " (" << Compat::funcPtrToStr(m_vtable.*memberPtr) << ')';
#endif #endif
m_vtable.*memberPtr = &hookFunc<memberPtr>; m_vtable.*memberPtr = &hookFunc<memberPtr>;
@ -67,13 +67,6 @@ public:
} }
private: private:
template <auto memberPtr>
static std::string& getFuncName()
{
static std::string funcName;
return funcName;
}
static std::string getVtableTypeName() static std::string getVtableTypeName()
{ {
std::string name = typeid(Vtable).name(); std::string name = typeid(Vtable).name();
@ -87,10 +80,7 @@ private:
template <auto memberPtr, typename Result, typename FirstParam, typename... Params> template <auto memberPtr, typename Result, typename FirstParam, typename... Params>
static Result STDMETHODCALLTYPE hookFunc(FirstParam firstParam, Params... params) static Result STDMETHODCALLTYPE hookFunc(FirstParam firstParam, Params... params)
{ {
#ifdef DEBUGLOGS LOG_FUNC(s_funcName<memberPtr>.c_str(), firstParam, params...);
const char* funcName = getFuncName<memberPtr>().c_str();
#endif
LOG_FUNC(funcName, firstParam, params...);
[[maybe_unused]] Lock lock; [[maybe_unused]] Lock lock;
constexpr auto compatFunc = getCompatFunc<memberPtr, Vtable>(); constexpr auto compatFunc = getCompatFunc<memberPtr, Vtable>();
if constexpr (std::is_void_v<Result>) if constexpr (std::is_void_v<Result>)
@ -105,10 +95,17 @@ private:
Vtable& m_vtable; Vtable& m_vtable;
template <auto memberPtr>
static std::string s_funcName;
static std::string s_vtableTypeName; static std::string s_vtableTypeName;
}; };
#ifdef DEBUGLOGS #ifdef DEBUGLOGS
template <typename Vtable, typename Lock>
template <auto memberPtr>
std::string VtableHookVisitor<Vtable, Lock>::s_funcName;
template <typename Vtable, typename Lock> template <typename Vtable, typename Lock>
std::string VtableHookVisitor<Vtable, Lock>::s_vtableTypeName(getVtableTypeName()); std::string VtableHookVisitor<Vtable, Lock>::s_vtableTypeName(getVtableTypeName());
#endif #endif

View File

@ -87,7 +87,7 @@
<LanguageStandard>stdcpp17</LanguageStandard> <LanguageStandard>stdcpp17</LanguageStandard>
</ClCompile> </ClCompile>
<Link> <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> <GenerateDebugInformation>DebugFull</GenerateDebugInformation>
<OptimizeReferences>true</OptimizeReferences> <OptimizeReferences>true</OptimizeReferences>
<ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary> <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
@ -105,7 +105,7 @@
<LanguageStandard>stdcpp17</LanguageStandard> <LanguageStandard>stdcpp17</LanguageStandard>
</ClCompile> </ClCompile>
<Link> <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> <GenerateDebugInformation>DebugFull</GenerateDebugInformation>
<OptimizeReferences>true</OptimizeReferences> <OptimizeReferences>true</OptimizeReferences>
<ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary> <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
@ -123,7 +123,7 @@
<LanguageStandard>stdcpp17</LanguageStandard> <LanguageStandard>stdcpp17</LanguageStandard>
</ClCompile> </ClCompile>
<Link> <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> <GenerateDebugInformation>DebugFull</GenerateDebugInformation>
<OptimizeReferences>true</OptimizeReferences> <OptimizeReferences>true</OptimizeReferences>
<ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary> <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
@ -199,7 +199,6 @@
<ClInclude Include="Direct3d\Direct3dViewport.h" /> <ClInclude Include="Direct3d\Direct3dViewport.h" />
<ClInclude Include="Direct3d\Hooks.h" /> <ClInclude Include="Direct3d\Hooks.h" />
<ClInclude Include="Direct3d\Log.h" /> <ClInclude Include="Direct3d\Log.h" />
<ClInclude Include="Direct3d\Types.h" />
<ClInclude Include="Direct3d\Visitors\Direct3dDeviceVtblVisitor.h" /> <ClInclude Include="Direct3d\Visitors\Direct3dDeviceVtblVisitor.h" />
<ClInclude Include="Direct3d\Visitors\Direct3dExecuteBufferVtblVisitor.h" /> <ClInclude Include="Direct3d\Visitors\Direct3dExecuteBufferVtblVisitor.h" />
<ClInclude Include="Direct3d\Visitors\Direct3dLightVtblVisitor.h" /> <ClInclude Include="Direct3d\Visitors\Direct3dLightVtblVisitor.h" />

View File

@ -135,9 +135,6 @@
<ClInclude Include="Direct3d\Direct3dDevice.h"> <ClInclude Include="Direct3d\Direct3dDevice.h">
<Filter>Header Files\Direct3d</Filter> <Filter>Header Files\Direct3d</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="Direct3d\Types.h">
<Filter>Header Files\Direct3d</Filter>
</ClInclude>
<ClInclude Include="Direct3d\Hooks.h"> <ClInclude Include="Direct3d\Hooks.h">
<Filter>Header Files\Direct3d</Filter> <Filter>Header Files\Direct3d</Filter>
</ClInclude> </ClInclude>

View File

@ -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 {};
}

View File

@ -1,8 +1,6 @@
#include <string> #include <string>
#include <vector>
#include <Windows.h> #include <Windows.h>
#include <Psapi.h>
#include <ShellScalingApi.h> #include <ShellScalingApi.h>
#include <timeapi.h> #include <timeapi.h>
#include <Uxtheme.h> #include <Uxtheme.h>
@ -73,17 +71,6 @@ namespace
return path; 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() std::string getSystemDirectory()
{ {
char path[MAX_PATH] = {}; 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() bool isOtherDDrawWrapperLoaded()
{ {
auto currentDllPath = getModulePath(Dll::g_currentModule); const auto currentDllPath = getModulePath(Dll::g_currentModule);
auto systemDirectory = getSystemDirectory(); const auto currentDllDir = getDirName(currentDllPath);
auto processModules = getProcessModules(GetCurrentProcess()); const auto ddrawDllPath = currentDllDir + "\\ddraw.dll";
for (HMODULE module : processModules) const auto dciman32DllPath = currentDllDir + "\\dciman32.dll";
{
auto path = getModulePath(module); return (!isEqual(currentDllPath, ddrawDllPath) && GetModuleHandle(ddrawDllPath.c_str())) ||
auto fileName = getFileName(path); (!isEqual(currentDllPath, dciman32DllPath) && GetModuleHandle(dciman32DllPath.c_str()));
if ((isEqualPath(fileName, "ddraw.dll") || isEqualPath(fileName, "dciman32.dll")) &&
!isEqualPath(path, currentDllPath) &&
!isEqualPath(getDirName(path), systemDirectory))
{
return true;
}
}
return false;
} }
void printEnvironmentVariable(const char* var) 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; Compat::Log() << "Loading DDrawCompat " << (lpvReserved ? "statically" : "dynamically") << " from " << currentDllPath;
auto systemDirectory = getSystemDirectory(); auto systemDirectory = getSystemDirectory();
if (isEqualPath(getDirName(currentDllPath), systemDirectory)) if (isEqual(getDirName(currentDllPath), systemDirectory))
{ {
Compat::Log() << "DDrawCompat cannot be installed in the Windows system directory"; Compat::Log() << "DDrawCompat cannot be installed in the Windows system directory";
return FALSE; return FALSE;

View File

@ -1,5 +1,3 @@
#include <unordered_map>
#include <Common/Hook.h> #include <Common/Hook.h>
#include <Common/Log.h> #include <Common/Log.h>
#include <Gdi/CompatDc.h> #include <Gdi/CompatDc.h>
@ -13,11 +11,13 @@
namespace namespace
{ {
std::unordered_map<void*, const char*> g_funcNames; template <auto func>
const char* g_funcName = nullptr;
thread_local UINT g_disableDibRedirection = 0; thread_local UINT g_disableDibRedirection = 0;
#define CREATE_DC_FUNC_ATTRIBUTE(attribute) \ #define CREATE_DC_FUNC_ATTRIBUTE(attribute) \
template <typename OrigFuncPtr, OrigFuncPtr origFunc> \ template <auto origFunc> \
bool attribute() \ bool attribute() \
{ \ { \
return false; \ return false; \
@ -25,7 +25,7 @@ namespace
#define SET_DC_FUNC_ATTRIBUTE(attribute, func) \ #define SET_DC_FUNC_ATTRIBUTE(attribute, func) \
template <> \ template <> \
bool attribute<decltype(&func), &func>() \ bool attribute<&func>() \
{ \ { \
return true; \ return true; \
} }
@ -53,9 +53,6 @@ namespace
BOOL WINAPI GdiDrawStream(HDC, DWORD, DWORD) { return FALSE; } BOOL WINAPI GdiDrawStream(HDC, DWORD, DWORD) { return FALSE; }
BOOL WINAPI PolyPatBlt(HDC, DWORD, DWORD, 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) bool hasDisplayDcArg(HDC dc)
{ {
return Gdi::isDisplayDc(dc); return Gdi::isDisplayDc(dc);
@ -94,18 +91,16 @@ namespace
return Gdi::CompatDc(dc); 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) Result WINAPI compatGdiDcFunc(HDC hdc, Params... params)
{ {
#ifdef DEBUGLOGS LOG_FUNC(g_funcName<origFunc>, hdc, params...);
LOG_FUNC(g_funcNames[origFunc], hdc, params...);
#endif
if (hasDisplayDcArg(hdc, params...)) if (hasDisplayDcArg(hdc, params...))
{ {
Gdi::CompatDc compatDc(hdc, isReadOnly<OrigFuncPtr, origFunc>()); Gdi::CompatDc compatDc(hdc, isReadOnly<origFunc>());
Result result = Compat::getOrigFuncPtr<OrigFuncPtr, origFunc>()(compatDc, replaceDc(params)...); Result result = Compat::g_origFuncPtr<origFunc>(compatDc, replaceDc(params)...);
if (isPositionUpdated<OrigFuncPtr, origFunc>() && result) if (isPositionUpdated<origFunc>() && result)
{ {
POINT currentPos = {}; POINT currentPos = {};
GetCurrentPositionEx(compatDc, &currentPos); GetCurrentPositionEx(compatDc, &currentPos);
@ -114,11 +109,11 @@ namespace
return LOG_RESULT(result); return LOG_RESULT(result);
} }
return LOG_RESULT(Compat::getOrigFuncPtr<OrigFuncPtr, origFunc>()(hdc, params...)); return LOG_RESULT(Compat::g_origFuncPtr<origFunc>(hdc, params...));
} }
template <> 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) 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); LOG_FUNC("ExtTextOutW", hdc, x, y, options, lprect, lpString, c, lpDx);
@ -164,11 +159,11 @@ namespace
return LOG_RESULT(TRUE); 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) Result WINAPI compatGdiTextDcFunc(HDC dc, Params... params)
{ {
Gdi::Font::Mapper fontMapper(dc); 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) 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)); return LOG_RESULT(CALL_ORIG_FUNC(DrawCaption)(hwnd, hdc, lprect, flags));
} }
template <typename OrigFuncPtr, OrigFuncPtr origFunc, typename Result, typename... Params> template <auto origFunc>
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>
void hookGdiDcFunction(const char* moduleName, const char* funcName) void hookGdiDcFunction(const char* moduleName, const char* funcName)
{ {
#ifdef DEBUGLOGS #ifdef DEBUGLOGS
g_funcNames[origFunc] = funcName; g_funcName<origFunc> = funcName;
#endif #endif
Compat::hookFunction<OrigFuncPtr, origFunc>( Compat::hookFunction<origFunc>(moduleName, funcName, &compatGdiDcFunc<origFunc>);
moduleName, funcName, getCompatGdiDcFuncPtr<OrigFuncPtr, origFunc>(origFunc));
} }
template <typename OrigFuncPtr, OrigFuncPtr origFunc> template <auto origFunc>
void hookGdiTextDcFunction(const char* moduleName, const char* funcName) void hookGdiTextDcFunction(const char* moduleName, const char* funcName)
{ {
#ifdef DEBUGLOGS #ifdef DEBUGLOGS
g_funcNames[origFunc] = funcName; g_funcName<origFunc> = funcName;
#endif #endif
Compat::hookFunction<OrigFuncPtr, origFunc>( Compat::hookFunction<origFunc>(moduleName, funcName, &compatGdiTextDcFunc<origFunc>);
moduleName, funcName, getCompatGdiTextDcFuncPtr<OrigFuncPtr, origFunc>(origFunc));
} }
HWND WINAPI windowFromDc(HDC dc) HWND WINAPI windowFromDc(HDC dc)
@ -263,11 +244,11 @@ namespace
} }
#define HOOK_GDI_DC_FUNCTION(module, func) \ #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) \ #define HOOK_GDI_TEXT_DC_FUNCTION(module, func) \
HOOK_GDI_DC_FUNCTION(module, func##A); \ hookGdiTextDcFunction<&func##A>(#module, #func"A"); \
HOOK_GDI_DC_FUNCTION(module, func##W) hookGdiTextDcFunction<&func##W>(#module, #func"W")
namespace Gdi namespace Gdi
{ {

View File

@ -1,5 +1,3 @@
#include <map>
#include <Common/Hook.h> #include <Common/Hook.h>
#include <Common/Log.h> #include <Common/Log.h>
#include <Gdi/DcFunctions.h> #include <Gdi/DcFunctions.h>
@ -7,71 +5,57 @@
namespace namespace
{ {
std::map<void*, const char*> g_funcNames; template <auto func>
const char* g_funcName = nullptr;
template <typename Result, typename... Params> template <auto origFunc, typename... Params>
using FuncPtr = Result(WINAPI*)(Params...); bool isDibRedirectionEnabled(Params...)
template <typename OrigFuncPtr, OrigFuncPtr origFunc, typename... Params>
struct EnableDibRedirection
{ {
bool operator()(Params...) { return false; } return false;
}; }
template <typename... Params> template <>
struct EnableDibRedirection<decltype(&CopyImage), &CopyImage, Params...> 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> return IMAGE_CURSOR != type && IMAGE_ICON != type;
bool operator()(HINSTANCE, String, UINT type, int, int, UINT) }
{
return IMAGE_CURSOR != type && IMAGE_ICON != type;
}
};
template <typename... Params> template <>
struct EnableDibRedirection<decltype(&LoadImageA), &LoadImageA, Params...> : EnableDibRedirectionLoadImage {}; bool isDibRedirectionEnabled<&LoadImageW>(HINSTANCE, LPCWSTR, UINT type, int, int, UINT)
template <typename... Params> {
struct EnableDibRedirection<decltype(&LoadImageW), &LoadImageW, Params...> : EnableDibRedirectionLoadImage {}; 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) 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); Gdi::DcFunctions::disableDibRedirection(true);
Result result = Compat::getOrigFuncPtr<OrigFuncPtr, origFunc>()(params...); Result result = Compat::g_origFuncPtr<origFunc>(params...);
Gdi::DcFunctions::disableDibRedirection(false); Gdi::DcFunctions::disableDibRedirection(false);
return LOG_RESULT(result); return LOG_RESULT(result);
} }
template <typename OrigFuncPtr, OrigFuncPtr origFunc, typename Result, typename... Params> template <auto origFunc>
OrigFuncPtr getIconFuncPtr(FuncPtr<Result, Params...>)
{
return &iconFunc<OrigFuncPtr, origFunc, Result, Params...>;
}
template <typename OrigFuncPtr, OrigFuncPtr origFunc>
void hookIconFunc(const char* moduleName, const char* funcName) void hookIconFunc(const char* moduleName, const char* funcName)
{ {
#ifdef DEBUGLOGS #ifdef DEBUGLOGS
g_funcNames[origFunc] = funcName; g_funcName<origFunc> = funcName;
#endif #endif
Compat::hookFunction<OrigFuncPtr, origFunc>( Compat::hookFunction<origFunc>(moduleName, funcName, &iconFunc<origFunc>);
moduleName, funcName, getIconFuncPtr<OrigFuncPtr, origFunc>(origFunc));
} }
template <typename WndClass, typename WndClassEx> 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 namespace Gdi
{ {

View File

@ -1,5 +1,3 @@
#include <vector>
#include <D3dDdi/ScopedCriticalSection.h> #include <D3dDdi/ScopedCriticalSection.h>
#include <Gdi/CompatDc.h> #include <Gdi/CompatDc.h>
#include <Gdi/ScrollBar.h> #include <Gdi/ScrollBar.h>
@ -40,6 +38,11 @@ namespace
bool isUnicode; 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);
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); const char* origWndProcName);
@ -218,20 +221,6 @@ namespace
return defPaintProc(hwnd, msg, wParam, lParam, origWndProc); 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, void hookUser32WndProc(User32WndProc& user32WndProc, WNDPROC newWndProc,
const std::string& procName, const std::string& className, bool isUnicode) const std::string& procName, const std::string& className, bool isUnicode)
{ {
@ -270,14 +259,14 @@ namespace
template <WndProcHook wndProcHook> template <WndProcHook wndProcHook>
void hookUser32WndProcA(const std::string& className, const std::string& procName) 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); procName + 'A', className, false);
} }
template <WndProcHook wndProcHook> template <WndProcHook wndProcHook>
void hookUser32WndProcW(const std::string& className, const std::string& procName) 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); procName + 'W', className, true);
} }
@ -465,14 +454,14 @@ namespace
template <WndProcHook wndProcHook> template <WndProcHook wndProcHook>
LRESULT CALLBACK user32WndProcA(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) 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); return user32WndProc(hwnd, uMsg, wParam, lParam, wp.procName, wndProcHook, wp.oldWndProcTrampoline);
} }
template <WndProcHook wndProcHook> template <WndProcHook wndProcHook>
LRESULT CALLBACK user32WndProcW(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) 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); return user32WndProc(hwnd, uMsg, wParam, lParam, wp.procName, wndProcHook, wp.oldWndProcTrampoline);
} }
} }

View File

@ -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) Result WINAPI mitigatedBusyWaitingFunc(Params... params)
{ {
mitigateBusyWaiting(); mitigateBusyWaiting();
return Compat::getOrigFuncPtr<FuncPtr, func>()(params...); return Compat::g_origFuncPtr<func>(params...);
} }
} }
#define MITIGATE_BUSY_WAITING(module, func) \ #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 namespace Win32
{ {