Skip to content

Commit

Permalink
Use ansi codepage for internal multibyte strings on windows (fixes #976
Browse files Browse the repository at this point in the history
…, fixes #974, fixes #444)
  • Loading branch information
albertony committed Dec 10, 2020
1 parent e032d14 commit 4e487ed
Show file tree
Hide file tree
Showing 5 changed files with 130 additions and 33 deletions.
9 changes: 8 additions & 1 deletion src/lib/barrier/win32/DaemonApp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
#include "base/log_outputters.h"
#include "base/Log.h"
#include "common/DataDirectories.h"
#include "common/win32/StringConverters.h"

#include "arch/win32/ArchMiscWindows.h"
#include "arch/win32/XArchWindows.h"
Expand Down Expand Up @@ -250,14 +251,20 @@ DaemonApp::logFilename()
return logFilename;
}

static std::string from_ipc_string(const std::string& msg)
{
// Client sends UTF-8 encoded narrow strings (QString::toStdString()), convert to ANSI encoding used
return ansi_from_utf8(msg);
}

void
DaemonApp::handleIpcMessage(const Event& e, void*)
{
IpcMessage* m = static_cast<IpcMessage*>(e.getDataObject());
switch (m->type()) {
case kIpcCommand: {
IpcCommandMessage* cm = static_cast<IpcCommandMessage*>(m);
String command = cm->command();
String command = from_ipc_string(cm->command());

// if empty quotes, clear.
if (command == "\"\"") {
Expand Down
28 changes: 3 additions & 25 deletions src/lib/common/win32/DataDirectories.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,34 +16,12 @@
*/

#include "../DataDirectories.h"

#include <Shlobj.h>

std::string unicode_to_mb(const WCHAR* utfStr)
{
int utfLength = lstrlenW(utfStr);
int mbLength = WideCharToMultiByte(CP_UTF8, 0, utfStr, utfLength, NULL, 0, NULL, NULL);
std::string mbStr(mbLength, 0);
WideCharToMultiByte(CP_UTF8, 0, utfStr, utfLength, &mbStr[0], mbLength, NULL, NULL);
return mbStr;
}

std::string known_folder_path(const KNOWNFOLDERID& id)
{
std::string path;
WCHAR* buffer;
HRESULT result = SHGetKnownFolderPath(id, 0, NULL, &buffer);
if (result == S_OK) {
path = unicode_to_mb(buffer);
CoTaskMemFree(buffer);
}
return path;
}
#include "KnownFolderPaths.h"

const std::string& DataDirectories::profile()
{
if (_profile.empty())
_profile = known_folder_path(FOLDERID_LocalAppData) + "\\Barrier";
_profile = localAppDataPath() + "\\Barrier";
return _profile;
}
const std::string& DataDirectories::profile(const std::string& path)
Expand All @@ -55,7 +33,7 @@ const std::string& DataDirectories::profile(const std::string& path)
const std::string& DataDirectories::global()
{
if (_global.empty())
_global = known_folder_path(FOLDERID_ProgramData) + "\\Barrier";
_global = programDataPath() + "\\Barrier";
return _global;
}
const std::string& DataDirectories::global(const std::string& path)
Expand Down
48 changes: 48 additions & 0 deletions src/lib/common/win32/KnownFolderPaths.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/*
* barrier -- mouse and keyboard sharing utility
* Copyright (C) 2018 Debauchee Open Source Group
*
* 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 <http://www.gnu.org/licenses/>.
*/

#pragma once
#include "StringConverters.h"
#include <string>
#include <Shlobj.h>

static std::string known_folder_path(const KNOWNFOLDERID& id)
{
std::string path;
WCHAR* buffer;
HRESULT result = SHGetKnownFolderPath(id, 0, NULL, &buffer);
if (result == S_OK) {
path = ansi_from_wide(buffer);
CoTaskMemFree(buffer);
}
return path;
}

static std::string desktopPath()
{
return known_folder_path(FOLDERID_Desktop);
}

static std::string localAppDataPath()
{
return known_folder_path(FOLDERID_LocalAppData);
}

static std::string programDataPath()
{
return known_folder_path(FOLDERID_ProgramData);
}
66 changes: 66 additions & 0 deletions src/lib/common/win32/StringConverters.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
/*
* barrier -- mouse and keyboard sharing utility
* Copyright (C) 2018 Debauchee Open Source Group
*
* 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 <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <string>

#define WIN32_LEAN_AND_MEAN
#include <Windows.h>

static std::string ansi_from_wide(const wchar_t* wideString)
{
int wideLength = lstrlenW(wideString);
int ansiLength = WideCharToMultiByte(CP_ACP, 0, wideString, wideLength, NULL, 0, NULL, NULL);
if (ansiLength > 0) {
std::string ansiString(ansiLength, 0);
ansiLength = WideCharToMultiByte(CP_ACP, 0, wideString, wideLength, &ansiString[0], ansiLength, NULL, NULL);
if (ansiLength > 0) {
return ansiString;
}
}
return {};
}

static std::string ansi_from_wide(const std::wstring& wideString)
{
int ansiLength = WideCharToMultiByte(CP_ACP, 0, wideString.c_str(), (int)wideString.length(), NULL, 0, NULL, NULL);
if (ansiLength > 0) {
std::string ansiString(ansiLength, 0);
ansiLength = WideCharToMultiByte(CP_ACP, 0, wideString.c_str(), (int)wideString.length(), &ansiString[0], (int)ansiString.length(), NULL, NULL);
if (ansiLength > 0) {
return ansiString;
}
}
return {};
}

static std::wstring wide_from_utf8(const std::string& utf8String)
{
int wideLength = MultiByteToWideChar(CP_UTF8, 0, utf8String.c_str(), (int)utf8String.length(), NULL, 0);
if (wideLength > 0) {
std::wstring wideString(wideLength, 0);
wideLength = MultiByteToWideChar(CP_UTF8, 0, utf8String.c_str(), (int)utf8String.length(), &wideString[0], wideLength);
if (wideLength > 0) {
return wideString;
}
}
return {};
}

static std::string ansi_from_utf8(const std::string& utf8String)
{
return ansi_from_wide(wide_from_utf8(utf8String));
}
12 changes: 5 additions & 7 deletions src/lib/platform/MSWindowsScreen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,9 @@
#include "base/IEventQueue.h"
#include "base/TMethodEventJob.h"
#include "base/TMethodJob.h"
#include "common/win32/KnownFolderPaths.h"

#include <string.h>
#include <Shlobj.h>
#include <comutil.h>
#include <algorithm>

Expand Down Expand Up @@ -1916,14 +1916,12 @@ const std::string&
MSWindowsScreen::getDropTarget() const
{
if (m_dropTargetPath.empty()) {
// SHGetFolderPath is deprecated in vista, but use it for xp support.
char desktopPath[MAX_PATH];
if (SUCCEEDED(SHGetFolderPath(NULL, CSIDL_DESKTOP, NULL, 0, desktopPath))) {
m_dropTargetPath = std::string(desktopPath);
LOG((CLOG_INFO "using desktop for drop target: %s", m_dropTargetPath.c_str()));
m_dropTargetPath = desktopPath();
if (!m_dropTargetPath.empty()) {
LOG((CLOG_DEBUG "using desktop for drop target: %s", m_desktopPath.c_str()));
}
else {
LOG((CLOG_ERR "failed to get desktop path, no drop target available, error=%d", GetLastError()));
LOG((CLOG_ERR "failed to get desktop path, no drop target available"));
}
}
return m_dropTargetPath;
Expand Down

0 comments on commit 4e487ed

Please sign in to comment.