diff options
Diffstat (limited to 'zerotierone/windows/ZeroTierOne/ServiceBase.cpp')
| -rw-r--r-- | zerotierone/windows/ZeroTierOne/ServiceBase.cpp | 563 |
1 files changed, 0 insertions, 563 deletions
diff --git a/zerotierone/windows/ZeroTierOne/ServiceBase.cpp b/zerotierone/windows/ZeroTierOne/ServiceBase.cpp deleted file mode 100644 index 59d384c..0000000 --- a/zerotierone/windows/ZeroTierOne/ServiceBase.cpp +++ /dev/null @@ -1,563 +0,0 @@ -/****************************** Module Header ******************************\ -* Module Name: ServiceBase.cpp -* Project: CppWindowsService -* Copyright (c) Microsoft Corporation. -* -* Provides a base class for a service that will exist as part of a service -* application. CServiceBase must be derived from when creating a new service -* class. -* -* This source is subject to the Microsoft Public License. -* See http://www.microsoft.com/en-us/openness/resources/licenses.aspx#MPL. -* All other rights reserved. -* -* THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, -* EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED -* WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE. -\***************************************************************************/ - -#pragma region Includes -#include "ServiceBase.h" -#include <assert.h> -#include <strsafe.h> -#include <string> -#pragma endregion - - -#pragma region Static Members - -// Initialize the singleton service instance. -CServiceBase *CServiceBase::s_service = NULL; - - -// -// FUNCTION: CServiceBase::Run(CServiceBase &) -// -// PURPOSE: Register the executable for a service with the Service Control -// Manager (SCM). After you call Run(ServiceBase), the SCM issues a Start -// command, which results in a call to the OnStart method in the service. -// This method blocks until the service has stopped. -// -// PARAMETERS: -// * service - the reference to a CServiceBase object. It will become the -// singleton service instance of this service application. -// -// RETURN VALUE: If the function succeeds, the return value is TRUE. If the -// function fails, the return value is FALSE. To get extended error -// information, call GetLastError. -// -BOOL CServiceBase::Run(CServiceBase &service) -{ - s_service = &service; - - SERVICE_TABLE_ENTRYA serviceTable[] = - { - { service.m_name, ServiceMain }, - { NULL, NULL } - }; - - // Connects the main thread of a service process to the service control - // manager, which causes the thread to be the service control dispatcher - // thread for the calling process. This call returns when the service has - // stopped. The process should simply terminate when the call returns. - return StartServiceCtrlDispatcher(serviceTable); -} - - -// -// FUNCTION: CServiceBase::ServiceMain(DWORD, PWSTR *) -// -// PURPOSE: Entry point for the service. It registers the handler function -// for the service and starts the service. -// -// PARAMETERS: -// * dwArgc - number of command line arguments -// * lpszArgv - array of command line arguments -// -void WINAPI CServiceBase::ServiceMain(DWORD dwArgc, PSTR *pszArgv) -{ - assert(s_service != NULL); - - // Register the handler function for the service - s_service->m_statusHandle = RegisterServiceCtrlHandler( - s_service->m_name, ServiceCtrlHandler); - if (s_service->m_statusHandle == NULL) - { - throw GetLastError(); - } - - // Start the service. - s_service->Start(dwArgc, pszArgv); -} - - -// -// FUNCTION: CServiceBase::ServiceCtrlHandler(DWORD) -// -// PURPOSE: The function is called by the SCM whenever a control code is -// sent to the service. -// -// PARAMETERS: -// * dwCtrlCode - the control code. This parameter can be one of the -// following values: -// -// SERVICE_CONTROL_CONTINUE -// SERVICE_CONTROL_INTERROGATE -// SERVICE_CONTROL_NETBINDADD -// SERVICE_CONTROL_NETBINDDISABLE -// SERVICE_CONTROL_NETBINDREMOVE -// SERVICE_CONTROL_PARAMCHANGE -// SERVICE_CONTROL_PAUSE -// SERVICE_CONTROL_SHUTDOWN -// SERVICE_CONTROL_STOP -// -// This parameter can also be a user-defined control code ranges from 128 -// to 255. -// -void WINAPI CServiceBase::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; - } -} - -#pragma endregion - - -#pragma region Service Constructor and Destructor - -// -// FUNCTION: CServiceBase::CServiceBase(PWSTR, BOOL, BOOL, BOOL) -// -// PURPOSE: The constructor of CServiceBase. It initializes a new instance -// of the CServiceBase class. The optional parameters (fCanStop, -/// fCanShutdown and fCanPauseContinue) allow you to specify whether the -// service can be stopped, paused and continued, or be notified when system -// shutdown occurs. -// -// PARAMETERS: -// * pszServiceName - the name of the service -// * fCanStop - the service can be stopped -// * fCanShutdown - the service is notified when system shutdown occurs -// * fCanPauseContinue - the service can be paused and continued -// -CServiceBase::CServiceBase(PSTR pszServiceName, - BOOL fCanStop, - BOOL fCanShutdown, - BOOL fCanPauseContinue) -{ - // Service name must be a valid string and cannot be NULL. - m_name = (pszServiceName == NULL) ? "" : pszServiceName; - - m_statusHandle = NULL; - - // The service runs in its own process. - m_status.dwServiceType = SERVICE_WIN32_OWN_PROCESS; - - // The service is starting. - m_status.dwCurrentState = SERVICE_START_PENDING; - - // The accepted commands of the service. - 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; -} - - -// -// FUNCTION: CServiceBase::~CServiceBase() -// -// PURPOSE: The virtual destructor of CServiceBase. -// -CServiceBase::~CServiceBase(void) -{ -} - -#pragma endregion - - -#pragma region Service Start, Stop, Pause, Continue, and Shutdown - -// -// FUNCTION: CServiceBase::Start(DWORD, PWSTR *) -// -// PURPOSE: The function starts the service. It calls the OnStart virtual -// function in which you can specify the actions to take when the service -// starts. If an error occurs during the startup, the error will be logged -// in the Application event log, and the service will be stopped. -// -// PARAMETERS: -// * dwArgc - number of command line arguments -// * lpszArgv - array of command line arguments -// -void CServiceBase::Start(DWORD dwArgc, PSTR *pszArgv) -{ - try - { - // Tell SCM that the service is starting. - SetServiceStatus(SERVICE_START_PENDING); - - // Perform service-specific initialization. - OnStart(dwArgc, pszArgv); - - // Tell SCM that the service is started. - SetServiceStatus(SERVICE_RUNNING); - } - catch (DWORD dwError) - { - // Log the error. - WriteErrorLogEntry("Service Start", dwError); - - // Set the service status to be stopped. - SetServiceStatus(SERVICE_STOPPED, dwError); - } - catch (...) - { - // Log the error. - WriteEventLogEntry("Service failed to start.", EVENTLOG_ERROR_TYPE); - - // Set the service status to be stopped. - SetServiceStatus(SERVICE_STOPPED); - } -} - - -// -// FUNCTION: CServiceBase::OnStart(DWORD, PWSTR *) -// -// PURPOSE: When implemented in a derived class, executes when a Start -// command is sent to the service by the SCM or when the operating system -// starts (for a service that starts automatically). Specifies actions to -// take when the service starts. Be sure to periodically call -// CServiceBase::SetServiceStatus() with SERVICE_START_PENDING if the -// procedure is going to take long time. You may also consider spawning a -// new thread in OnStart to perform time-consuming initialization tasks. -// -// PARAMETERS: -// * dwArgc - number of command line arguments -// * lpszArgv - array of command line arguments -// -void CServiceBase::OnStart(DWORD dwArgc, PSTR *pszArgv) -{ -} - - -// -// FUNCTION: CServiceBase::Stop() -// -// PURPOSE: The function stops the service. It calls the OnStop virtual -// function in which you can specify the actions to take when the service -// stops. If an error occurs, the error will be logged in the Application -// event log, and the service will be restored to the original state. -// -void CServiceBase::Stop() -{ - DWORD dwOriginalState = m_status.dwCurrentState; - try - { - // Tell SCM that the service is stopping. - SetServiceStatus(SERVICE_STOP_PENDING); - - // Perform service-specific stop operations. - OnStop(); - - // Tell SCM that the service is stopped. - SetServiceStatus(SERVICE_STOPPED); - } - catch (DWORD dwError) - { - // Log the error. - WriteErrorLogEntry("Service Stop", dwError); - - // Set the orginal service status. - SetServiceStatus(dwOriginalState); - } - catch (...) - { - // Log the error. - WriteEventLogEntry("Service failed to stop.", EVENTLOG_ERROR_TYPE); - - // Set the orginal service status. - SetServiceStatus(dwOriginalState); - } -} - - -// -// FUNCTION: CServiceBase::OnStop() -// -// PURPOSE: When implemented in a derived class, executes when a Stop -// command is sent to the service by the SCM. Specifies actions to take -// when a service stops running. Be sure to periodically call -// CServiceBase::SetServiceStatus() with SERVICE_STOP_PENDING if the -// procedure is going to take long time. -// -void CServiceBase::OnStop() -{ -} - - -// -// FUNCTION: CServiceBase::Pause() -// -// PURPOSE: The function pauses the service if the service supports pause -// and continue. It calls the OnPause virtual function in which you can -// specify the actions to take when the service pauses. If an error occurs, -// the error will be logged in the Application event log, and the service -// will become running. -// -void CServiceBase::Pause() -{ - try - { - // Tell SCM that the service is pausing. - SetServiceStatus(SERVICE_PAUSE_PENDING); - - // Perform service-specific pause operations. - OnPause(); - - // Tell SCM that the service is paused. - SetServiceStatus(SERVICE_PAUSED); - } - catch (DWORD dwError) - { - // Log the error. - WriteErrorLogEntry("Service Pause", dwError); - - // Tell SCM that the service is still running. - SetServiceStatus(SERVICE_RUNNING); - } - catch (...) - { - // Log the error. - WriteEventLogEntry("Service failed to pause.", EVENTLOG_ERROR_TYPE); - - // Tell SCM that the service is still running. - SetServiceStatus(SERVICE_RUNNING); - } -} - - -// -// FUNCTION: CServiceBase::OnPause() -// -// PURPOSE: When implemented in a derived class, executes when a Pause -// command is sent to the service by the SCM. Specifies actions to take -// when a service pauses. -// -void CServiceBase::OnPause() -{ -} - - -// -// FUNCTION: CServiceBase::Continue() -// -// PURPOSE: The function resumes normal functioning after being paused if -// the service supports pause and continue. It calls the OnContinue virtual -// function in which you can specify the actions to take when the service -// continues. If an error occurs, the error will be logged in the -// Application event log, and the service will still be paused. -// -void CServiceBase::Continue() -{ - try - { - // Tell SCM that the service is resuming. - SetServiceStatus(SERVICE_CONTINUE_PENDING); - - // Perform service-specific continue operations. - OnContinue(); - - // Tell SCM that the service is running. - SetServiceStatus(SERVICE_RUNNING); - } - catch (DWORD dwError) - { - // Log the error. - WriteErrorLogEntry("Service Continue", dwError); - - // Tell SCM that the service is still paused. - SetServiceStatus(SERVICE_PAUSED); - } - catch (...) - { - // Log the error. - WriteEventLogEntry("Service failed to resume.", EVENTLOG_ERROR_TYPE); - - // Tell SCM that the service is still paused. - SetServiceStatus(SERVICE_PAUSED); - } -} - - -// -// FUNCTION: CServiceBase::OnContinue() -// -// PURPOSE: When implemented in a derived class, OnContinue runs when a -// Continue command is sent to the service by the SCM. Specifies actions to -// take when a service resumes normal functioning after being paused. -// -void CServiceBase::OnContinue() -{ -} - - -// -// FUNCTION: CServiceBase::Shutdown() -// -// PURPOSE: The function executes when the system is shutting down. It -// calls the OnShutdown virtual function in which you can specify what -// should occur immediately prior to the system shutting down. If an error -// occurs, the error will be logged in the Application event log. -// -void CServiceBase::Shutdown() -{ - try - { - // Perform service-specific shutdown operations. - OnShutdown(); - - // Tell SCM that the service is stopped. - SetServiceStatus(SERVICE_STOPPED); - } - catch (DWORD dwError) - { - // Log the error. - WriteErrorLogEntry("Service Shutdown", dwError); - } - catch (...) - { - // Log the error. - WriteEventLogEntry("Service failed to shut down.", EVENTLOG_ERROR_TYPE); - } -} - - -// -// FUNCTION: CServiceBase::OnShutdown() -// -// PURPOSE: When implemented in a derived class, executes when the system -// is shutting down. Specifies what should occur immediately prior to the -// system shutting down. -// -void CServiceBase::OnShutdown() -{ -} - -#pragma endregion - - -#pragma region Helper Functions - -// -// FUNCTION: CServiceBase::SetServiceStatus(DWORD, DWORD, DWORD) -// -// PURPOSE: The function sets the service status and reports the status to -// the SCM. -// -// PARAMETERS: -// * dwCurrentState - the state of the service -// * dwWin32ExitCode - error code to report -// * dwWaitHint - estimated time for pending operation, in milliseconds -// -void CServiceBase::SetServiceStatus(DWORD dwCurrentState, - DWORD dwWin32ExitCode, - DWORD dwWaitHint) -{ - static DWORD dwCheckPoint = 1; - - // Fill in the SERVICE_STATUS structure of the service. - - m_status.dwCurrentState = dwCurrentState; - m_status.dwWin32ExitCode = dwWin32ExitCode; - m_status.dwWaitHint = dwWaitHint; - - m_status.dwCheckPoint = - ((dwCurrentState == SERVICE_RUNNING) || - (dwCurrentState == SERVICE_STOPPED)) ? - 0 : dwCheckPoint++; - - // Report the status of the service to the SCM. - ::SetServiceStatus(m_statusHandle, &m_status); -} - - -// -// FUNCTION: CServiceBase::WriteEventLogEntry(PWSTR, WORD) -// -// PURPOSE: Log a message to the Application event log. -// -// PARAMETERS: -// * pszMessage - string message to be logged. -// * wType - the type of event to be logged. The parameter can be one of -// the following values. -// -// EVENTLOG_SUCCESS -// EVENTLOG_AUDIT_FAILURE -// EVENTLOG_AUDIT_SUCCESS -// EVENTLOG_ERROR_TYPE -// EVENTLOG_INFORMATION_TYPE -// EVENTLOG_WARNING_TYPE -// -void CServiceBase::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); - } -} - - -// -// FUNCTION: CServiceBase::WriteErrorLogEntry(PWSTR, DWORD) -// -// PURPOSE: Log an error message to the Application event log. -// -// PARAMETERS: -// * pszFunction - the function that gives the error -// * dwError - the error code -// -void CServiceBase::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); -} - -#pragma endregion
\ No newline at end of file |
