diff options
Diffstat (limited to 'src/lib/arch/win32/ArchDaemonWindows.h')
| -rw-r--r-- | src/lib/arch/win32/ArchDaemonWindows.h | 151 |
1 files changed, 151 insertions, 0 deletions
diff --git a/src/lib/arch/win32/ArchDaemonWindows.h b/src/lib/arch/win32/ArchDaemonWindows.h new file mode 100644 index 0000000..2db9792 --- /dev/null +++ b/src/lib/arch/win32/ArchDaemonWindows.h @@ -0,0 +1,151 @@ +/* + * barrier -- mouse and keyboard sharing utility + * Copyright (C) 2012-2016 Symless Ltd. + * Copyright (C) 2002 Chris Schoeneman + * + * This package is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * found in the file LICENSE that should have accompanied this file. + * + * This package is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#pragma once + +#include "arch/IArchDaemon.h" +#include "arch/IArchMultithread.h" +#include "common/stdstring.h" + +#define WIN32_LEAN_AND_MEAN +#include <Windows.h> +#include <tchar.h> + +#define ARCH_DAEMON ArchDaemonWindows + +//! Win32 implementation of IArchDaemon +class ArchDaemonWindows : public IArchDaemon { +public: + typedef int (*RunFunc)(void); + + ArchDaemonWindows(); + virtual ~ArchDaemonWindows(); + + //! Run the daemon + /*! + When the client calls \c daemonize(), the \c DaemonFunc should call this + function after initialization and argument parsing to perform the + daemon processing. The \c runFunc should perform the daemon's + main loop, calling \c daemonRunning(true) when it enters the main loop + (i.e. after initialization) and \c daemonRunning(false) when it leaves + the main loop. The \c runFunc is called in a new thread and when the + daemon must exit the main loop due to some external control the + getDaemonQuitMessage() is posted to the thread. This function returns + what \c runFunc returns. \c runFunc should call \c daemonFailed() if + the daemon fails. + */ + static int runDaemon(RunFunc runFunc); + + //! Indicate daemon is in main loop + /*! + The \c runFunc passed to \c runDaemon() should call this function + to indicate when it has entered (\c running is \c true) or exited + (\c running is \c false) the main loop. + */ + static void daemonRunning(bool running); + + //! Indicate failure of running daemon + /*! + The \c runFunc passed to \c runDaemon() should call this function + to indicate failure. \c result is returned by \c daemonize(). + */ + static void daemonFailed(int result); + + //! Get daemon quit message + /*! + The windows NT daemon tells daemon thread to exit by posting this + message to it. The thread must, of course, have a message queue + for this to work. + */ + static UINT getDaemonQuitMessage(); + + // IArchDaemon overrides + virtual void installDaemon(const char* name, + const char* description, + const char* pathname, + const char* commandLine, + const char* dependencies); + virtual void uninstallDaemon(const char* name); + virtual void installDaemon(); + virtual void uninstallDaemon(); + virtual int daemonize(const char* name, DaemonFunc func); + virtual bool canInstallDaemon(const char* name); + virtual bool isDaemonInstalled(const char* name); + std::string commandLine() const { return m_commandLine; } + +private: + static HKEY openNTServicesKey(); + + int doRunDaemon(RunFunc runFunc); + void doDaemonRunning(bool running); + UINT doGetDaemonQuitMessage(); + + static void setStatus(DWORD state); + static void setStatus(DWORD state, DWORD step, DWORD waitHint); + static void setStatusError(DWORD error); + + static bool isRunState(DWORD state); + + void serviceMain(DWORD, LPTSTR*); + static void WINAPI serviceMainEntry(DWORD, LPTSTR*); + + void serviceHandler(DWORD ctrl); + static void WINAPI serviceHandlerEntry(DWORD ctrl); + + void start(const char* name); + void stop(const char* name); + +private: + class XArchDaemonRunFailed { + public: + XArchDaemonRunFailed(int result) : m_result(result) { } + + public: + int m_result; + }; + +private: + static ArchDaemonWindows* s_daemon; + + ArchMutex m_serviceMutex; + ArchCond m_serviceCondVar; + DWORD m_serviceState; + bool m_serviceHandlerWaiting; + bool m_serviceRunning; + + DWORD m_daemonThreadID; + DaemonFunc m_daemonFunc; + int m_daemonResult; + + SERVICE_STATUS_HANDLE m_statusHandle; + + UINT m_quitMessage; + + std::string m_commandLine; +}; + +#define DEFAULT_DAEMON_NAME _T("Barrier") +#define DEFAULT_DAEMON_INFO _T("Manages the Barrier foreground processes.") + +static const TCHAR* const g_daemonKeyPath[] = { + _T("SOFTWARE"), + _T("The Barrier Project"), + _T("Barrier"), + _T("Service"), + NULL +}; |
