From ad383ad9d4a4dea885dd6c4f0a2484e447fa856b Mon Sep 17 00:00:00 2001 From: Nick Bolton Date: Wed, 10 Sep 2025 12:01:41 +0100 Subject: [PATCH] chore: Remove unused daemon installation and uninstallation methods --- src/apps/deskflow-daemon/deskflow-daemon.cpp | 16 +- src/lib/arch/ArchDaemonNone.cpp | 30 --- src/lib/arch/ArchDaemonNone.h | 13 +- src/lib/arch/IArchDaemon.h | 51 ----- src/lib/arch/win32/ArchDaemonWindows.cpp | 206 ------------------- src/lib/arch/win32/ArchDaemonWindows.h | 13 -- src/lib/deskflow/DaemonApp.cpp | 12 -- src/lib/deskflow/DaemonApp.h | 2 - 8 files changed, 3 insertions(+), 340 deletions(-) diff --git a/src/apps/deskflow-daemon/deskflow-daemon.cpp b/src/apps/deskflow-daemon/deskflow-daemon.cpp index 1c21c1977..7cdbd2578 100644 --- a/src/apps/deskflow-daemon/deskflow-daemon.cpp +++ b/src/apps/deskflow-daemon/deskflow-daemon.cpp @@ -59,12 +59,6 @@ int main(int argc, char **argv) const auto foregroundOption = QCommandLineOption({"f", "foreground"}, "Run in the foreground (show console)"); parser.addOption(foregroundOption); - const auto installOption = QCommandLineOption({"i", "install"}, "Install as a Windows service"); - parser.addOption(installOption); - - const auto uninstallOption = QCommandLineOption({"u", "uninstall"}, "Uninstall the Windows service"); - parser.addOption(uninstallOption); - parser.process(app); if (parser.isSet(foregroundOption)) { @@ -83,7 +77,7 @@ int main(int argc, char **argv) // Default log level to system setting (found in Registry). auto logLevel = Settings::value(Settings::Daemon::LogLevel).toString().toStdString(); - if (logLevel != "") { + if (!logLevel.empty()) { CLOG->setFilter(logLevel.c_str()); LOG_DEBUG("log level: %s", logLevel.c_str()); } @@ -97,14 +91,6 @@ int main(int argc, char **argv) } #endif - if (parser.isSet(installOption)) { - daemon.install(); - return s_exitSuccess; - } else if (parser.isSet(uninstallOption)) { - daemon.uninstall(); - return s_exitSuccess; - } - const auto ipcServer = new ipc::DaemonIpcServer(&app, qPrintable(DaemonApp::logFilename())); // NOSONAR - Qt managed ipcServer->listen(); daemon.connectIpcServer(ipcServer); diff --git a/src/lib/arch/ArchDaemonNone.cpp b/src/lib/arch/ArchDaemonNone.cpp index 8323d8313..c4c293a21 100644 --- a/src/lib/arch/ArchDaemonNone.cpp +++ b/src/lib/arch/ArchDaemonNone.cpp @@ -11,16 +11,6 @@ // ArchDaemonNone // -void ArchDaemonNone::installDaemon(const char *, const char *, const char *, const char *, const char *) -{ - // do nothing -} - -void ArchDaemonNone::uninstallDaemon(const char *) -{ - // do nothing -} - int ArchDaemonNone::daemonize(const char *name, DaemonFunc const &func) { // simply forward the call to func. obviously, this doesn't @@ -28,26 +18,6 @@ int ArchDaemonNone::daemonize(const char *name, DaemonFunc const &func) return func(1, &name); } -bool ArchDaemonNone::canInstallDaemon(const char *) -{ - return false; -} - -bool ArchDaemonNone::isDaemonInstalled(const char *) -{ - return false; -} - -void ArchDaemonNone::installDaemon() -{ - // do nothing -} - -void ArchDaemonNone::uninstallDaemon() -{ - // do nothing -} - std::string ArchDaemonNone::commandLine() const { return ""; diff --git a/src/lib/arch/ArchDaemonNone.h b/src/lib/arch/ArchDaemonNone.h index 541410b2d..d6546bdfc 100644 --- a/src/lib/arch/ArchDaemonNone.h +++ b/src/lib/arch/ArchDaemonNone.h @@ -13,9 +13,8 @@ //! Dummy implementation of IArchDaemon /*! -This class implements IArchDaemon for a platform that does not have -daemons. The install and uninstall functions do nothing, the query -functions return false, and \c daemonize() simply calls the passed +This class implements IArchDaemon for a platform that does not have daemons. +The query functions return false, and \c daemonize() simply calls the passed function and returns its result. */ class ArchDaemonNone : public IArchDaemon @@ -25,14 +24,6 @@ public: ~ArchDaemonNone() override = default; // IArchDaemon overrides - void installDaemon( - const char *name, const char *description, const char *pathname, const char *commandLine, const char *dependencies - ) override; - void uninstallDaemon(const char *name) override; int daemonize(const char *name, DaemonFunc const &func) override; - bool canInstallDaemon(const char *name) override; - bool isDaemonInstalled(const char *name) override; - void installDaemon() override; - void uninstallDaemon() override; std::string commandLine() const override; }; diff --git a/src/lib/arch/IArchDaemon.h b/src/lib/arch/IArchDaemon.h index 6a2487b39..3a2e76441 100644 --- a/src/lib/arch/IArchDaemon.h +++ b/src/lib/arch/IArchDaemon.h @@ -26,41 +26,6 @@ public: //! @name manipulators //@{ - //! Install daemon - /*! - Install a daemon. \c name is the name of the daemon passed to the - system and \c description is a short human readable description of - the daemon. \c pathname is the path to the daemon executable. - \c commandLine should \b not include the name of program as the - first argument. If \c allUsers is true then the daemon will be - installed to start at boot time, otherwise it will be installed to - start when the current user logs in. If \p dependencies is not nullptr - then it's a concatenation of NUL terminated other daemon names - followed by a NUL; the daemon will be configured to startup after - the listed daemons. Throws an \c ArchDaemonException exception on failure. - */ - virtual void installDaemon( - const char *name, const char *description, const char *pathname, const char *commandLine, const char *dependencies - ) = 0; - - //! Uninstall daemon - /*! - Uninstall a daemon. Throws an \c ArchDaemonException on failure. - */ - virtual void uninstallDaemon(const char *name) = 0; - - //! Install daemon - /*! - Installs the default daemon. - */ - virtual void installDaemon() = 0; - - //! Uninstall daemon - /*! - Uninstalls the default daemon. - */ - virtual void uninstallDaemon() = 0; - //! Daemonize the process /*! Daemonize. Throw ArchDaemonFailedException on error. \c name is the name @@ -90,22 +55,6 @@ public: */ virtual int daemonize(const char *name, DaemonFunc const &func) = 0; - //! Check if user has permission to install the daemon - /*! - Returns true iff the caller has permission to install or - uninstall the daemon. Note that even if this method returns - true it's possible that installing/uninstalling the service - may still fail. This method ignores whether or not the - service is already installed. - */ - virtual bool canInstallDaemon(const char *name) = 0; - - //! Check if the daemon is installed - /*! - Returns true iff the daemon is installed. - */ - virtual bool isDaemonInstalled(const char *name) = 0; - //@} //! Get the command line diff --git a/src/lib/arch/win32/ArchDaemonWindows.cpp b/src/lib/arch/win32/ArchDaemonWindows.cpp index 6d3d63e85..499aba3b2 100644 --- a/src/lib/arch/win32/ArchDaemonWindows.cpp +++ b/src/lib/arch/win32/ArchDaemonWindows.cpp @@ -12,9 +12,7 @@ #include "arch/win32/ArchMiscWindows.h" #include "arch/win32/XArchWindows.h" #include "base/Log.h" -#include "common/Constants.h" -inline static const auto kDefaultDaemonName = _T(kAppName); // // ArchDaemonWindows // @@ -54,142 +52,6 @@ void ArchDaemonWindows::daemonFailed(int result) throw ArchDaemonRunException(result); } -void ArchDaemonWindows::installDaemon( - const char *name, const char *description, const char *pathname, const char *commandLine, const char *dependencies -) -{ - LOG_DEBUG("installing windows service: %s", name); - - // open service manager - SC_HANDLE mgr = OpenSCManager(nullptr, nullptr, GENERIC_WRITE); - if (mgr == nullptr) { - // can't open service manager - throw ArchDaemonInstallException(windowsErrorToString(GetLastError())); - } - - // create the service - SC_HANDLE service = CreateService( - mgr, name, name, 0, SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS, SERVICE_AUTO_START, - SERVICE_ERROR_NORMAL, pathname, nullptr, nullptr, dependencies, nullptr, nullptr - ); - - if (service == nullptr) { - // can't create service - DWORD err = GetLastError(); - if (err != ERROR_SERVICE_EXISTS) { - CloseServiceHandle(mgr); - throw ArchDaemonInstallException(windowsErrorToString(err)); - } - } else { - // done with service (but only try to close if not null) - CloseServiceHandle(service); - } - - // done with manager - CloseServiceHandle(mgr); - - // open the registry key for this service - HKEY key = openNTServicesKey(); - key = ArchMiscWindows::addKey(key, name); - if (key == nullptr) { - // can't open key - DWORD err = GetLastError(); - try { - uninstallDaemon(name); - } catch (...) { - // ignore - } - throw ArchDaemonInstallException(windowsErrorToString(err)); - } - - // set the description - ArchMiscWindows::setValue(key, _T("Description"), description); - - // set command line - key = ArchMiscWindows::addKey(key, _T("Parameters")); - if (key == nullptr) { - // can't open key - DWORD err = GetLastError(); - ArchMiscWindows::closeKey(key); - try { - uninstallDaemon(name); - } catch (...) { - // ignore - } - throw ArchDaemonInstallException(windowsErrorToString(err)); - } - ArchMiscWindows::setValue(key, _T("CommandLine"), commandLine); - - // done with registry - ArchMiscWindows::closeKey(key); -} - -void ArchDaemonWindows::uninstallDaemon(const char *name) -{ - LOG_DEBUG("uninstalling windows service: %s", name); - - // remove parameters for this service. ignore failures. - HKEY key = openNTServicesKey(); - key = ArchMiscWindows::openKey(key, name); - if (key != nullptr) { - ArchMiscWindows::deleteKey(key, _T("Parameters")); - ArchMiscWindows::closeKey(key); - } - - // open service manager - SC_HANDLE mgr = OpenSCManager(nullptr, nullptr, GENERIC_WRITE); - if (mgr == nullptr) { - // can't open service manager - throw ArchDaemonUninstallFailedException(windowsErrorToString(GetLastError())); - } - - // open the service. oddly, you must open a service to delete it. - SC_HANDLE service = OpenService(mgr, name, DELETE | SERVICE_STOP); - if (service == nullptr) { - DWORD err = GetLastError(); - CloseServiceHandle(mgr); - if (err != ERROR_SERVICE_DOES_NOT_EXIST) { - throw ArchDaemonUninstallFailedException(windowsErrorToString(err)); - } - throw ArchDaemonUninstallNotInstalledException(windowsErrorToString(err)); - } - - // stop the service. we don't care if we fail. - SERVICE_STATUS status; - ControlService(service, SERVICE_CONTROL_STOP, &status); - - // delete the service - const bool okay = (DeleteService(service) == 0); - const DWORD err = GetLastError(); - - // clean up - CloseServiceHandle(service); - CloseServiceHandle(mgr); - - // give windows a chance to remove the service before we check if it still exists. - // 100ms should be plenty of time. - LOG_DEBUG("waiting for service to be removed"); - Arch::sleep(0.1); - - // handle failure. ignore error if service isn't installed anymore. - if (!okay && isDaemonInstalled(name)) { - if (err == ERROR_SUCCESS) { - // this seems to occur even though the uninstall was successful. - // it could be a timing issue, i.e., isDaemonInstalled is - // called too soon. i've added a sleep to try and stop this. - return; - } - if (err == ERROR_IO_PENDING) { - // this seems to be a spurious error - return; - } - if (err != ERROR_SERVICE_MARKED_FOR_DELETE) { - throw ArchDaemonUninstallFailedException(windowsErrorToString(err)); - } - throw ArchDaemonUninstallNotInstalledException(windowsErrorToString(err)); - } -} - int ArchDaemonWindows::daemonize(const char *name, DaemonFunc const &func) { assert(name != nullptr); @@ -218,42 +80,6 @@ int ArchDaemonWindows::daemonize(const char *name, DaemonFunc const &func) return m_daemonResult; } -bool ArchDaemonWindows::canInstallDaemon(const char * /*name*/) -{ - // check if we can open service manager for write - SC_HANDLE mgr = OpenSCManager(nullptr, nullptr, GENERIC_WRITE); - if (mgr == nullptr) { - return false; - } - CloseServiceHandle(mgr); - - // check if we can open the registry key - HKEY key = openNTServicesKey(); - ArchMiscWindows::closeKey(key); - - return (key != nullptr); -} - -bool ArchDaemonWindows::isDaemonInstalled(const char *name) -{ - // open service manager - SC_HANDLE mgr = OpenSCManager(nullptr, nullptr, GENERIC_READ); - if (mgr == nullptr) { - return false; - } - - // open the service - SC_HANDLE service = OpenService(mgr, name, GENERIC_READ); - - // clean up - if (service != nullptr) { - CloseServiceHandle(service); - } - CloseServiceHandle(mgr); - - return (service != nullptr); -} - HKEY ArchDaemonWindows::openNTServicesKey() { static const char *s_keyNames[] = {_T("SYSTEM"), _T("CurrentControlSet"), _T("Services"), nullptr}; @@ -602,35 +428,3 @@ void ArchDaemonWindows::stop(const char *name) } } } - -void ArchDaemonWindows::installDaemon() -{ - // install default daemon if not already installed. - if (!isDaemonInstalled(kDefaultDaemonName)) { - char binPath[MAX_PATH]; - GetModuleFileName(ArchMiscWindows::instanceWin32(), binPath, MAX_PATH); - - // wrap in quotes so a malicious user can't start \Program.exe as admin. - const auto command = "\"" + std::string(binPath) + "\""; - - installDaemon(kDefaultDaemonName, DEFAULT_DAEMON_INFO, command.c_str(), "", ""); - } - - start(kDefaultDaemonName); -} - -void ArchDaemonWindows::uninstallDaemon() -{ - // remove legacy services if installed. - if (isDaemonInstalled(LEGACY_SERVER_DAEMON_NAME)) { - uninstallDaemon(LEGACY_SERVER_DAEMON_NAME); - } - if (isDaemonInstalled(LEGACY_CLIENT_DAEMON_NAME)) { - uninstallDaemon(LEGACY_CLIENT_DAEMON_NAME); - } - - // remove new service if installed. - if (isDaemonInstalled(kDefaultDaemonName)) { - uninstallDaemon(kDefaultDaemonName); - } -} diff --git a/src/lib/arch/win32/ArchDaemonWindows.h b/src/lib/arch/win32/ArchDaemonWindows.h index 78a29ed96..c0711f535 100644 --- a/src/lib/arch/win32/ArchDaemonWindows.h +++ b/src/lib/arch/win32/ArchDaemonWindows.h @@ -67,15 +67,7 @@ public: static UINT getDaemonQuitMessage(); // IArchDaemon overrides - void installDaemon( - const char *name, const char *description, const char *pathname, const char *commandLine, const char *dependencies - ) override; - void uninstallDaemon(const char *name) override; - void installDaemon() override; - void uninstallDaemon() override; int daemonize(const char *name, DaemonFunc const &func) override; - bool canInstallDaemon(const char *name) override; - bool isDaemonInstalled(const char *name) override; std::string commandLine() const override { return m_commandLine; @@ -134,8 +126,3 @@ private: std::string m_commandLine; }; - -#define DEFAULT_DAEMON_INFO _T("Runs the Core process on secure desktops (UAC prompts, login screen, etc).") - -#define LEGACY_SERVER_DAEMON_NAME _T("Deskflow Server") -#define LEGACY_CLIENT_DAEMON_NAME _T("Deskflow Client") diff --git a/src/lib/deskflow/DaemonApp.cpp b/src/lib/deskflow/DaemonApp.cpp index 6d7d30d22..9062c1d16 100644 --- a/src/lib/deskflow/DaemonApp.cpp +++ b/src/lib/deskflow/DaemonApp.cpp @@ -122,18 +122,6 @@ void DaemonApp::connectIpcServer(const ipc::DaemonIpcServer *ipcServer) const ); } -void DaemonApp::install() const -{ - LOG_NOTE("installing windows daemon"); - ARCH->installDaemon(); -} - -void DaemonApp::uninstall() const -{ - LOG_NOTE("uninstalling windows daemon"); - ARCH->uninstallDaemon(); -} - void DaemonApp::run(QThread &daemonThread) { LOG_NOTE("starting daemon"); diff --git a/src/lib/deskflow/DaemonApp.h b/src/lib/deskflow/DaemonApp.h index ea71c00de..6ed5db645 100644 --- a/src/lib/deskflow/DaemonApp.h +++ b/src/lib/deskflow/DaemonApp.h @@ -48,8 +48,6 @@ public: ~DaemonApp() override; InitResult init(int argc, char **argv); - void install() const; - void uninstall() const; void run(QThread &daemonThread); void setForeground(); void initLogging();