From bb85a4caa8c48e61d5b698f2718b227678ad180a Mon Sep 17 00:00:00 2001 From: ishitatsuyuki Date: Thu, 10 Sep 2020 12:02:53 +0900 Subject: [PATCH] Handle non-ASCII characters properly in paths --- src/d3d11/d3d11_shader.cpp | 4 ++-- src/d3d9/d3d9_fixed_function.cpp | 4 ++-- src/d3d9/d3d9_shader.cpp | 8 ++++---- src/dxvk/dxvk_state_cache.cpp | 12 ++++++------ src/dxvk/dxvk_state_cache.h | 4 ++-- src/util/config/config.cpp | 2 +- src/util/log/log.cpp | 2 +- src/util/util_env.cpp | 11 +++++++---- src/util/util_string.cpp | 16 ++++++++++++++++ src/util/util_string.h | 2 ++ 10 files changed, 43 insertions(+), 22 deletions(-) diff --git a/src/d3d11/d3d11_shader.cpp b/src/d3d11/d3d11_shader.cpp index a5ab47b120b..3fe686cf96d 100644 --- a/src/d3d11/d3d11_shader.cpp +++ b/src/d3d11/d3d11_shader.cpp @@ -27,7 +27,7 @@ namespace dxvk { const std::string dumpPath = env::getEnvVar("DXVK_SHADER_DUMP_PATH"); if (dumpPath.size() != 0) { - reader.store(std::ofstream(str::format(dumpPath, "/", name, ".dxbc"), + reader.store(std::ofstream(str::tows(str::format(dumpPath, "/", name, ".dxbc").c_str()).c_str(), std::ios_base::binary | std::ios_base::trunc)); } @@ -43,7 +43,7 @@ namespace dxvk { if (dumpPath.size() != 0) { std::ofstream dumpStream( - str::format(dumpPath, "/", name, ".spv"), + str::tows(str::format(dumpPath, "/", name, ".spv").c_str()).c_str(), std::ios_base::binary | std::ios_base::trunc); m_shader->dump(dumpStream); diff --git a/src/d3d9/d3d9_fixed_function.cpp b/src/d3d9/d3d9_fixed_function.cpp index b4c459fce21..7ed22f5e36b 100644 --- a/src/d3d9/d3d9_fixed_function.cpp +++ b/src/d3d9/d3d9_fixed_function.cpp @@ -2340,7 +2340,7 @@ namespace dxvk { if (dumpPath.size() != 0) { std::ofstream dumpStream( - str::format(dumpPath, "/", Name, ".spv"), + str::tows(str::format(dumpPath, "/", Name, ".spv").c_str()).c_str(), std::ios_base::binary | std::ios_base::trunc); m_shader->dump(dumpStream); @@ -2460,4 +2460,4 @@ namespace dxvk { DxsoIsgn g_ffIsgn = CreateFixedFunctionIsgn(); -} \ No newline at end of file +} diff --git a/src/d3d9/d3d9_shader.cpp b/src/d3d9/d3d9_shader.cpp index 2e40737bc8b..cfa3eb86b7c 100644 --- a/src/d3d9/d3d9_shader.cpp +++ b/src/d3d9/d3d9_shader.cpp @@ -32,7 +32,7 @@ namespace dxvk { DxsoReader reader( reinterpret_cast(pShaderBytecode)); - reader.store(std::ofstream(str::format(dumpPath, "/", name, ".dxso"), + reader.store(std::ofstream(str::tows(str::format(dumpPath, "/", name, ".dxso").c_str()).c_str(), std::ios_base::binary | std::ios_base::trunc), bytecodeLength); char comment[2048]; @@ -44,7 +44,7 @@ namespace dxvk { &blob); if (SUCCEEDED(hr)) { - std::ofstream disassembledOut(str::format(dumpPath, "/", name, ".dxso.dis"), std::ios_base::binary | std::ios_base::trunc); + std::ofstream disassembledOut(str::tows(str::format(dumpPath, "/", name, ".dxso.dis").c_str()).c_str(), std::ios_base::binary | std::ios_base::trunc); disassembledOut.write( reinterpret_cast(blob->GetBufferPointer()), blob->GetBufferSize()); @@ -83,7 +83,7 @@ namespace dxvk { if (dumpPath.size() != 0) { std::ofstream dumpStream( - str::format(dumpPath, "/", name, ".spv"), + str::tows(str::format(dumpPath, "/", name, ".spv").c_str()).c_str(), std::ios_base::binary | std::ios_base::trunc); m_shaders[0]->dump(dumpStream); @@ -147,4 +147,4 @@ namespace dxvk { return commonShader; } -} \ No newline at end of file +} diff --git a/src/dxvk/dxvk_state_cache.cpp b/src/dxvk/dxvk_state_cache.cpp index f8ccf65bea8..3c01fa9f1f2 100644 --- a/src/dxvk/dxvk_state_cache.cpp +++ b/src/dxvk/dxvk_state_cache.cpp @@ -128,12 +128,12 @@ namespace dxvk { Logger::warn("DXVK: Creating new state cache file"); // Start with an empty file - std::ofstream file(getCacheFileName(), + std::ofstream file(getCacheFileName().c_str(), std::ios_base::binary | std::ios_base::trunc); if (!file && env::createDirectory(getCacheDir())) { - file = std::ofstream(getCacheFileName(), + file = std::ofstream(getCacheFileName().c_str(), std::ios_base::binary | std::ios_base::trunc); } @@ -349,7 +349,7 @@ namespace dxvk { bool DxvkStateCache::readCacheFile() { // Open state file and just fail if it doesn't exist - std::ifstream ifile(getCacheFileName(), std::ios_base::binary); + std::ifstream ifile(getCacheFileName().c_str(), std::ios_base::binary); if (!ifile) { Logger::warn("DXVK: No state cache file found"); @@ -935,7 +935,7 @@ namespace dxvk { } if (!file) { - file = std::ofstream(getCacheFileName(), + file = std::ofstream(getCacheFileName().c_str(), std::ios_base::binary | std::ios_base::app); } @@ -945,7 +945,7 @@ namespace dxvk { } - std::string DxvkStateCache::getCacheFileName() const { + std::wstring DxvkStateCache::getCacheFileName() const { std::string path = getCacheDir(); if (!path.empty() && *path.rbegin() != '/') @@ -958,7 +958,7 @@ namespace dxvk { exeName.erase(extp); path += exeName + ".dxvk-cache"; - return path; + return str::tows(path.c_str()); } diff --git a/src/dxvk/dxvk_state_cache.h b/src/dxvk/dxvk_state_cache.h index f4992e33003..28c9868b5b4 100644 --- a/src/dxvk/dxvk_state_cache.h +++ b/src/dxvk/dxvk_state_cache.h @@ -176,7 +176,7 @@ namespace dxvk { void writerFunc(); - std::string getCacheFileName() const; + std::wstring getCacheFileName() const; std::string getCacheDir() const; @@ -191,4 +191,4 @@ namespace dxvk { }; -} \ No newline at end of file +} diff --git a/src/util/config/config.cpp b/src/util/config/config.cpp index f95beafa3ea..5fe0f569606 100644 --- a/src/util/config/config.cpp +++ b/src/util/config/config.cpp @@ -593,7 +593,7 @@ namespace dxvk { filePath = "dxvk.conf"; // Open the file if it exists - std::ifstream stream(filePath); + std::ifstream stream(str::tows(filePath.c_str()).c_str()); if (!stream) return config; diff --git a/src/util/log/log.cpp b/src/util/log/log.cpp index 14b0dc02764..a64a0c31545 100644 --- a/src/util/log/log.cpp +++ b/src/util/log/log.cpp @@ -10,7 +10,7 @@ namespace dxvk { auto path = getFileName(file_name); if (!path.empty()) - m_fileStream = std::ofstream(path); + m_fileStream = std::ofstream(str::tows(path.c_str()).c_str()); } } diff --git a/src/util/util_env.cpp b/src/util/util_env.cpp index a804de6aae6..0df61a17443 100644 --- a/src/util/util_env.cpp +++ b/src/util/util_env.cpp @@ -5,10 +5,13 @@ namespace dxvk::env { std::string getEnvVar(const char* name) { - char* result = std::getenv(name); - return (result) - ? result - : ""; + std::vector result; + result.resize(MAX_PATH + 1); + + DWORD len = ::GetEnvironmentVariableW(str::tows(name).c_str(), result.data(), MAX_PATH); + result.resize(len); + + return str::fromws(result.data()); } diff --git a/src/util/util_string.cpp b/src/util/util_string.cpp index d19e0db7d4b..2151c1e4085 100644 --- a/src/util/util_string.cpp +++ b/src/util/util_string.cpp @@ -24,4 +24,20 @@ namespace dxvk::str { wcs, wcsLen); } + std::wstring tows(const char* mbs) { + size_t len = ::MultiByteToWideChar(CP_UTF8, + 0, mbs, -1, nullptr, 0); + + if (len <= 1) + return L""; + + len -= 1; + + std::wstring result; + result.resize(len); + ::MultiByteToWideChar(CP_UTF8, 0, mbs, -1, + &result.at(0), len); + return result; + } + } diff --git a/src/util/util_string.h b/src/util/util_string.h index 8bf8802bb99..cd738477407 100644 --- a/src/util/util_string.h +++ b/src/util/util_string.h @@ -16,6 +16,8 @@ namespace dxvk::str { void tows(const char* mbs, WCHAR (&wcs)[N]) { return tows(mbs, wcs, N); } + + std::wstring tows(const char* mbs); inline void format1(std::stringstream&) { }