From cd4eed0704b91f8beba9f5b21e6296891cd44114 Mon Sep 17 00:00:00 2001 From: RipleyTom Date: Thu, 26 Mar 2020 20:48:56 +0000 Subject: [PATCH] Gives ANSI path to curl CURLOPT_CAINFO --- Utilities/StrFmt.cpp | 43 ++++++++++++++++++++++++++++++++++- Utilities/StrUtil.h | 6 +++++ rpcs3/Emu/System.cpp | 12 ++++++++++ rpcs3/Emu/System.h | 4 ++++ rpcs3/rpcs3qt/curl_handle.cpp | 10 ++++++-- 5 files changed, 72 insertions(+), 3 deletions(-) diff --git a/Utilities/StrFmt.cpp b/Utilities/StrFmt.cpp index e2cde956ae..ae179fdd61 100644 --- a/Utilities/StrFmt.cpp +++ b/Utilities/StrFmt.cpp @@ -1,4 +1,4 @@ -#include "StrFmt.h" +#include "StrFmt.h" #include "BEType.h" #include "StrUtil.h" #include "cfmt.h" @@ -14,6 +14,47 @@ #include #endif +#ifdef _WIN32 +std::string wchar_to_utf8(wchar_t *src) +{ + std::string utf8_string; + auto tmp_size = WideCharToMultiByte(CP_UTF8, 0, src, -1, nullptr, 0, nullptr, nullptr); + utf8_string.resize(tmp_size); + WideCharToMultiByte(CP_UTF8, 0, src, -1, utf8_string.data(), tmp_size, nullptr, nullptr); + return utf8_string; +} + +std::string wchar_path_to_ansi_path(const std::wstring& src) +{ + std::wstring buf_short; + std::string buf_final; + + // Get the short path from the wide char path(short path should only contain ansi characters) + auto tmp_size = GetShortPathNameW(src.data(), nullptr, 0); + buf_short.resize(tmp_size); + GetShortPathNameW(src.data(), buf_short.data(), tmp_size); + + // Convert wide char to ansi + tmp_size = WideCharToMultiByte(CP_ACP, 0, buf_short.data(), -1, nullptr, 0, nullptr, nullptr); + buf_final.resize(tmp_size); + WideCharToMultiByte(CP_ACP, 0, buf_short.data(), -1, buf_final.data(), tmp_size, nullptr, nullptr); + + return buf_final; +} + +std::string utf8_path_to_ansi_path(const std::string& src) +{ + std::wstring buf_wide; + + // Converts the utf-8 path to wide char + auto tmp_size = MultiByteToWideChar(CP_UTF8, 0, src.c_str(), -1, nullptr, 0); + buf_wide.resize(tmp_size); + MultiByteToWideChar(CP_UTF8, 0, src.c_str(), -1, buf_wide.data(), tmp_size); + + return wchar_path_to_ansi_path(buf_wide); +} +#endif + template <> void fmt_class_string>::format(std::string& out, u64 arg) { diff --git a/Utilities/StrUtil.h b/Utilities/StrUtil.h index 9b6179c3c2..c9a47a9f78 100644 --- a/Utilities/StrUtil.h +++ b/Utilities/StrUtil.h @@ -7,6 +7,12 @@ #include #include +#ifdef _WIN32 +std::string wchar_to_utf8(wchar_t *src); +std::string wchar_path_to_ansi_path(const std::wstring& src); +std::string utf8_path_to_ansi_path(const std::string& src); +#endif + // Copy null-terminated string from a std::string or a char array to a char array with truncation template inline void strcpy_trunc(D& dst, const T& src) diff --git a/rpcs3/Emu/System.cpp b/rpcs3/Emu/System.cpp index cccfaa47b4..8a47b90241 100644 --- a/rpcs3/Emu/System.cpp +++ b/rpcs3/Emu/System.cpp @@ -655,6 +655,18 @@ std::string Emulator::GetHdd1Dir() return fmt::replace_all(g_cfg.vfs.dev_hdd1, "$(EmulatorDir)", GetEmuDir()); } +#ifdef _WIN32 +std::string Emulator::GetExeDir() +{ + wchar_t buffer[32767]; + GetModuleFileNameW(nullptr, buffer, sizeof(buffer)/2); + + std::string path_to_exe = wchar_to_utf8(buffer); + size_t last = path_to_exe.find_last_of("\\"); + return last == std::string::npos ? std::string("") : path_to_exe.substr(0, last+1); +} +#endif + std::string Emulator::GetSfoDirFromGamePath(const std::string& game_path, const std::string& user, const std::string& title_id) { if (fs::is_file(game_path + "/PS3_DISC.SFB")) diff --git a/rpcs3/Emu/System.h b/rpcs3/Emu/System.h index af5af926d1..b870f077d0 100644 --- a/rpcs3/Emu/System.h +++ b/rpcs3/Emu/System.h @@ -179,6 +179,10 @@ private: void LimitCacheSize(); public: +#ifdef _WIN32 + static std::string GetExeDir(); +#endif + static std::string GetEmuDir(); static std::string GetHddDir(); static std::string GetHdd1Dir(); diff --git a/rpcs3/rpcs3qt/curl_handle.cpp b/rpcs3/rpcs3qt/curl_handle.cpp index be68210454..10cf5a0206 100644 --- a/rpcs3/rpcs3qt/curl_handle.cpp +++ b/rpcs3/rpcs3qt/curl_handle.cpp @@ -2,14 +2,20 @@ #include "curl_handle.h" #include "Emu/System.h" +#ifdef _WIN32 +#include "Utilities/StrUtil.h" +#endif + curl_handle::curl_handle(QObject* parent) : QObject(parent) { m_curl = curl_easy_init(); #ifdef _WIN32 // This shouldn't be needed on linux - const std::string path_to_cert = Emulator::GetEmuDir() + "cacert.pem"; - curl_easy_setopt(m_curl, CURLOPT_CAINFO, path_to_cert.c_str()); + const std::string path_to_cert = Emulator::GetExeDir() + "cacert.pem"; + const std::string ansi_path = utf8_path_to_ansi_path(path_to_cert); + + curl_easy_setopt(m_curl, CURLOPT_CAINFO, ansi_path.data()); #endif }