|
|
@ -15,7 +15,6 @@ I2PService *I2PService::s_service = NULL; |
|
|
|
BOOL I2PService::isService() |
|
|
|
BOOL I2PService::isService() |
|
|
|
{ |
|
|
|
{ |
|
|
|
BOOL bIsService = FALSE; |
|
|
|
BOOL bIsService = FALSE; |
|
|
|
|
|
|
|
|
|
|
|
HWINSTA hWinStation = GetProcessWindowStation(); |
|
|
|
HWINSTA hWinStation = GetProcessWindowStation(); |
|
|
|
if (hWinStation != NULL) |
|
|
|
if (hWinStation != NULL) |
|
|
|
{ |
|
|
|
{ |
|
|
@ -31,28 +30,23 @@ BOOL I2PService::isService() |
|
|
|
BOOL I2PService::Run(I2PService &service) |
|
|
|
BOOL I2PService::Run(I2PService &service) |
|
|
|
{ |
|
|
|
{ |
|
|
|
s_service = &service; |
|
|
|
s_service = &service; |
|
|
|
|
|
|
|
|
|
|
|
SERVICE_TABLE_ENTRY serviceTable[] = |
|
|
|
SERVICE_TABLE_ENTRY serviceTable[] = |
|
|
|
{ |
|
|
|
{ |
|
|
|
{ service.m_name, ServiceMain }, |
|
|
|
{ service.m_name, ServiceMain }, |
|
|
|
{ NULL, NULL } |
|
|
|
{ NULL, NULL } |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
return StartServiceCtrlDispatcher(serviceTable); |
|
|
|
return StartServiceCtrlDispatcher(serviceTable); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void WINAPI I2PService::ServiceMain(DWORD dwArgc, PSTR *pszArgv) |
|
|
|
void WINAPI I2PService::ServiceMain(DWORD dwArgc, PSTR *pszArgv) |
|
|
|
{ |
|
|
|
{ |
|
|
|
assert(s_service != NULL); |
|
|
|
assert(s_service != NULL); |
|
|
|
|
|
|
|
|
|
|
|
s_service->m_statusHandle = RegisterServiceCtrlHandler( |
|
|
|
s_service->m_statusHandle = RegisterServiceCtrlHandler( |
|
|
|
s_service->m_name, ServiceCtrlHandler); |
|
|
|
s_service->m_name, ServiceCtrlHandler); |
|
|
|
if (s_service->m_statusHandle == NULL) |
|
|
|
if (s_service->m_statusHandle == NULL) |
|
|
|
{ |
|
|
|
{ |
|
|
|
throw GetLastError(); |
|
|
|
throw GetLastError(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
s_service->Start(dwArgc, pszArgv); |
|
|
|
s_service->Start(dwArgc, pszArgv); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -76,11 +70,8 @@ I2PService::I2PService(PSTR pszServiceName, |
|
|
|
BOOL fCanPauseContinue) |
|
|
|
BOOL fCanPauseContinue) |
|
|
|
{ |
|
|
|
{ |
|
|
|
m_name = (pszServiceName == NULL) ? (PSTR)"" : pszServiceName; |
|
|
|
m_name = (pszServiceName == NULL) ? (PSTR)"" : pszServiceName; |
|
|
|
|
|
|
|
|
|
|
|
m_statusHandle = NULL; |
|
|
|
m_statusHandle = NULL; |
|
|
|
|
|
|
|
|
|
|
|
m_status.dwServiceType = SERVICE_WIN32_OWN_PROCESS; |
|
|
|
m_status.dwServiceType = SERVICE_WIN32_OWN_PROCESS; |
|
|
|
|
|
|
|
|
|
|
|
m_status.dwCurrentState = SERVICE_START_PENDING; |
|
|
|
m_status.dwCurrentState = SERVICE_START_PENDING; |
|
|
|
|
|
|
|
|
|
|
|
DWORD dwControlsAccepted = 0; |
|
|
|
DWORD dwControlsAccepted = 0; |
|
|
@ -90,15 +81,13 @@ I2PService::I2PService(PSTR pszServiceName, |
|
|
|
dwControlsAccepted |= SERVICE_ACCEPT_SHUTDOWN; |
|
|
|
dwControlsAccepted |= SERVICE_ACCEPT_SHUTDOWN; |
|
|
|
if (fCanPauseContinue) |
|
|
|
if (fCanPauseContinue) |
|
|
|
dwControlsAccepted |= SERVICE_ACCEPT_PAUSE_CONTINUE; |
|
|
|
dwControlsAccepted |= SERVICE_ACCEPT_PAUSE_CONTINUE; |
|
|
|
m_status.dwControlsAccepted = dwControlsAccepted; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
m_status.dwControlsAccepted = dwControlsAccepted; |
|
|
|
m_status.dwWin32ExitCode = NO_ERROR; |
|
|
|
m_status.dwWin32ExitCode = NO_ERROR; |
|
|
|
m_status.dwServiceSpecificExitCode = 0; |
|
|
|
m_status.dwServiceSpecificExitCode = 0; |
|
|
|
m_status.dwCheckPoint = 0; |
|
|
|
m_status.dwCheckPoint = 0; |
|
|
|
m_status.dwWaitHint = 0; |
|
|
|
m_status.dwWaitHint = 0; |
|
|
|
|
|
|
|
|
|
|
|
m_fStopping = FALSE; |
|
|
|
m_fStopping = FALSE; |
|
|
|
|
|
|
|
|
|
|
|
// Create a manual-reset event that is not signaled at first to indicate
|
|
|
|
// Create a manual-reset event that is not signaled at first to indicate
|
|
|
|
// the stopped signal of the service.
|
|
|
|
// the stopped signal of the service.
|
|
|
|
m_hStoppedEvent = CreateEvent(NULL, TRUE, FALSE, NULL); |
|
|
|
m_hStoppedEvent = CreateEvent(NULL, TRUE, FALSE, NULL); |
|
|
@ -108,7 +97,6 @@ I2PService::I2PService(PSTR pszServiceName, |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
I2PService::~I2PService(void) |
|
|
|
I2PService::~I2PService(void) |
|
|
|
{ |
|
|
|
{ |
|
|
|
if (m_hStoppedEvent) |
|
|
|
if (m_hStoppedEvent) |
|
|
@ -118,92 +106,73 @@ I2PService::~I2PService(void) |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void I2PService::Start(DWORD dwArgc, PSTR *pszArgv) |
|
|
|
void I2PService::Start(DWORD dwArgc, PSTR *pszArgv) |
|
|
|
{ |
|
|
|
{ |
|
|
|
try |
|
|
|
try |
|
|
|
{ |
|
|
|
{ |
|
|
|
SetServiceStatus(SERVICE_START_PENDING); |
|
|
|
SetServiceStatus(SERVICE_START_PENDING); |
|
|
|
|
|
|
|
|
|
|
|
OnStart(dwArgc, pszArgv); |
|
|
|
OnStart(dwArgc, pszArgv); |
|
|
|
|
|
|
|
|
|
|
|
SetServiceStatus(SERVICE_RUNNING); |
|
|
|
SetServiceStatus(SERVICE_RUNNING); |
|
|
|
} |
|
|
|
} |
|
|
|
catch (DWORD dwError) |
|
|
|
catch (DWORD dwError) |
|
|
|
{ |
|
|
|
{ |
|
|
|
LogPrint(eLogError, "Win32Service Start", dwError); |
|
|
|
LogPrint(eLogError, "Win32Service Start", dwError); |
|
|
|
|
|
|
|
|
|
|
|
SetServiceStatus(SERVICE_STOPPED, dwError); |
|
|
|
SetServiceStatus(SERVICE_STOPPED, dwError); |
|
|
|
} |
|
|
|
} |
|
|
|
catch (...) |
|
|
|
catch (...) |
|
|
|
{ |
|
|
|
{ |
|
|
|
LogPrint(eLogError, "Win32Service failed to start.", EVENTLOG_ERROR_TYPE); |
|
|
|
LogPrint(eLogError, "Win32Service failed to start.", EVENTLOG_ERROR_TYPE); |
|
|
|
|
|
|
|
|
|
|
|
SetServiceStatus(SERVICE_STOPPED); |
|
|
|
SetServiceStatus(SERVICE_STOPPED); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void I2PService::OnStart(DWORD dwArgc, PSTR *pszArgv) |
|
|
|
void I2PService::OnStart(DWORD dwArgc, PSTR *pszArgv) |
|
|
|
{ |
|
|
|
{ |
|
|
|
LogPrint(eLogInfo, "Win32Service in OnStart", EVENTLOG_INFORMATION_TYPE); |
|
|
|
LogPrint(eLogInfo, "Win32Service in OnStart", EVENTLOG_INFORMATION_TYPE); |
|
|
|
|
|
|
|
|
|
|
|
Daemon.start(); |
|
|
|
Daemon.start(); |
|
|
|
|
|
|
|
|
|
|
|
//i2p::util::config::OptionParser(dwArgc, pszArgv);
|
|
|
|
//i2p::util::config::OptionParser(dwArgc, pszArgv);
|
|
|
|
//i2p::util::filesystem::ReadConfigFile(i2p::util::config::mapArgs, i2p::util::config::mapMultiArgs);
|
|
|
|
//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::context.OverrideNTCPAddress(i2p::util::config::GetCharArg("-host", "127.0.0.1"),
|
|
|
|
// i2p::util::config::GetArg("-port", 17070));
|
|
|
|
// i2p::util::config::GetArg("-port", 17070));
|
|
|
|
|
|
|
|
|
|
|
|
_worker = new std::thread(std::bind(&I2PService::WorkerThread, this)); |
|
|
|
_worker = new std::thread(std::bind(&I2PService::WorkerThread, this)); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void I2PService::WorkerThread() |
|
|
|
void I2PService::WorkerThread() |
|
|
|
{ |
|
|
|
{ |
|
|
|
while (!m_fStopping) |
|
|
|
while (!m_fStopping) |
|
|
|
{ |
|
|
|
{ |
|
|
|
::Sleep(1000); // Simulate some lengthy operations.
|
|
|
|
::Sleep(1000); // Simulate some lengthy operations.
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Signal the stopped event.
|
|
|
|
// Signal the stopped event.
|
|
|
|
SetEvent(m_hStoppedEvent); |
|
|
|
SetEvent(m_hStoppedEvent); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void I2PService::Stop() |
|
|
|
void I2PService::Stop() |
|
|
|
{ |
|
|
|
{ |
|
|
|
DWORD dwOriginalState = m_status.dwCurrentState; |
|
|
|
DWORD dwOriginalState = m_status.dwCurrentState; |
|
|
|
try |
|
|
|
try |
|
|
|
{ |
|
|
|
{ |
|
|
|
SetServiceStatus(SERVICE_STOP_PENDING); |
|
|
|
SetServiceStatus(SERVICE_STOP_PENDING); |
|
|
|
|
|
|
|
|
|
|
|
OnStop(); |
|
|
|
OnStop(); |
|
|
|
|
|
|
|
|
|
|
|
SetServiceStatus(SERVICE_STOPPED); |
|
|
|
SetServiceStatus(SERVICE_STOPPED); |
|
|
|
} |
|
|
|
} |
|
|
|
catch (DWORD dwError) |
|
|
|
catch (DWORD dwError) |
|
|
|
{ |
|
|
|
{ |
|
|
|
LogPrint(eLogInfo, "Win32Service Stop", dwError); |
|
|
|
LogPrint(eLogInfo, "Win32Service Stop", dwError); |
|
|
|
|
|
|
|
|
|
|
|
SetServiceStatus(dwOriginalState); |
|
|
|
SetServiceStatus(dwOriginalState); |
|
|
|
} |
|
|
|
} |
|
|
|
catch (...) |
|
|
|
catch (...) |
|
|
|
{ |
|
|
|
{ |
|
|
|
LogPrint(eLogError, "Win32Service failed to stop.", EVENTLOG_ERROR_TYPE); |
|
|
|
LogPrint(eLogError, "Win32Service failed to stop.", EVENTLOG_ERROR_TYPE); |
|
|
|
|
|
|
|
|
|
|
|
SetServiceStatus(dwOriginalState); |
|
|
|
SetServiceStatus(dwOriginalState); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void I2PService::OnStop() |
|
|
|
void I2PService::OnStop() |
|
|
|
{ |
|
|
|
{ |
|
|
|
// Log a service stop message to the Application log.
|
|
|
|
// Log a service stop message to the Application log.
|
|
|
|
LogPrint(eLogInfo, "Win32Service in OnStop", EVENTLOG_INFORMATION_TYPE); |
|
|
|
LogPrint(eLogInfo, "Win32Service in OnStop", EVENTLOG_INFORMATION_TYPE); |
|
|
|
|
|
|
|
|
|
|
|
Daemon.stop(); |
|
|
|
Daemon.stop(); |
|
|
|
|
|
|
|
|
|
|
|
m_fStopping = TRUE; |
|
|
|
m_fStopping = TRUE; |
|
|
|
if (WaitForSingleObject(m_hStoppedEvent, INFINITE) != WAIT_OBJECT_0) |
|
|
|
if (WaitForSingleObject(m_hStoppedEvent, INFINITE) != WAIT_OBJECT_0) |
|
|
|
{ |
|
|
|
{ |
|
|
@ -213,57 +182,46 @@ void I2PService::OnStop() |
|
|
|
delete _worker; |
|
|
|
delete _worker; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void I2PService::Pause() |
|
|
|
void I2PService::Pause() |
|
|
|
{ |
|
|
|
{ |
|
|
|
try |
|
|
|
try |
|
|
|
{ |
|
|
|
{ |
|
|
|
SetServiceStatus(SERVICE_PAUSE_PENDING); |
|
|
|
SetServiceStatus(SERVICE_PAUSE_PENDING); |
|
|
|
|
|
|
|
|
|
|
|
OnPause(); |
|
|
|
OnPause(); |
|
|
|
|
|
|
|
|
|
|
|
SetServiceStatus(SERVICE_PAUSED); |
|
|
|
SetServiceStatus(SERVICE_PAUSED); |
|
|
|
} |
|
|
|
} |
|
|
|
catch (DWORD dwError) |
|
|
|
catch (DWORD dwError) |
|
|
|
{ |
|
|
|
{ |
|
|
|
LogPrint(eLogError, "Win32Service Pause", dwError); |
|
|
|
LogPrint(eLogError, "Win32Service Pause", dwError); |
|
|
|
|
|
|
|
|
|
|
|
SetServiceStatus(SERVICE_RUNNING); |
|
|
|
SetServiceStatus(SERVICE_RUNNING); |
|
|
|
} |
|
|
|
} |
|
|
|
catch (...) |
|
|
|
catch (...) |
|
|
|
{ |
|
|
|
{ |
|
|
|
LogPrint(eLogError, "Win32Service failed to pause.", EVENTLOG_ERROR_TYPE); |
|
|
|
LogPrint(eLogError, "Win32Service failed to pause.", EVENTLOG_ERROR_TYPE); |
|
|
|
|
|
|
|
|
|
|
|
SetServiceStatus(SERVICE_RUNNING); |
|
|
|
SetServiceStatus(SERVICE_RUNNING); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void I2PService::OnPause() |
|
|
|
void I2PService::OnPause() |
|
|
|
{ |
|
|
|
{ |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void I2PService::Continue() |
|
|
|
void I2PService::Continue() |
|
|
|
{ |
|
|
|
{ |
|
|
|
try |
|
|
|
try |
|
|
|
{ |
|
|
|
{ |
|
|
|
SetServiceStatus(SERVICE_CONTINUE_PENDING); |
|
|
|
SetServiceStatus(SERVICE_CONTINUE_PENDING); |
|
|
|
|
|
|
|
|
|
|
|
OnContinue(); |
|
|
|
OnContinue(); |
|
|
|
|
|
|
|
|
|
|
|
SetServiceStatus(SERVICE_RUNNING); |
|
|
|
SetServiceStatus(SERVICE_RUNNING); |
|
|
|
} |
|
|
|
} |
|
|
|
catch (DWORD dwError) |
|
|
|
catch (DWORD dwError) |
|
|
|
{ |
|
|
|
{ |
|
|
|
LogPrint(eLogError, "Win32Service Continue", dwError); |
|
|
|
LogPrint(eLogError, "Win32Service Continue", dwError); |
|
|
|
|
|
|
|
|
|
|
|
SetServiceStatus(SERVICE_PAUSED); |
|
|
|
SetServiceStatus(SERVICE_PAUSED); |
|
|
|
} |
|
|
|
} |
|
|
|
catch (...) |
|
|
|
catch (...) |
|
|
|
{ |
|
|
|
{ |
|
|
|
LogPrint(eLogError, "Win32Service failed to resume.", EVENTLOG_ERROR_TYPE); |
|
|
|
LogPrint(eLogError, "Win32Service failed to resume.", EVENTLOG_ERROR_TYPE); |
|
|
|
|
|
|
|
|
|
|
|
SetServiceStatus(SERVICE_PAUSED); |
|
|
|
SetServiceStatus(SERVICE_PAUSED); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
@ -277,7 +235,6 @@ void I2PService::Shutdown() |
|
|
|
try |
|
|
|
try |
|
|
|
{ |
|
|
|
{ |
|
|
|
OnShutdown(); |
|
|
|
OnShutdown(); |
|
|
|
|
|
|
|
|
|
|
|
SetServiceStatus(SERVICE_STOPPED); |
|
|
|
SetServiceStatus(SERVICE_STOPPED); |
|
|
|
} |
|
|
|
} |
|
|
|
catch (DWORD dwError) |
|
|
|
catch (DWORD dwError) |
|
|
@ -299,11 +256,9 @@ void I2PService::SetServiceStatus(DWORD dwCurrentState, |
|
|
|
DWORD dwWaitHint) |
|
|
|
DWORD dwWaitHint) |
|
|
|
{ |
|
|
|
{ |
|
|
|
static DWORD dwCheckPoint = 1; |
|
|
|
static DWORD dwCheckPoint = 1; |
|
|
|
|
|
|
|
|
|
|
|
m_status.dwCurrentState = dwCurrentState; |
|
|
|
m_status.dwCurrentState = dwCurrentState; |
|
|
|
m_status.dwWin32ExitCode = dwWin32ExitCode; |
|
|
|
m_status.dwWin32ExitCode = dwWin32ExitCode; |
|
|
|
m_status.dwWaitHint = dwWaitHint; |
|
|
|
m_status.dwWaitHint = dwWaitHint; |
|
|
|
|
|
|
|
|
|
|
|
m_status.dwCheckPoint = |
|
|
|
m_status.dwCheckPoint = |
|
|
|
((dwCurrentState == SERVICE_RUNNING) || |
|
|
|
((dwCurrentState == SERVICE_RUNNING) || |
|
|
|
(dwCurrentState == SERVICE_STOPPED)) ? |
|
|
|
(dwCurrentState == SERVICE_STOPPED)) ? |
|
|
@ -328,7 +283,7 @@ void FreeHandles(SC_HANDLE schSCManager, SC_HANDLE schService) |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void InstallService(PSTR pszServiceName, PSTR pszDisplayName, DWORD dwStartType, PSTR pszDependencies, PSTR pszAccount, PSTR pszPassword) |
|
|
|
void InstallService(PCSTR pszServiceName, PCSTR pszDisplayName, DWORD dwStartType, PCSTR pszDependencies, PCSTR pszAccount, PCSTR pszPassword) |
|
|
|
{ |
|
|
|
{ |
|
|
|
printf("Try to install Win32Service (%s).\n", pszServiceName); |
|
|
|
printf("Try to install Win32Service (%s).\n", pszServiceName); |
|
|
|
|
|
|
|
|
|
|
@ -383,7 +338,7 @@ void InstallService(PSTR pszServiceName, PSTR pszDisplayName, DWORD dwStartType, |
|
|
|
FreeHandles(schSCManager, schService); |
|
|
|
FreeHandles(schSCManager, schService); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void UninstallService(PSTR pszServiceName) |
|
|
|
void UninstallService(PCSTR pszServiceName) |
|
|
|
{ |
|
|
|
{ |
|
|
|
printf("Try to uninstall Win32Service (%s).\n", pszServiceName); |
|
|
|
printf("Try to uninstall Win32Service (%s).\n", pszServiceName); |
|
|
|
|
|
|
|
|
|
|
|