mirror of
https://github.com/narzoul/DDrawCompat
synced 2024-12-30 08:55:36 +01:00
Support unicode file paths
This commit is contained in:
parent
ded2c92c3a
commit
7c506d86c9
@ -10,11 +10,12 @@
|
|||||||
|
|
||||||
#include <Common/Hook.h>
|
#include <Common/Hook.h>
|
||||||
#include <Common/Log.h>
|
#include <Common/Log.h>
|
||||||
|
#include <Common/Path.h>
|
||||||
#include <Dll/Dll.h>
|
#include <Dll/Dll.h>
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
IDebugClient* g_debugClient = nullptr;
|
IDebugClient4* g_debugClient = nullptr;
|
||||||
IDebugControl* g_debugControl = nullptr;
|
IDebugControl* g_debugControl = nullptr;
|
||||||
IDebugSymbols* g_debugSymbols = nullptr;
|
IDebugSymbols* g_debugSymbols = nullptr;
|
||||||
IDebugDataSpaces4* g_debugDataSpaces = nullptr;
|
IDebugDataSpaces4* g_debugDataSpaces = nullptr;
|
||||||
@ -22,7 +23,6 @@ namespace
|
|||||||
bool g_isDbgEngInitialized = false;
|
bool g_isDbgEngInitialized = false;
|
||||||
|
|
||||||
PIMAGE_NT_HEADERS getImageNtHeaders(HMODULE module);
|
PIMAGE_NT_HEADERS getImageNtHeaders(HMODULE module);
|
||||||
std::string getModulePath(HMODULE module);
|
|
||||||
bool initDbgEng();
|
bool initDbgEng();
|
||||||
|
|
||||||
FARPROC* findProcAddressInIat(HMODULE module, const char* procName)
|
FARPROC* findProcAddressInIat(HMODULE module, const char* procName)
|
||||||
@ -106,13 +106,6 @@ namespace
|
|||||||
return static_cast<unsigned>(endOffset - g_debugBase);
|
return static_cast<unsigned>(endOffset - g_debugBase);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string getModulePath(HMODULE module)
|
|
||||||
{
|
|
||||||
char path[MAX_PATH] = {};
|
|
||||||
GetModuleFileName(module, path, sizeof(path));
|
|
||||||
return path;
|
|
||||||
}
|
|
||||||
|
|
||||||
void hookFunction(void*& origFuncPtr, void* newFuncPtr, const char* funcName)
|
void hookFunction(void*& origFuncPtr, void* newFuncPtr, const char* funcName)
|
||||||
{
|
{
|
||||||
BYTE* targetFunc = reinterpret_cast<BYTE*>(origFuncPtr);
|
BYTE* targetFunc = reinterpret_cast<BYTE*>(origFuncPtr);
|
||||||
@ -216,7 +209,7 @@ namespace
|
|||||||
g_isDbgEngInitialized = true;
|
g_isDbgEngInitialized = true;
|
||||||
|
|
||||||
HRESULT result = S_OK;
|
HRESULT result = S_OK;
|
||||||
if (FAILED(result = DebugCreate(IID_IDebugClient, reinterpret_cast<void**>(&g_debugClient))) ||
|
if (FAILED(result = DebugCreate(IID_IDebugClient4, reinterpret_cast<void**>(&g_debugClient))) ||
|
||||||
FAILED(result = g_debugClient->QueryInterface(IID_IDebugControl, reinterpret_cast<void**>(&g_debugControl))) ||
|
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_IDebugSymbols, reinterpret_cast<void**>(&g_debugSymbols))) ||
|
||||||
FAILED(result = g_debugClient->QueryInterface(IID_IDebugDataSpaces4, reinterpret_cast<void**>(&g_debugDataSpaces))))
|
FAILED(result = g_debugClient->QueryInterface(IID_IDebugDataSpaces4, reinterpret_cast<void**>(&g_debugDataSpaces))))
|
||||||
@ -225,10 +218,7 @@ namespace
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
char dllPath[MAX_PATH] = {};
|
result = g_debugClient->OpenDumpFileWide(Compat::getModulePath(Dll::g_currentModule).c_str(), 0);
|
||||||
GetModuleFileName(Dll::g_currentModule, dllPath, sizeof(dllPath));
|
|
||||||
|
|
||||||
result = g_debugClient->OpenDumpFile(dllPath);
|
|
||||||
if (FAILED(result))
|
if (FAILED(result))
|
||||||
{
|
{
|
||||||
Compat::Log() << "ERROR: DbgEng: OpenDumpFile failed: " << Compat::hex(result);
|
Compat::Log() << "ERROR: DbgEng: OpenDumpFile failed: " << Compat::hex(result);
|
||||||
@ -302,7 +292,7 @@ namespace Compat
|
|||||||
HMODULE module = Compat::getModuleHandleFromAddress(funcPtr);
|
HMODULE module = Compat::getModuleHandleFromAddress(funcPtr);
|
||||||
if (module)
|
if (module)
|
||||||
{
|
{
|
||||||
oss << getModulePath(module) << "+0x" << std::hex <<
|
oss << Compat::getModulePath(module).u8string() << "+0x" << std::hex <<
|
||||||
reinterpret_cast<DWORD>(funcPtr) - reinterpret_cast<DWORD>(module);
|
reinterpret_cast<DWORD>(funcPtr) - reinterpret_cast<DWORD>(module);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
#include <sstream>
|
|
||||||
|
|
||||||
#include <Common/Log.h>
|
#include <Common/Log.h>
|
||||||
|
#include <Common/Path.h>
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
@ -61,8 +60,12 @@ namespace Compat
|
|||||||
GetLocalTime(&st);
|
GetLocalTime(&st);
|
||||||
|
|
||||||
char header[20];
|
char header[20];
|
||||||
|
#ifdef DEBUGLOGS
|
||||||
sprintf_s(header, "%04hx %02hu:%02hu:%02hu.%03hu ",
|
sprintf_s(header, "%04hx %02hu:%02hu:%02hu.%03hu ",
|
||||||
GetCurrentThreadId(), st.wHour, st.wMinute, st.wSecond, st.wMilliseconds);
|
GetCurrentThreadId(), st.wHour, st.wMinute, st.wSecond, st.wMilliseconds);
|
||||||
|
#else
|
||||||
|
sprintf_s(header, "%02hu:%02hu:%02hu.%03hu ", st.wHour, st.wMinute, st.wSecond, st.wMilliseconds);
|
||||||
|
#endif
|
||||||
s_logFile << header;
|
s_logFile << header;
|
||||||
|
|
||||||
if (0 != s_indent)
|
if (0 != s_indent)
|
||||||
@ -76,25 +79,24 @@ namespace Compat
|
|||||||
s_logFile << std::endl;
|
s_logFile << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Log::initLogging(const std::string& processDir, std::string processName)
|
void Log::initLogging(std::filesystem::path processPath)
|
||||||
{
|
{
|
||||||
if (processName.length() >= 4 &&
|
if (Compat::isEqual(processPath.extension(), ".exe"))
|
||||||
0 == _strcmpi(processName.substr(processName.length() - 4).c_str(), ".exe"))
|
|
||||||
{
|
{
|
||||||
processName.resize(processName.length() - 4);
|
processPath.replace_extension();
|
||||||
}
|
}
|
||||||
|
processPath.replace_filename(L"DDrawCompat-" + processPath.filename().native());
|
||||||
|
|
||||||
for (int i = 1; i < 100; ++i)
|
for (int i = 1; i < 100; ++i)
|
||||||
{
|
{
|
||||||
std::ostringstream logFileName;
|
auto logFilePath(processPath);
|
||||||
logFileName << processDir << '\\' << "DDrawCompat-" << processName;
|
|
||||||
if (i > 1)
|
if (i > 1)
|
||||||
{
|
{
|
||||||
logFileName << '[' << i << ']';
|
logFilePath += '[' + std::to_string(i) + ']';
|
||||||
}
|
}
|
||||||
logFileName << ".log";
|
logFilePath += ".log";
|
||||||
|
|
||||||
s_logFile.open(logFileName.str(), std::ios_base::out, SH_DENYWR);
|
s_logFile.open(logFilePath, std::ios_base::out, SH_DENYWR);
|
||||||
if (!s_logFile.fail())
|
if (!s_logFile.fail())
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <filesystem>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <ostream>
|
#include <ostream>
|
||||||
@ -183,7 +184,7 @@ namespace Compat
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void initLogging(const std::string& processDir, std::string processName);
|
static void initLogging(std::filesystem::path processPath);
|
||||||
static bool isPointerDereferencingAllowed() { return s_isLeaveLog || 0 == s_outParamDepth; }
|
static bool isPointerDereferencingAllowed() { return s_isLeaveLog || 0 == s_outParamDepth; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
30
DDrawCompat/Common/Path.cpp
Normal file
30
DDrawCompat/Common/Path.cpp
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
#include <Common/Path.h>
|
||||||
|
|
||||||
|
namespace Compat
|
||||||
|
{
|
||||||
|
std::filesystem::path getModulePath(HMODULE module)
|
||||||
|
{
|
||||||
|
wchar_t path[MAX_PATH];
|
||||||
|
GetModuleFileNameW(module, path, MAX_PATH);
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::filesystem::path getSystemPath()
|
||||||
|
{
|
||||||
|
wchar_t path[MAX_PATH] = {};
|
||||||
|
GetSystemDirectoryW(path, MAX_PATH);
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isEqual(const std::filesystem::path& p1, const std::filesystem::path& p2)
|
||||||
|
{
|
||||||
|
return 0 == _wcsicmp(p1.c_str(), p2.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
std::filesystem::path replaceFilename(const std::filesystem::path& path, const std::filesystem::path& filename)
|
||||||
|
{
|
||||||
|
std::filesystem::path result(path);
|
||||||
|
result.replace_filename(filename);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
13
DDrawCompat/Common/Path.h
Normal file
13
DDrawCompat/Common/Path.h
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <filesystem>
|
||||||
|
|
||||||
|
#include <Windows.h>
|
||||||
|
|
||||||
|
namespace Compat
|
||||||
|
{
|
||||||
|
std::filesystem::path getModulePath(HMODULE module);
|
||||||
|
std::filesystem::path getSystemPath();
|
||||||
|
bool isEqual(const std::filesystem::path& p1, const std::filesystem::path& p2);
|
||||||
|
std::filesystem::path replaceFilename(const std::filesystem::path& path, const std::filesystem::path& filename);
|
||||||
|
}
|
@ -169,6 +169,7 @@
|
|||||||
<ClInclude Include="Common\CompatWeakPtr.h" />
|
<ClInclude Include="Common\CompatWeakPtr.h" />
|
||||||
<ClInclude Include="Common\HResultException.h" />
|
<ClInclude Include="Common\HResultException.h" />
|
||||||
<ClInclude Include="Common\Log.h" />
|
<ClInclude Include="Common\Log.h" />
|
||||||
|
<ClInclude Include="Common\Path.h" />
|
||||||
<ClInclude Include="Common\ScopedSrwLock.h" />
|
<ClInclude Include="Common\ScopedSrwLock.h" />
|
||||||
<ClInclude Include="Common\VtableHookVisitor.h" />
|
<ClInclude Include="Common\VtableHookVisitor.h" />
|
||||||
<ClInclude Include="Common\VtableSizeVisitor.h" />
|
<ClInclude Include="Common\VtableSizeVisitor.h" />
|
||||||
@ -268,6 +269,7 @@
|
|||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="Common\Log.cpp" />
|
<ClCompile Include="Common\Log.cpp" />
|
||||||
<ClCompile Include="Common\Hook.cpp" />
|
<ClCompile Include="Common\Hook.cpp" />
|
||||||
|
<ClCompile Include="Common\Path.cpp" />
|
||||||
<ClCompile Include="Common\Time.cpp" />
|
<ClCompile Include="Common\Time.cpp" />
|
||||||
<ClCompile Include="D3dDdi\Adapter.cpp" />
|
<ClCompile Include="D3dDdi\Adapter.cpp" />
|
||||||
<ClCompile Include="D3dDdi\AdapterCallbacks.cpp" />
|
<ClCompile Include="D3dDdi\AdapterCallbacks.cpp" />
|
||||||
|
@ -387,6 +387,9 @@
|
|||||||
<ClInclude Include="Common\VtableSizeVisitor.h">
|
<ClInclude Include="Common\VtableSizeVisitor.h">
|
||||||
<Filter>Header Files\Common</Filter>
|
<Filter>Header Files\Common</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="Common\Path.h">
|
||||||
|
<Filter>Header Files\Common</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="Gdi\Gdi.cpp">
|
<ClCompile Include="Gdi\Gdi.cpp">
|
||||||
@ -605,6 +608,9 @@
|
|||||||
<ClCompile Include="Gdi\Icon.cpp">
|
<ClCompile Include="Gdi\Icon.cpp">
|
||||||
<Filter>Source Files\Gdi</Filter>
|
<Filter>Source Files\Gdi</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="Common\Path.cpp">
|
||||||
|
<Filter>Source Files\Common</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ResourceCompile Include="DDrawCompat.rc">
|
<ResourceCompile Include="DDrawCompat.rc">
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
|
|
||||||
#include <Common/Hook.h>
|
#include <Common/Hook.h>
|
||||||
#include <Common/Log.h>
|
#include <Common/Log.h>
|
||||||
|
#include <Common/Path.h>
|
||||||
#include <Common/Time.h>
|
#include <Common/Time.h>
|
||||||
#include <D3dDdi/Hooks.h>
|
#include <D3dDdi/Hooks.h>
|
||||||
#include <DDraw/DirectDraw.h>
|
#include <DDraw/DirectDraw.h>
|
||||||
@ -47,31 +48,6 @@ namespace
|
|||||||
return LOG_RESULT(reinterpret_cast<OrigFuncPtrType>(Dll::g_origProcs.*origFunc)(firstParam, params...));
|
return LOG_RESULT(reinterpret_cast<OrigFuncPtrType>(Dll::g_origProcs.*origFunc)(firstParam, 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::string getSystemDirectory()
|
|
||||||
{
|
|
||||||
char path[MAX_PATH] = {};
|
|
||||||
GetSystemDirectory(path, sizeof(path));
|
|
||||||
return path;
|
|
||||||
}
|
|
||||||
|
|
||||||
void installHooks()
|
void installHooks()
|
||||||
{
|
{
|
||||||
static bool isAlreadyInstalled = false;
|
static bool isAlreadyInstalled = false;
|
||||||
@ -123,20 +99,14 @@ namespace
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isEqual(const std::string& p1, const std::string& p2)
|
|
||||||
{
|
|
||||||
return 0 == _stricmp(p1.c_str(), p2.c_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isOtherDDrawWrapperLoaded()
|
bool isOtherDDrawWrapperLoaded()
|
||||||
{
|
{
|
||||||
const auto currentDllPath = getModulePath(Dll::g_currentModule);
|
const auto currentDllPath(Compat::getModulePath(Dll::g_currentModule));
|
||||||
const auto currentDllDir = getDirName(currentDllPath);
|
const auto ddrawDllPath(Compat::replaceFilename(currentDllPath, "ddraw.dll"));
|
||||||
const auto ddrawDllPath = currentDllDir + "\\ddraw.dll";
|
const auto dciman32DllPath(Compat::replaceFilename(currentDllPath, "dciman32.dll"));
|
||||||
const auto dciman32DllPath = currentDllDir + "\\dciman32.dll";
|
|
||||||
|
|
||||||
return (!isEqual(currentDllPath, ddrawDllPath) && GetModuleHandle(ddrawDllPath.c_str())) ||
|
return (!Compat::isEqual(currentDllPath, ddrawDllPath) && GetModuleHandleW(ddrawDllPath.c_str())) ||
|
||||||
(!isEqual(currentDllPath, dciman32DllPath) && GetModuleHandle(dciman32DllPath.c_str()));
|
(!Compat::isEqual(currentDllPath, dciman32DllPath) && GetModuleHandleW(dciman32DllPath.c_str()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void printEnvironmentVariable(const char* var)
|
void printEnvironmentVariable(const char* var)
|
||||||
@ -203,26 +173,25 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto processPath = getModulePath(nullptr);
|
auto processPath(Compat::getModulePath(nullptr));
|
||||||
Compat::Log::initLogging(getDirName(processPath), getFileName(processPath));
|
Compat::Log::initLogging(processPath);
|
||||||
|
|
||||||
Compat::Log() << "Process path: " << processPath;
|
Compat::Log() << "Process path: " << processPath.u8string();
|
||||||
printEnvironmentVariable("__COMPAT_LAYER");
|
printEnvironmentVariable("__COMPAT_LAYER");
|
||||||
auto currentDllPath = getModulePath(hinstDLL);
|
auto currentDllPath(Compat::getModulePath(hinstDLL));
|
||||||
Compat::Log() << "Loading DDrawCompat " << (lpvReserved ? "statically" : "dynamically") << " from " << currentDllPath;
|
Compat::Log() << "Loading DDrawCompat " << (lpvReserved ? "statically" : "dynamically") << " from " << currentDllPath.u8string();
|
||||||
|
|
||||||
auto systemDirectory = getSystemDirectory();
|
auto systemPath(Compat::getSystemPath());
|
||||||
if (isEqual(getDirName(currentDllPath), systemDirectory))
|
if (Compat::isEqual(currentDllPath.parent_path(), systemPath))
|
||||||
{
|
{
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto systemDDrawDllPath = systemDirectory + "\\ddraw.dll";
|
Dll::g_origDDrawModule = LoadLibraryW((systemPath / "ddraw.dll").c_str());
|
||||||
Dll::g_origDDrawModule = LoadLibrary(systemDDrawDllPath.c_str());
|
|
||||||
if (!Dll::g_origDDrawModule)
|
if (!Dll::g_origDDrawModule)
|
||||||
{
|
{
|
||||||
Compat::Log() << "ERROR: Failed to load system ddraw.dll from " << systemDDrawDllPath;
|
Compat::Log() << "ERROR: Failed to load system ddraw.dll from " << systemPath.u8string();
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -232,8 +201,7 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
|
|||||||
HMODULE origModule = Dll::g_origDDrawModule;
|
HMODULE origModule = Dll::g_origDDrawModule;
|
||||||
VISIT_DDRAW_PROCS(LOAD_ORIG_PROC);
|
VISIT_DDRAW_PROCS(LOAD_ORIG_PROC);
|
||||||
|
|
||||||
auto systemDciman32DllPath = systemDirectory + "\\dciman32.dll";
|
Dll::g_origDciman32Module = LoadLibraryW((systemPath / "dciman32.dll").c_str());
|
||||||
Dll::g_origDciman32Module = LoadLibrary(systemDciman32DllPath.c_str());
|
|
||||||
if (Dll::g_origDciman32Module)
|
if (Dll::g_origDciman32Module)
|
||||||
{
|
{
|
||||||
origModule = Dll::g_origDciman32Module;
|
origModule = Dll::g_origDciman32Module;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user