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/Log.h>
#include <Common/Path.h>
#include <Dll/Dll.h>
namespace
{
IDebugClient* g_debugClient = nullptr;
IDebugClient4* g_debugClient = nullptr;
IDebugControl* g_debugControl = nullptr;
IDebugSymbols* g_debugSymbols = nullptr;
IDebugDataSpaces4* g_debugDataSpaces = nullptr;
@ -22,7 +23,6 @@ namespace
bool g_isDbgEngInitialized = false;
PIMAGE_NT_HEADERS getImageNtHeaders(HMODULE module);
std::string getModulePath(HMODULE module);
bool initDbgEng();
FARPROC* findProcAddressInIat(HMODULE module, const char* procName)
@ -106,13 +106,6 @@ namespace
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)
{
BYTE* targetFunc = reinterpret_cast<BYTE*>(origFuncPtr);
@ -216,7 +209,7 @@ namespace
g_isDbgEngInitialized = true;
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_IDebugSymbols, reinterpret_cast<void**>(&g_debugSymbols))) ||
FAILED(result = g_debugClient->QueryInterface(IID_IDebugDataSpaces4, reinterpret_cast<void**>(&g_debugDataSpaces))))
@ -225,10 +218,7 @@ namespace
return false;
}
char dllPath[MAX_PATH] = {};
GetModuleFileName(Dll::g_currentModule, dllPath, sizeof(dllPath));
result = g_debugClient->OpenDumpFile(dllPath);
result = g_debugClient->OpenDumpFileWide(Compat::getModulePath(Dll::g_currentModule).c_str(), 0);
if (FAILED(result))
{
Compat::Log() << "ERROR: DbgEng: OpenDumpFile failed: " << Compat::hex(result);
@ -302,7 +292,7 @@ namespace Compat
HMODULE module = Compat::getModuleHandleFromAddress(funcPtr);
if (module)
{
oss << getModulePath(module) << "+0x" << std::hex <<
oss << Compat::getModulePath(module).u8string() << "+0x" << std::hex <<
reinterpret_cast<DWORD>(funcPtr) - reinterpret_cast<DWORD>(module);
}
else

View File

@ -1,6 +1,5 @@
#include <sstream>
#include <Common/Log.h>
#include <Common/Path.h>
namespace
{
@ -61,8 +60,12 @@ namespace Compat
GetLocalTime(&st);
char header[20];
#ifdef DEBUGLOGS
sprintf_s(header, "%04hx %02hu:%02hu:%02hu.%03hu ",
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;
if (0 != s_indent)
@ -76,25 +79,24 @@ namespace Compat
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 &&
0 == _strcmpi(processName.substr(processName.length() - 4).c_str(), ".exe"))
if (Compat::isEqual(processPath.extension(), ".exe"))
{
processName.resize(processName.length() - 4);
processPath.replace_extension();
}
processPath.replace_filename(L"DDrawCompat-" + processPath.filename().native());
for (int i = 1; i < 100; ++i)
{
std::ostringstream logFileName;
logFileName << processDir << '\\' << "DDrawCompat-" << processName;
auto logFilePath(processPath);
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())
{
return;

View File

@ -1,5 +1,6 @@
#pragma once
#include <filesystem>
#include <fstream>
#include <functional>
#include <ostream>
@ -183,7 +184,7 @@ namespace Compat
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; }
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\HResultException.h" />
<ClInclude Include="Common\Log.h" />
<ClInclude Include="Common\Path.h" />
<ClInclude Include="Common\ScopedSrwLock.h" />
<ClInclude Include="Common\VtableHookVisitor.h" />
<ClInclude Include="Common\VtableSizeVisitor.h" />
@ -268,6 +269,7 @@
<ItemGroup>
<ClCompile Include="Common\Log.cpp" />
<ClCompile Include="Common\Hook.cpp" />
<ClCompile Include="Common\Path.cpp" />
<ClCompile Include="Common\Time.cpp" />
<ClCompile Include="D3dDdi\Adapter.cpp" />
<ClCompile Include="D3dDdi\AdapterCallbacks.cpp" />

View File

@ -387,6 +387,9 @@
<ClInclude Include="Common\VtableSizeVisitor.h">
<Filter>Header Files\Common</Filter>
</ClInclude>
<ClInclude Include="Common\Path.h">
<Filter>Header Files\Common</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="Gdi\Gdi.cpp">
@ -605,6 +608,9 @@
<ClCompile Include="Gdi\Icon.cpp">
<Filter>Source Files\Gdi</Filter>
</ClCompile>
<ClCompile Include="Common\Path.cpp">
<Filter>Source Files\Common</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="DDrawCompat.rc">

View File

@ -7,6 +7,7 @@
#include <Common/Hook.h>
#include <Common/Log.h>
#include <Common/Path.h>
#include <Common/Time.h>
#include <D3dDdi/Hooks.h>
#include <DDraw/DirectDraw.h>
@ -47,31 +48,6 @@ namespace
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()
{
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()
{
const auto currentDllPath = getModulePath(Dll::g_currentModule);
const auto currentDllDir = getDirName(currentDllPath);
const auto ddrawDllPath = currentDllDir + "\\ddraw.dll";
const auto dciman32DllPath = currentDllDir + "\\dciman32.dll";
const auto currentDllPath(Compat::getModulePath(Dll::g_currentModule));
const auto ddrawDllPath(Compat::replaceFilename(currentDllPath, "ddraw.dll"));
const auto dciman32DllPath(Compat::replaceFilename(currentDllPath, "dciman32.dll"));
return (!isEqual(currentDllPath, ddrawDllPath) && GetModuleHandle(ddrawDllPath.c_str())) ||
(!isEqual(currentDllPath, dciman32DllPath) && GetModuleHandle(dciman32DllPath.c_str()));
return (!Compat::isEqual(currentDllPath, ddrawDllPath) && GetModuleHandleW(ddrawDllPath.c_str())) ||
(!Compat::isEqual(currentDllPath, dciman32DllPath) && GetModuleHandleW(dciman32DllPath.c_str()));
}
void printEnvironmentVariable(const char* var)
@ -203,26 +173,25 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
return TRUE;
}
auto processPath = getModulePath(nullptr);
Compat::Log::initLogging(getDirName(processPath), getFileName(processPath));
auto processPath(Compat::getModulePath(nullptr));
Compat::Log::initLogging(processPath);
Compat::Log() << "Process path: " << processPath;
Compat::Log() << "Process path: " << processPath.u8string();
printEnvironmentVariable("__COMPAT_LAYER");
auto currentDllPath = getModulePath(hinstDLL);
Compat::Log() << "Loading DDrawCompat " << (lpvReserved ? "statically" : "dynamically") << " from " << currentDllPath;
auto currentDllPath(Compat::getModulePath(hinstDLL));
Compat::Log() << "Loading DDrawCompat " << (lpvReserved ? "statically" : "dynamically") << " from " << currentDllPath.u8string();
auto systemDirectory = getSystemDirectory();
if (isEqual(getDirName(currentDllPath), systemDirectory))
auto systemPath(Compat::getSystemPath());
if (Compat::isEqual(currentDllPath.parent_path(), systemPath))
{
Compat::Log() << "DDrawCompat cannot be installed in the Windows system directory";
return FALSE;
}
auto systemDDrawDllPath = systemDirectory + "\\ddraw.dll";
Dll::g_origDDrawModule = LoadLibrary(systemDDrawDllPath.c_str());
Dll::g_origDDrawModule = LoadLibraryW((systemPath / "ddraw.dll").c_str());
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;
}
@ -232,8 +201,7 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
HMODULE origModule = Dll::g_origDDrawModule;
VISIT_DDRAW_PROCS(LOAD_ORIG_PROC);
auto systemDciman32DllPath = systemDirectory + "\\dciman32.dll";
Dll::g_origDciman32Module = LoadLibrary(systemDciman32DllPath.c_str());
Dll::g_origDciman32Module = LoadLibraryW((systemPath / "dciman32.dll").c_str());
if (Dll::g_origDciman32Module)
{
origModule = Dll::g_origDciman32Module;