diff --git a/src/lib/barrier/DropHelper.cpp b/src/lib/barrier/DropHelper.cpp index e3e15939..32f20cfc 100644 --- a/src/lib/barrier/DropHelper.cpp +++ b/src/lib/barrier/DropHelper.cpp @@ -18,6 +18,7 @@ #include "barrier/DropHelper.h" #include "base/Log.h" +#include "io/fstream.h" #include @@ -35,7 +36,7 @@ DropHelper::writeToDir(const String& destination, DragFileList& fileList, String dropTarget.append("/"); #endif dropTarget.append(fileList.at(0).getFilename()); - file.open(dropTarget.c_str(), std::ios::out | std::ios::binary); + barrier::open_utf8_path(file, dropTarget, std::ios::out | std::ios::binary); if (!file.is_open()) { LOG((CLOG_ERR "drop file failed: can not open %s", dropTarget.c_str())); } diff --git a/src/lib/base/log_outputters.cpp b/src/lib/base/log_outputters.cpp index 1d43f605..6d3374b5 100644 --- a/src/lib/base/log_outputters.cpp +++ b/src/lib/base/log_outputters.cpp @@ -20,7 +20,7 @@ #include "base/TMethodJob.h" #include "arch/Arch.h" #include "base/String.h" - +#include "io/fstream.h" #include enum EFileLogOutputter { @@ -260,7 +260,7 @@ FileLogOutputter::write(ELevel level, const char *message) bool moveFile = false; std::ofstream m_handle; - m_handle.open(m_fileName.c_str(), std::fstream::app); + barrier::open_utf8_path(m_handle, m_fileName, std::fstream::app); if (m_handle.is_open() && m_handle.fail() != true) { m_handle << message << std::endl; diff --git a/src/lib/common/win32/encoding_utilities.cpp b/src/lib/common/win32/encoding_utilities.cpp index 16379316..11781d36 100644 --- a/src/lib/common/win32/encoding_utilities.cpp +++ b/src/lib/common/win32/encoding_utilities.cpp @@ -16,6 +16,7 @@ */ #include "encoding_utilities.h" +#include std::string win_wchar_to_utf8(const WCHAR* utfStr) { @@ -25,3 +26,12 @@ std::string win_wchar_to_utf8(const WCHAR* utfStr) WideCharToMultiByte(CP_UTF8, 0, utfStr, utfLength, &mbStr[0], mbLength, NULL, NULL); return mbStr; } + +std::vector utf8_to_win_char(const std::string& str) +{ + int result_len = MultiByteToWideChar(CP_UTF8, 0, str.data(), str.size(), NULL, 0); + std::vector result; + result.resize(result_len + 1, 0); + MultiByteToWideChar(CP_UTF8, 0, str.data(), str.size(), result.data(), result_len); + return result; +} diff --git a/src/lib/common/win32/encoding_utilities.h b/src/lib/common/win32/encoding_utilities.h index f09cf531..747371e8 100644 --- a/src/lib/common/win32/encoding_utilities.h +++ b/src/lib/common/win32/encoding_utilities.h @@ -18,8 +18,11 @@ #ifndef BARRIER_LIB_COMMON_WIN32_ENCODING_UTILITIES_H #define BARRIER_LIB_COMMON_WIN32_ENCODING_UTILITIES_H +#include #include +#include std::string win_wchar_to_utf8(const WCHAR* utfStr); +std::vector utf8_to_win_char(const std::string& str); #endif diff --git a/src/lib/io/fstream.cpp b/src/lib/io/fstream.cpp new file mode 100644 index 00000000..4aef9073 --- /dev/null +++ b/src/lib/io/fstream.cpp @@ -0,0 +1,57 @@ +/* + barrier -- mouse and keyboard sharing utility + Copyright (C) Barrier contributors + + This package is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + found in the file LICENSE that should have accompanied this file. + + This package is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include "fstream.h" +#if SYSAPI_WIN32 +#include "common/win32/encoding_utilities.h" +#endif +#include + +namespace barrier { + +namespace { + +template +void open_utf8_path_impl(Stream& stream, const std::string& path, std::ios_base::openmode mode) +{ +#if SYSAPI_WIN32 + // on Windows we need to use a private constructor from wchar_t* string. + auto wchar_path = utf8_to_win_char(path); + stream.open(wchar_path.data(), mode); +#else + stream.open(path.c_str(), mode); +#endif +} + +} // namespace + +void open_utf8_path(std::ifstream& stream, const std::string& path, std::ios_base::openmode mode) +{ + open_utf8_path_impl(stream, path, mode); +} + +void open_utf8_path(std::ofstream& stream, const std::string& path, std::ios_base::openmode mode) +{ + open_utf8_path_impl(stream, path, mode); +} + +void open_utf8_path(std::fstream& stream, const std::string& path, std::ios_base::openmode mode) +{ + open_utf8_path_impl(stream, path, mode); +} + +} // namespace barrier diff --git a/src/lib/io/fstream.h b/src/lib/io/fstream.h new file mode 100644 index 00000000..26288373 --- /dev/null +++ b/src/lib/io/fstream.h @@ -0,0 +1,35 @@ +/* + barrier -- mouse and keyboard sharing utility + Copyright (C) Barrier contributors + + This package is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + found in the file LICENSE that should have accompanied this file. + + This package is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#ifndef BARRIER_LIB_IO_FSTREAM_H +#define BARRIER_LIB_IO_FSTREAM_H + +#include +#include + +namespace barrier { + +void open_utf8_path(std::ifstream& stream, const std::string& path, + std::ios_base::openmode mode = std::ios_base::in); +void open_utf8_path(std::ofstream& stream, const std::string& path, + std::ios_base::openmode mode = std::ios_base::out); +void open_utf8_path(std::fstream& stream, const std::string& path, + std::ios_base::openmode mode = std::ios_base::in | std::ios_base::out); + +} // namespace barrier + +#endif diff --git a/src/lib/net/SecureSocket.cpp b/src/lib/net/SecureSocket.cpp index 6982d0f1..c3c1a064 100644 --- a/src/lib/net/SecureSocket.cpp +++ b/src/lib/net/SecureSocket.cpp @@ -25,6 +25,7 @@ #include "base/Log.h" #include "base/String.h" #include "common/DataDirectories.h" +#include "io/fstream.h" #include #include @@ -708,7 +709,7 @@ SecureSocket::verifyCertFingerprint() // check if this fingerprint exist std::string fileLine; std::ifstream file; - file.open(trustedServersFilename.c_str()); + barrier::open_utf8_path(file, trustedServersFilename); if (!file.is_open()) { LOG((CLOG_NOTE "Unable to open trustedServersFile: %s", trustedServersFilename.c_str() ));