From 3921dc7ec57c5fad3aa3e7662bbf6ed5d7f7ad6a Mon Sep 17 00:00:00 2001 From: albertony <12441419+albertony@users.noreply.github.com> Date: Wed, 9 Dec 2020 23:36:34 +0100 Subject: [PATCH] Use ansi codepage for internal multibyte strings on windows (fixes #976, fixes #974, fixes #444) --- src/gui/src/CommandProcess.cpp | 14 ++-- src/gui/src/Fingerprint.cpp | 4 +- src/gui/src/IpcClient.cpp | 5 +- src/gui/src/MainWindow.cpp | 3 +- src/gui/src/QUtility.cpp | 55 ++++++++++++++ src/gui/src/QUtility.h | 12 ++++ src/gui/src/SslCertificate.cpp | 47 ++++++------ src/gui/src/SslCertificate.h | 8 +-- src/lib/barrier/win32/DaemonApp.cpp | 3 +- src/lib/common/win32/DataDirectories.cpp | 28 +------- src/lib/common/win32/KnownFolderPaths.cpp | 48 +++++++++++++ src/lib/common/win32/KnownFolderPaths.h | 24 +++++++ src/lib/common/win32/StringConverters.cpp | 87 +++++++++++++++++++++++ src/lib/common/win32/StringConverters.h | 32 +++++++++ src/lib/ipc/IpcLogOutputter.cpp | 3 +- src/lib/platform/MSWindowsScreen.cpp | 12 ++-- 16 files changed, 308 insertions(+), 77 deletions(-) create mode 100644 src/lib/common/win32/KnownFolderPaths.cpp create mode 100644 src/lib/common/win32/KnownFolderPaths.h create mode 100644 src/lib/common/win32/StringConverters.cpp create mode 100644 src/lib/common/win32/StringConverters.h diff --git a/src/gui/src/CommandProcess.cpp b/src/gui/src/CommandProcess.cpp index c85e847bf37..ccd726927a7 100644 --- a/src/gui/src/CommandProcess.cpp +++ b/src/gui/src/CommandProcess.cpp @@ -16,6 +16,7 @@ */ #include "CommandProcess.h" +#include "QUtility.h" #include #include @@ -32,18 +33,18 @@ QString CommandProcess::run() QProcess process; process.setReadChannel(QProcess::StandardOutput); process.start(m_Command, m_Arguments); - bool success = process.waitForStarted(); + bool success = process.waitForStarted(); QString output, error; if (success) { if (!m_Input.isEmpty()) { - process.write(m_Input.toStdString().c_str()); + process.write(toStdString(m_Input).c_str()); } if (process.waitForFinished()) { - output = process.readAllStandardOutput().trimmed(); - error = process.readAllStandardError().trimmed(); + output = fromByteArrayString(process.readAllStandardOutput().trimmed()); + error = fromByteArrayString(process.readAllStandardError().trimmed()); } } @@ -51,10 +52,9 @@ QString CommandProcess::run() if (!error.isEmpty() || !success || code != 0) { throw std::runtime_error( - QString("Code: %1\nError: %2") + toStdString(QString("Code: %1\nError: %2") .arg(process.exitCode()) - .arg(error.isEmpty() ? "Unknown" : error) - .toStdString()); + .arg(error.isEmpty() ? "Unknown" : error))); } emit finished(); diff --git a/src/gui/src/Fingerprint.cpp b/src/gui/src/Fingerprint.cpp index 24c8a1a35b8..9166d7186bb 100644 --- a/src/gui/src/Fingerprint.cpp +++ b/src/gui/src/Fingerprint.cpp @@ -17,7 +17,7 @@ #include "Fingerprint.h" -#include "common/DataDirectories.h" +#include "QUtility.h" #include #include @@ -125,7 +125,7 @@ void Fingerprint::persistDirectory() QString Fingerprint::directoryPath() { - auto profileDir = QString::fromStdString(DataDirectories::profile()); + auto profileDir = profilePath(); return QString("%1/%2") .arg(profileDir) diff --git a/src/gui/src/IpcClient.cpp b/src/gui/src/IpcClient.cpp index 1b0e147adaf..a400d98dacb 100644 --- a/src/gui/src/IpcClient.cpp +++ b/src/gui/src/IpcClient.cpp @@ -17,6 +17,7 @@ */ #include "IpcClient.h" +#include "QUtility.h" #include #include #include @@ -104,8 +105,8 @@ void IpcClient::sendCommand(const QString& command, ElevateMode const elevate) stream.writeRawData(kIpcMsgCommand, 4); - std::string stdStringCommand = command.toStdString(); - const char* charCommand = stdStringCommand.c_str(); + std::string stringCommand = toUtf8String(command); + const char* charCommand = stringCommand.c_str(); int length = (int)strlen(charCommand); char lenBuf[4]; diff --git a/src/gui/src/MainWindow.cpp b/src/gui/src/MainWindow.cpp index 9ca104bb25e..62dd86425d0 100644 --- a/src/gui/src/MainWindow.cpp +++ b/src/gui/src/MainWindow.cpp @@ -31,7 +31,6 @@ #include "ProcessorArch.h" #include "SslCertificate.h" #include "ShutdownCh.h" -#include "common/DataDirectories.h" #include #include @@ -526,7 +525,7 @@ void MainWindow::startBarrier() // launched the process (e.g. when launched with elevation). setting the // profile dir on launch ensures it uses the same profile dir is used // no matter how its relaunched. - args << "--profile-dir" << QString::fromStdString("\"" + DataDirectories::profile() + "\""); + args << "--profile-dir \"" << profilePath() << "\""; #endif if ((barrierType() == barrierClient && !clientArgs(args, app)) diff --git a/src/gui/src/QUtility.cpp b/src/gui/src/QUtility.cpp index 7757adfec26..73c4b1e90cf 100644 --- a/src/gui/src/QUtility.cpp +++ b/src/gui/src/QUtility.cpp @@ -19,6 +19,7 @@ #include "ProcessorArch.h" #include "CommandProcess.h" +#include "common/DataDirectories.h" #if defined(Q_OS_LINUX) #include @@ -27,6 +28,7 @@ #if defined(Q_OS_WIN) #define WIN32_LEAN_AND_MEAN #include +#include "common/win32/StringConverters.h" #endif void setIndexFromItemData(QComboBox* comboBox, const QVariant& itemData) @@ -113,3 +115,56 @@ QString getOSInformation() return result; } + +QString fromStdString(const std::string& str) +{ + // Convert from ANSI encoded std::string on Windows, not UTF-8 which is what QString::fromStdString does. +#if defined(Q_OS_WIN) + return QString::fromStdWString(wide_from_ansi(str)); +#else + return QString::fromStdString(str); +#endif +} + +std::string toStdString(const QString& str) +{ + // Convert to ANSI encoded std::string on Windows, not UTF-8 which is what QString::toStdString does. +#if defined(Q_OS_WIN) + return ansi_from_wide(str.toStdWString()); +#else + return str.toStdString(); +#endif +} + +std::string toUtf8String(const QString& str) +{ + // Convert to UTF-8 encoded std::string, which is what QString::toStdString does. + // Just to be explicit when UTF-8 is intended (e.g. for network communication), and not + // a standard std::string, which may or may not be UTF-8 (usually ANSI on Windows). + return str.toStdString(); +} + +QString fromByteArrayString(const QByteArray& str) +{ + // Convert from ANSI encoded raw byte string on Windows, not UTF-8 which is what QString(QByteArray) does. +#if defined(Q_OS_WIN) + return QString::fromStdWString(wide_from_ansi(str.constData(), str.count())); +#else + return{ str }; +#endif +} + +QByteArray toByteArrayString(const QString& str) +{ + // Convert to ANSI encoded raw byte string on Windows, not UTF-8 which is what QString::toUtf8 does. +#if defined(Q_OS_WIN) + return QByteArray::fromStdString(ansi_from_wide(str.toStdWString())); +#else + return str.toUtf8(); +#endif +} + +QString profilePath() +{ + return fromStdString(DataDirectories::profile()); +} diff --git a/src/gui/src/QUtility.h b/src/gui/src/QUtility.h index 62a60825f22..b1dbd1e90a6 100644 --- a/src/gui/src/QUtility.h +++ b/src/gui/src/QUtility.h @@ -19,6 +19,8 @@ #include "ProcessorArch.h" +#include +#include #include #include #include @@ -29,3 +31,13 @@ QString hash(const QString& string); QString getFirstMacAddress(); qProcessorArch getProcessorArch(); QString getOSInformation(); + +QString fromStdString(const std::string& str); +std::string toStdString(const QString& str); + +QString fromByteArrayString(const QByteArray& str); +QByteArray toByteArrayString(const QString& str); + +std::string toUtf8String(const QString& str); + +QString profilePath(); diff --git a/src/gui/src/SslCertificate.cpp b/src/gui/src/SslCertificate.cpp index 08863ae6e7b..dfb080eb09f 100644 --- a/src/gui/src/SslCertificate.cpp +++ b/src/gui/src/SslCertificate.cpp @@ -17,7 +17,7 @@ #include "SslCertificate.h" #include "Fingerprint.h" -#include "common/DataDirectories.h" +#include "QUtility.h" #include #include @@ -43,13 +43,13 @@ static const char kConfigFile[] = "barrier.conf"; SslCertificate::SslCertificate(QObject *parent) : QObject(parent) { - m_ProfileDir = DataDirectories::profile(); - if (m_ProfileDir.empty()) { + m_ProfileDir = profilePath(); + if (m_ProfileDir.isEmpty()) { emit error(tr("Failed to get profile directory.")); } } -std::pair SslCertificate::runTool(const QStringList& args) +std::pair SslCertificate::runTool(const QStringList& args) { QString program; #if defined(Q_OS_WIN) @@ -72,13 +72,11 @@ std::pair SslCertificate::runTool(const QStringList& args) process.start(program, args); bool success = process.waitForStarted(); - std::string output; - - QString standardError; + QString standardOutput, standardError; if (success && process.waitForFinished()) { - output = process.readAllStandardOutput().trimmed().toStdString(); - standardError = process.readAllStandardError().trimmed(); + standardOutput = fromByteArrayString(process.readAllStandardOutput().trimmed()); + standardError = fromByteArrayString(process.readAllStandardError().trimmed()); } int code = process.exitCode(); @@ -89,15 +87,15 @@ std::pair SslCertificate::runTool(const QStringList& args) .arg(program) .arg(process.exitCode()) .arg(standardError.isEmpty() ? "Unknown" : standardError)); - return {false, output}; + return {false, standardError}; } - return {true, output}; + return {true, standardOutput}; } void SslCertificate::generateCertificate() { - auto filename = QString::fromStdString(getCertificatePath()); + auto filename = getCertificatePath(); QFile file(filename); if (!file.exists() || !isCertificateValid(filename)) { @@ -122,7 +120,7 @@ void SslCertificate::generateCertificate() arguments.append("-newkey"); arguments.append("rsa:2048"); - QDir sslDir(QString::fromStdString(getCertificateDirectory())); + QDir sslDir(getCertificateDirectory()); if (!sslDir.exists()) { sslDir.mkpath("."); } @@ -159,20 +157,17 @@ void SslCertificate::generateFingerprint(const QString& certificateFilename) auto ret = runTool(arguments); bool success = ret.first; - std::string output = ret.second; - if (!success) { return; } // find the fingerprint from the tool output - auto i = output.find_first_of('='); - if (i != std::string::npos) { - i++; - auto fingerprint = output.substr( - i, output.size() - i); + QString fingerprint = ret.second; + auto i = fingerprint.indexOf('='); + if (i != -1) { + fingerprint.remove(0, i+1); - Fingerprint::local().trust(QString::fromStdString(fingerprint), false); + Fingerprint::local().trust(fingerprint, false); emit info(tr("SSL fingerprint generated.")); } else { @@ -180,14 +175,14 @@ void SslCertificate::generateFingerprint(const QString& certificateFilename) } } -std::string SslCertificate::getCertificatePath() +QString SslCertificate::getCertificatePath() { - return getCertificateDirectory() + QDir::separator().toLatin1() + kCertificateFilename; + return getCertificateDirectory() + QDir::separator() + kCertificateFilename; } -std::string SslCertificate::getCertificateDirectory() +QString SslCertificate::getCertificateDirectory() { - return m_ProfileDir + QDir::separator().toLatin1() + kSslDir; + return m_ProfileDir + QDir::separator() + kSslDir; } bool SslCertificate::isCertificateValid(const QString& path) @@ -198,7 +193,7 @@ bool SslCertificate::isCertificateValid(const QString& path) BIO* bio = BIO_new(BIO_s_file()); - auto ret = BIO_read_filename(bio, path.toStdString().c_str()); + auto ret = BIO_read_filename(bio, toStdString(path).c_str()); if (!ret) { emit info(tr("Could not read from default certificate file.")); BIO_free_all(bio); diff --git a/src/gui/src/SslCertificate.h b/src/gui/src/SslCertificate.h index b29a6b167ae..3ff3ff5cb6f 100644 --- a/src/gui/src/SslCertificate.h +++ b/src/gui/src/SslCertificate.h @@ -36,13 +36,13 @@ public slots: void generateFinished(); private: - std::pair runTool(const QStringList& args); + std::pair runTool(const QStringList& args); void generateFingerprint(const QString& certificateFilename); - std::string getCertificatePath(); - std::string getCertificateDirectory(); + QString getCertificatePath(); + QString getCertificateDirectory(); bool isCertificateValid(const QString& path); private: - std::string m_ProfileDir; + QString m_ProfileDir; }; diff --git a/src/lib/barrier/win32/DaemonApp.cpp b/src/lib/barrier/win32/DaemonApp.cpp index 88e6b4ef0af..f8cf591afda 100644 --- a/src/lib/barrier/win32/DaemonApp.cpp +++ b/src/lib/barrier/win32/DaemonApp.cpp @@ -34,6 +34,7 @@ #include "base/log_outputters.h" #include "base/Log.h" #include "common/DataDirectories.h" +#include "base/Unicode.h" #include "arch/win32/ArchMiscWindows.h" #include "arch/win32/XArchWindows.h" @@ -257,7 +258,7 @@ DaemonApp::handleIpcMessage(const Event& e, void*) switch (m->type()) { case kIpcCommand: { IpcCommandMessage* cm = static_cast(m); - String command = cm->command(); + String command = Unicode::UTF8ToText(cm->command()); // if empty quotes, clear. if (command == "\"\"") { diff --git a/src/lib/common/win32/DataDirectories.cpp b/src/lib/common/win32/DataDirectories.cpp index 15cb64e1377..3e86c59b8e8 100644 --- a/src/lib/common/win32/DataDirectories.cpp +++ b/src/lib/common/win32/DataDirectories.cpp @@ -16,34 +16,12 @@ */ #include "../DataDirectories.h" - -#include - -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) @@ -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) diff --git a/src/lib/common/win32/KnownFolderPaths.cpp b/src/lib/common/win32/KnownFolderPaths.cpp new file mode 100644 index 00000000000..9f873f66bec --- /dev/null +++ b/src/lib/common/win32/KnownFolderPaths.cpp @@ -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 . +*/ + +#include "KnownFolderPaths.h" +#include "StringConverters.h" + +#include + +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; +} + +std::string desktopPath() +{ + return known_folder_path(FOLDERID_Desktop); +} + +std::string localAppDataPath() +{ + return known_folder_path(FOLDERID_LocalAppData); +} + +std::string programDataPath() +{ + return known_folder_path(FOLDERID_ProgramData); +} diff --git a/src/lib/common/win32/KnownFolderPaths.h b/src/lib/common/win32/KnownFolderPaths.h new file mode 100644 index 00000000000..81b650ec57c --- /dev/null +++ b/src/lib/common/win32/KnownFolderPaths.h @@ -0,0 +1,24 @@ +/* +* 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 . +*/ + +#pragma once + +#include + +std::string desktopPath(); +std::string localAppDataPath(); +std::string programDataPath(); diff --git a/src/lib/common/win32/StringConverters.cpp b/src/lib/common/win32/StringConverters.cpp new file mode 100644 index 00000000000..b5b04f07634 --- /dev/null +++ b/src/lib/common/win32/StringConverters.cpp @@ -0,0 +1,87 @@ +/* +* 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 . +*/ + +#include "StringConverters.h" + +#define WIN32_LEAN_AND_MEAN +#include + +static std::string from_wide(const wchar_t* source, int length, int codePage) +{ + int ansiLength = WideCharToMultiByte(codePage, 0, source, length, NULL, 0, NULL, NULL); + if (ansiLength > 0) { + std::string ansiString(ansiLength, 0); + ansiLength = WideCharToMultiByte(codePage, 0, source, length, &ansiString[0], ansiLength, NULL, NULL); + if (ansiLength > 0) { + return ansiString; + } + } + return {}; +} + +std::string ansi_from_wide(const wchar_t* source, int length) +{ + return from_wide(source, length, CP_ACP); +} + +std::string ansi_from_wide(const std::wstring& source) +{ + return from_wide(source.c_str(), (int)source.size(), CP_ACP); +} + +std::string utf8_from_wide(const std::wstring& source) +{ + return from_wide(source.c_str(), (int)source.size(), CP_UTF8); +} + +static std::wstring to_wide(const char* source, int length, UINT codePage) +{ + int wideLength = MultiByteToWideChar(codePage, 0, source, length, NULL, 0); + if (wideLength > 0) { + std::wstring wideString(wideLength, 0); + wideLength = MultiByteToWideChar(codePage, 0, source, length, &wideString[0], wideLength); + if (wideLength > 0) { + return wideString; + } + } + return {}; +} + +std::wstring wide_from_ansi(const char* source, int length) +{ + return to_wide(source, length, CP_ACP); +} + +std::wstring wide_from_ansi(const std::string& source) +{ + return to_wide(source.c_str(), (int)source.length(), CP_ACP); +} + +std::wstring wide_from_utf8(const std::string& source) +{ + return to_wide(source.c_str(), (int)source.length(), CP_UTF8); +} + +std::string utf8_from_ansi(const std::string& source) +{ + return utf8_from_wide(wide_from_ansi(source)); +} + +std::string ansi_from_utf8(const std::string& source) +{ + return ansi_from_wide(wide_from_utf8(source)); +} diff --git a/src/lib/common/win32/StringConverters.h b/src/lib/common/win32/StringConverters.h new file mode 100644 index 00000000000..b051fe0bb6b --- /dev/null +++ b/src/lib/common/win32/StringConverters.h @@ -0,0 +1,32 @@ +/* +* 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 . +*/ + +#pragma once + +#include + +std::string ansi_from_wide(const wchar_t* source, int length); +std::string ansi_from_wide(const std::wstring& source); + +std::wstring wide_from_ansi(const char* source, int length); +std::wstring wide_from_ansi(const std::string& source); + +std::string ansi_from_utf8(const std::string& source); +std::wstring wide_from_utf8(const std::string& source); + +std::string utf8_from_ansi(const std::string& source); +std::string utf8_from_wide(const std::wstring& source); diff --git a/src/lib/ipc/IpcLogOutputter.cpp b/src/lib/ipc/IpcLogOutputter.cpp index 223f52f72ad..c895dc126a2 100644 --- a/src/lib/ipc/IpcLogOutputter.cpp +++ b/src/lib/ipc/IpcLogOutputter.cpp @@ -29,6 +29,7 @@ #include "base/EventQueue.h" #include "base/TMethodEventJob.h" #include "base/TMethodJob.h" +#include "base/Unicode.h" enum EIpcLogOutputter { kBufferMaxSize = 1000, @@ -196,7 +197,7 @@ IpcLogOutputter::sendBuffer() return; } - IpcLogLineMessage message(getChunk(kMaxSendLines)); + IpcLogLineMessage message(Unicode::textToUTF8(getChunk(kMaxSendLines))); m_sending = true; m_ipcServer.send(message, kIpcClientGui); m_sending = false; diff --git a/src/lib/platform/MSWindowsScreen.cpp b/src/lib/platform/MSWindowsScreen.cpp index fd494c9878b..352368acc60 100644 --- a/src/lib/platform/MSWindowsScreen.cpp +++ b/src/lib/platform/MSWindowsScreen.cpp @@ -41,9 +41,9 @@ #include "base/IEventQueue.h" #include "base/TMethodEventJob.h" #include "base/TMethodJob.h" +#include "common/win32/KnownFolderPaths.h" #include -#include #include #include @@ -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_dropTargetPath.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;