mirror of
https://github.com/PurpleI2P/i2pd.git
synced 2025-04-23 17:36:37 +02:00
service
This commit is contained in:
parent
0438fc77bd
commit
6a7224d9f3
8 changed files with 819 additions and 1 deletions
2
Win32/.gitignore
vendored
2
Win32/.gitignore
vendored
|
@ -6,3 +6,5 @@
|
||||||
!*.vcxproj
|
!*.vcxproj
|
||||||
!*.vcxproj.filters
|
!*.vcxproj.filters
|
||||||
!.gitignore
|
!.gitignore
|
||||||
|
!*.cpp
|
||||||
|
!*.h
|
||||||
|
|
502
Win32/Win32Service.cpp
Normal file
502
Win32/Win32Service.cpp
Normal file
|
@ -0,0 +1,502 @@
|
||||||
|
#include "Win32Service.h"
|
||||||
|
#include <assert.h>
|
||||||
|
#include <strsafe.h>
|
||||||
|
#include <windows.h>
|
||||||
|
|
||||||
|
#include "Transports.h"
|
||||||
|
#include "NTCPSession.h"
|
||||||
|
#include "Tunnel.h"
|
||||||
|
#include "NetDb.h"
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
|
I2PService *I2PService::s_service = NULL;
|
||||||
|
|
||||||
|
|
||||||
|
BOOL I2PService::Run(I2PService &service)
|
||||||
|
{
|
||||||
|
s_service = &service;
|
||||||
|
|
||||||
|
SERVICE_TABLE_ENTRY serviceTable[] =
|
||||||
|
{
|
||||||
|
{ service.m_name, ServiceMain },
|
||||||
|
{ NULL, NULL }
|
||||||
|
};
|
||||||
|
|
||||||
|
return StartServiceCtrlDispatcher(serviceTable);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void WINAPI I2PService::ServiceMain(DWORD dwArgc, PSTR *pszArgv)
|
||||||
|
{
|
||||||
|
assert(s_service != NULL);
|
||||||
|
|
||||||
|
s_service->m_statusHandle = RegisterServiceCtrlHandler(
|
||||||
|
s_service->m_name, ServiceCtrlHandler);
|
||||||
|
if (s_service->m_statusHandle == NULL)
|
||||||
|
{
|
||||||
|
throw GetLastError();
|
||||||
|
}
|
||||||
|
|
||||||
|
s_service->Start(dwArgc, pszArgv);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void WINAPI I2PService::ServiceCtrlHandler(DWORD dwCtrl)
|
||||||
|
{
|
||||||
|
switch (dwCtrl)
|
||||||
|
{
|
||||||
|
case SERVICE_CONTROL_STOP: s_service->Stop(); break;
|
||||||
|
case SERVICE_CONTROL_PAUSE: s_service->Pause(); break;
|
||||||
|
case SERVICE_CONTROL_CONTINUE: s_service->Continue(); break;
|
||||||
|
case SERVICE_CONTROL_SHUTDOWN: s_service->Shutdown(); break;
|
||||||
|
case SERVICE_CONTROL_INTERROGATE: break;
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
I2PService::I2PService(PSTR pszServiceName,
|
||||||
|
BOOL fCanStop,
|
||||||
|
BOOL fCanShutdown,
|
||||||
|
BOOL fCanPauseContinue) : _httpServer(nullptr)
|
||||||
|
{
|
||||||
|
m_name = (pszServiceName == NULL) ? "" : pszServiceName;
|
||||||
|
|
||||||
|
m_statusHandle = NULL;
|
||||||
|
|
||||||
|
m_status.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
|
||||||
|
|
||||||
|
m_status.dwCurrentState = SERVICE_START_PENDING;
|
||||||
|
|
||||||
|
DWORD dwControlsAccepted = 0;
|
||||||
|
if (fCanStop)
|
||||||
|
dwControlsAccepted |= SERVICE_ACCEPT_STOP;
|
||||||
|
if (fCanShutdown)
|
||||||
|
dwControlsAccepted |= SERVICE_ACCEPT_SHUTDOWN;
|
||||||
|
if (fCanPauseContinue)
|
||||||
|
dwControlsAccepted |= SERVICE_ACCEPT_PAUSE_CONTINUE;
|
||||||
|
m_status.dwControlsAccepted = dwControlsAccepted;
|
||||||
|
|
||||||
|
m_status.dwWin32ExitCode = NO_ERROR;
|
||||||
|
m_status.dwServiceSpecificExitCode = 0;
|
||||||
|
m_status.dwCheckPoint = 0;
|
||||||
|
m_status.dwWaitHint = 0;
|
||||||
|
|
||||||
|
m_fStopping = FALSE;
|
||||||
|
|
||||||
|
// Create a manual-reset event that is not signaled at first to indicate
|
||||||
|
// the stopped signal of the service.
|
||||||
|
m_hStoppedEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
|
||||||
|
if (m_hStoppedEvent == NULL)
|
||||||
|
{
|
||||||
|
throw GetLastError();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
I2PService::~I2PService(void)
|
||||||
|
{
|
||||||
|
if (m_hStoppedEvent)
|
||||||
|
{
|
||||||
|
CloseHandle(m_hStoppedEvent);
|
||||||
|
m_hStoppedEvent = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void I2PService::Start(DWORD dwArgc, PSTR *pszArgv)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
SetServiceStatus(SERVICE_START_PENDING);
|
||||||
|
|
||||||
|
OnStart(dwArgc, pszArgv);
|
||||||
|
|
||||||
|
SetServiceStatus(SERVICE_RUNNING);
|
||||||
|
}
|
||||||
|
catch (DWORD dwError)
|
||||||
|
{
|
||||||
|
WriteErrorLogEntry("Service Start", dwError);
|
||||||
|
|
||||||
|
SetServiceStatus(SERVICE_STOPPED, dwError);
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
WriteEventLogEntry("Service failed to start.", EVENTLOG_ERROR_TYPE);
|
||||||
|
|
||||||
|
SetServiceStatus(SERVICE_STOPPED);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void I2PService::OnStart(DWORD dwArgc, PSTR *pszArgv)
|
||||||
|
{
|
||||||
|
WriteEventLogEntry("CppWindowsService in OnStart",
|
||||||
|
EVENTLOG_INFORMATION_TYPE);
|
||||||
|
|
||||||
|
i2p::util::config::OptionParser(dwArgc, pszArgv);
|
||||||
|
i2p::util::filesystem::ReadConfigFile(i2p::util::config::mapArgs, i2p::util::config::mapMultiArgs);
|
||||||
|
i2p::context.OverrideNTCPAddress(i2p::util::config::GetCharArg("-host", "127.0.0.1"),
|
||||||
|
i2p::util::config::GetArg("-port", 17070));
|
||||||
|
|
||||||
|
_httpServer = new i2p::util::HTTPServer(i2p::util::config::GetArg("-httpport", 7070));
|
||||||
|
_httpServer->Start();
|
||||||
|
WriteEventLogEntry("HTTPServer started",
|
||||||
|
EVENTLOG_INFORMATION_TYPE);
|
||||||
|
i2p::data::netdb.Start();
|
||||||
|
WriteEventLogEntry("NetDB started",
|
||||||
|
EVENTLOG_INFORMATION_TYPE);
|
||||||
|
i2p::transports.Start();
|
||||||
|
WriteEventLogEntry("Transports started",
|
||||||
|
EVENTLOG_INFORMATION_TYPE);
|
||||||
|
i2p::tunnel::tunnels.Start();
|
||||||
|
WriteEventLogEntry("Tunnels started",
|
||||||
|
EVENTLOG_INFORMATION_TYPE);
|
||||||
|
_worker = new std::thread(std::bind(&I2PService::WorkerThread, this));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void I2PService::WorkerThread()
|
||||||
|
{
|
||||||
|
while (!m_fStopping)
|
||||||
|
{
|
||||||
|
::Sleep(1000); // Simulate some lengthy operations.
|
||||||
|
}
|
||||||
|
|
||||||
|
// Signal the stopped event.
|
||||||
|
SetEvent(m_hStoppedEvent);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void I2PService::Stop()
|
||||||
|
{
|
||||||
|
DWORD dwOriginalState = m_status.dwCurrentState;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
SetServiceStatus(SERVICE_STOP_PENDING);
|
||||||
|
|
||||||
|
OnStop();
|
||||||
|
|
||||||
|
SetServiceStatus(SERVICE_STOPPED);
|
||||||
|
}
|
||||||
|
catch (DWORD dwError)
|
||||||
|
{
|
||||||
|
WriteErrorLogEntry("Service Stop", dwError);
|
||||||
|
|
||||||
|
SetServiceStatus(dwOriginalState);
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
WriteEventLogEntry("Service failed to stop.", EVENTLOG_ERROR_TYPE);
|
||||||
|
|
||||||
|
SetServiceStatus(dwOriginalState);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void I2PService::OnStop()
|
||||||
|
{
|
||||||
|
// Log a service stop message to the Application log.
|
||||||
|
WriteEventLogEntry("CppWindowsService in OnStop",
|
||||||
|
EVENTLOG_INFORMATION_TYPE);
|
||||||
|
|
||||||
|
i2p::tunnel::tunnels.Stop();
|
||||||
|
WriteEventLogEntry("Tunnels stoped",
|
||||||
|
EVENTLOG_INFORMATION_TYPE);
|
||||||
|
i2p::transports.Stop();
|
||||||
|
WriteEventLogEntry("Transports stoped",
|
||||||
|
EVENTLOG_INFORMATION_TYPE);
|
||||||
|
i2p::data::netdb.Stop();
|
||||||
|
WriteEventLogEntry("NetDB stoped",
|
||||||
|
EVENTLOG_INFORMATION_TYPE);
|
||||||
|
_httpServer->Stop();
|
||||||
|
WriteEventLogEntry("HTTPServer stoped",
|
||||||
|
EVENTLOG_INFORMATION_TYPE);
|
||||||
|
delete _httpServer;
|
||||||
|
|
||||||
|
m_fStopping = TRUE;
|
||||||
|
if (WaitForSingleObject(m_hStoppedEvent, INFINITE) != WAIT_OBJECT_0)
|
||||||
|
{
|
||||||
|
throw GetLastError();
|
||||||
|
}
|
||||||
|
_worker->join();
|
||||||
|
delete _worker;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void I2PService::Pause()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
SetServiceStatus(SERVICE_PAUSE_PENDING);
|
||||||
|
|
||||||
|
OnPause();
|
||||||
|
|
||||||
|
SetServiceStatus(SERVICE_PAUSED);
|
||||||
|
}
|
||||||
|
catch (DWORD dwError)
|
||||||
|
{
|
||||||
|
WriteErrorLogEntry("Service Pause", dwError);
|
||||||
|
|
||||||
|
SetServiceStatus(SERVICE_RUNNING);
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
WriteEventLogEntry("Service failed to pause.", EVENTLOG_ERROR_TYPE);
|
||||||
|
|
||||||
|
SetServiceStatus(SERVICE_RUNNING);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void I2PService::OnPause()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void I2PService::Continue()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
SetServiceStatus(SERVICE_CONTINUE_PENDING);
|
||||||
|
|
||||||
|
OnContinue();
|
||||||
|
|
||||||
|
SetServiceStatus(SERVICE_RUNNING);
|
||||||
|
}
|
||||||
|
catch (DWORD dwError)
|
||||||
|
{
|
||||||
|
WriteErrorLogEntry("Service Continue", dwError);
|
||||||
|
|
||||||
|
SetServiceStatus(SERVICE_PAUSED);
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
WriteEventLogEntry("Service failed to resume.", EVENTLOG_ERROR_TYPE);
|
||||||
|
|
||||||
|
SetServiceStatus(SERVICE_PAUSED);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void I2PService::OnContinue()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void I2PService::Shutdown()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
OnShutdown();
|
||||||
|
|
||||||
|
SetServiceStatus(SERVICE_STOPPED);
|
||||||
|
}
|
||||||
|
catch (DWORD dwError)
|
||||||
|
{
|
||||||
|
WriteErrorLogEntry("Service Shutdown", dwError);
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
WriteEventLogEntry("Service failed to shut down.", EVENTLOG_ERROR_TYPE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void I2PService::OnShutdown()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void I2PService::SetServiceStatus(DWORD dwCurrentState,
|
||||||
|
DWORD dwWin32ExitCode,
|
||||||
|
DWORD dwWaitHint)
|
||||||
|
{
|
||||||
|
static DWORD dwCheckPoint = 1;
|
||||||
|
|
||||||
|
|
||||||
|
m_status.dwCurrentState = dwCurrentState;
|
||||||
|
m_status.dwWin32ExitCode = dwWin32ExitCode;
|
||||||
|
m_status.dwWaitHint = dwWaitHint;
|
||||||
|
|
||||||
|
m_status.dwCheckPoint =
|
||||||
|
((dwCurrentState == SERVICE_RUNNING) ||
|
||||||
|
(dwCurrentState == SERVICE_STOPPED)) ?
|
||||||
|
0 : dwCheckPoint++;
|
||||||
|
|
||||||
|
::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)
|
||||||
|
{
|
||||||
|
if (schSCManager)
|
||||||
|
{
|
||||||
|
CloseServiceHandle(schSCManager);
|
||||||
|
schSCManager = NULL;
|
||||||
|
}
|
||||||
|
if (schService)
|
||||||
|
{
|
||||||
|
CloseServiceHandle(schService);
|
||||||
|
schService = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void InstallService(PSTR pszServiceName,
|
||||||
|
PSTR pszDisplayName,
|
||||||
|
DWORD dwStartType,
|
||||||
|
PSTR pszDependencies,
|
||||||
|
PSTR pszAccount,
|
||||||
|
PSTR pszPassword)
|
||||||
|
{
|
||||||
|
char szPath[MAX_PATH];
|
||||||
|
SC_HANDLE schSCManager = NULL;
|
||||||
|
SC_HANDLE schService = NULL;
|
||||||
|
|
||||||
|
if (GetModuleFileName(NULL, szPath, ARRAYSIZE(szPath)) == 0)
|
||||||
|
{
|
||||||
|
printf("GetModuleFileName failed w/err 0x%08lx\n", GetLastError());
|
||||||
|
FreeHandles(schSCManager, schService);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Open the local default service control manager database
|
||||||
|
schSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT |
|
||||||
|
SC_MANAGER_CREATE_SERVICE);
|
||||||
|
if (schSCManager == NULL)
|
||||||
|
{
|
||||||
|
printf("OpenSCManager failed w/err 0x%08lx\n", GetLastError());
|
||||||
|
FreeHandles(schSCManager, schService);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Install the service into SCM by calling CreateService
|
||||||
|
schService = CreateService(
|
||||||
|
schSCManager, // SCManager database
|
||||||
|
pszServiceName, // Name of service
|
||||||
|
pszDisplayName, // Name to display
|
||||||
|
SERVICE_QUERY_STATUS, // Desired access
|
||||||
|
SERVICE_WIN32_OWN_PROCESS, // Service type
|
||||||
|
dwStartType, // Service start type
|
||||||
|
SERVICE_ERROR_NORMAL, // Error control type
|
||||||
|
szPath, // Service's binary
|
||||||
|
NULL, // No load ordering group
|
||||||
|
NULL, // No tag identifier
|
||||||
|
pszDependencies, // Dependencies
|
||||||
|
pszAccount, // Service running account
|
||||||
|
pszPassword // Password of the account
|
||||||
|
);
|
||||||
|
if (schService == NULL)
|
||||||
|
{
|
||||||
|
printf("CreateService failed w/err 0x%08lx\n", GetLastError());
|
||||||
|
FreeHandles(schSCManager, schService);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("%s is installed.\n", pszServiceName);
|
||||||
|
|
||||||
|
// Centralized cleanup for all allocated resources.
|
||||||
|
FreeHandles(schSCManager, schService);
|
||||||
|
}
|
||||||
|
|
||||||
|
void UninstallService(PSTR pszServiceName)
|
||||||
|
{
|
||||||
|
SC_HANDLE schSCManager = NULL;
|
||||||
|
SC_HANDLE schService = NULL;
|
||||||
|
SERVICE_STATUS ssSvcStatus = {};
|
||||||
|
|
||||||
|
// Open the local default service control manager database
|
||||||
|
schSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT);
|
||||||
|
if (schSCManager == NULL)
|
||||||
|
{
|
||||||
|
printf("OpenSCManager failed w/err 0x%08lx\n", GetLastError());
|
||||||
|
FreeHandles(schSCManager, schService);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Open the service with delete, stop, and query status permissions
|
||||||
|
schService = OpenService(schSCManager, pszServiceName, SERVICE_STOP |
|
||||||
|
SERVICE_QUERY_STATUS | DELETE);
|
||||||
|
if (schService == NULL)
|
||||||
|
{
|
||||||
|
printf("OpenService failed w/err 0x%08lx\n", GetLastError());
|
||||||
|
FreeHandles(schSCManager, schService);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try to stop the service
|
||||||
|
if (ControlService(schService, SERVICE_CONTROL_STOP, &ssSvcStatus))
|
||||||
|
{
|
||||||
|
printf("Stopping %s.", pszServiceName);
|
||||||
|
Sleep(1000);
|
||||||
|
|
||||||
|
while (QueryServiceStatus(schService, &ssSvcStatus))
|
||||||
|
{
|
||||||
|
if (ssSvcStatus.dwCurrentState == SERVICE_STOP_PENDING)
|
||||||
|
{
|
||||||
|
printf(".");
|
||||||
|
Sleep(1000);
|
||||||
|
}
|
||||||
|
else break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ssSvcStatus.dwCurrentState == SERVICE_STOPPED)
|
||||||
|
{
|
||||||
|
printf("\n%s is stopped.\n", pszServiceName);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf("\n%s failed to stop.\n", pszServiceName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now remove the service by calling DeleteService.
|
||||||
|
if (!DeleteService(schService))
|
||||||
|
{
|
||||||
|
printf("DeleteService failed w/err 0x%08lx\n", GetLastError());
|
||||||
|
FreeHandles(schSCManager, schService);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("%s is removed.\n", pszServiceName);
|
||||||
|
|
||||||
|
// Centralized cleanup for all allocated resources.
|
||||||
|
FreeHandles(schSCManager, schService);
|
||||||
|
}
|
66
Win32/Win32Service.h
Normal file
66
Win32/Win32Service.h
Normal file
|
@ -0,0 +1,66 @@
|
||||||
|
#ifndef WIN_32_SERVICE_H__
|
||||||
|
#define WIN_32_SERVICE_H__
|
||||||
|
|
||||||
|
#include "HTTPServer.h"
|
||||||
|
#include <thread>
|
||||||
|
#define WIN32_LEAN_AND_MEAN
|
||||||
|
#include <windows.h>
|
||||||
|
|
||||||
|
class I2PService
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
I2PService(PSTR pszServiceName,
|
||||||
|
BOOL fCanStop = TRUE,
|
||||||
|
BOOL fCanShutdown = TRUE,
|
||||||
|
BOOL fCanPauseContinue = FALSE);
|
||||||
|
|
||||||
|
virtual ~I2PService(void);
|
||||||
|
|
||||||
|
static BOOL Run(I2PService &service);
|
||||||
|
void Stop();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
virtual void OnStart(DWORD dwArgc, PSTR *pszArgv);
|
||||||
|
virtual void OnStop();
|
||||||
|
virtual void OnPause();
|
||||||
|
virtual void OnContinue();
|
||||||
|
virtual void OnShutdown();
|
||||||
|
void SetServiceStatus(DWORD dwCurrentState,
|
||||||
|
DWORD dwWin32ExitCode = NO_ERROR,
|
||||||
|
DWORD dwWaitHint = 0);
|
||||||
|
void WriteEventLogEntry(PSTR pszMessage, WORD wType);
|
||||||
|
void WriteErrorLogEntry(PSTR pszFunction,
|
||||||
|
DWORD dwError = GetLastError());
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
static void WINAPI ServiceMain(DWORD dwArgc, LPSTR *lpszArgv);
|
||||||
|
static void WINAPI ServiceCtrlHandler(DWORD dwCtrl);
|
||||||
|
void WorkerThread();
|
||||||
|
void Start(DWORD dwArgc, PSTR *pszArgv);
|
||||||
|
void Pause();
|
||||||
|
void Continue();
|
||||||
|
void Shutdown();
|
||||||
|
static I2PService* s_service;
|
||||||
|
PSTR m_name;
|
||||||
|
SERVICE_STATUS m_status;
|
||||||
|
SERVICE_STATUS_HANDLE m_statusHandle;
|
||||||
|
|
||||||
|
BOOL m_fStopping;
|
||||||
|
HANDLE m_hStoppedEvent;
|
||||||
|
i2p::util::HTTPServer* _httpServer;
|
||||||
|
std::thread* _worker;
|
||||||
|
};
|
||||||
|
|
||||||
|
void InstallService(PSTR pszServiceName,
|
||||||
|
PSTR pszDisplayName,
|
||||||
|
DWORD dwStartType,
|
||||||
|
PSTR pszDependencies,
|
||||||
|
PSTR pszAccount,
|
||||||
|
PSTR pszPassword);
|
||||||
|
|
||||||
|
void UninstallService(PSTR pszServiceName);
|
||||||
|
|
||||||
|
#endif // WIN_32_SERVICE_H__
|
|
@ -8,13 +8,19 @@ EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|Win32 = Debug|Win32
|
Debug|Win32 = Debug|Win32
|
||||||
|
Debug|x64 = Debug|x64
|
||||||
Release|Win32 = Release|Win32
|
Release|Win32 = Release|Win32
|
||||||
|
Release|x64 = Release|x64
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
{930568EC-31C9-406A-AD1C-9636DF5D8FAA}.Debug|Win32.ActiveCfg = Debug|Win32
|
{930568EC-31C9-406A-AD1C-9636DF5D8FAA}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||||
{930568EC-31C9-406A-AD1C-9636DF5D8FAA}.Debug|Win32.Build.0 = Debug|Win32
|
{930568EC-31C9-406A-AD1C-9636DF5D8FAA}.Debug|Win32.Build.0 = Debug|Win32
|
||||||
|
{930568EC-31C9-406A-AD1C-9636DF5D8FAA}.Debug|x64.ActiveCfg = Debug|x64
|
||||||
|
{930568EC-31C9-406A-AD1C-9636DF5D8FAA}.Debug|x64.Build.0 = Debug|x64
|
||||||
{930568EC-31C9-406A-AD1C-9636DF5D8FAA}.Release|Win32.ActiveCfg = Release|Win32
|
{930568EC-31C9-406A-AD1C-9636DF5D8FAA}.Release|Win32.ActiveCfg = Release|Win32
|
||||||
{930568EC-31C9-406A-AD1C-9636DF5D8FAA}.Release|Win32.Build.0 = Release|Win32
|
{930568EC-31C9-406A-AD1C-9636DF5D8FAA}.Release|Win32.Build.0 = Release|Win32
|
||||||
|
{930568EC-31C9-406A-AD1C-9636DF5D8FAA}.Release|x64.ActiveCfg = Release|x64
|
||||||
|
{930568EC-31C9-406A-AD1C-9636DF5D8FAA}.Release|x64.Build.0 = Release|x64
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
|
|
|
@ -5,10 +5,18 @@
|
||||||
<Configuration>Debug</Configuration>
|
<Configuration>Debug</Configuration>
|
||||||
<Platform>Win32</Platform>
|
<Platform>Win32</Platform>
|
||||||
</ProjectConfiguration>
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Debug|x64">
|
||||||
|
<Configuration>Debug</Configuration>
|
||||||
|
<Platform>x64</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
<ProjectConfiguration Include="Release|Win32">
|
<ProjectConfiguration Include="Release|Win32">
|
||||||
<Configuration>Release</Configuration>
|
<Configuration>Release</Configuration>
|
||||||
<Platform>Win32</Platform>
|
<Platform>Win32</Platform>
|
||||||
</ProjectConfiguration>
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Release|x64">
|
||||||
|
<Configuration>Release</Configuration>
|
||||||
|
<Platform>x64</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="..\base64.cpp" />
|
<ClCompile Include="..\base64.cpp" />
|
||||||
|
@ -33,6 +41,7 @@
|
||||||
<ClCompile Include="..\TunnelEndpoint.cpp" />
|
<ClCompile Include="..\TunnelEndpoint.cpp" />
|
||||||
<ClCompile Include="..\TunnelGateway.cpp" />
|
<ClCompile Include="..\TunnelGateway.cpp" />
|
||||||
<ClCompile Include="..\util.cpp" />
|
<ClCompile Include="..\util.cpp" />
|
||||||
|
<ClCompile Include="Win32Service.cpp" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="..\base64.h" />
|
<ClInclude Include="..\base64.h" />
|
||||||
|
@ -63,6 +72,7 @@
|
||||||
<ClInclude Include="..\TunnelEndpoint.h" />
|
<ClInclude Include="..\TunnelEndpoint.h" />
|
||||||
<ClInclude Include="..\TunnelGateway.h" />
|
<ClInclude Include="..\TunnelGateway.h" />
|
||||||
<ClInclude Include="..\util.h" />
|
<ClInclude Include="..\util.h" />
|
||||||
|
<ClInclude Include="Win32Service.h" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<PropertyGroup Label="Globals">
|
<PropertyGroup Label="Globals">
|
||||||
<ProjectGuid>{930568EC-31C9-406A-AD1C-9636DF5D8FAA}</ProjectGuid>
|
<ProjectGuid>{930568EC-31C9-406A-AD1C-9636DF5D8FAA}</ProjectGuid>
|
||||||
|
@ -75,6 +85,12 @@
|
||||||
<PlatformToolset>v120</PlatformToolset>
|
<PlatformToolset>v120</PlatformToolset>
|
||||||
<CharacterSet>MultiByte</CharacterSet>
|
<CharacterSet>MultiByte</CharacterSet>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<UseDebugLibraries>true</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v120</PlatformToolset>
|
||||||
|
<CharacterSet>MultiByte</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||||
<ConfigurationType>Application</ConfigurationType>
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
<UseDebugLibraries>false</UseDebugLibraries>
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
|
@ -82,25 +98,47 @@
|
||||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
<CharacterSet>MultiByte</CharacterSet>
|
<CharacterSet>MultiByte</CharacterSet>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v120</PlatformToolset>
|
||||||
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
|
<CharacterSet>MultiByte</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||||
<ImportGroup Label="ExtensionSettings">
|
<ImportGroup Label="ExtensionSettings">
|
||||||
</ImportGroup>
|
</ImportGroup>
|
||||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
</ImportGroup>
|
</ImportGroup>
|
||||||
|
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
</ImportGroup>
|
</ImportGroup>
|
||||||
|
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
<PropertyGroup Label="UserMacros" />
|
<PropertyGroup Label="UserMacros" />
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
<IncludePath>./..;$(BOOST);$(CRYPTOPP);$(IncludePath)</IncludePath>
|
<IncludePath>./..;$(BOOST);$(CRYPTOPP);$(IncludePath)</IncludePath>
|
||||||
<LibraryPath>$(BOOST)\stage\lib;$(CRYPTOPP)\cryptopp\Win32\Output\$(Configuration)\;$(LibraryPath)</LibraryPath>
|
<LibraryPath>$(BOOST)\stage\lib;$(CRYPTOPP)\cryptopp\Win32\Output\$(Configuration)\;$(LibraryPath)</LibraryPath>
|
||||||
<SourcePath>./..;$(VC_SourcePath);</SourcePath>
|
<SourcePath>./..;$(VC_SourcePath);</SourcePath>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
|
<IncludePath>./..;$(BOOST);$(CRYPTOPP);$(IncludePath)</IncludePath>
|
||||||
|
<LibraryPath>$(BOOST)\stage\lib;$(CRYPTOPP)\cryptopp\Win32\Output\$(Configuration)\;$(LibraryPath)</LibraryPath>
|
||||||
|
<SourcePath>./..;$(VC_SourcePath);</SourcePath>
|
||||||
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
<IncludePath>.\boost;.\cryptopp;$(IncludePath)</IncludePath>
|
<IncludePath>.\boost;.\cryptopp;$(IncludePath)</IncludePath>
|
||||||
<LibraryPath>.\stage-x86\lib;$(LibraryPath)</LibraryPath>
|
<LibraryPath>.\stage-x86\lib;$(LibraryPath)</LibraryPath>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
|
<IncludePath>.\boost;.\cryptopp;$(IncludePath)</IncludePath>
|
||||||
|
<LibraryPath>.\stage-x86\lib;$(LibraryPath)</LibraryPath>
|
||||||
|
</PropertyGroup>
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
<ClCompile>
|
<ClCompile>
|
||||||
<WarningLevel>Level3</WarningLevel>
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
@ -114,6 +152,19 @@
|
||||||
<AdditionalDependencies>cryptlib.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
<AdditionalDependencies>cryptlib.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
</Link>
|
</Link>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
|
<ClCompile>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<Optimization>Disabled</Optimization>
|
||||||
|
<SDLCheck>true</SDLCheck>
|
||||||
|
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
||||||
|
<PreprocessorDefinitions>_MBCS;_WIN32_WINNT=0x0501;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
<AdditionalDependencies>cryptlib.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
<ClCompile>
|
<ClCompile>
|
||||||
<WarningLevel>Level3</WarningLevel>
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
@ -128,6 +179,20 @@
|
||||||
<OptimizeReferences>true</OptimizeReferences>
|
<OptimizeReferences>true</OptimizeReferences>
|
||||||
</Link>
|
</Link>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
|
<ClCompile>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<Optimization>MaxSpeed</Optimization>
|
||||||
|
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||||
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
|
<SDLCheck>true</SDLCheck>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||||
|
<OptimizeReferences>true</OptimizeReferences>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
<ImportGroup Label="ExtensionTargets">
|
<ImportGroup Label="ExtensionTargets">
|
||||||
</ImportGroup>
|
</ImportGroup>
|
||||||
|
|
|
@ -81,6 +81,9 @@
|
||||||
<ClCompile Include="..\Reseed.cpp">
|
<ClCompile Include="..\Reseed.cpp">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="Win32Service.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="..\Identity.h">
|
<ClInclude Include="..\Identity.h">
|
||||||
|
@ -167,5 +170,8 @@
|
||||||
<ClInclude Include="..\Reseed.h">
|
<ClInclude Include="..\Reseed.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="Win32Service.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
58
i2p.cpp
58
i2p.cpp
|
@ -11,6 +11,8 @@
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#else
|
||||||
|
#include "./Win32/Win32Service.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "Log.h"
|
#include "Log.h"
|
||||||
|
@ -25,6 +27,26 @@
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
// Internal name of the service
|
||||||
|
#define SERVICE_NAME "i2pService"
|
||||||
|
|
||||||
|
// Displayed name of the service
|
||||||
|
#define SERVICE_DISPLAY_NAME "i2p router service"
|
||||||
|
|
||||||
|
// Service start options.
|
||||||
|
#define SERVICE_START_TYPE SERVICE_DEMAND_START
|
||||||
|
|
||||||
|
// List of service dependencies - "dep1\0dep2\0\0"
|
||||||
|
#define SERVICE_DEPENDENCIES ""
|
||||||
|
|
||||||
|
// The name of the account under which the service should run
|
||||||
|
#define SERVICE_ACCOUNT "NT AUTHORITY\\LocalService"
|
||||||
|
|
||||||
|
// The password to the service account name
|
||||||
|
#define SERVICE_PASSWORD NULL
|
||||||
|
#endif
|
||||||
|
|
||||||
// Global
|
// Global
|
||||||
int running = 1;
|
int running = 1;
|
||||||
int isDaemon;
|
int isDaemon;
|
||||||
|
@ -60,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", 0);
|
isDaemon = i2p::util::config::GetArg("-daemon", 1);
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
setlocale(LC_CTYPE, "");
|
setlocale(LC_CTYPE, "");
|
||||||
SetConsoleCP(1251);
|
SetConsoleCP(1251);
|
||||||
|
@ -139,6 +161,40 @@ 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.
|
||||||
|
|
115
portable_endian.h
Normal file
115
portable_endian.h
Normal file
|
@ -0,0 +1,115 @@
|
||||||
|
#ifndef PORTABLE_ENDIAN_H__
|
||||||
|
#define PORTABLE_ENDIAN_H__
|
||||||
|
|
||||||
|
#if (defined(_WIN16) || defined(_WIN32) || defined(_WIN64)) && !defined(__WINDOWS__)
|
||||||
|
|
||||||
|
# define __WINDOWS__
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(__linux__) || defined(__CYGWIN__)
|
||||||
|
|
||||||
|
# include <endian.h>
|
||||||
|
|
||||||
|
#elif defined(__APPLE__)
|
||||||
|
|
||||||
|
# include <libkern/OSByteOrder.h>
|
||||||
|
|
||||||
|
# define htobe16 OSSwapHostToBigInt16
|
||||||
|
# define htole16 OSSwapHostToLittleInt16
|
||||||
|
# define be16toh OSSwapBigToHostInt16
|
||||||
|
# define le16toh OSSwapLittleToHostInt16
|
||||||
|
|
||||||
|
# define htobe32 OSSwapHostToBigInt32
|
||||||
|
# define htole32 OSSwapHostToLittleInt32
|
||||||
|
# define be32toh OSSwapBigToHostInt32
|
||||||
|
# define le32toh OSSwapLittleToHostInt32
|
||||||
|
|
||||||
|
# define htobe64 OSSwapHostToBigInt64
|
||||||
|
# define htole64 OSSwapHostToLittleInt64
|
||||||
|
# define be64toh OSSwapBigToHostInt64
|
||||||
|
# define le64toh OSSwapLittleToHostInt64
|
||||||
|
|
||||||
|
# define __BYTE_ORDER BYTE_ORDER
|
||||||
|
# define __BIG_ENDIAN BIG_ENDIAN
|
||||||
|
# define __LITTLE_ENDIAN LITTLE_ENDIAN
|
||||||
|
# define __PDP_ENDIAN PDP_ENDIAN
|
||||||
|
|
||||||
|
#elif defined(__OpenBSD__)
|
||||||
|
|
||||||
|
# include <sys/endian.h>
|
||||||
|
|
||||||
|
#elif defined(__NetBSD__) || defined(__FreeBSD__) || defined(__DragonFly__)
|
||||||
|
|
||||||
|
# include <sys/endian.h>
|
||||||
|
|
||||||
|
# define be16toh betoh16
|
||||||
|
# define le16toh letoh16
|
||||||
|
|
||||||
|
# define be32toh betoh32
|
||||||
|
# define le32toh letoh32
|
||||||
|
|
||||||
|
# define be64toh betoh64
|
||||||
|
# define le64toh letoh64
|
||||||
|
|
||||||
|
#elif defined(__WINDOWS__)
|
||||||
|
|
||||||
|
#define INCL_EXTRA_HTON_FUNCTIONS
|
||||||
|
#define NOMINMAX
|
||||||
|
# include <winsock2.h>
|
||||||
|
#undef NOMINMAX
|
||||||
|
//# include <sys/param.h>
|
||||||
|
|
||||||
|
# if BYTE_ORDER == LITTLE_ENDIAN
|
||||||
|
|
||||||
|
# define htobe16 htons
|
||||||
|
# define htole16(x) (x)
|
||||||
|
# define be16toh ntohs
|
||||||
|
# define le16toh(x) (x)
|
||||||
|
|
||||||
|
# define htobe32 htonl
|
||||||
|
# define htole32(x) (x)
|
||||||
|
# define be32toh ntohl
|
||||||
|
# define le32toh(x) (x)
|
||||||
|
|
||||||
|
# define htobe64 htonll
|
||||||
|
# define htole64(x) (x)
|
||||||
|
# define be64toh ntohll
|
||||||
|
# define le64toh(x) (x)
|
||||||
|
|
||||||
|
# elif BYTE_ORDER == BIG_ENDIAN
|
||||||
|
|
||||||
|
/* that would be xbox 360 */
|
||||||
|
# define htobe16(x) (x)
|
||||||
|
# define htole16(x) __builtin_bswap16(x)
|
||||||
|
# define be16toh(x) (x)
|
||||||
|
# define le16toh(x) __builtin_bswap16(x)
|
||||||
|
|
||||||
|
# define htobe32(x) (x)
|
||||||
|
# define htole32(x) __builtin_bswap32(x)
|
||||||
|
# define be32toh(x) (x)
|
||||||
|
# define le32toh(x) __builtin_bswap32(x)
|
||||||
|
|
||||||
|
# define htobe64(x) (x)
|
||||||
|
# define htole64(x) __builtin_bswap64(x)
|
||||||
|
# define be64toh(x) (x)
|
||||||
|
# define le64toh(x) __builtin_bswap64(x)
|
||||||
|
|
||||||
|
# else
|
||||||
|
|
||||||
|
# error byte order not supported
|
||||||
|
|
||||||
|
# endif
|
||||||
|
|
||||||
|
# define __BYTE_ORDER BYTE_ORDER
|
||||||
|
# define __BIG_ENDIAN BIG_ENDIAN
|
||||||
|
# define __LITTLE_ENDIAN LITTLE_ENDIAN
|
||||||
|
# define __PDP_ENDIAN PDP_ENDIAN
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
# error platform not supported
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
Loading…
Add table
Reference in a new issue