#include "../anytunError.h"\r
#include "../threadUtils.hpp"\r
\r
-WinService* WinService::inst = NULL;\r
-Mutex WinService::instMutex;\r
-WinService& gWinService = WinService::instance();\r
-\r
-WinService& WinService::instance()\r
-{\r
- Lock lock(instMutex);\r
- static instanceCleaner c;\r
- if(!inst)\r
- inst = new WinService();\r
- \r
- return *inst;\r
-}\r
-\r
-WinService::~WinService()\r
-{\r
- if(started_)\r
- CloseHandle(stop_event_);\r
-}\r
-\r
void WinService::install()\r
{\r
SC_HANDLE schSCManager;\r
AnytunError::throwErr() << "Error on StartServiceCtrlDispatcher: " << AnytunErrno(GetLastError());\r
}\r
\r
-void WinService::waitForStop()\r
-{\r
- if(!started_)\r
- AnytunError::throwErr() << "Service not started correctly";\r
- \r
- reportStatus(SERVICE_RUNNING, NO_ERROR);\r
- WaitForSingleObject(stop_event_, INFINITE);\r
- reportStatus(SERVICE_STOP_PENDING, NO_ERROR);\r
- cLog.msg(Log::PRIO_NOTICE) << "WinService received stop signal, exitting";\r
-}\r
-\r
-void WinService::stop()\r
-{\r
- if(!started_)\r
- AnytunError::throwErr() << "Service not started correctly";\r
-\r
- reportStatus(SERVICE_STOPPED, NO_ERROR);\r
-}\r
-\r
-int real_main(int argc, char* argv[]);\r
+int real_main(int argc, char* argv[], WinService& service);\r
\r
VOID WINAPI WinService::main(DWORD dwArgc, LPTSTR *lpszArgv)\r
{\r
- if(gWinService.started_) {\r
- cLog.msg(Log::PRIO_ERROR) << "Service is already running";\r
- return;\r
- }\r
+ WinService service;\r
\r
- gWinService.status_handle_ = RegisterServiceCtrlHandlerA(SVC_NAME, WinService::ctrlHandler);\r
- if(!gWinService.status_handle_) { \r
+ service.status_handle_ = RegisterServiceCtrlHandlerA(SVC_NAME, WinService::ctrlHandler);\r
+ if(!service.status_handle_) { \r
cLog.msg(Log::PRIO_ERROR) << "Error on RegisterServiceCtrlHandler: " << AnytunErrno(GetLastError());\r
return;\r
}\r
- gWinService.status_.dwServiceType = SERVICE_WIN32_OWN_PROCESS; \r
- gWinService.status_.dwServiceSpecificExitCode = 0; \r
- gWinService.reportStatus(SERVICE_START_PENDING, NO_ERROR);\r
- gWinService.started_ = true;\r
+ service.status_.dwServiceType = SERVICE_WIN32_OWN_PROCESS; \r
+ service.status_.dwServiceSpecificExitCode = 0; \r
+ service.reportStatus(SERVICE_START_PENDING, NO_ERROR);\r
\r
- gWinService.stop_event_ = CreateEvent(NULL, true, false, NULL);\r
- if(!gWinService.stop_event_) {\r
- cLog.msg(Log::PRIO_ERROR) << "WinService Error on CreateEvent: " << AnytunErrno(GetLastError());\r
- gWinService.reportStatus(SERVICE_STOPPED, -1);\r
- return;\r
- }\r
-\r
- real_main(dwArgc, lpszArgv);\r
+ real_main(dwArgc, lpszArgv, service);\r
+ \r
+ service.reportStatus(SERVICE_STOPPED, NO_ERROR);\r
}\r
\r
VOID WINAPI WinService::ctrlHandler(DWORD dwCtrl)\r
{\r
- switch(dwCtrl) {\r
+ gSignalController.inject(dwCtrl);\r
+}\r
+\r
+int WinService::handleCtrlSignal(int sig, const std::string& msg)\r
+{\r
+ switch(sig) {\r
case SERVICE_CONTROL_STOP: {\r
- gWinService.reportStatus(SERVICE_STOP_PENDING, NO_ERROR);\r
- SetEvent(gWinService.stop_event_);\r
- return;\r
+ reportStatus(SERVICE_STOP_PENDING, NO_ERROR);\r
+ cLog.msg(Log::PRIO_NOTICE) << "received service stop signal, exitting";\r
+ return 1;\r
}\r
case SERVICE_CONTROL_INTERROGATE: break;\r
default: break;\r
}\r
- gWinService.reportStatus(gWinService.status_.dwCurrentState, NO_ERROR);\r
+ reportStatus(status_.dwCurrentState, NO_ERROR);\r
+\r
+ return 0;\r
}\r
\r
-void WinService::reportStatus(DWORD dwCurrentState, DWORD dwWin32ExitCode, DWORD dwWaitHint)\r
+void WinService::reportStatus(DWORD dwCurrentState, DWORD dwWin32ExitCode)\r
{\r
static DWORD dwCheckPoint = 1;\r
\r
status_.dwCurrentState = dwCurrentState;\r
status_.dwWin32ExitCode = dwWin32ExitCode;\r
- status_.dwWaitHint = dwWaitHint;\r
+ status_.dwWaitHint = 0;\r
\r
if((dwCurrentState == SERVICE_START_PENDING) ||\r
(dwCurrentState == SERVICE_STOP_PENDING))\r
SetServiceStatus(status_handle_, &status_);\r
}\r
\r
+void WinService::initPrivs(std::string const& username, std::string const& groupname)\r
+{\r
+// nothing here\r
+}\r
+\r
+void WinService::dropPrivs()\r
+{\r
+// nothing here\r
+}\r
+\r
+void WinService::chroot(std::string const& dir)\r
+{\r
+// nothing here\r
+}\r
+\r
+void WinService::daemonize()\r
+{\r
+// nothing here\r
+}\r
+\r
+bool WinService::isDaemonized()\r
+{\r
+ return true;\r
+}\r
+\r
#endif\r