win32_service

This commit is contained in:
mikhail4021 2014-02-22 12:01:51 +04:00
parent 6a7224d9f3
commit 7f57980c20
5 changed files with 86 additions and 98 deletions

View file

@ -99,6 +99,13 @@ namespace util
public: public:
MsgQueue (): m_Thread (std::bind (&MsgQueue<Msg>::Run, this)) , running(1) {}; MsgQueue (): m_Thread (std::bind (&MsgQueue<Msg>::Run, this)) , running(1) {};
/*
~MsgQueue()
{
WakeUp();
Stop();
}
*/
void Stop() void Stop()
{ {
running = 0; running = 0;
@ -109,7 +116,7 @@ namespace util
void Run () void Run ()
{ {
Msg * msg = nullptr; Msg * msg = nullptr;
while ((msg = Queue<Msg>::GetNext ()) != nullptr && running) while (((msg = Queue<Msg>::GetNext ()) != nullptr) && running)
{ {
msg->Process (); msg->Process ();
delete msg; delete msg;

View file

@ -66,8 +66,11 @@ namespace i2p
m_NTCPSessions.clear (); m_NTCPSessions.clear ();
delete m_NTCPAcceptor; delete m_NTCPAcceptor;
m_Timer->cancel (); if (m_Timer)
delete m_Timer; {
m_Timer->cancel();
delete m_Timer;
}
if (m_SSUServer) if (m_SSUServer)
{ {

View file

@ -3,6 +3,7 @@
#include <strsafe.h> #include <strsafe.h>
#include <windows.h> #include <windows.h>
#include "Log.h"
#include "Transports.h" #include "Transports.h"
#include "NTCPSession.h" #include "NTCPSession.h"
#include "Tunnel.h" #include "Tunnel.h"
@ -116,13 +117,13 @@ void I2PService::Start(DWORD dwArgc, PSTR *pszArgv)
} }
catch (DWORD dwError) catch (DWORD dwError)
{ {
WriteErrorLogEntry("Service Start", dwError); LogPrint("Service Start", dwError);
SetServiceStatus(SERVICE_STOPPED, dwError); SetServiceStatus(SERVICE_STOPPED, dwError);
} }
catch (...) catch (...)
{ {
WriteEventLogEntry("Service failed to start.", EVENTLOG_ERROR_TYPE); LogPrint("Service failed to start.", EVENTLOG_ERROR_TYPE);
SetServiceStatus(SERVICE_STOPPED); SetServiceStatus(SERVICE_STOPPED);
} }
@ -131,7 +132,7 @@ void I2PService::Start(DWORD dwArgc, PSTR *pszArgv)
void I2PService::OnStart(DWORD dwArgc, PSTR *pszArgv) void I2PService::OnStart(DWORD dwArgc, PSTR *pszArgv)
{ {
WriteEventLogEntry("CppWindowsService in OnStart", LogPrint("CppWindowsService in OnStart",
EVENTLOG_INFORMATION_TYPE); EVENTLOG_INFORMATION_TYPE);
i2p::util::config::OptionParser(dwArgc, pszArgv); i2p::util::config::OptionParser(dwArgc, pszArgv);
@ -141,16 +142,16 @@ void I2PService::OnStart(DWORD dwArgc, PSTR *pszArgv)
_httpServer = new i2p::util::HTTPServer(i2p::util::config::GetArg("-httpport", 7070)); _httpServer = new i2p::util::HTTPServer(i2p::util::config::GetArg("-httpport", 7070));
_httpServer->Start(); _httpServer->Start();
WriteEventLogEntry("HTTPServer started", LogPrint("HTTPServer started",
EVENTLOG_INFORMATION_TYPE); EVENTLOG_INFORMATION_TYPE);
i2p::data::netdb.Start(); i2p::data::netdb.Start();
WriteEventLogEntry("NetDB started", LogPrint("NetDB started",
EVENTLOG_INFORMATION_TYPE); EVENTLOG_INFORMATION_TYPE);
i2p::transports.Start(); i2p::transports.Start();
WriteEventLogEntry("Transports started", LogPrint("Transports started",
EVENTLOG_INFORMATION_TYPE); EVENTLOG_INFORMATION_TYPE);
i2p::tunnel::tunnels.Start(); i2p::tunnel::tunnels.Start();
WriteEventLogEntry("Tunnels started", LogPrint("Tunnels started",
EVENTLOG_INFORMATION_TYPE); EVENTLOG_INFORMATION_TYPE);
_worker = new std::thread(std::bind(&I2PService::WorkerThread, this)); _worker = new std::thread(std::bind(&I2PService::WorkerThread, this));
} }
@ -181,13 +182,13 @@ void I2PService::Stop()
} }
catch (DWORD dwError) catch (DWORD dwError)
{ {
WriteErrorLogEntry("Service Stop", dwError); LogPrint("Service Stop", dwError);
SetServiceStatus(dwOriginalState); SetServiceStatus(dwOriginalState);
} }
catch (...) catch (...)
{ {
WriteEventLogEntry("Service failed to stop.", EVENTLOG_ERROR_TYPE); LogPrint("Service failed to stop.", EVENTLOG_ERROR_TYPE);
SetServiceStatus(dwOriginalState); SetServiceStatus(dwOriginalState);
} }
@ -197,20 +198,20 @@ void I2PService::Stop()
void I2PService::OnStop() void I2PService::OnStop()
{ {
// Log a service stop message to the Application log. // Log a service stop message to the Application log.
WriteEventLogEntry("CppWindowsService in OnStop", LogPrint("CppWindowsService in OnStop",
EVENTLOG_INFORMATION_TYPE); EVENTLOG_INFORMATION_TYPE);
i2p::tunnel::tunnels.Stop(); i2p::tunnel::tunnels.Stop();
WriteEventLogEntry("Tunnels stoped", LogPrint("Tunnels stoped",
EVENTLOG_INFORMATION_TYPE); EVENTLOG_INFORMATION_TYPE);
i2p::transports.Stop(); i2p::transports.Stop();
WriteEventLogEntry("Transports stoped", LogPrint("Transports stoped",
EVENTLOG_INFORMATION_TYPE); EVENTLOG_INFORMATION_TYPE);
i2p::data::netdb.Stop(); i2p::data::netdb.Stop();
WriteEventLogEntry("NetDB stoped", LogPrint("NetDB stoped",
EVENTLOG_INFORMATION_TYPE); EVENTLOG_INFORMATION_TYPE);
_httpServer->Stop(); _httpServer->Stop();
WriteEventLogEntry("HTTPServer stoped", LogPrint("HTTPServer stoped",
EVENTLOG_INFORMATION_TYPE); EVENTLOG_INFORMATION_TYPE);
delete _httpServer; delete _httpServer;
@ -236,13 +237,13 @@ void I2PService::Pause()
} }
catch (DWORD dwError) catch (DWORD dwError)
{ {
WriteErrorLogEntry("Service Pause", dwError); LogPrint("Service Pause", dwError);
SetServiceStatus(SERVICE_RUNNING); SetServiceStatus(SERVICE_RUNNING);
} }
catch (...) catch (...)
{ {
WriteEventLogEntry("Service failed to pause.", EVENTLOG_ERROR_TYPE); LogPrint("Service failed to pause.", EVENTLOG_ERROR_TYPE);
SetServiceStatus(SERVICE_RUNNING); SetServiceStatus(SERVICE_RUNNING);
} }
@ -266,13 +267,13 @@ void I2PService::Continue()
} }
catch (DWORD dwError) catch (DWORD dwError)
{ {
WriteErrorLogEntry("Service Continue", dwError); LogPrint("Service Continue", dwError);
SetServiceStatus(SERVICE_PAUSED); SetServiceStatus(SERVICE_PAUSED);
} }
catch (...) catch (...)
{ {
WriteEventLogEntry("Service failed to resume.", EVENTLOG_ERROR_TYPE); LogPrint("Service failed to resume.", EVENTLOG_ERROR_TYPE);
SetServiceStatus(SERVICE_PAUSED); SetServiceStatus(SERVICE_PAUSED);
} }
@ -294,11 +295,11 @@ void I2PService::Shutdown()
} }
catch (DWORD dwError) catch (DWORD dwError)
{ {
WriteErrorLogEntry("Service Shutdown", dwError); LogPrint("Service Shutdown", dwError);
} }
catch (...) catch (...)
{ {
WriteEventLogEntry("Service failed to shut down.", EVENTLOG_ERROR_TYPE); LogPrint("Service failed to shut down.", EVENTLOG_ERROR_TYPE);
} }
} }
@ -327,42 +328,6 @@ void I2PService::SetServiceStatus(DWORD dwCurrentState,
::SetServiceStatus(m_statusHandle, &m_status); ::SetServiceStatus(m_statusHandle, &m_status);
} }
void I2PService::WriteEventLogEntry(PSTR pszMessage, WORD wType)
{
HANDLE hEventSource = NULL;
LPCSTR lpszStrings[2] = { NULL, NULL };
hEventSource = RegisterEventSource(NULL, m_name);
if (hEventSource)
{
lpszStrings[0] = m_name;
lpszStrings[1] = pszMessage;
ReportEvent(hEventSource, // Event log handle
wType, // Event type
0, // Event category
0, // Event identifier
NULL, // No security identifier
2, // Size of lpszStrings array
0, // No binary data
lpszStrings, // Array of strings
NULL // No binary data
);
DeregisterEventSource(hEventSource);
}
}
void I2PService::WriteErrorLogEntry(PSTR pszFunction, DWORD dwError)
{
char szMessage[260];
StringCchPrintf(szMessage, ARRAYSIZE(szMessage),
"%s failed w/err 0x%08lx", pszFunction, dwError);
WriteEventLogEntry(szMessage, EVENTLOG_ERROR_TYPE);
}
//***************************************************************************** //*****************************************************************************
void FreeHandles(SC_HANDLE schSCManager, SC_HANDLE schService) void FreeHandles(SC_HANDLE schSCManager, SC_HANDLE schService)

