mirror of
https://github.com/narzoul/DDrawCompat
synced 2024-12-30 08:55:36 +01:00
Support injection via dciman32.dll
This commit is contained in:
parent
b7aae9e403
commit
757f648385
@ -5,11 +5,9 @@
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include <Windows.h>
|
||||
#include <detours.h>
|
||||
#include <Psapi.h>
|
||||
|
||||
#include <Common/Hook.h>
|
||||
#include <Common/Log.h>
|
||||
@ -92,17 +90,6 @@ namespace
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
PIMAGE_NT_HEADERS getImageNtHeaders(HMODULE module)
|
||||
{
|
||||
PIMAGE_DOS_HEADER dosHeader = reinterpret_cast<PIMAGE_DOS_HEADER>(module);
|
||||
|
@ -74,9 +74,14 @@ namespace Compat
|
||||
s_logFile << std::endl;
|
||||
}
|
||||
|
||||
void Log::initLogging()
|
||||
{
|
||||
s_logFile.open("ddraw.log");
|
||||
}
|
||||
|
||||
thread_local DWORD Log::s_indent = 0;
|
||||
thread_local DWORD Log::s_outParamDepth = 0;
|
||||
thread_local bool Log::s_isLeaveLog = false;
|
||||
|
||||
std::ofstream Log::s_logFile("ddraw.log");
|
||||
std::ofstream Log::s_logFile;
|
||||
}
|
||||
|
@ -145,6 +145,7 @@ namespace Compat
|
||||
return *this;
|
||||
}
|
||||
|
||||
static void initLogging();
|
||||
static bool isPointerDereferencingAllowed() { return s_isLeaveLog || 0 == s_outParamDepth; }
|
||||
|
||||
protected:
|
||||
@ -276,7 +277,7 @@ operator<<(std::ostream& os, T* t)
|
||||
return os << "null";
|
||||
}
|
||||
|
||||
if (!Compat::Log::isPointerDereferencingAllowed())
|
||||
if (!Compat::Log::isPointerDereferencingAllowed() || reinterpret_cast<DWORD>(t) <= 0xFFFF)
|
||||
{
|
||||
return os << static_cast<const void*>(t);
|
||||
}
|
||||
@ -294,10 +295,10 @@ std::ostream& operator<<(std::ostream& os, T** t)
|
||||
|
||||
os << static_cast<const void*>(t);
|
||||
|
||||
if (Compat::Log::isPointerDereferencingAllowed())
|
||||
if (!Compat::Log::isPointerDereferencingAllowed() || reinterpret_cast<DWORD>(t) <= 0xFFFF)
|
||||
{
|
||||
os << '=' << *t;
|
||||
return os;
|
||||
}
|
||||
|
||||
return os;
|
||||
return os << '=' << *t;
|
||||
}
|
||||
|
@ -51,6 +51,11 @@ namespace DDraw
|
||||
return pf;
|
||||
}
|
||||
|
||||
void logComInstantiation()
|
||||
{
|
||||
LOG_ONCE("COM instantiation of DirectDraw detected");
|
||||
}
|
||||
|
||||
void suppressEmulatedDirectDraw(GUID*& guid)
|
||||
{
|
||||
if (reinterpret_cast<GUID*>(DDCREATE_EMULATIONONLY) == guid)
|
||||
@ -119,6 +124,7 @@ namespace DDraw
|
||||
template <typename TDirectDraw>
|
||||
HRESULT STDMETHODCALLTYPE DirectDraw<TDirectDraw>::Initialize(TDirectDraw* This, GUID* lpGUID)
|
||||
{
|
||||
logComInstantiation();
|
||||
suppressEmulatedDirectDraw(lpGUID);
|
||||
return s_origVtable.Initialize(This, lpGUID);
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include "Dll/Procs.h"
|
||||
#include <Dll/Dll.h>
|
||||
|
||||
namespace DDraw
|
||||
{
|
||||
|
@ -7,7 +7,7 @@
|
||||
#include <DDraw/RealPrimarySurface.h>
|
||||
#include <DDraw/Surfaces/PrimarySurface.h>
|
||||
#include <DDraw/Surfaces/PrimarySurfaceImpl.h>
|
||||
#include <Dll/Procs.h>
|
||||
#include <Dll/Dll.h>
|
||||
#include <Gdi/Gdi.h>
|
||||
#include <Gdi/Region.h>
|
||||
#include <Gdi/VirtualScreen.h>
|
||||
|
@ -87,7 +87,6 @@
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<ModuleDefinitionFile>Dll/DDrawCompat.def</ModuleDefinitionFile>
|
||||
<AdditionalDependencies>dxguid.lib;detours.lib;msimg32.lib;oleacc.lib;psapi.lib;uxtheme.lib;dwmapi.lib;winmm.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<GenerateDebugInformation>DebugFull</GenerateDebugInformation>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
@ -106,7 +105,6 @@
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<ModuleDefinitionFile>Dll/DDrawCompat.def</ModuleDefinitionFile>
|
||||
<AdditionalDependencies>dxguid.lib;detours.lib;msimg32.lib;oleacc.lib;psapi.lib;uxtheme.lib;dwmapi.lib;winmm.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<GenerateDebugInformation>DebugFull</GenerateDebugInformation>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
@ -125,7 +123,6 @@
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<ModuleDefinitionFile>Dll/DDrawCompat.def</ModuleDefinitionFile>
|
||||
<AdditionalDependencies>dxguid.lib;detours.lib;msimg32.lib;oleacc.lib;psapi.lib;uxtheme.lib;dwmapi.lib;winmm.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<GenerateDebugInformation>DebugFull</GenerateDebugInformation>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
@ -211,7 +208,7 @@
|
||||
<ClInclude Include="Direct3d\Visitors\Direct3dVertexBufferVtblVisitor.h" />
|
||||
<ClInclude Include="Direct3d\Visitors\Direct3dViewportVtblVisitor.h" />
|
||||
<ClInclude Include="Direct3d\Visitors\Direct3dVtblVisitor.h" />
|
||||
<ClInclude Include="Dll\Procs.h" />
|
||||
<ClInclude Include="Dll\Dll.h" />
|
||||
<ClInclude Include="Gdi\AccessGuard.h" />
|
||||
<ClInclude Include="Gdi\Font.h" />
|
||||
<ClInclude Include="Gdi\Gdi.h" />
|
||||
@ -279,9 +276,8 @@
|
||||
<ClCompile Include="Direct3d\Direct3dViewport.cpp" />
|
||||
<ClCompile Include="Direct3d\Hooks.cpp" />
|
||||
<ClCompile Include="Direct3d\Log.cpp" />
|
||||
<ClCompile Include="Dll\Procs.cpp" />
|
||||
<ClCompile Include="Dll\DllMain.cpp" />
|
||||
<ClCompile Include="Dll\UnmodifiedProcs.cpp" />
|
||||
<ClCompile Include="Dll\Dll.cpp" />
|
||||
<ClCompile Include="Gdi\AccessGuard.cpp" />
|
||||
<ClCompile Include="Gdi\Font.cpp" />
|
||||
<ClCompile Include="Gdi\Gdi.cpp" />
|
||||
@ -305,9 +301,6 @@
|
||||
<ClCompile Include="Win32\TimeFunctions.cpp" />
|
||||
<ClCompile Include="Win32\WaitFunctions.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="Dll\DDrawCompat.def" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
|
@ -231,9 +231,6 @@
|
||||
<ClInclude Include="Config\Config.h">
|
||||
<Filter>Header Files\Config</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Dll\Procs.h">
|
||||
<Filter>Header Files\Dll</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="DDraw\Surfaces\Surface.h">
|
||||
<Filter>Header Files\DDraw\Surfaces</Filter>
|
||||
</ClInclude>
|
||||
@ -384,6 +381,9 @@
|
||||
<ClInclude Include="Gdi\Font.h">
|
||||
<Filter>Header Files\Gdi</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Dll\Dll.h">
|
||||
<Filter>Header Files\Dll</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="Gdi\Gdi.cpp">
|
||||
@ -476,15 +476,6 @@
|
||||
<ClCompile Include="Win32\Registry.cpp">
|
||||
<Filter>Source Files\Win32</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Dll\DllMain.cpp">
|
||||
<Filter>Source Files\Dll</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Dll\Procs.cpp">
|
||||
<Filter>Source Files\Dll</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Dll\UnmodifiedProcs.cpp">
|
||||
<Filter>Source Files\Dll</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="DDraw\Surfaces\Surface.cpp">
|
||||
<Filter>Source Files\DDraw\Surfaces</Filter>
|
||||
</ClCompile>
|
||||
@ -590,10 +581,11 @@
|
||||
<ClCompile Include="Gdi\Font.cpp">
|
||||
<Filter>Source Files\Gdi</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="Dll\DDrawCompat.def">
|
||||
<ClCompile Include="Dll\DllMain.cpp">
|
||||
<Filter>Source Files\Dll</Filter>
|
||||
</None>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Dll\Dll.cpp">
|
||||
<Filter>Source Files\Dll</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
@ -1,25 +0,0 @@
|
||||
LIBRARY ddraw
|
||||
|
||||
EXPORTS
|
||||
AcquireDDThreadLock
|
||||
CompleteCreateSysmemSurface
|
||||
D3DParseUnknownCommand
|
||||
DDGetAttachedSurfaceLcl
|
||||
DDInternalLock
|
||||
DDInternalUnlock
|
||||
DSoundHelp
|
||||
DirectDrawCreate
|
||||
DirectDrawCreateClipper
|
||||
DirectDrawCreateEx
|
||||
DirectDrawEnumerateA
|
||||
DirectDrawEnumerateExA
|
||||
DirectDrawEnumerateExW
|
||||
DirectDrawEnumerateW
|
||||
DllCanUnloadNow PRIVATE
|
||||
DllGetClassObject PRIVATE
|
||||
GetDDSurfaceLocal
|
||||
GetOLEThunkData
|
||||
GetSurfaceFromDC
|
||||
RegisterSpecialCase
|
||||
ReleaseDDThreadLock
|
||||
SetAppCompatData
|
16
DDrawCompat/Dll/Dll.cpp
Normal file
16
DDrawCompat/Dll/Dll.cpp
Normal file
@ -0,0 +1,16 @@
|
||||
#include <Dll/Dll.h>
|
||||
|
||||
namespace Dll
|
||||
{
|
||||
HMODULE g_currentModule = nullptr;
|
||||
Procs g_origProcs = {};
|
||||
Procs g_jmpTargetProcs = {};
|
||||
}
|
||||
|
||||
#define CREATE_PROC_STUB(procName) \
|
||||
extern "C" __declspec(dllexport, naked) void procName() \
|
||||
{ \
|
||||
__asm jmp Dll::g_jmpTargetProcs.procName \
|
||||
}
|
||||
|
||||
VISIT_ALL_PROCS(CREATE_PROC_STUB)
|
@ -2,7 +2,17 @@
|
||||
|
||||
#include <Windows.h>
|
||||
|
||||
#define VISIT_UNMODIFIED_PROCS(visit) \
|
||||
#define VISIT_PUBLIC_DDRAW_PROCS(visit) \
|
||||
visit(DirectDrawCreate) \
|
||||
visit(DirectDrawCreateClipper) \
|
||||
visit(DirectDrawCreateEx) \
|
||||
visit(DirectDrawEnumerateA) \
|
||||
visit(DirectDrawEnumerateExA) \
|
||||
visit(DirectDrawEnumerateExW) \
|
||||
visit(DirectDrawEnumerateW) \
|
||||
visit(DllGetClassObject)
|
||||
|
||||
#define VISIT_PRIVATE_DDRAW_PROCS(visit) \
|
||||
visit(AcquireDDThreadLock) \
|
||||
visit(CompleteCreateSysmemSurface) \
|
||||
visit(D3DParseUnknownCommand) \
|
||||
@ -10,11 +20,6 @@
|
||||
visit(DDInternalLock) \
|
||||
visit(DDInternalUnlock) \
|
||||
visit(DSoundHelp) \
|
||||
visit(DirectDrawCreateClipper) \
|
||||
visit(DirectDrawEnumerateA) \
|
||||
visit(DirectDrawEnumerateExA) \
|
||||
visit(DirectDrawEnumerateExW) \
|
||||
visit(DirectDrawEnumerateW) \
|
||||
visit(DllCanUnloadNow) \
|
||||
visit(GetDDSurfaceLocal) \
|
||||
visit(GetOLEThunkData) \
|
||||
@ -23,25 +28,48 @@
|
||||
visit(ReleaseDDThreadLock) \
|
||||
visit(SetAppCompatData)
|
||||
|
||||
#define VISIT_MODIFIED_PROCS(visit) \
|
||||
visit(DirectDrawCreate) \
|
||||
visit(DirectDrawCreateEx) \
|
||||
visit(DllGetClassObject)
|
||||
#define VISIT_DDRAW_PROCS(visit) \
|
||||
VISIT_PUBLIC_DDRAW_PROCS(visit) \
|
||||
VISIT_PRIVATE_DDRAW_PROCS(visit)
|
||||
|
||||
#define VISIT_DCIMAN32_PROCS(visit) \
|
||||
visit(DCIBeginAccess) \
|
||||
visit(DCICloseProvider) \
|
||||
visit(DCICreateOffscreen) \
|
||||
visit(DCICreateOverlay) \
|
||||
visit(DCICreatePrimary) \
|
||||
visit(DCIDestroy) \
|
||||
visit(DCIDraw) \
|
||||
visit(DCIEndAccess) \
|
||||
visit(DCIEnum) \
|
||||
visit(DCIOpenProvider) \
|
||||
visit(DCISetClipList) \
|
||||
visit(DCISetDestination) \
|
||||
visit(DCISetSrcDestClip) \
|
||||
visit(GetDCRegionData) \
|
||||
visit(GetWindowRegionData) \
|
||||
visit(WinWatchClose) \
|
||||
visit(WinWatchDidStatusChange) \
|
||||
visit(WinWatchGetClipList) \
|
||||
visit(WinWatchNotify) \
|
||||
visit(WinWatchOpen)
|
||||
|
||||
#define VISIT_ALL_PROCS(visit) \
|
||||
VISIT_UNMODIFIED_PROCS(visit) \
|
||||
VISIT_MODIFIED_PROCS(visit)
|
||||
|
||||
#define ADD_FARPROC_MEMBER(memberName) FARPROC memberName;
|
||||
VISIT_DDRAW_PROCS(visit) \
|
||||
VISIT_DCIMAN32_PROCS(visit)
|
||||
|
||||
namespace Dll
|
||||
{
|
||||
struct Procs
|
||||
{
|
||||
#define ADD_FARPROC_MEMBER(memberName) FARPROC memberName;
|
||||
VISIT_ALL_PROCS(ADD_FARPROC_MEMBER);
|
||||
#undef ADD_FARPROC_MEMBER
|
||||
};
|
||||
|
||||
extern HMODULE g_currentModule;
|
||||
extern Procs g_origProcs;
|
||||
extern Procs g_jmpTargetProcs;
|
||||
}
|
||||
|
||||
#undef ADD_FARPROC_MEMBER
|
@ -1,6 +1,8 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <Windows.h>
|
||||
#include <Psapi.h>
|
||||
#include <timeapi.h>
|
||||
#include <Uxtheme.h>
|
||||
|
||||
@ -11,7 +13,7 @@
|
||||
#include <DDraw/DirectDraw.h>
|
||||
#include <DDraw/Hooks.h>
|
||||
#include <Direct3d/Hooks.h>
|
||||
#include <Dll/Procs.h>
|
||||
#include <Dll/Dll.h>
|
||||
#include <Gdi/Gdi.h>
|
||||
#include <Gdi/VirtualScreen.h>
|
||||
#include <Win32/DisplayMode.h>
|
||||
@ -24,7 +26,72 @@ HRESULT WINAPI SetAppCompatData(DWORD, DWORD);
|
||||
|
||||
namespace
|
||||
{
|
||||
template <typename Result, typename... Params>
|
||||
using FuncPtr = Result(WINAPI*)(Params...);
|
||||
|
||||
HMODULE g_origDDrawModule = nullptr;
|
||||
HMODULE g_origDciman32Module = nullptr;
|
||||
|
||||
template <FARPROC(Dll::Procs::* origFunc)>
|
||||
const char* getFuncName();
|
||||
|
||||
#define DEFINE_FUNC_NAME(func) template <> const char* getFuncName<&Dll::Procs::func>() { return #func; }
|
||||
VISIT_PUBLIC_DDRAW_PROCS(DEFINE_FUNC_NAME)
|
||||
#undef DEFINE_FUNC_NAME
|
||||
|
||||
void installHooks();
|
||||
|
||||
template <FARPROC(Dll::Procs::* origFunc), typename Result, typename FirstParam, typename... Params>
|
||||
Result WINAPI directDrawFunc(FirstParam firstParam, Params... params)
|
||||
{
|
||||
LOG_FUNC(getFuncName<origFunc>(), firstParam, params...);
|
||||
installHooks();
|
||||
suppressEmulatedDirectDraw(firstParam);
|
||||
return LOG_RESULT(reinterpret_cast<FuncPtr<Result, FirstParam, Params...>>(Dll::g_origProcs.*origFunc)(
|
||||
firstParam, params...));
|
||||
}
|
||||
|
||||
template <FARPROC(Dll::Procs::* origFunc), typename Result, typename... Params>
|
||||
FuncPtr<Result, Params...> getDirectDrawFuncPtr(FuncPtr<Result, Params...>)
|
||||
{
|
||||
return &directDrawFunc<origFunc, Result, Params...>;
|
||||
}
|
||||
|
||||
std::string getDirName(const std::string& path)
|
||||
{
|
||||
return path.substr(0, path.find_last_of('\\'));
|
||||
}
|
||||
|
||||
std::string getFileName(const std::string& path)
|
||||
{
|
||||
auto lastSeparatorPos = path.find_last_of('\\');
|
||||
return std::string::npos == lastSeparatorPos ? path : path.substr(lastSeparatorPos + 1, std::string::npos);
|
||||
}
|
||||
|
||||
std::string getModulePath(HMODULE module)
|
||||
{
|
||||
char path[MAX_PATH] = {};
|
||||
GetModuleFileName(module, path, sizeof(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()
|
||||
{
|
||||
char path[MAX_PATH] = {};
|
||||
GetSystemDirectory(path, sizeof(path));
|
||||
return path;
|
||||
}
|
||||
|
||||
void installHooks()
|
||||
{
|
||||
@ -74,18 +141,28 @@ namespace
|
||||
}
|
||||
}
|
||||
|
||||
bool loadLibrary(const std::string& systemDirectory, const std::string& dllName, HMODULE& module)
|
||||
bool isEqualPath(const std::string& p1, const std::string& p2)
|
||||
{
|
||||
const std::string systemDllPath = systemDirectory + '\\' + dllName;
|
||||
return 0 == _strcmpi(p1.c_str(), p2.c_str());
|
||||
}
|
||||
|
||||
module = LoadLibrary(systemDllPath.c_str());
|
||||
if (!module)
|
||||
bool isOtherDDrawWrapperLoaded()
|
||||
{
|
||||
auto currentDllPath = getModulePath(Dll::g_currentModule);
|
||||
auto systemDirectory = getSystemDirectory();
|
||||
auto processModules = getProcessModules(GetCurrentProcess());
|
||||
for (HMODULE module : processModules)
|
||||
{
|
||||
Compat::Log() << "ERROR: Failed to load system " << dllName << " from " << systemDllPath;
|
||||
return false;
|
||||
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 true;
|
||||
return false;
|
||||
}
|
||||
|
||||
void printEnvironmentVariable(const char* var)
|
||||
@ -99,42 +176,79 @@ namespace
|
||||
}
|
||||
Compat::Log() << "Environment variable " << var << " = \"" << value << '"';
|
||||
}
|
||||
|
||||
template <typename Param>
|
||||
void suppressEmulatedDirectDraw(Param)
|
||||
{
|
||||
}
|
||||
|
||||
void suppressEmulatedDirectDraw(GUID*& guid)
|
||||
{
|
||||
DDraw::suppressEmulatedDirectDraw(guid);
|
||||
}
|
||||
}
|
||||
|
||||
#define LOAD_ORIGINAL_PROC(procName) \
|
||||
Dll::g_origProcs.procName = Compat::getProcAddress(g_origDDrawModule, #procName);
|
||||
#define LOAD_ORIG_PROC(proc) \
|
||||
Dll::g_origProcs.proc = Compat::getProcAddress(origModule, #proc);
|
||||
|
||||
#define HOOK_DDRAW_PROC(proc) \
|
||||
Compat::hookFunction( \
|
||||
reinterpret_cast<void*&>(Dll::g_origProcs.proc), \
|
||||
getDirectDrawFuncPtr<&Dll::Procs::proc>(static_cast<decltype(&proc)>(nullptr)), \
|
||||
#proc);
|
||||
|
||||
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
|
||||
{
|
||||
static bool skipDllMain = false;
|
||||
if (skipDllMain)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (fdwReason == DLL_PROCESS_ATTACH)
|
||||
{
|
||||
char currentProcessPath[MAX_PATH] = {};
|
||||
GetModuleFileName(nullptr, currentProcessPath, MAX_PATH);
|
||||
Compat::Log() << "Process path: " << currentProcessPath;
|
||||
Dll::g_currentModule = hinstDLL;
|
||||
if (isOtherDDrawWrapperLoaded())
|
||||
{
|
||||
skipDllMain = true;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
Compat::Log::initLogging();
|
||||
Compat::Log() << "Process path: " << getModulePath(nullptr);
|
||||
printEnvironmentVariable("__COMPAT_LAYER");
|
||||
auto currentDllPath = getModulePath(hinstDLL);
|
||||
Compat::Log() << "Loading DDrawCompat " << (lpvReserved ? "statically" : "dynamically") << " from " << currentDllPath;
|
||||
|
||||
char currentDllPath[MAX_PATH] = {};
|
||||
GetModuleFileName(hinstDLL, currentDllPath, MAX_PATH);
|
||||
Compat::Log() << "Loading DDrawCompat " << (lpvReserved ? "statically" : "dynamically")
|
||||
<< " from " << currentDllPath;
|
||||
|
||||
char systemDirectory[MAX_PATH] = {};
|
||||
GetSystemDirectory(systemDirectory, MAX_PATH);
|
||||
|
||||
std::string systemDDrawDllPath = std::string(systemDirectory) + "\\ddraw.dll";
|
||||
if (0 == _stricmp(currentDllPath, systemDDrawDllPath.c_str()))
|
||||
auto systemDirectory = getSystemDirectory();
|
||||
if (isEqualPath(getDirName(currentDllPath), systemDirectory))
|
||||
{
|
||||
Compat::Log() << "DDrawCompat cannot be installed as the system ddraw.dll";
|
||||
Compat::Log() << "DDrawCompat cannot be installed in the Windows system directory";
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!loadLibrary(systemDirectory, "ddraw.dll", g_origDDrawModule))
|
||||
auto systemDDrawDllPath = systemDirectory + "\\ddraw.dll";
|
||||
g_origDDrawModule = LoadLibrary(systemDDrawDllPath.c_str());
|
||||
if (!g_origDDrawModule)
|
||||
{
|
||||
Compat::Log() << "ERROR: Failed to load system ddraw.dll from " << systemDDrawDllPath;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
VISIT_ALL_PROCS(LOAD_ORIGINAL_PROC);
|
||||
HMODULE origModule = g_origDDrawModule;
|
||||
VISIT_DDRAW_PROCS(LOAD_ORIG_PROC);
|
||||
|
||||
auto systemDciman32DllPath = systemDirectory + "\\dciman32.dll";
|
||||
g_origDciman32Module = LoadLibrary(systemDciman32DllPath.c_str());
|
||||
if (g_origDciman32Module)
|
||||
{
|
||||
origModule = g_origDciman32Module;
|
||||
VISIT_DCIMAN32_PROCS(LOAD_ORIG_PROC);
|
||||
}
|
||||
|
||||
Dll::g_jmpTargetProcs = Dll::g_origProcs;
|
||||
|
||||
VISIT_PUBLIC_DDRAW_PROCS(HOOK_DDRAW_PROC)
|
||||
|
||||
const BOOL disablePriorityBoost = TRUE;
|
||||
SetProcessPriorityBoost(GetCurrentProcess(), disablePriorityBoost);
|
||||
@ -160,6 +274,7 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
|
||||
D3dDdi::uninstallHooks();
|
||||
Gdi::uninstallHooks();
|
||||
Compat::unhookAllFunctions();
|
||||
FreeLibrary(g_origDciman32Module);
|
||||
FreeLibrary(g_origDDrawModule);
|
||||
}
|
||||
timeEndPeriod(1);
|
||||
@ -172,34 +287,3 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
extern "C" HRESULT WINAPI DirectDrawCreate(
|
||||
GUID* lpGUID,
|
||||
LPDIRECTDRAW* lplpDD,
|
||||
IUnknown* pUnkOuter)
|
||||
{
|
||||
LOG_FUNC(__func__, lpGUID, lplpDD, pUnkOuter);
|
||||
installHooks();
|
||||
DDraw::suppressEmulatedDirectDraw(lpGUID);
|
||||
return LOG_RESULT(CALL_ORIG_PROC(DirectDrawCreate)(lpGUID, lplpDD, pUnkOuter));
|
||||
}
|
||||
|
||||
extern "C" HRESULT WINAPI DirectDrawCreateEx(
|
||||
GUID* lpGUID,
|
||||
LPVOID* lplpDD,
|
||||
REFIID iid,
|
||||
IUnknown* pUnkOuter)
|
||||
{
|
||||
LOG_FUNC(__func__, lpGUID, lplpDD, iid, pUnkOuter);
|
||||
installHooks();
|
||||
DDraw::suppressEmulatedDirectDraw(lpGUID);
|
||||
return LOG_RESULT(CALL_ORIG_PROC(DirectDrawCreateEx)(lpGUID, lplpDD, iid, pUnkOuter));
|
||||
}
|
||||
|
||||
extern "C" HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv)
|
||||
{
|
||||
LOG_FUNC(__func__, rclsid, riid, ppv);
|
||||
LOG_ONCE("COM instantiation of DirectDraw detected");
|
||||
installHooks();
|
||||
return LOG_RESULT(CALL_ORIG_PROC(DllGetClassObject)(rclsid, riid, ppv));
|
||||
}
|
||||
|
@ -1,6 +0,0 @@
|
||||
#include "Dll/Procs.h"
|
||||
|
||||
namespace Dll
|
||||
{
|
||||
Procs g_origProcs = {};
|
||||
}
|
@ -1,9 +0,0 @@
|
||||
#include "Dll/Procs.h"
|
||||
|
||||
#define CREATE_PROC_STUB(procName) \
|
||||
extern "C" __declspec(naked) void __stdcall procName() \
|
||||
{ \
|
||||
__asm jmp Dll::g_origProcs.procName \
|
||||
}
|
||||
|
||||
VISIT_UNMODIFIED_PROCS(CREATE_PROC_STUB)
|
@ -1,11 +1,10 @@
|
||||
#include <Windows.h>
|
||||
|
||||
#include "Common/Hook.h"
|
||||
#include "Common/Time.h"
|
||||
#include "D3dDdi/ScopedCriticalSection.h"
|
||||
#include "Gdi/Caret.h"
|
||||
|
||||
extern "C" IMAGE_DOS_HEADER __ImageBase;
|
||||
#include <Common/Hook.h>
|
||||
#include <Common/Time.h>
|
||||
#include <D3dDdi/ScopedCriticalSection.h>
|
||||
#include <Dll/Dll.h>
|
||||
#include <Gdi/Caret.h>
|
||||
|
||||
namespace
|
||||
{
|
||||
@ -114,14 +113,10 @@ namespace Gdi
|
||||
|
||||
void installHooks()
|
||||
{
|
||||
g_caretGeneralEventHook = SetWinEventHook(
|
||||
EVENT_OBJECT_SHOW, EVENT_OBJECT_HIDE,
|
||||
reinterpret_cast<HMODULE>(&__ImageBase), &caretEvent,
|
||||
GetCurrentProcessId(), 0, WINEVENT_INCONTEXT);
|
||||
g_caretLocationChangeEventHook = SetWinEventHook(
|
||||
EVENT_OBJECT_LOCATIONCHANGE, EVENT_OBJECT_LOCATIONCHANGE,
|
||||
reinterpret_cast<HMODULE>(&__ImageBase), &caretEvent,
|
||||
GetCurrentProcessId(), 0, WINEVENT_INCONTEXT);
|
||||
g_caretGeneralEventHook = SetWinEventHook(EVENT_OBJECT_SHOW, EVENT_OBJECT_HIDE,
|
||||
Dll::g_currentModule, &caretEvent, GetCurrentProcessId(), 0, WINEVENT_INCONTEXT);
|
||||
g_caretLocationChangeEventHook = SetWinEventHook(EVENT_OBJECT_LOCATIONCHANGE, EVENT_OBJECT_LOCATIONCHANGE,
|
||||
Dll::g_currentModule, &caretEvent, GetCurrentProcessId(), 0, WINEVENT_INCONTEXT);
|
||||
}
|
||||
|
||||
void uninstallHooks()
|
||||
|
@ -6,6 +6,7 @@
|
||||
#include <Common/Hook.h>
|
||||
#include <Common/Log.h>
|
||||
#include <Common/ScopedCriticalSection.h>
|
||||
#include <Dll/Dll.h>
|
||||
#include <Gdi/AccessGuard.h>
|
||||
#include <Gdi/Dc.h>
|
||||
#include <Win32/DisplayMode.h>
|
||||
@ -16,8 +17,6 @@
|
||||
#include <Gdi/Window.h>
|
||||
#include <Gdi/WinProc.h>
|
||||
|
||||
extern "C" IMAGE_DOS_HEADER __ImageBase;
|
||||
|
||||
namespace
|
||||
{
|
||||
const char* PROP_DDRAWCOMPAT = "DDrawCompat";
|
||||
@ -316,11 +315,9 @@ namespace Gdi
|
||||
HOOK_FUNCTION(user32, SetWindowPos, setWindowPos);
|
||||
|
||||
g_objectCreateEventHook = SetWinEventHook(EVENT_OBJECT_CREATE, EVENT_OBJECT_CREATE,
|
||||
reinterpret_cast<HMODULE>(&__ImageBase), &objectCreateEvent,
|
||||
GetCurrentProcessId(), 0, WINEVENT_INCONTEXT);
|
||||
Dll::g_currentModule, &objectCreateEvent, GetCurrentProcessId(), 0, WINEVENT_INCONTEXT);
|
||||
g_objectStateChangeEventHook = SetWinEventHook(EVENT_OBJECT_STATECHANGE, EVENT_OBJECT_STATECHANGE,
|
||||
reinterpret_cast<HMODULE>(&__ImageBase), &objectStateChangeEvent,
|
||||
GetCurrentProcessId(), 0, WINEVENT_INCONTEXT);
|
||||
Dll::g_currentModule, &objectStateChangeEvent, GetCurrentProcessId(), 0, WINEVENT_INCONTEXT);
|
||||
|
||||
EnumWindows(initTopLevelWindow, 0);
|
||||
Gdi::Window::updateAll();
|
||||
|
@ -7,8 +7,6 @@
|
||||
#include <Gdi/Gdi.h>
|
||||
#include <Gdi/Window.h>
|
||||
|
||||
extern "C" IMAGE_DOS_HEADER __ImageBase;
|
||||
|
||||
namespace
|
||||
{
|
||||
const UINT WM_CREATEPRESENTATIONWINDOW = WM_USER;
|
||||
@ -132,7 +130,7 @@ namespace
|
||||
|
||||
WNDCLASS wc = {};
|
||||
wc.lpfnWndProc = &messageWindowProc;
|
||||
wc.hInstance = reinterpret_cast<HINSTANCE>(&__ImageBase);
|
||||
wc.hInstance = Dll::g_currentModule;
|
||||
wc.lpszClassName = "DDrawCompatMessageWindow";
|
||||
RegisterClass(&wc);
|
||||
|
||||
@ -329,7 +327,7 @@ namespace Gdi
|
||||
|
||||
WNDCLASS wc = {};
|
||||
wc.lpfnWndProc = &presentationWindowProc;
|
||||
wc.hInstance = reinterpret_cast<HINSTANCE>(&__ImageBase);
|
||||
wc.hInstance = Dll::g_currentModule;
|
||||
wc.lpszClassName = "DDrawCompatPresentationWindow";
|
||||
RegisterClass(&wc);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user