From 314899ac7df8a47bc1781f10c6f5e93169307866 Mon Sep 17 00:00:00 2001 From: Povilas Kanapickas Date: Sun, 25 May 2025 00:38:01 -0400 Subject: [PATCH] chore: arch, Remove support for lazy error code to string evaluations This functionality is not needed because in all code paths the error code is immediately converted to string without actually using the lazy evaluation functionality. based-on: https://github.com/input-leap/input-leap/pull/1544/commits/53dff5b803233cf9c364898fd664d3ab13f855e4 ported and expanded by sithlord48 --- src/lib/arch/XArch.h | 22 ----------- src/lib/arch/unix/ArchDaemonUnix.cpp | 4 +- src/lib/arch/unix/ArchNetworkBSD.cpp | 29 ++++++++------- src/lib/arch/unix/XArchUnix.cpp | 9 ++--- src/lib/arch/unix/XArchUnix.h | 19 ++-------- src/lib/arch/win32/ArchDaemonWindows.cpp | 33 +++++++++-------- src/lib/arch/win32/ArchMiscWindows.cpp | 7 ++-- src/lib/arch/win32/ArchNetworkWinsock.cpp | 45 ++++++++++++----------- src/lib/arch/win32/XArchWindows.cpp | 19 +++------- src/lib/arch/win32/XArchWindows.h | 37 ++----------------- src/lib/deskflow/win32/AppUtilWindows.cpp | 5 ++- src/lib/platform/MSWindowsKeyState.cpp | 12 ++++-- src/lib/platform/MSWindowsProcess.cpp | 37 ++++++++++--------- src/lib/platform/MSWindowsScreen.cpp | 21 ++++------- src/lib/platform/MSWindowsSession.cpp | 11 +++--- src/lib/platform/MSWindowsWatchdog.cpp | 26 ++++++------- 16 files changed, 135 insertions(+), 201 deletions(-) diff --git a/src/lib/arch/XArch.h b/src/lib/arch/XArch.h index 897725fbc..0405af279 100644 --- a/src/lib/arch/XArch.h +++ b/src/lib/arch/XArch.h @@ -45,29 +45,10 @@ cleanup but before leaving or returning from the handler. } catch (...) { \ } -//! Lazy error message string evaluation -/*! -This class encapsulates platform dependent error string lookup. -Platforms subclass this type, taking an appropriate error code -type in the c'tor and overriding eval() to return the error -string for that error code. -*/ -class XArchEval -{ -public: - XArchEval() = default; - virtual ~XArchEval() noexcept = default; - virtual std::string eval() const = 0; -}; - //! Generic exception architecture dependent library class XArch : public std::runtime_error { public: - explicit XArch(XArchEval *adopted) : std::runtime_error(adopted->eval()) - { - delete adopted; - } explicit XArch(const std::string &msg) : std::runtime_error(msg) { } @@ -79,9 +60,6 @@ public: class name_ : public super_ \ { \ public: \ - name_(XArchEval *adoptedEvaluator) : super_(adoptedEvaluator) \ - { \ - } \ name_(const std::string &msg) : super_(msg) \ { \ } \ diff --git a/src/lib/arch/unix/ArchDaemonUnix.cpp b/src/lib/arch/unix/ArchDaemonUnix.cpp index 347cc3bf1..6602773bd 100644 --- a/src/lib/arch/unix/ArchDaemonUnix.cpp +++ b/src/lib/arch/unix/ArchDaemonUnix.cpp @@ -1,5 +1,6 @@ /* * Deskflow -- mouse and keyboard sharing utility + * SPDX-FileCopyrightText: (C) 2025 Deskflow Developers * SPDX-FileCopyrightText: (C) 2012 - 2016 Symless Ltd. * SPDX-FileCopyrightText: (C) 2002 Chris Schoeneman * SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception @@ -7,6 +8,7 @@ #include "arch/unix/ArchDaemonUnix.h" +#include "arch/XArch.h" #include "arch/unix/XArchUnix.h" #include "base/Log.h" @@ -56,7 +58,7 @@ int ArchDaemonUnix::daemonize(const char *name, DaemonFunc const &func) switch (fork()) { case -1: // failed - throw XArchDaemonFailed(new XArchEvalUnix(errno)); + throw XArchDaemonFailed(errorToString(errno)); case 0: // child diff --git a/src/lib/arch/unix/ArchNetworkBSD.cpp b/src/lib/arch/unix/ArchNetworkBSD.cpp index 43a9f5e10..f08632d4d 100644 --- a/src/lib/arch/unix/ArchNetworkBSD.cpp +++ b/src/lib/arch/unix/ArchNetworkBSD.cpp @@ -8,6 +8,7 @@ #include "arch/unix/ArchNetworkBSD.h" #include "arch/Arch.h" +#include "arch/XArch.h" #include "arch/unix/ArchMultithreadPosix.h" #include "arch/unix/XArchUnix.h" @@ -751,11 +752,11 @@ void ArchNetworkBSD::throwError(int err) const switch (err) { case EINTR: ARCH->testCancelThread(); - throw XArchNetworkInterrupted(new XArchEvalUnix(err)); + throw XArchNetworkInterrupted(errorToString(err)); case EACCES: case EPERM: - throw XArchNetworkAccess(new XArchEvalUnix(err)); + throw XArchNetworkAccess(errorToString(err)); case ENFILE: case EMFILE: @@ -766,7 +767,7 @@ void ArchNetworkBSD::throwError(int err) const #if defined(ENOSR) case ENOSR: #endif - throw XArchNetworkResource(new XArchEvalUnix(err)); + throw XArchNetworkResource(errorToString(err)); case EPROTOTYPE: case EPROTONOSUPPORT: @@ -780,40 +781,40 @@ void ArchNetworkBSD::throwError(int err) const #if defined(ENOPKG) case ENOPKG: #endif - throw XArchNetworkSupport(new XArchEvalUnix(err)); + throw XArchNetworkSupport(errorToString(err)); case EIO: - throw XArchNetworkIO(new XArchEvalUnix(err)); + throw XArchNetworkIO(errorToString(err)); case EADDRNOTAVAIL: - throw XArchNetworkNoAddress(new XArchEvalUnix(err)); + throw XArchNetworkNoAddress(errorToString(err)); case EADDRINUSE: - throw XArchNetworkAddressInUse(new XArchEvalUnix(err)); + throw XArchNetworkAddressInUse(errorToString(err)); case EHOSTUNREACH: case ENETUNREACH: - throw XArchNetworkNoRoute(new XArchEvalUnix(err)); + throw XArchNetworkNoRoute(errorToString(err)); case ENOTCONN: - throw XArchNetworkNotConnected(new XArchEvalUnix(err)); + throw XArchNetworkNotConnected(errorToString(err)); case EPIPE: - throw XArchNetworkShutdown(new XArchEvalUnix(err)); + throw XArchNetworkShutdown(errorToString(err)); case ECONNABORTED: case ECONNRESET: - throw XArchNetworkDisconnected(new XArchEvalUnix(err)); + throw XArchNetworkDisconnected(errorToString(err)); case ECONNREFUSED: - throw XArchNetworkConnectionRefused(new XArchEvalUnix(err)); + throw XArchNetworkConnectionRefused(errorToString(err)); case EHOSTDOWN: case ETIMEDOUT: - throw XArchNetworkTimedOut(new XArchEvalUnix(err)); + throw XArchNetworkTimedOut(errorToString(err)); default: - throw XArchNetwork(new XArchEvalUnix(err)); + throw XArchNetwork(errorToString(err)); } } diff --git a/src/lib/arch/unix/XArchUnix.cpp b/src/lib/arch/unix/XArchUnix.cpp index 8d8804f13..518fddc3e 100644 --- a/src/lib/arch/unix/XArchUnix.cpp +++ b/src/lib/arch/unix/XArchUnix.cpp @@ -1,5 +1,6 @@ /* * Deskflow -- mouse and keyboard sharing utility + * SPDX-FileCopyrightText: (C) 2025 Deskflow Developers * SPDX-FileCopyrightText: (C) 2012 - 2016 Symless Ltd. * SPDX-FileCopyrightText: (C) 2002 Chris Schoeneman * SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception @@ -9,12 +10,8 @@ #include -// -// XArchEvalUnix -// - -std::string XArchEvalUnix::eval() const +std::string errorToString(int error) { // FIXME -- not thread safe - return strerror(m_error); + return std::strerror(error); } diff --git a/src/lib/arch/unix/XArchUnix.h b/src/lib/arch/unix/XArchUnix.h index 23d99d515..14c154dac 100644 --- a/src/lib/arch/unix/XArchUnix.h +++ b/src/lib/arch/unix/XArchUnix.h @@ -1,5 +1,6 @@ /* * Deskflow -- mouse and keyboard sharing utility + * SPDX-FileCopyrightText: (C) 2025 Deskflow Developers * SPDX-FileCopyrightText: (C) 2012 - 2016 Symless Ltd. * SPDX-FileCopyrightText: (C) 2002 Chris Schoeneman * SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception @@ -7,20 +8,6 @@ #pragma once -#include "arch/XArch.h" +#include -//! Lazy error message string evaluation for unix -class XArchEvalUnix : public XArchEval -{ -public: - explicit XArchEvalUnix(int error) : m_error(error) - { - // do nothing - } - ~XArchEvalUnix() noexcept override = default; - - std::string eval() const override; - -private: - int m_error; -}; +std::string errorToString(int error); diff --git a/src/lib/arch/win32/ArchDaemonWindows.cpp b/src/lib/arch/win32/ArchDaemonWindows.cpp index 920a8537c..35f8530de 100644 --- a/src/lib/arch/win32/ArchDaemonWindows.cpp +++ b/src/lib/arch/win32/ArchDaemonWindows.cpp @@ -8,6 +8,7 @@ #include "arch/win32/ArchDaemonWindows.h" #include "arch/Arch.h" +#include "arch/XArch.h" #include "arch/win32/ArchMiscWindows.h" #include "arch/win32/XArchWindows.h" #include "base/Log.h" @@ -61,7 +62,7 @@ void ArchDaemonWindows::installDaemon( SC_HANDLE mgr = OpenSCManager(nullptr, nullptr, GENERIC_WRITE); if (mgr == nullptr) { // can't open service manager - throw XArchDaemonInstallFailed(new XArchEvalWindows); + throw XArchDaemonInstallFailed(windowsErrorToString(GetLastError())); } // create the service @@ -75,7 +76,7 @@ void ArchDaemonWindows::installDaemon( DWORD err = GetLastError(); if (err != ERROR_SERVICE_EXISTS) { CloseServiceHandle(mgr); - throw XArchDaemonInstallFailed(new XArchEvalWindows(err)); + throw XArchDaemonInstallFailed(windowsErrorToString(err)); } } else { // done with service (but only try to close if not null) @@ -96,7 +97,7 @@ void ArchDaemonWindows::installDaemon( } catch (...) { // ignore } - throw XArchDaemonInstallFailed(new XArchEvalWindows(err)); + throw XArchDaemonInstallFailed(windowsErrorToString(err)); } // set the description @@ -113,7 +114,7 @@ void ArchDaemonWindows::installDaemon( } catch (...) { // ignore } - throw XArchDaemonInstallFailed(new XArchEvalWindows(err)); + throw XArchDaemonInstallFailed(windowsErrorToString(err)); } ArchMiscWindows::setValue(key, _T("CommandLine"), commandLine); @@ -137,7 +138,7 @@ void ArchDaemonWindows::uninstallDaemon(const char *name) SC_HANDLE mgr = OpenSCManager(nullptr, nullptr, GENERIC_WRITE); if (mgr == nullptr) { // can't open service manager - throw XArchDaemonUninstallFailed(new XArchEvalWindows); + throw XArchDaemonUninstallFailed(windowsErrorToString(GetLastError())); } // open the service. oddly, you must open a service to delete it. @@ -146,9 +147,9 @@ void ArchDaemonWindows::uninstallDaemon(const char *name) DWORD err = GetLastError(); CloseServiceHandle(mgr); if (err != ERROR_SERVICE_DOES_NOT_EXIST) { - throw XArchDaemonUninstallFailed(new XArchEvalWindows(err)); + throw XArchDaemonUninstallFailed(windowsErrorToString(err)); } - throw XArchDaemonUninstallNotInstalled(new XArchEvalWindows(err)); + throw XArchDaemonUninstallNotInstalled(windowsErrorToString(err)); } // stop the service. we don't care if we fail. @@ -181,9 +182,9 @@ void ArchDaemonWindows::uninstallDaemon(const char *name) return; } if (err != ERROR_SERVICE_MARKED_FOR_DELETE) { - throw XArchDaemonUninstallFailed(new XArchEvalWindows(err)); + throw XArchDaemonUninstallFailed(windowsErrorToString(err)); } - throw XArchDaemonUninstallNotInstalled(new XArchEvalWindows(err)); + throw XArchDaemonUninstallNotInstalled(windowsErrorToString(err)); } } @@ -208,7 +209,7 @@ int ArchDaemonWindows::daemonize(const char *name, DaemonFunc const &func) if (StartServiceCtrlDispatcher(entry) == 0) { // StartServiceCtrlDispatcher failed s_daemon = nullptr; - throw XArchDaemonFailed(new XArchEvalWindows); + throw XArchDaemonFailed(windowsErrorToString(GetLastError())); } s_daemon = nullptr; @@ -557,7 +558,7 @@ void ArchDaemonWindows::start(const char *name) // open service manager SC_HANDLE mgr = OpenSCManager(nullptr, nullptr, GENERIC_READ); if (mgr == nullptr) { - throw XArchDaemonFailed(new XArchEvalWindows()); + throw XArchDaemonFailed(windowsErrorToString(GetLastError())); } // open the service @@ -565,12 +566,12 @@ void ArchDaemonWindows::start(const char *name) if (service == nullptr) { CloseServiceHandle(mgr); - throw XArchDaemonFailed(new XArchEvalWindows()); + throw XArchDaemonFailed(windowsErrorToString(GetLastError())); } // start the service if (!StartService(service, 0, nullptr)) { - throw XArchDaemonFailed(new XArchEvalWindows()); + throw XArchDaemonFailed(windowsErrorToString(GetLastError())); } } @@ -579,7 +580,7 @@ void ArchDaemonWindows::stop(const char *name) // open service manager SC_HANDLE mgr = OpenSCManager(nullptr, nullptr, GENERIC_READ); if (mgr == nullptr) { - throw XArchDaemonFailed(new XArchEvalWindows()); + throw XArchDaemonFailed(windowsErrorToString(GetLastError())); } // open the service @@ -587,7 +588,7 @@ void ArchDaemonWindows::stop(const char *name) if (service == nullptr) { CloseServiceHandle(mgr); - throw XArchDaemonFailed(new XArchEvalWindows()); + throw XArchDaemonFailed(windowsErrorToString(GetLastError())); } // ask the service to stop, asynchronously @@ -595,7 +596,7 @@ void ArchDaemonWindows::stop(const char *name) if (!ControlService(service, SERVICE_CONTROL_STOP, &ss)) { DWORD dwErrCode = GetLastError(); if (dwErrCode != ERROR_SERVICE_NOT_ACTIVE) { - throw XArchDaemonFailed(new XArchEvalWindows()); + throw XArchDaemonFailed(windowsErrorToString(GetLastError())); } } } diff --git a/src/lib/arch/win32/ArchMiscWindows.cpp b/src/lib/arch/win32/ArchMiscWindows.cpp index cdc30da31..2348a95b2 100644 --- a/src/lib/arch/win32/ArchMiscWindows.cpp +++ b/src/lib/arch/win32/ArchMiscWindows.cpp @@ -7,6 +7,7 @@ #include "arch/win32/ArchMiscWindows.h" +#include "arch/XArch.h" #include "arch/win32/ArchDaemonWindows.h" #include "arch/win32/XArchWindows.h" #include "base/Log.h" @@ -409,7 +410,7 @@ std::string ArchMiscWindows::getActiveDesktopName() HDESK desk = OpenInputDesktop(0, TRUE, GENERIC_READ); if (desk == nullptr) { LOG((CLOG_ERR "could not open input desktop")); - throw XArch(new XArchEvalWindows()); + throw XArch(windowsErrorToString(GetLastError())); } DWORD size; @@ -530,7 +531,7 @@ bool ArchMiscWindows::isProcessElevated() HANDLE hToken = nullptr; if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken)) { - throw XArch(new XArchEvalWindows()); + throw XArch(windowsErrorToString(GetLastError())); } TOKEN_ELEVATION elevation; @@ -538,7 +539,7 @@ bool ArchMiscWindows::isProcessElevated() try { DWORD dwSize = sizeof(TOKEN_ELEVATION); if (!GetTokenInformation(hToken, TokenElevation, &elevation, sizeof(elevation), &dwSize)) { - throw XArch(new XArchEvalWindows()); + throw XArch(windowsErrorToString(GetLastError())); } } catch (...) { CloseHandle(hToken); diff --git a/src/lib/arch/win32/ArchNetworkWinsock.cpp b/src/lib/arch/win32/ArchNetworkWinsock.cpp index 35d68667b..f82ab572a 100644 --- a/src/lib/arch/win32/ArchNetworkWinsock.cpp +++ b/src/lib/arch/win32/ArchNetworkWinsock.cpp @@ -8,6 +8,7 @@ #include "arch/win32/ArchNetworkWinsock.h" #include "arch/Arch.h" #include "arch/IArchMultithread.h" +#include "arch/XArch.h" #include "arch/win32/ArchMultithreadWindows.h" #include "arch/win32/XArchWindows.h" @@ -141,7 +142,7 @@ void ArchNetworkWinsock::initModule(HMODULE module) WSADATA data; int err = startup(version, &data); if (data.wVersion != version) { - throw XArchNetworkSupport(new XArchEvalWinsock(err)); + throw XArchNetworkSupport(winsockErrorToString(err)); } if (err != 0) { // some other initialization error @@ -851,12 +852,12 @@ void ArchNetworkWinsock::throwError(int err) { switch (err) { case WSAEACCES: - throw XArchNetworkAccess(new XArchEvalWinsock(err)); + throw XArchNetworkAccess(winsockErrorToString(err)); case WSAEMFILE: case WSAENOBUFS: case WSAENETDOWN: - throw XArchNetworkResource(new XArchEvalWinsock(err)); + throw XArchNetworkResource(winsockErrorToString(err)); case WSAEPROTOTYPE: case WSAEPROTONOSUPPORT: @@ -870,50 +871,50 @@ void ArchNetworkWinsock::throwError(int err) case WSANOTINITIALISED: case WSAVERNOTSUPPORTED: case WSASYSNOTREADY: - throw XArchNetworkSupport(new XArchEvalWinsock(err)); + throw XArchNetworkSupport(winsockErrorToString(err)); case WSAEADDRNOTAVAIL: - throw XArchNetworkNoAddress(new XArchEvalWinsock(err)); + throw XArchNetworkNoAddress(winsockErrorToString(err)); case WSAEADDRINUSE: - throw XArchNetworkAddressInUse(new XArchEvalWinsock(err)); + throw XArchNetworkAddressInUse(winsockErrorToString(err)); case WSAEHOSTUNREACH: case WSAENETUNREACH: - throw XArchNetworkNoRoute(new XArchEvalWinsock(err)); + throw XArchNetworkNoRoute(winsockErrorToString(err)); case WSAENOTCONN: - throw XArchNetworkNotConnected(new XArchEvalWinsock(err)); + throw XArchNetworkNotConnected(winsockErrorToString(err)); case WSAEDISCON: - throw XArchNetworkShutdown(new XArchEvalWinsock(err)); + throw XArchNetworkShutdown(winsockErrorToString(err)); case WSAENETRESET: case WSAECONNABORTED: case WSAECONNRESET: - throw XArchNetworkDisconnected(new XArchEvalWinsock(err)); + throw XArchNetworkDisconnected(winsockErrorToString(err)); case WSAECONNREFUSED: - throw XArchNetworkConnectionRefused(new XArchEvalWinsock(err)); + throw XArchNetworkConnectionRefused(winsockErrorToString(err)); case WSAEHOSTDOWN: case WSAETIMEDOUT: - throw XArchNetworkTimedOut(new XArchEvalWinsock(err)); + throw XArchNetworkTimedOut(winsockErrorToString(err)); case WSAHOST_NOT_FOUND: - throw XArchNetworkNameUnknown(new XArchEvalWinsock(err)); + throw XArchNetworkNameUnknown(winsockErrorToString(err)); case WSANO_DATA: - throw XArchNetworkNameNoAddress(new XArchEvalWinsock(err)); + throw XArchNetworkNameNoAddress(winsockErrorToString(err)); case WSANO_RECOVERY: - throw XArchNetworkNameFailure(new XArchEvalWinsock(err)); + throw XArchNetworkNameFailure(winsockErrorToString(err)); case WSATRY_AGAIN: - throw XArchNetworkNameUnavailable(new XArchEvalWinsock(err)); + throw XArchNetworkNameUnavailable(winsockErrorToString(err)); default: - throw XArchNetwork(new XArchEvalWinsock(err)); + throw XArchNetwork(winsockErrorToString(err)); } } @@ -921,18 +922,18 @@ void ArchNetworkWinsock::throwNameError(int err) { switch (err) { case WSAHOST_NOT_FOUND: - throw XArchNetworkNameUnknown(new XArchEvalWinsock(err)); + throw XArchNetworkNameUnknown(winsockErrorToString(err)); case WSANO_DATA: - throw XArchNetworkNameNoAddress(new XArchEvalWinsock(err)); + throw XArchNetworkNameNoAddress(winsockErrorToString(err)); case WSANO_RECOVERY: - throw XArchNetworkNameFailure(new XArchEvalWinsock(err)); + throw XArchNetworkNameFailure(winsockErrorToString(err)); case WSATRY_AGAIN: - throw XArchNetworkNameUnavailable(new XArchEvalWinsock(err)); + throw XArchNetworkNameUnavailable(winsockErrorToString(err)); default: - throw XArchNetworkName(new XArchEvalWinsock(err)); + throw XArchNetworkName(winsockErrorToString(err)); } } diff --git a/src/lib/arch/win32/XArchWindows.cpp b/src/lib/arch/win32/XArchWindows.cpp index 4c0ec2dc7..b469840d7 100644 --- a/src/lib/arch/win32/XArchWindows.cpp +++ b/src/lib/arch/win32/XArchWindows.cpp @@ -1,5 +1,6 @@ /* * Deskflow -- mouse and keyboard sharing utility + * SPDX-FileCopyrightText: (C) 2025 Deskflow Developers * SPDX-FileCopyrightText: (C) 2012 - 2016 Symless Ltd. * SPDX-FileCopyrightText: (C) 2002 Chris Schoeneman * SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception @@ -9,30 +10,22 @@ #include "arch/win32/ArchNetworkWinsock.h" #include "base/String.h" -// -// XArchEvalWindows -// - -std::string XArchEvalWindows::eval() const throw() +std::string windowsErrorToString(DWORD error) { char *cmsg; if (FormatMessage( - FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM, 0, m_error, + FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM, 0, error, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&cmsg, 0, nullptr ) == 0) { cmsg = nullptr; - return deskflow::string::sprintf("Unknown error, code %d", m_error); + return deskflow::string::sprintf("Unknown error, code %d", error); } std::string smsg(cmsg); LocalFree(cmsg); return smsg; } -// -// XArchEvalWinsock -// - -std::string XArchEvalWinsock::eval() const throw() +std::string winsockErrorToString(int error) { // built-in windows function for looking up error message strings // may not look up network error messages correctly. we'll have @@ -204,7 +197,7 @@ std::string XArchEvalWinsock::eval() const throw() }; for (unsigned int i = 0; s_netErrorCodes[i].m_code != 0; ++i) { - if (s_netErrorCodes[i].m_code == m_error) { + if (s_netErrorCodes[i].m_code == error) { return s_netErrorCodes[i].m_msg; } } diff --git a/src/lib/arch/win32/XArchWindows.h b/src/lib/arch/win32/XArchWindows.h index b4c5f769d..54933bd7e 100644 --- a/src/lib/arch/win32/XArchWindows.h +++ b/src/lib/arch/win32/XArchWindows.h @@ -1,5 +1,6 @@ /* * Deskflow -- mouse and keyboard sharing utility + * SPDX-FileCopyrightText: (C) 2025 Deskflow Developers * SPDX-FileCopyrightText: (C) 2012 - 2016 Symless Ltd. * SPDX-FileCopyrightText: (C) 2002 Chris Schoeneman * SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception @@ -7,40 +8,10 @@ #pragma once -#include "arch/XArch.h" +#include #define WIN32_LEAN_AND_MEAN #include -//! Lazy error message string evaluation for windows -class XArchEvalWindows : public XArchEval -{ -public: - XArchEvalWindows() : m_error(GetLastError()) - { - } - XArchEvalWindows(DWORD error) : m_error(error) - { - } - ~XArchEvalWindows() override = default; - - virtual std::string eval() const throw(); - -private: - DWORD m_error; -}; - -//! Lazy error message string evaluation for winsock -class XArchEvalWinsock : public XArchEval -{ -public: - XArchEvalWinsock(int error) : m_error(error) - { - } - ~XArchEvalWinsock() override = default; - - virtual std::string eval() const throw(); - -private: - int m_error; -}; +std::string winsockErrorToString(int error); +std::string windowsErrorToString(DWORD error); diff --git a/src/lib/deskflow/win32/AppUtilWindows.cpp b/src/lib/deskflow/win32/AppUtilWindows.cpp index 0af5ded54..244290884 100644 --- a/src/lib/deskflow/win32/AppUtilWindows.cpp +++ b/src/lib/deskflow/win32/AppUtilWindows.cpp @@ -7,6 +7,7 @@ #include "deskflow/win32/AppUtilWindows.h" +#include "arch/XArch.h" #include "arch/win32/ArchMiscWindows.h" #include "arch/win32/XArchWindows.h" #include "base/Event.h" @@ -28,7 +29,7 @@ AppUtilWindows::AppUtilWindows(IEventQueue *events) : m_events(events), m_exitMode(kExitModeNormal) { if (SetConsoleCtrlHandler((PHANDLER_ROUTINE)consoleHandler, TRUE) == FALSE) { - throw XArch(new XArchEvalWindows()); + throw XArch(windowsErrorToString(GetLastError())); } m_eventThread = std::thread(&AppUtilWindows::eventLoop, this); // NOSONAR - No jthread on Windows @@ -191,7 +192,7 @@ void AppUtilWindows::eventLoop() HANDLE hCloseEvent = CreateEventA(nullptr, TRUE, FALSE, kCloseEventName); if (!hCloseEvent) { LOG_CRIT("failed to create event for windows event loop"); - throw XArch(new XArchEvalWindows()); + throw XArch(windowsErrorToString(GetLastError())); } LOG_DEBUG("windows event loop running"); diff --git a/src/lib/platform/MSWindowsKeyState.cpp b/src/lib/platform/MSWindowsKeyState.cpp index 1c8e8c8e6..a4d564d03 100644 --- a/src/lib/platform/MSWindowsKeyState.cpp +++ b/src/lib/platform/MSWindowsKeyState.cpp @@ -767,16 +767,20 @@ bool MSWindowsKeyState::fakeCtrlAltDel() // elevated to be able to open it. If not elevated, an access denied error will be returned. MSWindowsHandle sendSasEvent(OpenEvent(EVENT_MODIFY_STATE, FALSE, kSendSasEventName)); if (!sendSasEvent.get()) { - XArchEvalWindows error; - LOG_ERR("couldn't open SAS event, unable to simulate ctrl+alt+del, error: %s", error.eval().c_str()); + LOG_ERR( + "couldn't open SAS event, unable to simulate ctrl+alt+del, error: %s", + windowsErrorToString(GetLastError()).c_str() + ); return false; } // Note: We don't directly call SendSAS, but rather we tell the daemon to do it by setting the event. LOG_DEBUG("setting SAS event to simulate ctrl+alt+del"); if (!SetEvent(sendSasEvent.get())) { - XArchEvalWindows error; - LOG_ERR("failed to set SAS event, unable to simulate ctrl+alt+del, error: %s", error.eval().c_str()); + LOG_ERR( + "failed to set SAS event, unable to simulate ctrl+alt+del, error: %s", + windowsErrorToString(GetLastError()).c_str() + ); return false; } diff --git a/src/lib/platform/MSWindowsProcess.cpp b/src/lib/platform/MSWindowsProcess.cpp index 04b4a68ff..e7585e6d4 100644 --- a/src/lib/platform/MSWindowsProcess.cpp +++ b/src/lib/platform/MSWindowsProcess.cpp @@ -1,11 +1,13 @@ /* * Deskflow -- mouse and keyboard sharing utility + * SPDX-FileCopyrightText: (C) 2025 Deskflow Developers * SPDX-FileCopyrightText: (C) 2025 Symless Ltd. * SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception */ #include "MSWindowsProcess.h" +#include "arch/XArch.h" #include "arch/win32/XArchWindows.h" #include "base/Log.h" @@ -59,7 +61,7 @@ BOOL MSWindowsProcess::startAsUser(HANDLE userToken, LPSECURITY_ATTRIBUTES sa) LPVOID environment; if (!CreateEnvironmentBlock(&environment, userToken, FALSE)) { LOG((CLOG_ERR "could not create environment block")); - throw XArch(new XArchEvalWindows); + throw XArch(windowsErrorToString(GetLastError())); } ZeroMemory(&m_info, sizeof(PROCESS_INFORMATION)); @@ -94,13 +96,13 @@ DWORD MSWindowsProcess::waitForExit() if (WaitForSingleObject(m_info.hProcess, kMaxWaitMilliseconds) != WAIT_OBJECT_0) { LOG_ERR("process did not exit within the expected time"); TerminateProcess(m_info.hProcess, 1); - throw XArch(new XArchEvalWindows()); + throw XArch(windowsErrorToString(GetLastError())); } DWORD exitCode = 0; if (!GetExitCodeProcess(m_info.hProcess, &exitCode)) { LOG_ERR("failed to get exit code, error: %lu", GetLastError()); - throw XArch(new XArchEvalWindows()); + throw XArch(windowsErrorToString(GetLastError())); } if (exitCode != 0) { @@ -151,8 +153,9 @@ void MSWindowsProcess::shutdown(HANDLE handle, DWORD pid, int timeout) return; } } else { - XArchEvalWindows error; - LOG_ERR("failed to get process exit code for process %d, error: %s", pid, error.eval().c_str()); + LOG_ERR( + "failed to get process exit code for process %d, error: %s", pid, windowsErrorToString(GetLastError()).c_str() + ); } // Wait for process to exit gracefully. @@ -160,8 +163,10 @@ void MSWindowsProcess::shutdown(HANDLE handle, DWORD pid, int timeout) DWORD waitResult = WaitForSingleObject(handle, timeout * 1000); if (waitResult == WAIT_OBJECT_0) { // NOSONAR - Readability if (!GetExitCodeProcess(handle, &exitCode)) { - XArchEvalWindows error; - LOG_ERR("failed to get exit code after process exit for process %d, error: %s", pid, error.eval().c_str()); + LOG_ERR( + "failed to get exit code after process exit for process %d, error: %s", pid, + windowsErrorToString(GetLastError()).c_str() + ); } LOG_DEBUG("process %d was shutdown gracefully with exit code %d", pid, exitCode); @@ -170,16 +175,14 @@ void MSWindowsProcess::shutdown(HANDLE handle, DWORD pid, int timeout) } else if (waitResult == WAIT_TIMEOUT) { LOG_WARN("process %d did not exit within the expected time", pid); } else { - XArchEvalWindows error; - LOG_ERR("error waiting for process %d to exit, error: %s", pid, error.eval().c_str()); + LOG_ERR("error waiting for process %d to exit, error: %s", pid, windowsErrorToString(GetLastError()).c_str()); } // Last resort, terminate the process forcefully. if (TerminateProcess(handle, kExitSuccess)) { LOG_WARN("forcefully terminated process %d", pid); } else { - XArchEvalWindows error; - LOG_ERR("failed to terminate process %d, error: %s", pid, error.eval().c_str()); + LOG_ERR("failed to terminate process %d, error: %s", pid, windowsErrorToString(GetLastError()).c_str()); } } @@ -192,22 +195,22 @@ void MSWindowsProcess::createPipes() if (!CreatePipe(&m_outputPipe, &m_stdOutput, &saAttr, 0)) { LOG_ERR("could not create output pipe"); - throw XArch(new XArchEvalWindows()); + throw XArch(windowsErrorToString(GetLastError())); } if (!CreatePipe(&m_errorPipe, &m_stdError, &saAttr, 0)) { LOG_ERR("could not create error pipe"); - throw XArch(new XArchEvalWindows()); + throw XArch(windowsErrorToString(GetLastError())); } // Set the pipes to non-blocking mode DWORD mode = PIPE_NOWAIT; if (!SetNamedPipeHandleState(m_outputPipe, &mode, nullptr, nullptr)) { - throw XArch(new XArchEvalWindows()); + throw XArch(windowsErrorToString(GetLastError())); } if (!SetNamedPipeHandleState(m_errorPipe, &mode, nullptr, nullptr)) { - throw XArch(new XArchEvalWindows()); + throw XArch(windowsErrorToString(GetLastError())); } } @@ -233,7 +236,7 @@ std::string MSWindowsProcess::readOutput(HANDLE handle) // Check if there is data available in the pipe, which prevents `ReadFile` from freezing execution. if (!PeekNamedPipe(handle, nullptr, 0, nullptr, &totalBytesAvail, &bytesLeftThisMessage)) { LOG_ERR("could not peek into pipe"); - throw XArch(new XArchEvalWindows()); + throw XArch(windowsErrorToString(GetLastError())); } if (totalBytesAvail == 0) { @@ -242,7 +245,7 @@ std::string MSWindowsProcess::readOutput(HANDLE handle) if (!ReadFile(handle, buffer, kOutputBufferSize, &bytesRead, nullptr)) { LOG_ERR("could not read from pipe"); - throw XArch(new XArchEvalWindows()); + throw XArch(windowsErrorToString(GetLastError())); } return std::string(buffer, bytesRead); diff --git a/src/lib/platform/MSWindowsScreen.cpp b/src/lib/platform/MSWindowsScreen.cpp index c4f40f27f..410b398f1 100644 --- a/src/lib/platform/MSWindowsScreen.cpp +++ b/src/lib/platform/MSWindowsScreen.cpp @@ -452,14 +452,12 @@ bool MSWindowsScreen::getThisCursorPos(LPPOINT pos) { auto result = GetCursorPos(pos); if (!result) { - XArchEvalWindows error1; - LOG_DEBUG("could not get cursor pos, error: %s", error1.eval().c_str()); + LOG_DEBUG("could not get cursor pos, error: %s", windowsErrorToString(GetLastError()).c_str()); LOG_DEBUG("retrying get cursor pos"); result = GetCursorPos(pos); if (!result) { - XArchEvalWindows error2; - LOG((CLOG_DEBUG "could not get cursor pos, error: %s", error2.eval().c_str())); + LOG((CLOG_DEBUG "could not get cursor pos, error: %s", windowsErrorToString(GetLastError()).c_str())); updateDesktopThread(); } @@ -472,14 +470,12 @@ bool MSWindowsScreen::setThisCursorPos(int x, int y) { auto result = SetCursorPos(x, y); if (!result) { - XArchEvalWindows error1; - LOG_DEBUG("could not set cursor pos, error: %s", error1.eval().c_str()); + LOG_DEBUG("could not set cursor pos, error: %s", windowsErrorToString(GetLastError()).c_str()); LOG_DEBUG("retrying to set cursor pos"); result = SetCursorPos(x, y); if (!result) { - XArchEvalWindows error2; - LOG((CLOG_DEBUG "could not set cursor pos, error: %s", error2.eval().c_str())); + LOG((CLOG_DEBUG "could not set cursor pos, error: %s", windowsErrorToString(GetLastError()).c_str())); updateDesktopThread(); } @@ -494,19 +490,16 @@ void MSWindowsScreen::updateDesktopThread() HDESK hDesk = OpenInputDesktop(0, true, GENERIC_ALL); if (hDesk == nullptr) { - XArchEvalWindows error1; - LOG_DEBUG("could not open input desktop, error: %s", error1.eval().c_str()); + LOG_DEBUG("could not open input desktop, error: %s", windowsErrorToString(GetLastError()).c_str()); return; } if (!SetThreadDesktop(hDesk)) { - XArchEvalWindows error1; - LOG_DEBUG("could not set thread desktop, error: %s", error1.eval().c_str()); + LOG_DEBUG("could not set thread desktop, error: %s", windowsErrorToString(GetLastError()).c_str()); } if (!CloseDesktop(hDesk)) { - XArchEvalWindows error1; - LOG_DEBUG("could not close desktop, error: %s", error1.eval().c_str()); + LOG_DEBUG("could not close desktop, error: %s", windowsErrorToString(GetLastError()).c_str()); } } diff --git a/src/lib/platform/MSWindowsSession.cpp b/src/lib/platform/MSWindowsSession.cpp index 198ba61f5..afabf8e3c 100644 --- a/src/lib/platform/MSWindowsSession.cpp +++ b/src/lib/platform/MSWindowsSession.cpp @@ -6,6 +6,7 @@ #include "platform/MSWindowsSession.h" +#include "arch/XArch.h" #include "arch/win32/XArchWindows.h" #include "base/Log.h" #include "deskflow/XDeskflow.h" @@ -22,7 +23,7 @@ bool MSWindowsSession::isProcessInSession(const char *name, PHANDLE process = nu HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); if (snapshot == INVALID_HANDLE_VALUE) { LOG((CLOG_ERR "could not get process snapshot")); - throw XArch(new XArchEvalWindows()); + throw XArch(windowsErrorToString(GetLastError())); } PROCESSENTRY32 entry; @@ -33,7 +34,7 @@ bool MSWindowsSession::isProcessInSession(const char *name, PHANDLE process = nu BOOL gotEntry = Process32First(snapshot, &entry); if (!gotEntry) { LOG((CLOG_ERR "could not get first process entry")); - throw XArch(new XArchEvalWindows()); + throw XArch(windowsErrorToString(GetLastError())); } // used to record process names for debug info @@ -105,7 +106,7 @@ MSWindowsSession::getUserToken(LPSECURITY_ATTRIBUTES security) HANDLE sourceToken; if (!WTSQueryUserToken(m_activeSessionId, &sourceToken)) { LOG((CLOG_ERR "could not get token from session %d", m_activeSessionId)); - throw XArch(new XArchEvalWindows); + throw XArch(windowsErrorToString(GetLastError())); } HANDLE newToken; @@ -114,7 +115,7 @@ MSWindowsSession::getUserToken(LPSECURITY_ATTRIBUTES security) )) { LOG((CLOG_ERR "could not duplicate token")); - throw XArch(new XArchEvalWindows); + throw XArch(windowsErrorToString(GetLastError())); } LOG((CLOG_DEBUG "duplicated, new token: %i", newToken)); @@ -148,7 +149,7 @@ BOOL MSWindowsSession::nextProcessEntry(HANDLE snapshot, LPPROCESSENTRY32 entry) // files' error then it's probably something serious. if (err != ERROR_NO_MORE_FILES) { LOG((CLOG_ERR "could not get next process entry")); - throw XArch(new XArchEvalWindows()); + throw XArch(windowsErrorToString(GetLastError())); } } diff --git a/src/lib/platform/MSWindowsWatchdog.cpp b/src/lib/platform/MSWindowsWatchdog.cpp index 61cd28102..e8c6ad910 100644 --- a/src/lib/platform/MSWindowsWatchdog.cpp +++ b/src/lib/platform/MSWindowsWatchdog.cpp @@ -7,6 +7,7 @@ #include "platform/MSWindowsWatchdog.h" #include "arch/Arch.h" +#include "arch/XArch.h" #include "arch/win32/XArchWindows.h" #include "base/ELevel.h" #include "base/Log.h" @@ -66,7 +67,7 @@ HANDLE openProcessForKill(const PROCESSENTRY32 &entry) HANDLE handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, entry.th32ProcessID); if (handle == nullptr) { LOG_ERR("could not open process handle for kill"); - throw XArch(new XArchEvalWindows); + throw XArch(windowsErrorToString(GetLastError())); } // only shut down if not current process (daemon is now the same unified binary). @@ -125,7 +126,7 @@ MSWindowsWatchdog::duplicateProcessToken(HANDLE process, LPSECURITY_ATTRIBUTES s if (!tokenRet) { LOG_ERR("could not open token, process handle: %d", process); - throw XArch(new XArchEvalWindows()); + throw XArch(windowsErrorToString(GetLastError())); } LOG_DEBUG("got token %i, duplicating", sourceToken); @@ -137,7 +138,7 @@ MSWindowsWatchdog::duplicateProcessToken(HANDLE process, LPSECURITY_ATTRIBUTES s if (!duplicateRet) { LOG_ERR("could not duplicate token %i", sourceToken); - throw XArch(new XArchEvalWindows()); + throw XArch(windowsErrorToString(GetLastError())); } LOG_DEBUG("duplicated, new token: %i", newToken); @@ -303,7 +304,7 @@ void MSWindowsWatchdog::startProcess() LOG_ERR("daemon failed to run command, exit code: %d", exitCode); } else { LOG_ERR("daemon failed to run command, unknown exit code"); - throw XArch(new XArchEvalWindows); + throw XArch(windowsErrorToString(GetLastError())); } } else { // Wait for program to fail. This needs to be 1 second, as the process may take some time to fail. @@ -387,7 +388,7 @@ void MSWindowsWatchdog::shutdownExistingProcesses() HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, kAllProcesses); if (snapshot == INVALID_HANDLE_VALUE) { LOG_ERR("could not get process snapshot"); - throw XArch(new XArchEvalWindows); + throw XArch(windowsErrorToString(GetLastError())); } PROCESSENTRY32 entry; @@ -398,7 +399,7 @@ void MSWindowsWatchdog::shutdownExistingProcesses() BOOL gotEntry = Process32First(snapshot, &entry); if (!gotEntry) { LOG_ERR("could not get first process entry"); - throw XArch(new XArchEvalWindows); + throw XArch(windowsErrorToString(GetLastError())); } // now just iterate until we can find winlogon.exe pid @@ -419,7 +420,7 @@ void MSWindowsWatchdog::shutdownExistingProcesses() // only worry about error if it's not the end of the snapshot LOG_ERR("could not get next process entry"); - throw XArch(new XArchEvalWindows); + throw XArch(windowsErrorToString(GetLastError())); } } } @@ -481,14 +482,14 @@ void MSWindowsWatchdog::initOutputReadPipe() if (!CreatePipe(&m_outputReadPipe, &m_outputWritePipe, &saAttr, 0)) { LOG_ERR("could not create output pipe"); - throw XArch(new XArchEvalWindows()); + throw XArch(windowsErrorToString(GetLastError())); } // Set the pipe to non-blocking mode, which allows us to stop the output reader thread immediately // in order to speed up the shutdown process when the Windows service needs to stop. if (DWORD mode = PIPE_NOWAIT; !SetNamedPipeHandleState(m_outputReadPipe, &mode, nullptr, nullptr)) { LOG_ERR("could not set pipe to non-blocking mode"); - throw XArch(new XArchEvalWindows()); + throw XArch(windowsErrorToString(GetLastError())); } } @@ -499,14 +500,14 @@ void MSWindowsWatchdog::initSasFunc() HINSTANCE sasLib = LoadLibrary("sas.dll"); if (!sasLib) { LOG_ERR("could not load sas.dll"); - throw XArch(new XArchEvalWindows()); + throw XArch(windowsErrorToString(GetLastError())); } LOG_DEBUG("loaded sas.dll, used to simulate ctrl-alt-del"); m_sendSasFunc = (SendSas)GetProcAddress(sasLib, "SendSAS"); if (!m_sendSasFunc) { LOG_ERR("could not find SendSAS function in sas.dll"); - throw XArch(new XArchEvalWindows()); + throw XArch(windowsErrorToString(GetLastError())); } LOG_DEBUG("found SendSAS function in sas.dll"); @@ -530,8 +531,7 @@ void MSWindowsWatchdog::sasLoop(void *) // NOSONAR - Thread entry point signatur // Create a an event so that other processes can tell the daemon to call the `SendSAS` function. MSWindowsHandle sendSasEvent(CreateEvent(nullptr, FALSE, FALSE, kSendSasEventName)); if (sendSasEvent.get() == nullptr) { - XArchEvalWindows error; - LOG_ERR("could not create SAS event, error: %s", error.eval().c_str()); + LOG_ERR("could not create SAS event, error: %s", windowsErrorToString(GetLastError()).c_str()); ARCH->sleep(1); continue; }