View file

@ -30,9 +30,6 @@ protected:
void SetServiceStatus(DWORD dwCurrentState, void SetServiceStatus(DWORD dwCurrentState,
DWORD dwWin32ExitCode = NO_ERROR, DWORD dwWin32ExitCode = NO_ERROR,
DWORD dwWaitHint = 0); DWORD dwWaitHint = 0);
void WriteEventLogEntry(PSTR pszMessage, WORD wType);
void WriteErrorLogEntry(PSTR pszFunction,
DWORD dwError = GetLastError());
private: private:

88
i2p.cpp
View file

@ -82,7 +82,7 @@ void handle_signal(int sig)
int main( int argc, char* argv[] ) int main( int argc, char* argv[] )
{ {
i2p::util::config::OptionParser(argc,argv); i2p::util::config::OptionParser(argc,argv);
isDaemon = i2p::util::config::GetArg("-daemon", 1); isDaemon = i2p::util::config::GetArg("-daemon", 0);
#ifdef _WIN32 #ifdef _WIN32
setlocale(LC_CTYPE, ""); setlocale(LC_CTYPE, "");
SetConsoleCP(1251); SetConsoleCP(1251);
@ -95,6 +95,50 @@ int main( int argc, char* argv[] )
LogPrint("data directory: ", i2p::util::filesystem::GetDataDir().string()); LogPrint("data directory: ", i2p::util::filesystem::GetDataDir().string());
i2p::util::filesystem::ReadConfigFile(i2p::util::config::mapArgs, i2p::util::config::mapMultiArgs); i2p::util::filesystem::ReadConfigFile(i2p::util::config::mapArgs, i2p::util::config::mapMultiArgs);
#ifdef _WIN32
std::string serviceControl = i2p::util::config::GetArg("-service", "none");
if (serviceControl == "install")
{
InstallService(
SERVICE_NAME, // Name of service
SERVICE_DISPLAY_NAME, // Name to display
SERVICE_START_TYPE, // Service start type
SERVICE_DEPENDENCIES, // Dependencies
SERVICE_ACCOUNT, // Service running account
SERVICE_PASSWORD // Password of the account
);
return 0;
}
else if (serviceControl == "remove")
{
UninstallService(SERVICE_NAME);
return 0;
}
else if (serviceControl != "none")
{
printf(" --service=install to install the service.\n");
printf(" --service=remove to remove the service.\n");
return 0;
}
else if (isDaemon)
{
std::string logfile = i2p::util::filesystem::GetDataDir().string();
logfile.append("\\debug.log");
FILE* openResult = freopen(logfile.c_str(), "a", stdout);
if (!openResult)
{
return -17;
}
LogPrint("Service logging enabled.");
I2PService service(SERVICE_NAME);
if (!I2PService::Run(service))
{
LogPrint("Service failed to run w/err 0x%08lx\n", GetLastError());
}
return 0;
}
#endif
int isLogging = i2p::util::config::GetArg("-log", 0); int isLogging = i2p::util::config::GetArg("-log", 0);
if (isLogging == 1) if (isLogging == 1)
{ {
@ -104,7 +148,13 @@ int main( int argc, char* argv[] )
#else #else
logfile.append("\\debug.log"); logfile.append("\\debug.log");
#endif #endif
freopen(logfile.c_str(),"a",stdout); FILE* openResult = freopen(logfile.c_str(),"a",stdout);
// It seems that we need to add FLUSH() for LogPrint and call it in some important places
if (!openResult)
{
LogPrint("Can't do [freopen()].");
return -17;
}
LogPrint("Logging to file enabled."); LogPrint("Logging to file enabled.");
} }
@ -161,40 +211,6 @@ int main( int argc, char* argv[] )
sigaction(SIGABRT,&sa,0); sigaction(SIGABRT,&sa,0);
sigaction(SIGTERM,&sa,0); sigaction(SIGTERM,&sa,0);
sigaction(SIGINT,&sa,0); sigaction(SIGINT,&sa,0);
#else
std::string serviceControl = i2p::util::config::GetArg("-service", "none");
if (serviceControl == "install")
{
InstallService(
SERVICE_NAME, // Name of service
SERVICE_DISPLAY_NAME, // Name to display
SERVICE_START_TYPE, // Service start type
SERVICE_DEPENDENCIES, // Dependencies
SERVICE_ACCOUNT, // Service running account
SERVICE_PASSWORD // Password of the account
);
return 0;
}
else if (serviceControl == "remove")
{
UninstallService(SERVICE_NAME);
return 0;
}
else if (serviceControl != "none")
{
LogPrint(" --service=install to install the service.");
LogPrint(" --service=remove to remove the service.");
return -1;
}
else if (isDaemon)
{
I2PService service(SERVICE_NAME);
if (!I2PService::Run(service))
{
LogPrint("Service failed to run w/err 0x%08lx\n", GetLastError());
}
return 0;
}
#endif #endif
//TODO: This is an ugly workaround. fix it. //TODO: This is an ugly workaround. fix it.