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/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
|
||||
|
@ -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;
|
||||
|
@ -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:
|
||||
|
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\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" />
|
||||
|
@ -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">
|
||||
|
@ -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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user