From 0fc5368253bed94c15e4002dc3a46483d67832e1 Mon Sep 17 00:00:00 2001 From: Nick Bolton Date: Fri, 28 Feb 2025 12:46:12 +0000 Subject: [PATCH] fix: Prevent access violation by moving events, arch, and log objects to top of stack in Windows daemon This is how we do it in the server/client apps, so it makes sense to mirror the same pattern. --- src/apps/deskflow-daemon/deskflow-daemon.cpp | 21 +++++++++++-- src/lib/deskflow/DaemonApp.cpp | 32 ++++++-------------- src/lib/deskflow/DaemonApp.h | 4 +-- 3 files changed, 31 insertions(+), 26 deletions(-) diff --git a/src/apps/deskflow-daemon/deskflow-daemon.cpp b/src/apps/deskflow-daemon/deskflow-daemon.cpp index 5a701e188..f24f2d478 100644 --- a/src/apps/deskflow-daemon/deskflow-daemon.cpp +++ b/src/apps/deskflow-daemon/deskflow-daemon.cpp @@ -7,7 +7,13 @@ #include "deskflow/DaemonApp.h" -#include +#include "arch/Arch.h" +#include "base/EventQueue.h" +#include "base/Log.h" + +#if SYSAPI_WIN32 +#include "arch/win32/ArchMiscWindows.h" +#endif #ifdef SYSAPI_UNIX @@ -24,7 +30,18 @@ int main(int argc, char **argv) int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int) { - DaemonApp app; +#if SYSAPI_WIN32 + // win32 instance needed for threading, etc. + ArchMiscWindows::setInstanceWin32(GetModuleHandle(nullptr)); +#endif + + Arch arch; + arch.init(); + + Log log; + EventQueue events; + + DaemonApp app(&events); return app.run(__argc, __argv); } diff --git a/src/lib/deskflow/DaemonApp.cpp b/src/lib/deskflow/DaemonApp.cpp index 7f0564f5d..2ff5e9747 100644 --- a/src/lib/deskflow/DaemonApp.cpp +++ b/src/lib/deskflow/DaemonApp.cpp @@ -10,7 +10,6 @@ #include "deskflow/DaemonApp.h" #include "arch/XArch.h" -#include "base/EventQueue.h" #include "base/Log.h" #include "base/TMethodEventJob.h" #include "base/log_outputters.h" @@ -96,7 +95,7 @@ int winMainLoopStatic(int, const char **) } #endif -DaemonApp::DaemonApp() +DaemonApp::DaemonApp(IEventQueue *events) : m_events(events) { s_instance = this; } @@ -108,22 +107,11 @@ DaemonApp::~DaemonApp() int DaemonApp::run(int argc, char **argv) { -#if SYSAPI_WIN32 - // win32 instance needed for threading, etc. - ArchMiscWindows::setInstanceWin32(GetModuleHandle(NULL)); -#endif - - Arch arch; - arch.init(); - - Log log; - m_events = std::make_unique(); - bool uninstall = false; try { // default log level to system setting. - if (string logLevel = arch.setting("LogLevel"); logLevel != "") - log.setFilter(logLevel.c_str()); + if (string logLevel = ARCH->setting("LogLevel"); logLevel != "") + CLOG->setFilter(logLevel.c_str()); bool foreground = false; @@ -137,11 +125,11 @@ int DaemonApp::run(int argc, char **argv) else if (arg == "/install") { LOG((CLOG_PRINT "installing windows daemon")); uninstall = true; - arch.installDaemon(); + ARCH->installDaemon(); return kExitSuccess; } else if (arg == "/uninstall") { LOG((CLOG_PRINT "uninstalling windows daemon")); - arch.uninstallDaemon(); + ARCH->uninstallDaemon(); return kExitSuccess; } #endif @@ -157,7 +145,7 @@ int DaemonApp::run(int argc, char **argv) if (!foreground) { // Only use MS debug outputter when the process is daemonized, since stdout won't be accessible // in that case, but is accessible when running in the foreground. - log.insert(new MSWindowsDebugOutputter()); // NOSONAR -- Adopted by `Log` + CLOG->insert(new MSWindowsDebugOutputter()); // NOSONAR -- Adopted by `Log` } #endif @@ -170,10 +158,10 @@ int DaemonApp::run(int argc, char **argv) } else { #if SYSAPI_WIN32 LOG((CLOG_PRINT "daemonizing windows service")); - arch.daemonize(kAppName, winMainLoopStatic); + ARCH->daemonize(kAppName, winMainLoopStatic); #elif SYSAPI_UNIX LOG((CLOG_PRINT "daemonizing unix service")); - arch.daemonize(kAppName, unixMainLoopStatic); + ARCH->daemonize(kAppName, unixMainLoopStatic); #endif } @@ -214,7 +202,7 @@ void DaemonApp::mainLoop(bool logToFile, bool foreground) SocketMultiplexer multiplexer; // uses event queue, must be created here. - m_ipcServer = std::make_unique(m_events.get(), &multiplexer); + m_ipcServer = std::make_unique(m_events, &multiplexer); // send logging to gui via ipc, log system adopts outputter. m_ipcLogOutputter = std::make_unique(*m_ipcServer, IpcClientType::GUI, true); @@ -235,7 +223,7 @@ void DaemonApp::mainLoop(bool logToFile, bool foreground) #if SYSAPI_WIN32 // install the platform event queue to handle service stop events. - m_events->adoptBuffer(new MSWindowsEventQueueBuffer(m_events.get())); + m_events->adoptBuffer(new MSWindowsEventQueueBuffer(m_events)); std::string command = ARCH->setting("Command"); bool elevate = ARCH->setting("Elevate") == "1"; diff --git a/src/lib/deskflow/DaemonApp.h b/src/lib/deskflow/DaemonApp.h index c801de0f2..2bbd96427 100644 --- a/src/lib/deskflow/DaemonApp.h +++ b/src/lib/deskflow/DaemonApp.h @@ -25,7 +25,7 @@ class DaemonApp { public: - DaemonApp(); + DaemonApp(IEventQueue *events); ~DaemonApp(); int run(int argc, char **argv); void mainLoop(bool logToFile, bool foreground = false); @@ -46,6 +46,6 @@ public: private: std::unique_ptr m_ipcServer; std::unique_ptr m_ipcLogOutputter; - std::unique_ptr m_events; + IEventQueue *m_events = nullptr; FileLogOutputter *m_fileLogOutputter = nullptr; };