1
0
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:
narzoul 2021-04-25 16:49:02 +02:00
parent ded2c92c3a
commit 7c506d86c9
8 changed files with 87 additions and 75 deletions

View File

@ -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

View File

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

View File

@ -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:

View 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
View 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);
}

View File

@ -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" />

View File

@ -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">

View File

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