Commit 25068e2e authored by Andreas Traczyk's avatar Andreas Traczyk Committed by Sébastien Blin

win32: convert utf-8/utf-16 when accessing win32 apis

- any functions that get strings from windows apis, are converted
  and stored as utf8 strings internally
- anytime an internal utf8 string is passed as a parameter to a
  windows api function, it is converted to a wstring
- all of these translations apply currently to file paths
- a windows client should make sure to setlocale to utf8 because
  we use some dependencies that call mbstowcs and wcstombs instead
  of WideCharToMultiByte/MultiByteToWideChar

Change-Id: Ic13f55ace491e1088c0a3d436d3a0d02df7216c3
Reviewed-by: Sébastien Blin's avatarSébastien Blin <sebastien.blin@savoirfairelinux.com>
parent 24947c36
......@@ -191,7 +191,8 @@ STACK_DIRECTION = 0 => direction of growth unknown */
#define TIME_WITH_SYS_TIME 1
/* Define to 1 for Unicode (Wide Chars) APIs. */
/* #undef UNICODE */
#define UNICODE 1
#undef _MBCS
/* Version number of package */
#define VERSION "2.3.0"
......
......@@ -118,7 +118,7 @@
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<WholeProgramOptimization>false</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet>
<CharacterSet>Unicode</CharacterSet>
<WindowsAppContainer>false</WindowsAppContainer>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseLib|x64'" Label="Configuration">
......@@ -579,7 +579,7 @@
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>false</SDLCheck>
<AdditionalIncludeDirectories>$(ProjectDir);$(ProjectDir)..\;$(ProjectDir)..\src;$(ProjectDir)..\src\client;$(ProjectDir)..\src\config;$(ProjectDir)..\src\dring;$(ProjectDir)..\src\hooks;$(ProjectDir)..\src\im;$(ProjectDir)..\src\media;$(ProjectDir)..\src\jamidht;$(ProjectDir)..\src\security;$(ProjectDir)..\src\sip;$(ProjectDir)..\src\upnp;$(ProjectDir)..\src\upnp\igd;$(ProjectDir)..\src\upnp\protocol;$(ProjectDir)..\src\upnp\mapping;$(ProjectDir)..\src\jamidht\eth;$(ProjectDir)..\contrib\msvc;$(ProjectDir)..\contrib\msvc\include;$(ProjectDir)..\contrib\build\pupnp\upnp\inc;$(ProjectDir)..\contrib\build\msgpack-c\include;$(ProjectDir)..\contrib\build\jsoncpp\include;$(ProjectDir)..\contrib\build\yaml-cpp\include;$(ProjectDir)..\contrib\build\pjproject\pjlib\include;$(ProjectDir)..\contrib\build\pjproject\pjnath\include;$(ProjectDir)..\contrib\build\pjproject\pjlib-util\include;$(ProjectDir)..\contrib\build\pjproject\pjsip\include;$(ProjectDir)..\contrib\build\pjproject\third_party;$(ProjectDir)..\contrib\build\pjproject\pjmedia\include;$(ProjectDir)..\contrib\build\restbed\source;$(ProjectDir)..\contrib\build\ffmpeg\Build\Windows10\x64\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>RING_UWP;STATICLIB;_USE_MATH_DEFINES;_SCL_SECURE_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;NOMINMAX;HAVE_CONFIG_H;WIN32_LEAN_AND_MEAN;WIN32_NATIVE;_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>STATICLIB;_USE_MATH_DEFINES;_SCL_SECURE_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;NOMINMAX;HAVE_CONFIG_H;WIN32_LEAN_AND_MEAN;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<DisableSpecificWarnings>4996;4503;4180;4244;4267;</DisableSpecificWarnings>
<SuppressStartupBanner>true</SuppressStartupBanner>
<BasicRuntimeChecks>
......@@ -587,6 +587,7 @@
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions>
</ClCompile>
<Link>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
......
......@@ -75,7 +75,7 @@ accountToJsonValue(const std::map<std::string, std::string>& details) {
i.first == DRing::Account::ConfProperties::TLS::CERTIFICATE_FILE ||
i.first == DRing::Account::ConfProperties::TLS::PRIVATE_KEY_FILE) {
// replace paths by the files content
std::ifstream ifs(i.second);
std::ifstream ifs = fileutils::ifstream(i.second);
std::string fileContent((std::istreambuf_iterator<char>(ifs)), std::istreambuf_iterator<char>());
root[i.first] = fileContent;
} else
......
......@@ -276,7 +276,7 @@ SubOutgoingFileTransfer::SubOutgoingFileTransfer(DRing::DataTransferId tid,
{
info_ = metaInfo_->info();
input_.open(info_.path, std::ios::binary);
fileutils::openStream(input_, info_.path, std::ios::binary);
if (!input_)
throw std::runtime_error("input file open failed");
metaInfo_->addLinkedTransfer(this);
......@@ -438,7 +438,7 @@ private:
OutgoingFileTransfer::OutgoingFileTransfer(DRing::DataTransferId tid, const DRing::DataTransferInfo& info)
: DataTransfer(tid)
{
input_.open(info.path, std::ios::binary);
fileutils::openStream(input_, info.path, std::ios::binary);
if (!input_)
throw std::runtime_error("input file open failed");
......@@ -518,7 +518,7 @@ IncomingFileTransfer::start()
if (!DataTransfer::start())
return false;
fout_.open(&info_.path[0], std::ios::binary);
fileutils::openStream(fout_, &info_.path[0], std::ios::binary);
if (!fout_) {
JAMI_ERR() << "[FTP] Can't open file " << info_.path;
return false;
......@@ -725,7 +725,7 @@ DataTransferFacade::acceptAsFile(const DRing::DataTransferId& id,
#ifndef _WIN32
iter->second->accept(file_path, offset);
#else
iter->second->accept(decodeMultibyteString(file_path), offset);
iter->second->accept(file_path, offset);
#endif
return DRing::DataTransferError::success;
}
......
......@@ -231,23 +231,29 @@ getFileLock(const std::string& path)
bool isFile(const std::string& path, bool resolveSymlink)
{
#ifdef _WIN32
if (resolveSymlink) {
struct stat s;
if (stat(path.c_str(), &s) == 0)
struct _stat64i32 s;
if (_wstat(jami::to_wstring(path).c_str(), &s) == 0)
return S_ISREG(s.st_mode);
} else {
#ifdef _WIN32
DWORD attr = GetFileAttributesA(path.c_str());
DWORD attr = GetFileAttributes(jami::to_wstring(path).c_str());
if ((attr != INVALID_FILE_ATTRIBUTES) &&
!(attr & FILE_ATTRIBUTE_DIRECTORY) &&
!(attr & FILE_ATTRIBUTE_REPARSE_POINT))
return true;
}
#else
if (resolveSymlink) {
struct stat s;
if (stat(path.c_str(), &s) == 0)
return S_ISREG(s.st_mode);
} else {
struct stat s;
if (lstat(path.c_str(), &s) == 0)
return S_ISREG(s.st_mode);
#endif
}
#endif
return false;
}
......@@ -262,10 +268,7 @@ bool isDirectory(const std::string& path)
bool isDirectoryWritable(const std::string &directory)
{
#ifdef _WIN32
return access(decodeMultibyteString(directory).c_str(), W_OK) == 0;
#endif
return access(directory.c_str(), W_OK) == 0;
return accessFile(directory, W_OK) == 0;
}
bool isSymLink(const std::string& path)
......@@ -301,10 +304,8 @@ writeTime(const std::string& path)
ext_params.lpSecurityAttributes = nullptr;
ext_params.hTemplateFile = nullptr;
HANDLE h = CreateFile2(jami::to_wstring(path).c_str(), GENERIC_READ, FILE_SHARE_READ, OPEN_EXISTING, &ext_params);
#elif _MSC_VER
HANDLE h = CreateFile(path.c_str(), GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr);
#else
HANDLE h = CreateFile(jami::to_wstring(path).c_str(), GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr);
#elif _WIN32
HANDLE h = CreateFileW(jami::to_wstring(path).c_str(), GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr);
#endif
if (h == INVALID_HANDLE_VALUE)
throw std::runtime_error("Can't open: " + path);
......@@ -359,7 +360,7 @@ std::vector<uint8_t>
loadFile(const std::string& path, const std::string& default_dir)
{
std::vector<uint8_t> buffer;
std::ifstream file(getFullPath(default_dir, path), std::ios::binary);
std::ifstream file = ifstream(getFullPath(default_dir, path), std::ios::binary);
if (!file)
throw std::runtime_error("Can't read file: "+path);
file.seekg(0, std::ios::end);
......@@ -378,7 +379,7 @@ saveFile(const std::string& path,
const std::vector<uint8_t>& data,
mode_t UNUSED mode)
{
std::ofstream file(path, std::ios::trunc | std::ios::binary);
std::ofstream file = fileutils::ofstream(path, std::ios::trunc | std::ios::binary);
if (!file.is_open()) {
JAMI_ERR("Could not write data to %s", path.c_str());
return;
......@@ -581,12 +582,9 @@ get_home_dir()
files_path = paths[0];
return files_path;
#elif defined _WIN32
WCHAR path[MAX_PATH];
if (SUCCEEDED(SHGetFolderPathW(nullptr, CSIDL_PROFILE, nullptr, 0, path))) {
char tmp[MAX_PATH];
char DefChar = ' ';
WideCharToMultiByte(CP_ACP, 0, path, -1, tmp, MAX_PATH, &DefChar, nullptr);
return std::string(tmp);
TCHAR path[MAX_PATH];
if (SUCCEEDED(SHGetFolderPath(nullptr, CSIDL_PROFILE, nullptr, 0, path))) {
return jami::to_string(path);
}
return program_dir;
#else
......@@ -727,14 +725,14 @@ recursive_mkdir(const std::string& path, mode_t mode)
#ifndef _WIN32
if (mkdir(path.data(), mode) != 0) {
#else
if (mkdir(path.data()) != 0) {
if (_wmkdir(jami::to_wstring(path.data()).c_str()) != 0) {
#endif
if (errno == ENOENT) {
recursive_mkdir(path.substr(0, path.find_last_of(DIR_SEPARATOR_CH)), mode);
#ifndef _WIN32
if (mkdir(path.data(), mode) != 0) {
#else
if (mkdir(path.data()) != 0) {
if (_wmkdir(jami::to_wstring(path.data()).c_str()) != 0) {
#endif
JAMI_ERR("Could not create directory.");
return false;
......@@ -891,4 +889,54 @@ removeAll(const std::string& path, bool erase)
return remove(path, erase);
}
void
openStream(std::ifstream& file, const std::string& path, std::ios_base::openmode mode)
{
#ifdef _WIN32
file.open(jami::to_wstring(path), mode);
#else
file.open(path, mode);
#endif
}
void
openStream(std::ofstream& file, const std::string& path, std::ios_base::openmode mode)
{
#ifdef _WIN32
file.open(jami::to_wstring(path), mode);
#else
file.open(path, mode);
#endif
}
std::ifstream
ifstream(const std::string& path, std::ios_base::openmode mode)
{
#ifdef _WIN32
return std::ifstream(jami::to_wstring(path), mode);
#else
return std::ifstream(path, mode);
#endif
}
std::ofstream
ofstream(const std::string& path, std::ios_base::openmode mode)
{
#ifdef _WIN32
return std::ofstream(jami::to_wstring(path), mode);
#else
return std::ofstream(path, mode);
#endif
}
int
accessFile(const std::string& file, int mode)
{
#ifdef _WIN32
return _waccess(jami::to_wstring(file).c_str(), mode);
#else
return access(file.c_str(), mode);
#endif
}
}} // namespace jami::fileutils
......@@ -26,6 +26,7 @@
#include <chrono>
#include <mutex>
#include <cstdio>
#include <ios>
#include "dring/def.h"
......@@ -134,6 +135,20 @@ namespace jami { namespace fileutils {
*/
int removeAll(const std::string& path, bool erase = false);
/**
* Wrappers for fstream opening that will convert paths to wstring
* on windows
*/
void openStream(std::ifstream& file, const std::string& path, std::ios_base::openmode mode = std::ios_base::in);
void openStream(std::ofstream& file, const std::string& path, std::ios_base::openmode mode = std::ios_base::out);
std::ifstream ifstream(const std::string& path, std::ios_base::openmode mode = std::ios_base::in);
std::ofstream ofstream(const std::string& path, std::ios_base::openmode mode = std::ios_base::out);
/**
* Windows compatibility wrapper for checking read-only attribute
*/
int accessFile(const std::string& file, int mode);
}} // namespace jami::fileutils
#endif // FILEUTILS_H_
......@@ -182,7 +182,7 @@ MessageEngine::load()
std::lock_guard<std::mutex> lock(fileutils::getFileLock(savePath_));
std::ifstream file;
file.exceptions(std::ifstream::failbit | std::ifstream::badbit);
file.open(savePath_);
fileutils::openStream(file, savePath_);
file >> root;
}
std::lock_guard<std::mutex> lock(messagesMutex_);
......@@ -262,7 +262,7 @@ MessageEngine::save_() const
const std::unique_ptr<Json::StreamWriter> writer(wbuilder.newStreamWriter());
std::ofstream file;
file.exceptions(std::ifstream::failbit | std::ifstream::badbit);
file.open(path, std::ios::trunc);
fileutils::openStream(file, path, std::ios::trunc);
writer->write(root, &file);
} catch (const std::exception& e) {
JAMI_ERR("[Account %s] Couldn't save messages to %s: %s", accountID.c_str(), path.c_str(), e.what());
......
......@@ -233,7 +233,6 @@ static const auto PROXY_REGEX = std::regex("(https?://)?([\\w\\.]+)(:(\\d+)|:\\[
static const std::string PEER_DISCOVERY_JAMI_SERVICE = "jami";
const constexpr auto PEER_DISCOVERY_EXPIRATION = std::chrono::minutes(1);
constexpr const char* const JamiAccount::ACCOUNT_TYPE;
/* constexpr */ const std::pair<uint16_t, uint16_t> JamiAccount::DHT_PORT_RANGE {4000, 8888};
......@@ -310,9 +309,9 @@ JamiAccount::JamiAccount(const std::string& accountID, bool /* presenceEnabled *
turnServerRealm_ = DEFAULT_TURN_REALM;
turnEnabled_ = true;
std::ifstream proxyCache(cachePath_ + DIR_SEPARATOR_STR "dhtproxy");
std::ifstream proxyCache = fileutils::ifstream(cachePath_ + DIR_SEPARATOR_STR "dhtproxy");
if (proxyCache)
std::getline(proxyCache, proxyServerCached_);
std::getline(proxyCache, proxyServerCached_);
setActiveCodecs({});
}
......@@ -662,7 +661,6 @@ JamiAccount::SIPStartCall(SIPCall& call, IpAddr target)
(int)pjContact.slen, pjContact.ptr, from.c_str(), toUri.c_str(),
(int)pjTarget.slen, pjTarget.ptr);
auto local_sdp = call.getSDP().getLocalSdpSession();
pjsip_dialog* dialog {nullptr};
pjsip_inv_session* inv {nullptr};
......@@ -712,7 +710,7 @@ void JamiAccount::saveConfig() const
auto accountConfig = getPath() + DIR_SEPARATOR_STR + "config.yml";
std::lock_guard<std::mutex> lock(fileutils::getFileLock(accountConfig));
std::ofstream fout(accountConfig);
std::ofstream fout = fileutils::ofstream(accountConfig);
fout << accountOut.c_str();
JAMI_DBG("Exported account to %s", accountConfig.c_str());
} catch (const std::exception& e) {
......@@ -1022,7 +1020,6 @@ JamiAccount::readArchive(const std::string& pwd) const
return AccountArchive(fileutils::getFullPath(idPath_, archivePath_), pwd);
}
void
JamiAccount::updateArchive(AccountArchive& archive) const
{
......@@ -1190,9 +1187,9 @@ JamiAccount::exportArchive(const std::string& destinationPath, const std::string
}
// Export the file
auto sourcePath = fileutils::getFullPath(idPath_, archivePath_);
std::ifstream src(sourcePath, std::ios::in | std::ios::binary);
std::ifstream src = fileutils::ifstream(sourcePath, std::ios::in | std::ios::binary);
if (!src) return false;
std::ofstream dst(destinationPath, std::ios::out | std::ios::binary);
std::ofstream dst = fileutils::ofstream(destinationPath, std::ios::out | std::ios::binary);
dst << src.rdbuf();
} catch (const std::runtime_error& ex) {
JAMI_ERR("[Account %s] Can't export archive: %s", getAccountID().c_str(), ex.what());
......@@ -2083,7 +2080,6 @@ JamiAccount::doRegister()
}
}
std::vector<std::string>
JamiAccount::loadBootstrap() const
{
......@@ -2809,7 +2805,7 @@ std::set<ID>
loadIdList(const std::string& path)
{
std::set<ID> ids;
std::ifstream file(path);
std::ifstream file = fileutils::ifstream(path);
if (!file.is_open()) {
JAMI_DBG("Could not load %s", path.c_str());
return ids;
......@@ -2828,7 +2824,7 @@ template<typename ID=dht::Value::Id>
void
saveIdList(const std::string& path, const std::set<ID>& ids)
{
std::ofstream file(path, std::ios::trunc | std::ios::binary);
std::ofstream file = fileutils::ofstream(path, std::ios::trunc | std::ios::binary);
if (!file.is_open()) {
JAMI_ERR("Could not save to %s", path.c_str());
return;
......@@ -2915,7 +2911,7 @@ JamiAccount::loadKnownDevices()
void
JamiAccount::saveKnownDevices() const
{
std::ofstream file(idPath_+DIR_SEPARATOR_STR "knownDevicesNames", std::ios::trunc | std::ios::binary);
std::ofstream file = fileutils::ofstream(idPath_+DIR_SEPARATOR_STR "knownDevicesNames", std::ios::trunc | std::ios::binary);
std::map<dht::InfoHash, std::pair<std::string, uint64_t>> devices;
for (const auto& id : knownDevices_)
......@@ -2996,7 +2992,7 @@ JamiAccount::getDhtProxyServer()
// Cache it!
fileutils::check_dir(cachePath_.c_str(), 0700);
std::string proxyCachePath = cachePath_ + DIR_SEPARATOR_STR "dhtproxy";
std::ofstream file(proxyCachePath);
std::ofstream file = fileutils::ofstream(proxyCachePath);
JAMI_DBG("Cache DHT proxy server: %s", proxyServerCached_.c_str());
if (file.is_open())
file << proxyServerCached_;
......@@ -3202,7 +3198,7 @@ JamiAccount::loadContacts()
void
JamiAccount::saveContacts() const
{
std::ofstream file(idPath_+DIR_SEPARATOR_STR "contacts", std::ios::trunc | std::ios::binary);
std::ofstream file = fileutils::ofstream(idPath_+DIR_SEPARATOR_STR "contacts", std::ios::trunc | std::ios::binary);
msgpack::pack(file, contacts_);
}
......@@ -3292,7 +3288,7 @@ JamiAccount::sendTrustRequestConfirm(const dht::InfoHash& to)
void
JamiAccount::saveTrustRequests() const
{
std::ofstream file(idPath_+DIR_SEPARATOR_STR "incomingTrustRequests", std::ios::trunc | std::ios::binary);
std::ofstream file = fileutils::ofstream(idPath_+DIR_SEPARATOR_STR "incomingTrustRequests", std::ios::trunc | std::ios::binary);
msgpack::pack(file, trustRequests_);
}
......@@ -3661,7 +3657,6 @@ void JamiAccount::pushNotificationReceived(const std::string& from, const std::m
dht_.pushNotificationReceived(data);
}
std::string
JamiAccount::getUserUri() const
{
......@@ -3672,7 +3667,6 @@ JamiAccount::getUserUri() const
return username_;
}
std::vector<DRing::Message>
JamiAccount::getLastMessages(const uint64_t& base_timestamp)
{
......@@ -3746,7 +3740,6 @@ JamiAccount::getNearbyPeers() const
return discoveredPeerMap_;
}
void
JamiAccount::setActiveCodecs(const std::vector<unsigned>& list)
{
......
......@@ -399,7 +399,7 @@ NameDirectory::saveCache()
{
fileutils::recursive_mkdir(fileutils::get_cache_dir()+DIR_SEPARATOR_STR+CACHE_DIRECTORY);
std::lock_guard<std::mutex> lock(fileutils::getFileLock(cachePath_));
std::ofstream file(cachePath_, std::ios::trunc | std::ios::binary);
std::ofstream file = fileutils::ofstream(cachePath_, std::ios::trunc | std::ios::binary);
{
std::lock_guard<std::mutex> l(lock_);
msgpack::pack(file, nameCache_);
......@@ -415,7 +415,7 @@ NameDirectory::loadCache()
// read file
{
std::lock_guard<std::mutex> lock(fileutils::getFileLock(cachePath_));
std::ifstream file(cachePath_);
std::ifstream file = fileutils::ifstream(cachePath_);
if (!file.is_open()) {
JAMI_DBG("Could not load %s", cachePath_.c_str());
return;
......
......@@ -120,8 +120,8 @@ std::atomic_bool Manager::initialized = {false};
static void
copy_over(const std::string &srcPath, const std::string &destPath)
{
std::ifstream src(srcPath.c_str());
std::ofstream dest(destPath.c_str());
std::ifstream src = fileutils::ifstream(srcPath.c_str());
std::ofstream dest = fileutils::ofstream(destPath.c_str());
dest << src.rdbuf();
src.close();
dest.close();
......@@ -439,7 +439,8 @@ Manager::ManagerPimpl::parseConfiguration()
bool result = true;
try {
YAML::Node parsedFile = YAML::LoadFile(path_);
std::ifstream file = fileutils::ifstream(path_);
YAML::Node parsedFile = YAML::Load(file);
const int error_count = base_.loadAccountMap(parsedFile);
if (error_count > 0) {
......@@ -1772,7 +1773,7 @@ Manager::saveConfig()
shortcutPreferences.serialize(out);
std::lock_guard<std::mutex> lock(fileutils::getFileLock(pimpl_->path_));
std::ofstream fout(pimpl_->path_);
std::ofstream fout = fileutils::ofstream(pimpl_->path_);
fout << out.c_str();
} catch (const YAML::Exception &e) {
JAMI_ERR("%s", e.what());
......@@ -2158,9 +2159,7 @@ Manager::playRingtone(const std::string& accountID)
CFStringEncoding encodingMethod = CFStringGetSystemEncoding();
const char *buindlePath = CFStringGetCStringPtr(stringPath, encodingMethod);
ringchoice = std::string(buindlePath) + DIR_SEPARATOR_STR + ringchoice;
#elif _WIN32
ringchoice = decodeMultibyteString(ringchoice);
#else
#elif !defined(_WIN32)
if (ringchoice.find(DIR_SEPARATOR_CH) == std::string::npos) {
// check inside global share directory
static const char * const RINGDIR = "ringtones";
......@@ -2858,7 +2857,8 @@ Manager::loadAccountMap(const YAML::Node& node)
if (fileutils::isFile(configFile)) {
try {
if (auto a = accountFactory.createAccount(JamiAccount::ACCOUNT_TYPE, dir)) {
YAML::Node parsedConfig = YAML::LoadFile(configFile);
std::ifstream file = fileutils::ifstream(configFile);
YAML::Node parsedConfig = YAML::Load(file);
a->unserialize(parsedConfig);
}
} catch (const std::exception& e) {
......
......@@ -832,7 +832,6 @@ MediaEncoder::getCurrentVideoAVCtx()
return nullptr;
}
void
MediaEncoder::stopEncoder()
{
......@@ -858,7 +857,7 @@ MediaEncoder::readConfig(AVCodecContext* encoderCtx)
if (fileutils::isFile(path)) {
try {
Json::Value root;
std::ifstream file(path);
std::ifstream file = fileutils::ifstream(path);
file >> root;
if (!root.isObject()) {
JAMI_ERR() << "Invalid encoder configuration: root is not an object";
......
......@@ -60,9 +60,6 @@ Recordable::toggleRecording()
auto startTime = *std::localtime(&t);
std::stringstream ss;
auto dir = Manager::instance().audioPreference.getRecordPath();
#ifdef _WIN32
dir = decodeMultibyteString(dir);
#endif
if (dir.empty())
dir = fileutils::get_home_dir();
ss << dir;
......
......@@ -1308,18 +1308,11 @@ std::string SIPAccount::getLoginName()
#elif defined (RING_UWP)
return "Unknown";
#else
TCHAR username[UNLEN + 1];
DWORD size = UNLEN + 1;
TCHAR username[UNLEN + 1];
std::string uname;
if (GetUserName((TCHAR*)username, &size)) {
#ifdef _MSC_VER
wchar_t* tmpstr = new wchar_t[UNLEN + 1];
mbstowcs(tmpstr, username, UNLEN + 1);
std::wstring wStr = tmpstr;
#else
std::wstring wStr = username;
#endif
uname = std::string(wStr.begin(), wStr.end());
uname = jami::to_string(username);
}
return uname;
#endif
......
......@@ -37,25 +37,33 @@ namespace jami {
#ifdef _WIN32
std::wstring
to_wstring(const std::string& s)
to_wstring(const std::string& str, int codePage)
{
int slength = (int)s.length();
int len = MultiByteToWideChar(CP_UTF8, 0, s.c_str(), slength, nullptr, 0);
if (not len)
throw std::runtime_error("Can't convert string to wchar");
std::wstring r((size_t)len, 0);
if (!MultiByteToWideChar(CP_UTF8, 0, s.c_str(), slength, &(*r.begin()), len))
throw std::runtime_error("Can't convert string to wchar");
return r;
int srcLength = (int)str.length();
int requiredSize = MultiByteToWideChar(codePage, 0, str.c_str(), srcLength, nullptr, 0);
if (!requiredSize) {
throw std::runtime_error("Can't convert string to wstring");
}
std::wstring result((size_t)requiredSize, 0);
if (!MultiByteToWideChar(codePage, 0, str.c_str(), srcLength, &(*result.begin()), requiredSize)) {
throw std::runtime_error("Can't convert string to wstring");
}
return result;
}
std::string
decodeMultibyteString(const std::string& s)
to_string(const std::wstring& wstr, int codePage)
{
if (not s.length())
return {};
auto wstr = to_wstring(s);
return std::string(wstr.begin(), wstr.end());
int srcLength = (int)wstr.length();
int requiredSize = WideCharToMultiByte(codePage, 0, wstr.c_str(), srcLength, nullptr, 0, 0, 0);
if (!requiredSize) {
throw std::runtime_error("Can't convert wstring to string");
}
std::string result((size_t)requiredSize, 0);
if (!WideCharToMultiByte(codePage, 0, wstr.c_str(), srcLength, &(*result.begin()), requiredSize, 0, 0)) {
throw std::runtime_error("Can't convert wstring to string");
}
return result;
}
std::string
......
......@@ -42,8 +42,8 @@ bool_to_str(bool b) noexcept
std::string to_string(double value);
#ifdef _WIN32
std::wstring to_wstring(const std::string& s);
std::string decodeMultibyteString(const std::string& s);
std::wstring to_wstring(const std::string& str, int codePage = CP_UTF8);
std::string to_string(const std::wstring& wstr, int codePage = CP_ACP);
std::string bstrToStdString(BSTR bstr);
#endif
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment