summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Pointner <equinox@anytun.org>2009-02-20 14:45:26 +0000
committerChristian Pointner <equinox@anytun.org>2009-02-20 14:45:26 +0000
commit76a437ed322ae5a5fe317d4a2dbe392a21ac9932 (patch)
tree390d3a66da5c7624d91872003c2914f1a463f162
parentmoved NO_SYSLOG to inverse LOG_SYSLOG switch (diff)
windows service works now
-rw-r--r--src/anytun.cpp52
-rw-r--r--src/anytun.sln6
-rw-r--r--src/anytun.suobin61952 -> 62976 bytes
-rw-r--r--src/anytun.vcproj166
-rw-r--r--src/win32/winService.cpp82
-rw-r--r--src/win32/winService.h19
6 files changed, 301 insertions, 24 deletions
diff --git a/src/anytun.cpp b/src/anytun.cpp
index 054013b..fc7404c 100644
--- a/src/anytun.cpp
+++ b/src/anytun.cpp
@@ -51,6 +51,9 @@
#ifndef NO_SIGNALCONTROLLER
#include "signalController.h"
#endif
+#ifdef WIN_SERVICE
+#include "win32/winService.h"
+#endif
#include "packetSource.h"
#include "tunDevice.h"
#include "options.h"
@@ -312,10 +315,43 @@ void receiver(void* p)
}
}
-
+#ifdef WIN_SERVICE
+int main(int argc, char* argv[])
+{
+ try {
+ if(argc > 1) {
+ if(std::string(argv[1]) == "install") {
+ WinService::install();
+ return 0;
+ }
+ else if(std::string(argv[1]) == "uninstall") {
+ WinService::uninstall();
+ return 0;
+ }
+ }
+ WinService::start();
+ return 0;
+ }
+ catch(std::runtime_error& e)
+ {
+ std::cout << "caught runtime error, exiting: " << e.what() << std::endl;
+ }
+ catch(std::exception& e)
+ {
+ std::cout << "caught exception, exiting: " << e.what() << std::endl;
+ }
+}
+
+int real_main(int argc, char* argv[])
+#else
int main(int argc, char* argv[])
+#endif
{
+#ifdef WIN_SERVICE
+ bool daemonized=true;
+#else
bool daemonized=false;
+#endif
try
{
cLog.msg(Log::PRIO_NOTICE) << "anytun started...";
@@ -434,7 +470,7 @@ int main(int argc, char* argv[])
ThreadParam p(dev, *src, *connTo);
boost::thread senderThread(boost::bind(sender,&p));
-#ifndef NO_SIGNALCONTROLLER
+#if defined(WIN_SERVICE) || !defined(NO_SIGNALCONTROLLER)
boost::thread receiverThread(boost::bind(receiver,&p));
#endif
#ifndef ANYTUN_NOSYNC
@@ -449,7 +485,10 @@ int main(int argc, char* argv[])
}
#endif
-#ifndef NO_SIGNALCONTROLLER
+#if defined(WIN_SERVICE)
+ int ret = 0;
+ gWinService.waitForStop();
+#elif !defined(NO_SIGNALCONTROLLER)
int ret = sig.run();
#else
receiver(&p);
@@ -480,6 +519,9 @@ int main(int argc, char* argv[])
if(connTo)
delete connTo;
*/
+#if defined(WIN_SERVICE)
+ gWinService.stop();
+#endif
return ret;
}
catch(std::runtime_error& e)
@@ -498,6 +540,10 @@ int main(int argc, char* argv[])
std::cout << "uncaught exception, exiting: " << e.what() << std::endl;
#endif
}
+#if defined(WIN_SERVICE)
+ gWinService.stop();
+#endif
+ return -1;
}
diff --git a/src/anytun.sln b/src/anytun.sln
index 256ef8c..b562246 100644
--- a/src/anytun.sln
+++ b/src/anytun.sln
@@ -7,12 +7,18 @@ Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Release|Win32 = Release|Win32
+ Service Debug|Win32 = Service Debug|Win32
+ Service Release|Win32 = Service Release|Win32
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{12460D00-D78A-4C68-BDE2-9E3B2F9CD0F3}.Debug|Win32.ActiveCfg = Debug|Win32
{12460D00-D78A-4C68-BDE2-9E3B2F9CD0F3}.Debug|Win32.Build.0 = Debug|Win32
{12460D00-D78A-4C68-BDE2-9E3B2F9CD0F3}.Release|Win32.ActiveCfg = Release|Win32
{12460D00-D78A-4C68-BDE2-9E3B2F9CD0F3}.Release|Win32.Build.0 = Release|Win32
+ {12460D00-D78A-4C68-BDE2-9E3B2F9CD0F3}.Service Debug|Win32.ActiveCfg = Service Debug|Win32
+ {12460D00-D78A-4C68-BDE2-9E3B2F9CD0F3}.Service Debug|Win32.Build.0 = Service Debug|Win32
+ {12460D00-D78A-4C68-BDE2-9E3B2F9CD0F3}.Service Release|Win32.ActiveCfg = Service Release|Win32
+ {12460D00-D78A-4C68-BDE2-9E3B2F9CD0F3}.Service Release|Win32.Build.0 = Service Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/src/anytun.suo b/src/anytun.suo
index 084470a..dc86967 100644
--- a/src/anytun.suo
+++ b/src/anytun.suo
Binary files differ
diff --git a/src/anytun.vcproj b/src/anytun.vcproj
index a74e715..3b0727f 100644
--- a/src/anytun.vcproj
+++ b/src/anytun.vcproj
@@ -165,6 +165,156 @@
Name="VCPostBuildEventTool"
/>
</Configuration>
+ <Configuration
+ Name="Service Debug|Win32"
+ OutputDirectory="$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalOptions="/I &quot;C:\Program Files\boost\boost_1_35_0\&quot;"
+ Optimization="0"
+ PreprocessorDefinitions="WIN_SERVICE;LOG_WINEVENTLOG;USE_SSL_CRYPTO;NO_DAEMON;NO_EXEC;NO_SIGNALCONTROLLER;WIN32_LEAN_AND_MEAN"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DebugInformationFormat="4"
+ ForcedIncludeFiles=""
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="libeay32MDd.lib"
+ OutputFile="$(OutDir)\$(ProjectName)svc.exe"
+ LinkIncremental="2"
+ AdditionalLibraryDirectories=""
+ IgnoreAllDefaultLibraries="false"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Service Release|Win32"
+ OutputDirectory="$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ PreprocessorDefinitions="WIN_SERVICE;LOG_EVENTLOG;USE_SSL_CRYPTO;NO_DAEMON;NO_EXEC;NO_SIGNALCONTROLLER;WIN32_LEAN_AND_MEAN"
+ RuntimeLibrary="2"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="libeay32MD.lib"
+ OutputFile="$(OutDir)\$(ProjectName)svc.exe"
+ LinkIncremental="2"
+ AdditionalLibraryDirectories=""
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
</Configurations>
<References>
</References>
@@ -417,6 +567,22 @@
PreprocessorDefinitions="ANYTUN_OPTIONS"
/>
</FileConfiguration>
+ <FileConfiguration
+ Name="Service Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ PreprocessorDefinitions="ANYTUN_OPTIONS"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Service Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ PreprocessorDefinitions="ANYTUN_OPTIONS"
+ />
+ </FileConfiguration>
</File>
<File
RelativePath=".\packetSource.cpp"
diff --git a/src/win32/winService.cpp b/src/win32/winService.cpp
index 659513e..78558de 100644
--- a/src/win32/winService.cpp
+++ b/src/win32/winService.cpp
@@ -29,6 +29,8 @@
* along with anytun. If not, see <http://www.gnu.org/licenses/>.
*/
+#ifdef WIN_SERVICE
+
#include <iostream>
#include <windows.h>
@@ -54,7 +56,7 @@ WinService& WinService::instance()
WinService::~WinService()
{
if(started_)
- CloseHandle(exit_event_);
+ CloseHandle(stop_event_);
}
void WinService::install()
@@ -76,8 +78,8 @@ void WinService::install()
throw std::runtime_error(msg.str());
}
- schService = CreateServiceA(schSCManager, name_.c_str(), name_.c_str(), SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS,
- SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL, szPath, NULL, NULL, NULL, NULL, NULL); // no password
+ schService = CreateServiceA(schSCManager, SVC_NAME, SVC_NAME, SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS,
+ SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL, szPath, NULL, NULL, NULL, NULL, NULL);
if(schService == NULL) {
CloseServiceHandle(schSCManager);
std::stringstream msg;
@@ -91,13 +93,44 @@ void WinService::install()
CloseServiceHandle(schSCManager);
}
-void WinService::start()
+void WinService::uninstall()
{
- if(started_)
- throw std::runtime_error("Service already started");
+ SC_HANDLE schSCManager;
+ SC_HANDLE schService;
+
+ schSCManager = OpenSCManagerA(NULL, NULL, SC_MANAGER_ALL_ACCESS);
+ if(NULL == schSCManager) {
+ std::stringstream msg;
+ msg << "Error on OpenSCManager: " << LogErrno(GetLastError());
+ throw std::runtime_error(msg.str());
+ }
+
+ schService = OpenServiceA(schSCManager, SVC_NAME, SERVICE_ALL_ACCESS);
+ if(schService == NULL) {
+ CloseServiceHandle(schSCManager);
+ std::stringstream msg;
+ msg << "Error on CreateService: " << LogErrno(GetLastError());
+ throw std::runtime_error(msg.str());
+ }
+ if(!DeleteService(schService)) {
+ CloseServiceHandle(schService);
+ CloseServiceHandle(schSCManager);
+ std::stringstream msg;
+ msg << "Error on DeleteService: " << LogErrno(GetLastError());
+ throw std::runtime_error(msg.str());
+ }
+
+ std::cout << "Service uninstalled successfully" << std::endl;
+
+ CloseServiceHandle(schService);
+ CloseServiceHandle(schSCManager);
+}
+
+void WinService::start()
+{
SERVICE_TABLE_ENTRY DispatchTable[] = {
- {(LPSTR)name_.c_str(), (LPSERVICE_MAIN_FUNCTION)WinService::main },
+ {SVC_NAME, (LPSERVICE_MAIN_FUNCTION)WinService::main },
{NULL, NULL}
};
@@ -108,26 +141,33 @@ void WinService::start()
}
}
-void WinService::waitForExit()
+void WinService::waitForStop()
{
- if(started_)
+ if(!started_)
throw std::runtime_error("Service not started correctly");
- WaitForSingleObject(exit_event_, INFINITE);
+ WaitForSingleObject(stop_event_, INFINITE);
reportStatus(SERVICE_STOP_PENDING, NO_ERROR);
}
void WinService::stop()
{
- if(started_)
+ if(!started_)
throw std::runtime_error("Service not started correctly");
reportStatus(SERVICE_STOPPED, NO_ERROR);
}
+int real_main(int argc, char* argv[]);
+
VOID WINAPI WinService::main(DWORD dwArgc, LPTSTR *lpszArgv)
{
- gWinService.status_handle_ = RegisterServiceCtrlHandlerA(gWinService.name_.c_str(), WinService::ctrlHandler);
+ if(gWinService.started_) {
+ cLog.msg(Log::PRIO_ERR) << "Service is already running";
+ return;
+ }
+
+ gWinService.status_handle_ = RegisterServiceCtrlHandlerA(SVC_NAME, WinService::ctrlHandler);
if(!gWinService.status_handle_) {
cLog.msg(Log::PRIO_ERR) << "Error on RegisterServiceCtrlHandler: " << LogErrno(GetLastError());
return;
@@ -136,18 +176,30 @@ VOID WINAPI WinService::main(DWORD dwArgc, LPTSTR *lpszArgv)
gWinService.status_.dwServiceSpecificExitCode = 0;
gWinService.reportStatus(SERVICE_START_PENDING, NO_ERROR);
- gWinService.exit_event_ = CreateEvent(NULL, true, false, NULL);
- if(!gWinService.exit_event_) {
+ gWinService.stop_event_ = CreateEvent(NULL, true, false, NULL);
+ if(!gWinService.stop_event_) {
cLog.msg(Log::PRIO_ERR) << "Error on CreateEvent: " << LogErrno(GetLastError());
gWinService.reportStatus(SERVICE_STOPPED, -1);
return;
}
gWinService.started_ = true;
gWinService.reportStatus(SERVICE_RUNNING, NO_ERROR);
+
+ real_main(dwArgc, lpszArgv);
}
VOID WINAPI WinService::ctrlHandler(DWORD dwCtrl)
{
+ switch(dwCtrl) {
+ case SERVICE_CONTROL_STOP: {
+ gWinService.reportStatus(SERVICE_STOP_PENDING, NO_ERROR);
+ SetEvent(gWinService.stop_event_);
+ return;
+ }
+ case SERVICE_CONTROL_INTERROGATE: break;
+ default: break;
+ }
+ gWinService.reportStatus(gWinService.status_.dwCurrentState, NO_ERROR);
}
void WinService::reportStatus(DWORD dwCurrentState, DWORD dwWin32ExitCode, DWORD dwWaitHint)
@@ -172,3 +224,5 @@ void WinService::reportStatus(DWORD dwCurrentState, DWORD dwWin32ExitCode, DWORD
SetServiceStatus(status_handle_, &status_);
}
+
+#endif \ No newline at end of file
diff --git a/src/win32/winService.h b/src/win32/winService.h
index dc648d8..53c2750 100644
--- a/src/win32/winService.h
+++ b/src/win32/winService.h
@@ -32,22 +32,26 @@
#ifndef _WIN_SERVICE_H_
#define _WIN_SERVICE_H_
+#ifdef WIN_SERVICE
+
#include "../threadUtils.hpp"
class WinService
{
public:
static WinService& instance();
+ #define SVC_NAME "anytun"
+ static void install();
+ static void uninstall();
+ static void start();
- void install();
- void start();
- void waitForExit();
+ void waitForStop();
void stop();
static VOID WINAPI main(DWORD dwArgc, LPTSTR *lpszArgv);
static VOID WINAPI ctrlHandler(DWORD dwCtrl);
private:
- WinService() : name_("anytun"), started_(false) {};
+ WinService() : started_(false) {};
~WinService();
WinService(const WinService &w);
void operator=(const WinService &w);
@@ -63,14 +67,15 @@ private:
}
};
friend class instanceCleaner;
-
- std::string name_;
+
bool started_;
SERVICE_STATUS status_;
SERVICE_STATUS_HANDLE status_handle_;
- HANDLE exit_event_;
+ HANDLE stop_event_;
};
extern WinService& gWinService;
+#endif
+
#endif \ No newline at end of file