mirror of
https://github.com/narzoul/DDrawCompat
synced 2024-12-30 08:55:36 +01:00
Removed dependency on Detours
This commit is contained in:
parent
ce991009be
commit
4e00ce0447
@ -1,36 +1,30 @@
|
||||
#include <algorithm>
|
||||
#undef CINTERFACE
|
||||
|
||||
#include <filesystem>
|
||||
#include <list>
|
||||
#include <map>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
#include <Windows.h>
|
||||
#include <detours.h>
|
||||
#include <initguid.h>
|
||||
#include <DbgEng.h>
|
||||
|
||||
#include <Common/Hook.h>
|
||||
#include <Common/Log.h>
|
||||
#include <Dll/Dll.h>
|
||||
|
||||
namespace
|
||||
{
|
||||
struct HookedFunctionInfo
|
||||
{
|
||||
HMODULE module;
|
||||
void*& origFunction;
|
||||
void* newFunction;
|
||||
};
|
||||
|
||||
std::map<void*, HookedFunctionInfo> g_hookedFunctions;
|
||||
IDebugClient* g_debugClient = nullptr;
|
||||
IDebugControl* g_debugControl = nullptr;
|
||||
IDebugSymbols* g_debugSymbols = nullptr;
|
||||
IDebugDataSpaces4* g_debugDataSpaces = nullptr;
|
||||
ULONG64 g_debugBase = 0;
|
||||
bool g_isDbgEngInitialized = false;
|
||||
|
||||
PIMAGE_NT_HEADERS getImageNtHeaders(HMODULE module);
|
||||
std::filesystem::path getModulePath(HMODULE module);
|
||||
|
||||
std::map<void*, HookedFunctionInfo>::iterator findOrigFunc(void* origFunc)
|
||||
{
|
||||
return std::find_if(g_hookedFunctions.begin(), g_hookedFunctions.end(),
|
||||
[=](const auto& i) { return origFunc == i.first || origFunc == i.second.origFunction; });
|
||||
}
|
||||
bool initDbgEng();
|
||||
|
||||
FARPROC* findProcAddressInIat(HMODULE module, const char* procName)
|
||||
{
|
||||
@ -91,6 +85,28 @@ namespace
|
||||
return ntHeaders;
|
||||
}
|
||||
|
||||
unsigned getInstructionSize(void* instruction)
|
||||
{
|
||||
const unsigned MAX_INSTRUCTION_SIZE = 15;
|
||||
HRESULT result = g_debugDataSpaces->WriteVirtual(g_debugBase, instruction, MAX_INSTRUCTION_SIZE, nullptr);
|
||||
if (FAILED(result))
|
||||
{
|
||||
LOG_ONCE("ERROR: DbgEng: WriteVirtual failed: " << Compat::hex(result));
|
||||
return 0;
|
||||
}
|
||||
|
||||
ULONG64 endOffset = 0;
|
||||
result = g_debugControl->Disassemble(g_debugBase, 0, nullptr, 0, nullptr, &endOffset);
|
||||
if (FAILED(result))
|
||||
{
|
||||
LOG_ONCE("ERROR: DbgEng: Disassemble failed: " << Compat::hex(result) << " "
|
||||
<< Compat::hexDump(instruction, MAX_INSTRUCTION_SIZE));
|
||||
return 0;
|
||||
}
|
||||
|
||||
return static_cast<unsigned>(endOffset - g_debugBase);
|
||||
}
|
||||
|
||||
std::filesystem::path getModulePath(HMODULE module)
|
||||
{
|
||||
char path[MAX_PATH] = {};
|
||||
@ -100,28 +116,11 @@ namespace
|
||||
|
||||
void hookFunction(void*& origFuncPtr, void* newFuncPtr, const char* funcName)
|
||||
{
|
||||
void* stubFuncPtr = nullptr;
|
||||
if (GetModuleHandle("ntdll") == Compat::getModuleHandleFromAddress(origFuncPtr))
|
||||
{
|
||||
// Avoid hooking ntdll stubs (e.g. ntdll/NtdllDialogWndProc_A instead of user32/DefDlgProcA)
|
||||
if (0xFF == reinterpret_cast<BYTE*>(origFuncPtr)[0] &&
|
||||
0x25 == reinterpret_cast<BYTE*>(origFuncPtr)[1])
|
||||
{
|
||||
void* jmpTarget = **reinterpret_cast<void***>(reinterpret_cast<BYTE*>(origFuncPtr) + 2);
|
||||
if (GetModuleHandle("user32") == Compat::getModuleHandleFromAddress(jmpTarget))
|
||||
{
|
||||
stubFuncPtr = origFuncPtr;
|
||||
origFuncPtr = jmpTarget;
|
||||
}
|
||||
}
|
||||
}
|
||||
BYTE* targetFunc = reinterpret_cast<BYTE*>(origFuncPtr);
|
||||
|
||||
const auto it = findOrigFunc(origFuncPtr);
|
||||
if (it != g_hookedFunctions.end())
|
||||
{
|
||||
origFuncPtr = it->second.origFunction;
|
||||
return;
|
||||
}
|
||||
std::ostringstream oss;
|
||||
#ifdef DEBUGLOGS
|
||||
oss << Compat::funcPtrToStr(targetFunc);
|
||||
|
||||
char origFuncPtrStr[20] = {};
|
||||
if (!funcName)
|
||||
@ -129,46 +128,171 @@ namespace
|
||||
sprintf_s(origFuncPtrStr, "%p", origFuncPtr);
|
||||
funcName = origFuncPtrStr;
|
||||
}
|
||||
#endif
|
||||
|
||||
void* const hookedFuncPtr = origFuncPtr;
|
||||
if (stubFuncPtr)
|
||||
while (true)
|
||||
{
|
||||
LOG_DEBUG << "Hooking function: " << funcName << " (" << Compat::funcPtrToStr(stubFuncPtr) << " -> "
|
||||
<< Compat::funcPtrToStr(origFuncPtr) << ')';
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_DEBUG << "Hooking function: " << funcName << " (" << Compat::funcPtrToStr(hookedFuncPtr) << ')';
|
||||
if (0xE9 == targetFunc[0])
|
||||
{
|
||||
targetFunc += 1 + *reinterpret_cast<int*>(targetFunc + 1);
|
||||
}
|
||||
else if (0xEB == targetFunc[0])
|
||||
{
|
||||
targetFunc += 1 + static_cast<signed char>(targetFunc[1]);
|
||||
}
|
||||
else if (0xFF == targetFunc[0] && 0x25 == targetFunc[1])
|
||||
{
|
||||
targetFunc = **reinterpret_cast<BYTE***>(targetFunc + 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
#ifdef DEBUGLOGS
|
||||
oss << " -> " << Compat::funcPtrToStr(targetFunc);
|
||||
#endif
|
||||
}
|
||||
|
||||
DetourTransactionBegin();
|
||||
const bool attachSuccessful = NO_ERROR == DetourAttach(&origFuncPtr, newFuncPtr);
|
||||
const bool commitSuccessful = NO_ERROR == DetourTransactionCommit();
|
||||
if (!attachSuccessful || !commitSuccessful)
|
||||
LOG_DEBUG << "Hooking function: " << funcName << " (" << oss.str() << ')';
|
||||
|
||||
if (Compat::getModuleHandleFromAddress(targetFunc) == Dll::g_currentModule)
|
||||
{
|
||||
LOG_DEBUG << "ERROR: Failed to hook a function: " << funcName;
|
||||
Compat::Log() << "ERROR: Target function is already hooked: " << funcName;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!initDbgEng())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
unsigned totalInstructionSize = 0;
|
||||
while (totalInstructionSize < 5)
|
||||
{
|
||||
unsigned instructionSize = getInstructionSize(targetFunc + totalInstructionSize);
|
||||
if (0 == instructionSize)
|
||||
{
|
||||
return;
|
||||
}
|
||||
totalInstructionSize += instructionSize;
|
||||
}
|
||||
|
||||
LOG_DEBUG << "Decoded instructions: " << Compat::hexDump(targetFunc, totalInstructionSize);
|
||||
|
||||
BYTE* trampoline = static_cast<BYTE*>(
|
||||
VirtualAlloc(nullptr, totalInstructionSize + 5, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE));
|
||||
memcpy(trampoline, targetFunc, totalInstructionSize);
|
||||
trampoline[totalInstructionSize] = 0xE9;
|
||||
reinterpret_cast<int&>(trampoline[totalInstructionSize + 1]) = targetFunc - (trampoline + 5);
|
||||
DWORD oldProtect = 0;
|
||||
VirtualProtect(trampoline, totalInstructionSize + 5, PAGE_EXECUTE_READ, &oldProtect);
|
||||
|
||||
VirtualProtect(targetFunc, totalInstructionSize, PAGE_EXECUTE_READWRITE, &oldProtect);
|
||||
targetFunc[0] = 0xE9;
|
||||
reinterpret_cast<int&>(targetFunc[1]) = static_cast<BYTE*>(newFuncPtr) - (targetFunc + 5);
|
||||
memset(targetFunc + 5, 0xCC, totalInstructionSize - 5);
|
||||
VirtualProtect(targetFunc, totalInstructionSize, PAGE_EXECUTE_READ, &oldProtect);
|
||||
|
||||
FlushInstructionCache(GetCurrentProcess(), nullptr, 0);
|
||||
|
||||
HMODULE module = nullptr;
|
||||
GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_PIN,
|
||||
static_cast<char*>(hookedFuncPtr), &module);
|
||||
reinterpret_cast<char*>(targetFunc), &module);
|
||||
|
||||
g_hookedFunctions.emplace(
|
||||
std::make_pair(hookedFuncPtr, HookedFunctionInfo{ module, origFuncPtr, newFuncPtr }));
|
||||
origFuncPtr = trampoline;
|
||||
}
|
||||
|
||||
void unhookFunction(const std::map<void*, HookedFunctionInfo>::iterator& hookedFunc)
|
||||
bool initDbgEng()
|
||||
{
|
||||
DetourTransactionBegin();
|
||||
DetourDetach(&hookedFunc->second.origFunction, hookedFunc->second.newFunction);
|
||||
DetourTransactionCommit();
|
||||
g_hookedFunctions.erase(hookedFunc);
|
||||
if (g_isDbgEngInitialized)
|
||||
{
|
||||
return 0 != g_debugBase;
|
||||
}
|
||||
g_isDbgEngInitialized = true;
|
||||
|
||||
CoInitialize(nullptr);
|
||||
|
||||
HRESULT result = S_OK;
|
||||
if (FAILED(result = DebugCreate(IID_IDebugClient, reinterpret_cast<void**>(&g_debugClient))) ||
|
||||
FAILED(result = g_debugClient->QueryInterface(IID_IDebugControl, reinterpret_cast<void**>(&g_debugControl))) ||
|
||||
FAILED(result = g_debugClient->QueryInterface(IID_IDebugSymbols, reinterpret_cast<void**>(&g_debugSymbols))) ||
|
||||
FAILED(result = g_debugClient->QueryInterface(IID_IDebugDataSpaces4, reinterpret_cast<void**>(&g_debugDataSpaces))))
|
||||
{
|
||||
Compat::Log() << "ERROR: DbgEng: object creation failed: " << Compat::hex(result);
|
||||
return false;
|
||||
}
|
||||
|
||||
char dllPath[MAX_PATH] = {};
|
||||
GetModuleFileName(Dll::g_currentModule, dllPath, sizeof(dllPath));
|
||||
|
||||
result = g_debugClient->OpenDumpFile(dllPath);
|
||||
if (FAILED(result))
|
||||
{
|
||||
Compat::Log() << "ERROR: DbgEng: OpenDumpFile failed: " << Compat::hex(result);
|
||||
return false;
|
||||
}
|
||||
|
||||
g_debugControl->SetEngineOptions(DEBUG_ENGOPT_DISABLE_MODULE_SYMBOL_LOAD);
|
||||
result = g_debugControl->WaitForEvent(0, INFINITE);
|
||||
if (FAILED(result))
|
||||
{
|
||||
Compat::Log() << "ERROR: DbgEng: WaitForEvent failed: " << Compat::hex(result);
|
||||
return false;
|
||||
}
|
||||
|
||||
DEBUG_MODULE_PARAMETERS dmp = {};
|
||||
result = g_debugSymbols->GetModuleParameters(1, 0, 0, &dmp);
|
||||
if (FAILED(result))
|
||||
{
|
||||
Compat::Log() << "ERROR: DbgEng: GetModuleParameters failed: " << Compat::hex(result);
|
||||
return false;
|
||||
}
|
||||
|
||||
ULONG size = 0;
|
||||
result = g_debugDataSpaces->GetValidRegionVirtual(dmp.Base, dmp.Size, &g_debugBase, &size);
|
||||
if (FAILED(result) || 0 == g_debugBase)
|
||||
{
|
||||
Compat::Log() << "ERROR: DbgEng: GetValidRegionVirtual failed: " << Compat::hex(result);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
namespace Compat
|
||||
{
|
||||
void closeDbgEng()
|
||||
{
|
||||
if (g_debugClient)
|
||||
{
|
||||
g_debugClient->EndSession(DEBUG_END_PASSIVE);
|
||||
}
|
||||
if (g_debugDataSpaces)
|
||||
{
|
||||
g_debugDataSpaces->Release();
|
||||
g_debugDataSpaces = nullptr;
|
||||
}
|
||||
if (g_debugSymbols)
|
||||
{
|
||||
g_debugSymbols->Release();
|
||||
g_debugSymbols = nullptr;
|
||||
}
|
||||
if (g_debugControl)
|
||||
{
|
||||
g_debugControl->Release();
|
||||
g_debugControl = nullptr;
|
||||
}
|
||||
if (g_debugClient)
|
||||
{
|
||||
g_debugClient->Release();
|
||||
g_debugClient = nullptr;
|
||||
}
|
||||
|
||||
g_debugBase = 0;
|
||||
g_isDbgEngInitialized = false;
|
||||
}
|
||||
|
||||
std::string funcPtrToStr(void* funcPtr)
|
||||
{
|
||||
std::ostringstream oss;
|
||||
@ -325,13 +449,4 @@ namespace Compat
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void unhookFunction(void* origFunc)
|
||||
{
|
||||
auto it = findOrigFunc(origFunc);
|
||||
if (it != g_hookedFunctions.end())
|
||||
{
|
||||
::unhookFunction(it);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -13,6 +13,7 @@
|
||||
|
||||
namespace Compat
|
||||
{
|
||||
void closeDbgEng();
|
||||
std::string funcPtrToStr(void* funcPtr);
|
||||
HMODULE getModuleHandleFromAddress(void* address);
|
||||
|
||||
@ -32,5 +33,4 @@ namespace Compat
|
||||
}
|
||||
|
||||
void removeShim(HMODULE module, const char* funcName);
|
||||
void unhookFunction(void* origFunc);
|
||||
}
|
||||
|
@ -56,6 +56,14 @@ namespace Compat
|
||||
{
|
||||
using ::operator<<;
|
||||
|
||||
template <typename Elem>
|
||||
struct Array
|
||||
{
|
||||
Array(const Elem* elem, const unsigned long size) : elem(elem), size(size) {}
|
||||
const Elem* elem;
|
||||
const unsigned long size;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct Hex
|
||||
{
|
||||
@ -63,12 +71,10 @@ namespace Compat
|
||||
T val;
|
||||
};
|
||||
|
||||
template <typename Elem>
|
||||
struct Array
|
||||
struct HexByte
|
||||
{
|
||||
Array(const Elem* elem, const unsigned long size) : elem(elem), size(size) {}
|
||||
const Elem* elem;
|
||||
const unsigned long size;
|
||||
explicit HexByte(BYTE val) : val(val) {}
|
||||
BYTE val;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
@ -102,13 +108,6 @@ namespace Compat
|
||||
std::ostream& m_os;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
std::ostream& operator<<(std::ostream& os, Hex<T> hex)
|
||||
{
|
||||
os << "0x" << std::hex << hex.val << std::dec;
|
||||
return os;
|
||||
}
|
||||
|
||||
template <typename Elem>
|
||||
std::ostream& operator<<(std::ostream& os, Array<Elem> array)
|
||||
{
|
||||
@ -127,6 +126,19 @@ namespace Compat
|
||||
return os << ']';
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
std::ostream& operator<<(std::ostream& os, Hex<T> hex)
|
||||
{
|
||||
return os << "0x" << std::hex << hex.val << std::dec;
|
||||
}
|
||||
|
||||
inline std::ostream& operator<<(std::ostream& os, HexByte hexByte)
|
||||
{
|
||||
os.fill('0');
|
||||
os.width(2);
|
||||
return os << std::hex << static_cast<DWORD>(hexByte.val) << std::dec;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
std::ostream& operator<<(std::ostream& os, Out<T> out)
|
||||
{
|
||||
@ -137,15 +149,20 @@ namespace Compat
|
||||
}
|
||||
}
|
||||
|
||||
template <typename Elem>
|
||||
detail::Array<Elem> array(const Elem* elem, const unsigned long size)
|
||||
{
|
||||
return detail::Array<Elem>(elem, size);
|
||||
}
|
||||
|
||||
template <typename T> detail::Hex<T> hex(T val)
|
||||
{
|
||||
return detail::Hex<T>(val);
|
||||
}
|
||||
|
||||
template <typename Elem>
|
||||
detail::Array<Elem> array(const Elem* elem, const unsigned long size)
|
||||
inline detail::Array<detail::HexByte> hexDump(const void* buf, const unsigned long size)
|
||||
{
|
||||
return detail::Array<Elem>(elem, size);
|
||||
return detail::Array<detail::HexByte>(static_cast<const detail::HexByte*>(buf), size);
|
||||
}
|
||||
|
||||
template <typename T> detail::Out<T> out(const T& val)
|
||||
|
@ -59,19 +59,21 @@
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<TargetName>ddraw</TargetName>
|
||||
<IncludePath>$(ProjectDir);C:\Program Files %28x86%29\Microsoft Research\Detours Express 3.0\include;$(IncludePath)</IncludePath>
|
||||
<LibraryPath>C:\Program Files %28x86%29\Microsoft Research\Detours Express 3.0\lib.X86;$(LibraryPath)</LibraryPath>
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<IncludePath>$(ProjectDir);$(IncludePath)</IncludePath>
|
||||
<LibraryPath>$(LibraryPath)</LibraryPath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<TargetName>ddraw</TargetName>
|
||||
<IncludePath>$(ProjectDir);C:\Program Files %28x86%29\Microsoft Research\Detours Express 3.0\include;$(IncludePath)</IncludePath>
|
||||
<LibraryPath>C:\Program Files %28x86%29\Microsoft Research\Detours Express 3.0\lib.X86;$(LibraryPath)</LibraryPath>
|
||||
<IncludePath>$(ProjectDir);$(IncludePath)</IncludePath>
|
||||
<LibraryPath>$(LibraryPath)</LibraryPath>
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithDebugLogs|Win32'">
|
||||
<TargetName>ddraw</TargetName>
|
||||
<IncludePath>$(ProjectDir);C:\Program Files %28x86%29\Microsoft Research\Detours Express 3.0\include;$(IncludePath)</IncludePath>
|
||||
<LibraryPath>C:\Program Files %28x86%29\Microsoft Research\Detours Express 3.0\lib.X86;$(LibraryPath)</LibraryPath>
|
||||
<IncludePath>$(ProjectDir);$(IncludePath)</IncludePath>
|
||||
<LibraryPath>$(LibraryPath)</LibraryPath>
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
@ -87,7 +89,7 @@
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>dxguid.lib;detours.lib;msimg32.lib;oleacc.lib;uxtheme.lib;dwmapi.lib;winmm.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalDependencies>dbgeng.lib;dxguid.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 +107,7 @@
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>dxguid.lib;detours.lib;msimg32.lib;oleacc.lib;uxtheme.lib;dwmapi.lib;winmm.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalDependencies>dbgeng.lib;dxguid.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 +125,7 @@
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>dxguid.lib;detours.lib;msimg32.lib;oleacc.lib;uxtheme.lib;dwmapi.lib;winmm.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalDependencies>dbgeng.lib;dxguid.lib;msimg32.lib;oleacc.lib;uxtheme.lib;dwmapi.lib;winmm.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<GenerateDebugInformation>DebugFull</GenerateDebugInformation>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
|
||||
|
@ -10,9 +10,9 @@ namespace Dll
|
||||
Procs g_origProcs = {};
|
||||
Procs g_jmpTargetProcs = {};
|
||||
|
||||
HANDLE createThread(unsigned(__stdcall* threadProc)(void*), unsigned int* threadId, int priority)
|
||||
HANDLE createThread(unsigned(__stdcall* threadProc)(void*), unsigned int* threadId, int priority, unsigned initFlags)
|
||||
{
|
||||
HANDLE thread = reinterpret_cast<HANDLE>(_beginthreadex(nullptr, 0, threadProc, nullptr, 0, threadId));
|
||||
HANDLE thread = reinterpret_cast<HANDLE>(_beginthreadex(nullptr, 0, threadProc, nullptr, initFlags, threadId));
|
||||
if (thread)
|
||||
{
|
||||
SetThreadPriority(thread, priority);
|
||||
|
@ -67,7 +67,7 @@ namespace Dll
|
||||
#undef ADD_FARPROC_MEMBER
|
||||
};
|
||||
|
||||
HANDLE createThread(unsigned(__stdcall* threadProc)(void*), unsigned int* threadId, int priority);
|
||||
HANDLE createThread(unsigned(__stdcall* threadProc)(void*), unsigned int* threadId, int priority, unsigned initFlags = 0);
|
||||
void pinModule(HMODULE module);
|
||||
void pinModule(LPCSTR moduleName);
|
||||
void pinModule(LPCWSTR moduleName);
|
||||
|
@ -14,6 +14,7 @@
|
||||
#include <Direct3d/Hooks.h>
|
||||
#include <Dll/Dll.h>
|
||||
#include <Gdi/Gdi.h>
|
||||
#include <Gdi/PresentationWindow.h>
|
||||
#include <Gdi/VirtualScreen.h>
|
||||
#include <Win32/DisplayMode.h>
|
||||
#include <Win32/MemoryManagement.h>
|
||||
@ -122,6 +123,8 @@ namespace
|
||||
Direct3d::installHooks(dd, dd7);
|
||||
Compat::Log() << "Installing GDI hooks";
|
||||
Gdi::installHooks();
|
||||
Compat::closeDbgEng();
|
||||
Gdi::PresentationWindow::startThread();
|
||||
Compat::Log() << "Finished installing hooks";
|
||||
isAlreadyInstalled = true;
|
||||
}
|
||||
@ -258,6 +261,7 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
|
||||
Win32::MemoryManagement::installHooks();
|
||||
Win32::MsgHooks::installHooks();
|
||||
Time::init();
|
||||
Compat::closeDbgEng();
|
||||
|
||||
const DWORD disableMaxWindowedMode = 12;
|
||||
CALL_ORIG_PROC(SetAppCompatData)(disableMaxWindowedMode, 0);
|
||||
|
@ -10,6 +10,7 @@ namespace
|
||||
const UINT WM_SETPRESENTATIONWINDOWPOS = WM_USER + 1;
|
||||
const UINT WM_SETPRESENTATIONWINDOWRGN = WM_USER + 2;
|
||||
|
||||
HANDLE g_presentationWindowThread = nullptr;
|
||||
unsigned g_presentationWindowThreadId = 0;
|
||||
HWND g_messageWindow = nullptr;
|
||||
|
||||
@ -97,6 +98,7 @@ namespace
|
||||
}
|
||||
|
||||
Gdi::WinProc::installHooks();
|
||||
Compat::closeDbgEng();
|
||||
|
||||
MSG msg = {};
|
||||
while (GetMessage(&msg, nullptr, 0, 0))
|
||||
@ -139,7 +141,8 @@ namespace Gdi
|
||||
wc.lpszClassName = "DDrawCompatPresentationWindow";
|
||||
CALL_ORIG_FUNC(RegisterClassA)(&wc);
|
||||
|
||||
Dll::createThread(presentationWindowThreadProc, &g_presentationWindowThreadId, THREAD_PRIORITY_TIME_CRITICAL);
|
||||
g_presentationWindowThread = Dll::createThread(presentationWindowThreadProc, &g_presentationWindowThreadId,
|
||||
THREAD_PRIORITY_TIME_CRITICAL, CREATE_SUSPENDED);
|
||||
}
|
||||
|
||||
bool isPresentationWindow(HWND hwnd)
|
||||
@ -156,5 +159,10 @@ namespace Gdi
|
||||
{
|
||||
sendMessageBlocking(hwnd, WM_SETPRESENTATIONWINDOWRGN, reinterpret_cast<WPARAM>(rgn), 0);
|
||||
}
|
||||
|
||||
void startThread()
|
||||
{
|
||||
ResumeThread(g_presentationWindowThread);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -11,6 +11,7 @@ namespace Gdi
|
||||
bool isPresentationWindow(HWND hwnd);
|
||||
void setWindowPos(HWND hwnd, const WINDOWPOS& wp);
|
||||
void setWindowRgn(HWND hwnd, HRGN rgn);
|
||||
void startThread();
|
||||
|
||||
void installHooks();
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user