mirror of
				https://github.com/PurpleI2P/i2pd.git
				synced 2025-11-04 08:30:46 +00:00 
			
		
		
		
	[win32] return back service control code (#1733)
Signed-off-by: R4SAS <r4sas@i2pmail.org>
This commit is contained in:
		
							parent
							
								
									9f1a125ed9
								
							
						
					
					
						commit
						df62b40ca7
					
				
					 4 changed files with 362 additions and 2 deletions
				
			
		
							
								
								
									
										2
									
								
								Makefile
									
										
									
									
									
								
							
							
						
						
									
										2
									
								
								Makefile
									
										
									
									
									
								
							| 
						 | 
					@ -62,7 +62,7 @@ else ifneq (, $(findstring freebsd, $(SYS))$(findstring openbsd, $(SYS)))
 | 
				
			||||||
	DAEMON_SRC += $(DAEMON_SRC_DIR)/UnixDaemon.cpp
 | 
						DAEMON_SRC += $(DAEMON_SRC_DIR)/UnixDaemon.cpp
 | 
				
			||||||
	include Makefile.bsd
 | 
						include Makefile.bsd
 | 
				
			||||||
else ifneq (, $(findstring mingw, $(SYS))$(findstring cygwin, $(SYS)))
 | 
					else ifneq (, $(findstring mingw, $(SYS))$(findstring cygwin, $(SYS)))
 | 
				
			||||||
	DAEMON_SRC += Win32/DaemonWin32.cpp Win32/Win32App.cpp Win32/Win32NetState.cpp
 | 
						DAEMON_SRC += Win32/DaemonWin32.cpp Win32/Win32App.cpp Win32/Win32Service.cpp Win32/Win32NetState.cpp
 | 
				
			||||||
	include Makefile.mingw
 | 
						include Makefile.mingw
 | 
				
			||||||
else # not supported
 | 
					else # not supported
 | 
				
			||||||
	$(error Not supported platform)
 | 
						$(error Not supported platform)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,5 +1,5 @@
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
* Copyright (c) 2013-2020, The PurpleI2P Project
 | 
					* Copyright (c) 2013-2022, The PurpleI2P Project
 | 
				
			||||||
*
 | 
					*
 | 
				
			||||||
* This file is part of Purple i2pd project and licensed under BSD3
 | 
					* This file is part of Purple i2pd project and licensed under BSD3
 | 
				
			||||||
*
 | 
					*
 | 
				
			||||||
| 
						 | 
					@ -14,6 +14,7 @@
 | 
				
			||||||
#include "Log.h"
 | 
					#include "Log.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef _WIN32
 | 
					#ifdef _WIN32
 | 
				
			||||||
 | 
					#include "Win32Service.h"
 | 
				
			||||||
#ifdef WIN32_APP
 | 
					#ifdef WIN32_APP
 | 
				
			||||||
#include <windows.h>
 | 
					#include <windows.h>
 | 
				
			||||||
#include "Win32App.h"
 | 
					#include "Win32App.h"
 | 
				
			||||||
| 
						 | 
					@ -39,6 +40,19 @@ namespace util
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (!Daemon_Singleton::init(argc, argv))
 | 
							if (!Daemon_Singleton::init(argc, argv))
 | 
				
			||||||
			return false;
 | 
								return false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (isDaemon)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								LogPrint(eLogDebug, "Daemon: running as service");
 | 
				
			||||||
 | 
								I2PService service((PSTR)SERVICE_NAME);
 | 
				
			||||||
 | 
								if (!I2PService::Run(service))
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									LogPrint(eLogError, "Daemon: Service failed to run w/err 0x%08lx\n", GetLastError());
 | 
				
			||||||
 | 
									return false;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								return false;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		return true;
 | 
							return true;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										283
									
								
								Win32/Win32Service.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										283
									
								
								Win32/Win32Service.cpp
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,283 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					* Copyright (c) 2013-2022, The PurpleI2P Project
 | 
				
			||||||
 | 
					*
 | 
				
			||||||
 | 
					* This file is part of Purple i2pd project and licensed under BSD3
 | 
				
			||||||
 | 
					*
 | 
				
			||||||
 | 
					* See full license text in LICENSE file at top of project tree
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "Win32Service.h"
 | 
				
			||||||
 | 
					#include <assert.h>
 | 
				
			||||||
 | 
					#include <windows.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "Daemon.h"
 | 
				
			||||||
 | 
					#include "Log.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					I2PService *I2PService::s_service = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					BOOL I2PService::isService()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						BOOL bIsService = FALSE;
 | 
				
			||||||
 | 
						HWINSTA hWinStation = GetProcessWindowStation();
 | 
				
			||||||
 | 
						if (hWinStation != NULL)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							USEROBJECTFLAGS uof = { 0 };
 | 
				
			||||||
 | 
							if (GetUserObjectInformation(hWinStation, UOI_FLAGS, &uof, sizeof(USEROBJECTFLAGS), NULL) && ((uof.dwFlags & WSF_VISIBLE) == 0))
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								bIsService = TRUE;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return bIsService;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					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)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						m_name = (pszServiceName == NULL) ? (PSTR)"" : 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)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							LogPrint(eLogError, "Win32Service: Start error: ", dwError);
 | 
				
			||||||
 | 
							SetServiceStatus(SERVICE_STOPPED, dwError);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						catch (...)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							LogPrint(eLogError, "Win32Service: failed to start: ", EVENTLOG_ERROR_TYPE);
 | 
				
			||||||
 | 
							SetServiceStatus(SERVICE_STOPPED);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void I2PService::OnStart(DWORD dwArgc, PSTR *pszArgv)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						LogPrint(eLogInfo, "Win32Service: in OnStart (", EVENTLOG_INFORMATION_TYPE, ")");
 | 
				
			||||||
 | 
						Daemon.start();
 | 
				
			||||||
 | 
						_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)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							LogPrint(eLogInfo, "Win32Service: Stop error: ", dwError);
 | 
				
			||||||
 | 
							SetServiceStatus(dwOriginalState);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						catch (...)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							LogPrint(eLogError, "Win32Service: Failed to stop: ", EVENTLOG_ERROR_TYPE);
 | 
				
			||||||
 | 
							SetServiceStatus(dwOriginalState);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void I2PService::OnStop()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						// Log a service stop message to the Application log.
 | 
				
			||||||
 | 
						LogPrint(eLogInfo, "Win32Service: in OnStop (", EVENTLOG_INFORMATION_TYPE, ")");
 | 
				
			||||||
 | 
						Daemon.stop();
 | 
				
			||||||
 | 
						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)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							LogPrint(eLogError, "Win32Service: Pause error: ", dwError);
 | 
				
			||||||
 | 
							SetServiceStatus(SERVICE_RUNNING);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						catch (...)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							LogPrint(eLogError, "Win32Service: 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)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							LogPrint(eLogError, "Win32Service: Continue error: ", dwError);
 | 
				
			||||||
 | 
							SetServiceStatus(SERVICE_PAUSED);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						catch (...)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							LogPrint(eLogError, "Win32Service: Failed to resume: ", EVENTLOG_ERROR_TYPE);
 | 
				
			||||||
 | 
							SetServiceStatus(SERVICE_PAUSED);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void I2PService::OnContinue()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void I2PService::Shutdown()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						try
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							OnShutdown();
 | 
				
			||||||
 | 
							SetServiceStatus(SERVICE_STOPPED);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						catch (DWORD dwError)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							LogPrint(eLogError, "Win32Service: Shutdown error: ", dwError);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						catch (...)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							LogPrint(eLogError, "Win32Service: 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 FreeHandles(SC_HANDLE schSCManager, SC_HANDLE schService)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (schSCManager)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							CloseServiceHandle(schSCManager);
 | 
				
			||||||
 | 
							schSCManager = NULL;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if (schService)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							CloseServiceHandle(schService);
 | 
				
			||||||
 | 
							schService = NULL;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										63
									
								
								Win32/Win32Service.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										63
									
								
								Win32/Win32Service.h
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,63 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					* Copyright (c) 2013-2022, The PurpleI2P Project
 | 
				
			||||||
 | 
					*
 | 
				
			||||||
 | 
					* This file is part of Purple i2pd project and licensed under BSD3
 | 
				
			||||||
 | 
					*
 | 
				
			||||||
 | 
					* See full license text in LICENSE file at top of project tree
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef WIN_32_SERVICE_H__
 | 
				
			||||||
 | 
					#define WIN_32_SERVICE_H__
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <thread>
 | 
				
			||||||
 | 
					#include <windows.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define SERVICE_NAME "i2pdService"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class I2PService
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						public:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							I2PService(PSTR pszServiceName,
 | 
				
			||||||
 | 
								BOOL fCanStop = TRUE,
 | 
				
			||||||
 | 
								BOOL fCanShutdown = TRUE,
 | 
				
			||||||
 | 
								BOOL fCanPauseContinue = FALSE);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							virtual ~I2PService(void);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							static BOOL isService();
 | 
				
			||||||
 | 
							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);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						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;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							std::thread* _worker;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif // WIN_32_SERVICE_H__
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue