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; }