| 1 | /* | 
|---|
| 2 | * synergy -- mouse and keyboard sharing utility | 
|---|
| 3 | * Copyright (C) 2002 Chris Schoeneman | 
|---|
| 4 | * | 
|---|
| 5 | * This package is free software; you can redistribute it and/or | 
|---|
| 6 | * modify it under the terms of the GNU General Public License | 
|---|
| 7 | * found in the file COPYING that should have accompanied this file. | 
|---|
| 8 | * | 
|---|
| 9 | * This package is distributed in the hope that it will be useful, | 
|---|
| 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | 
|---|
| 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
|---|
| 12 | * GNU General Public License for more details. | 
|---|
| 13 | */ | 
|---|
| 14 |  | 
|---|
| 15 | #ifndef CARCHDAEMONWINDOWS_H | 
|---|
| 16 | #define CARCHDAEMONWINDOWS_H | 
|---|
| 17 |  | 
|---|
| 18 | #define WIN32_LEAN_AND_MEAN | 
|---|
| 19 |  | 
|---|
| 20 | #include "IArchDaemon.h" | 
|---|
| 21 | #include "IArchMultithread.h" | 
|---|
| 22 | #include "stdstring.h" | 
|---|
| 23 | #include <windows.h> | 
|---|
| 24 | #include <tchar.h> | 
|---|
| 25 |  | 
|---|
| 26 | #define ARCH_DAEMON CArchDaemonWindows | 
|---|
| 27 |  | 
|---|
| 28 | //! Win32 implementation of IArchDaemon | 
|---|
| 29 | class CArchDaemonWindows : public IArchDaemon { | 
|---|
| 30 | public: | 
|---|
| 31 | typedef int                     (*RunFunc)(void); | 
|---|
| 32 |  | 
|---|
| 33 | CArchDaemonWindows(); | 
|---|
| 34 | virtual ~CArchDaemonWindows(); | 
|---|
| 35 |  | 
|---|
| 36 | //! Run the daemon | 
|---|
| 37 | /*! | 
|---|
| 38 | When the client calls \c daemonize(), the \c DaemonFunc should call this | 
|---|
| 39 | function after initialization and argument parsing to perform the | 
|---|
| 40 | daemon processing.  The \c runFunc should perform the daemon's | 
|---|
| 41 | main loop, calling \c daemonRunning(true) when it enters the main loop | 
|---|
| 42 | (i.e. after initialization) and \c daemonRunning(false) when it leaves | 
|---|
| 43 | the main loop.  The \c runFunc is called in a new thread and when the | 
|---|
| 44 | daemon must exit the main loop due to some external control the | 
|---|
| 45 | getDaemonQuitMessage() is posted to the thread.  This function returns | 
|---|
| 46 | what \c runFunc returns.  \c runFunc should call \c daemonFailed() if | 
|---|
| 47 | the daemon fails. | 
|---|
| 48 | */ | 
|---|
| 49 | static int                      runDaemon(RunFunc runFunc); | 
|---|
| 50 |  | 
|---|
| 51 | //! Indicate daemon is in main loop | 
|---|
| 52 | /*! | 
|---|
| 53 | The \c runFunc passed to \c runDaemon() should call this function | 
|---|
| 54 | to indicate when it has entered (\c running is \c true) or exited | 
|---|
| 55 | (\c running is \c false) the main loop. | 
|---|
| 56 | */ | 
|---|
| 57 | static void                     daemonRunning(bool running); | 
|---|
| 58 |  | 
|---|
| 59 | //! Indicate failure of running daemon | 
|---|
| 60 | /*! | 
|---|
| 61 | The \c runFunc passed to \c runDaemon() should call this function | 
|---|
| 62 | to indicate failure.  \c result is returned by \c daemonize(). | 
|---|
| 63 | */ | 
|---|
| 64 | static void                     daemonFailed(int result); | 
|---|
| 65 |  | 
|---|
| 66 | //! Get daemon quit message | 
|---|
| 67 | /*! | 
|---|
| 68 | The windows NT daemon tells daemon thread to exit by posting this | 
|---|
| 69 | message to it.  The thread must, of course, have a message queue | 
|---|
| 70 | for this to work. | 
|---|
| 71 | */ | 
|---|
| 72 | static UINT                     getDaemonQuitMessage(); | 
|---|
| 73 |  | 
|---|
| 74 | // IArchDaemon overrides | 
|---|
| 75 | virtual void            installDaemon(const char* name, | 
|---|
| 76 | const char* description, | 
|---|
| 77 | const char* pathname, | 
|---|
| 78 | const char* commandLine, | 
|---|
| 79 | const char* dependencies, | 
|---|
| 80 | bool allUsers); | 
|---|
| 81 | virtual void            uninstallDaemon(const char* name, bool allUsers); | 
|---|
| 82 | virtual int                     daemonize(const char* name, DaemonFunc func); | 
|---|
| 83 | virtual bool            canInstallDaemon(const char* name, bool allUsers); | 
|---|
| 84 | virtual bool            isDaemonInstalled(const char* name, bool allUsers); | 
|---|
| 85 |  | 
|---|
| 86 | private: | 
|---|
| 87 | static HKEY                     openNTServicesKey(); | 
|---|
| 88 | static HKEY                     open95ServicesKey(); | 
|---|
| 89 | static HKEY                     openUserStartupKey(); | 
|---|
| 90 |  | 
|---|
| 91 | int                                     doRunDaemon(RunFunc runFunc); | 
|---|
| 92 | void                            doDaemonRunning(bool running); | 
|---|
| 93 | UINT                            doGetDaemonQuitMessage(); | 
|---|
| 94 |  | 
|---|
| 95 | static void                     setStatus(DWORD state); | 
|---|
| 96 | static void                     setStatus(DWORD state, DWORD step, DWORD waitHint); | 
|---|
| 97 | static void                     setStatusError(DWORD error); | 
|---|
| 98 |  | 
|---|
| 99 | static bool                     isRunState(DWORD state); | 
|---|
| 100 |  | 
|---|
| 101 | void                            serviceMain(DWORD, LPTSTR*); | 
|---|
| 102 | static void WINAPI      serviceMainEntry(DWORD, LPTSTR*); | 
|---|
| 103 |  | 
|---|
| 104 | void                            serviceHandler(DWORD ctrl); | 
|---|
| 105 | static void WINAPI      serviceHandlerEntry(DWORD ctrl); | 
|---|
| 106 |  | 
|---|
| 107 | private: | 
|---|
| 108 | class XArchDaemonRunFailed { | 
|---|
| 109 | public: | 
|---|
| 110 | XArchDaemonRunFailed(int result) : m_result(result) { } | 
|---|
| 111 |  | 
|---|
| 112 | public: | 
|---|
| 113 | int                             m_result; | 
|---|
| 114 | }; | 
|---|
| 115 |  | 
|---|
| 116 | private: | 
|---|
| 117 | static CArchDaemonWindows*      s_daemon; | 
|---|
| 118 |  | 
|---|
| 119 | CArchMutex                      m_serviceMutex; | 
|---|
| 120 | CArchCond                       m_serviceCondVar; | 
|---|
| 121 | DWORD                           m_serviceState; | 
|---|
| 122 | bool                            m_serviceHandlerWaiting; | 
|---|
| 123 | bool                            m_serviceRunning; | 
|---|
| 124 |  | 
|---|
| 125 | DWORD                           m_daemonThreadID; | 
|---|
| 126 | DaemonFunc                      m_daemonFunc; | 
|---|
| 127 | int                                     m_daemonResult; | 
|---|
| 128 |  | 
|---|
| 129 | SERVICE_STATUS_HANDLE m_statusHandle; | 
|---|
| 130 |  | 
|---|
| 131 | UINT                            m_quitMessage; | 
|---|
| 132 | }; | 
|---|
| 133 |  | 
|---|
| 134 | #endif | 
|---|