Skip to content

Commit

Permalink
Handle non-ASCII characters properly in paths
Browse files Browse the repository at this point in the history
  • Loading branch information
ishitatsuyuki authored and doitsujin committed Sep 10, 2020
1 parent 7bf02a1 commit bb85a4c
Show file tree
Hide file tree
Showing 10 changed files with 43 additions and 22 deletions.
4 changes: 2 additions & 2 deletions src/d3d11/d3d11_shader.cpp
Expand Up @@ -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));
}

Expand All @@ -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);
Expand Down
4 changes: 2 additions & 2 deletions src/d3d9/d3d9_fixed_function.cpp
Expand Up @@ -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);
Expand Down Expand Up @@ -2460,4 +2460,4 @@ namespace dxvk {

DxsoIsgn g_ffIsgn = CreateFixedFunctionIsgn();

}
}
8 changes: 4 additions & 4 deletions src/d3d9/d3d9_shader.cpp
Expand Up @@ -32,7 +32,7 @@ namespace dxvk {
DxsoReader reader(
reinterpret_cast<const char*>(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];
Expand All @@ -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<const char*>(blob->GetBufferPointer()),
blob->GetBufferSize());
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -147,4 +147,4 @@ namespace dxvk {
return commonShader;
}

}
}
12 changes: 6 additions & 6 deletions src/dxvk/dxvk_state_cache.cpp
Expand Up @@ -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);
}
Expand Down Expand Up @@ -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");
Expand Down Expand Up @@ -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);
}
Expand All @@ -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() != '/')
Expand All @@ -958,7 +958,7 @@ namespace dxvk {
exeName.erase(extp);

path += exeName + ".dxvk-cache";
return path;
return str::tows(path.c_str());
}


Expand Down
4 changes: 2 additions & 2 deletions src/dxvk/dxvk_state_cache.h
Expand Up @@ -176,7 +176,7 @@ namespace dxvk {

void writerFunc();

std::string getCacheFileName() const;
std::wstring getCacheFileName() const;

std::string getCacheDir() const;

Expand All @@ -191,4 +191,4 @@ namespace dxvk {

};

}
}
2 changes: 1 addition & 1 deletion src/util/config/config.cpp
Expand Up @@ -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;
Expand Down
2 changes: 1 addition & 1 deletion src/util/log/log.cpp
Expand Up @@ -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());
}
}

Expand Down
11 changes: 7 additions & 4 deletions src/util/util_env.cpp
Expand Up @@ -5,10 +5,13 @@
namespace dxvk::env {

std::string getEnvVar(const char* name) {
char* result = std::getenv(name);
return (result)
? result
: "";
std::vector<WCHAR> 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());
}


Expand Down
16 changes: 16 additions & 0 deletions src/util/util_string.cpp
Expand Up @@ -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;
}

}
2 changes: 2 additions & 0 deletions src/util/util_string.h
Expand Up @@ -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&) { }

Expand Down

2 comments on commit bb85a4c

@allfoxwy
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I play World of Warcraft Classic. And after this commit, the Battle.net Agent program no longer working.

The WOW game itself works fine, just the Battle.net Agent no longer working. As I could run the game directly via WowClassic.exe

The Battle.net Agent shows up the login window, in which I got my username and password input, then it turns up a Blizzard error reporter window asking me to send a crash report.

I'm on a Chinese server, so my game and Battle.net Agent is in Chinese either.

I'm using Debian with LANG=en_US.UTF-8, but set LANG=zh_cn.UTF-8 in Lutris' system options.

As it's not the game itself which is not working, I'm not sure how to provide more info about this. The game works, but the loader crash.

I tried DXVK_LOG_LEVEL=debug , but can't see useful info, just my graphic card description.

@allfoxwy
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't mind my last comment, it's now working again.

Maybe some Debian Testing upgrade helped.

Please sign in to comment.