diff options
| author | Stefan Boberg <[email protected]> | 2021-09-17 23:18:20 +0200 |
|---|---|---|
| committer | Stefan Boberg <[email protected]> | 2021-09-17 23:18:48 +0200 |
| commit | 0ee89539ead8631b02953ddf601770aefa557edb (patch) | |
| tree | ef2e09d747bb3d7497507362bda560b905d478d6 /zenserver/windows/service.cpp | |
| parent | Added IsInteractiveSession() query to help identify if the process is running... (diff) | |
| download | zen-0ee89539ead8631b02953ddf601770aefa557edb.tar.xz zen-0ee89539ead8631b02953ddf601770aefa557edb.zip | |
zenserver can now run as a Windows service. We'll still need to improve how data files are found as the current defaults are relative to the user directory which ends up being in the Windows folder when running as the local system user
Diffstat (limited to 'zenserver/windows/service.cpp')
| -rw-r--r-- | zenserver/windows/service.cpp | 246 |
1 files changed, 111 insertions, 135 deletions
diff --git a/zenserver/windows/service.cpp b/zenserver/windows/service.cpp index 7a7864b39..bd80e0c2c 100644 --- a/zenserver/windows/service.cpp +++ b/zenserver/windows/service.cpp @@ -1,3 +1,5 @@ +// Copyright Epic Games, Inc. All Rights Reserved. + #include "service.h" #include <zencore/zencore.h> @@ -12,14 +14,19 @@ SERVICE_STATUS gSvcStatus; SERVICE_STATUS_HANDLE gSvcStatusHandle; HANDLE ghSvcStopEvent = NULL; -void SvcInstall(void); -void WINAPI SvcCtrlHandler(DWORD); -void WINAPI SvcMain(DWORD, LPTSTR*); +void SvcInstall(void); void ReportSvcStatus(DWORD, DWORD, DWORD); -void SvcInit(DWORD, LPTSTR*); void SvcReportEvent(LPTSTR); +WindowsService::WindowsService() +{ +} + +WindowsService::~WindowsService() +{ +} + // // Purpose: // Installs a service in the SCM database @@ -31,7 +38,7 @@ void SvcReportEvent(LPTSTR); // None // VOID -SvcInstall() +WindowsService::Install() { SC_HANDLE schSCManager; SC_HANDLE schService; @@ -84,17 +91,8 @@ SvcInstall() CloseServiceHandle(schSCManager); } -// -// Purpose: -// Deletes a service from the SCM database -// -// Parameters: -// None -// -// Return value: -// None -// -void SvcDelete() +void +WindowsService::Delete() { SC_HANDLE schSCManager; SC_HANDLE schService; @@ -137,6 +135,89 @@ void SvcDelete() CloseServiceHandle(schSCManager); } +WindowsService* gSvc; + +void WINAPI +CallMain(DWORD, LPSTR*) +{ + gSvc->SvcMain(); +} + +int +WindowsService::ServiceMain() +{ + if (zen::IsInteractiveSession()) + { + // Not actually running as a service + return Run(); + } + else + { + gSvc = this; + + SERVICE_TABLE_ENTRY DispatchTable[] = {{(LPWSTR)SVCNAME, (LPSERVICE_MAIN_FUNCTION)&CallMain}, {NULL, NULL}}; + + // This call returns when the service has stopped. + // The process should simply terminate when the call returns. + + if (!StartServiceCtrlDispatcher(DispatchTable)) + { + SvcReportEvent((LPTSTR)L"StartServiceCtrlDispatcher"); + } + } + + return 0; +} + +int +WindowsService::SvcMain() +{ + // Register the handler function for the service + + gSvcStatusHandle = RegisterServiceCtrlHandler(SVCNAME, SvcCtrlHandler); + + if (!gSvcStatusHandle) + { + SvcReportEvent((LPTSTR)TEXT("RegisterServiceCtrlHandler")); + + return 1; + } + + // These SERVICE_STATUS members remain as set here + + gSvcStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS; + gSvcStatus.dwServiceSpecificExitCode = 0; + + // Report initial status to the SCM + + ReportSvcStatus(SERVICE_START_PENDING, NO_ERROR, 3000); + + // Create an event. The control handler function, SvcCtrlHandler, + // signals this event when it receives the stop control code. + + ghSvcStopEvent = CreateEvent(NULL, // default security attributes + TRUE, // manual reset event + FALSE, // not signaled + NULL); // no name + + if (ghSvcStopEvent == NULL) + { + ReportSvcStatus(SERVICE_STOPPED, GetLastError(), 0); + + return 1; + } + + // Report running status when initialization is complete. + + ReportSvcStatus(SERVICE_RUNNING, NO_ERROR, 0); + + int ReturnCode = Run(); + + ReportSvcStatus(SERVICE_STOPPED, NO_ERROR, 0); + + return ReturnCode; +} + // // Purpose: // Retrieves and displays the current service configuration. @@ -147,7 +228,8 @@ void SvcDelete() // Return value: // None // -void __stdcall DoQuerySvc() +void +DoQuerySvc() { SC_HANDLE schSCManager{}; SC_HANDLE schService{}; @@ -249,6 +331,7 @@ cleanup: CloseServiceHandle(schService); CloseServiceHandle(schSCManager); } + // // Purpose: // Disables the service. @@ -259,7 +342,8 @@ cleanup: // Return value: // None // -VOID __stdcall DoDisableSvc() +void +DoDisableSvc() { SC_HANDLE schSCManager; SC_HANDLE schService; @@ -384,7 +468,8 @@ VOID __stdcall DoEnableSvc() // Return value: // None // -VOID __stdcall DoUpdateSvcDesc() +void +DoUpdateSvcDesc() { SC_HANDLE schSCManager; SC_HANDLE schService; @@ -435,100 +520,6 @@ VOID __stdcall DoUpdateSvcDesc() // // Purpose: -// Entry point for the service -// -// Parameters: -// dwArgc - Number of arguments in the lpszArgv array -// lpszArgv - Array of strings. The first string is the name of -// the service and subsequent strings are passed by the process -// that called the StartService function to start the service. -// -// Return value: -// None. -// -VOID WINAPI -SvcMain(DWORD dwArgc, LPTSTR* lpszArgv) -{ - // Register the handler function for the service - - gSvcStatusHandle = RegisterServiceCtrlHandler(SVCNAME, SvcCtrlHandler); - - if (!gSvcStatusHandle) - { - SvcReportEvent((LPTSTR)TEXT("RegisterServiceCtrlHandler")); - return; - } - - // These SERVICE_STATUS members remain as set here - - gSvcStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS; - gSvcStatus.dwServiceSpecificExitCode = 0; - - // Report initial status to the SCM - - ReportSvcStatus(SERVICE_START_PENDING, NO_ERROR, 3000); - - // Perform service-specific initialization and work. - - SvcInit(dwArgc, lpszArgv); -} - -// -// Purpose: -// The service code -// -// Parameters: -// dwArgc - Number of arguments in the lpszArgv array -// lpszArgv - Array of strings. The first string is the name of -// the service and subsequent strings are passed by the process -// that called the StartService function to start the service. -// -// Return value: -// None -// -VOID -SvcInit(DWORD dwArgc, LPTSTR* lpszArgv) -{ - // TO_DO: Declare and set any required variables. - // Be sure to periodically call ReportSvcStatus() with - // SERVICE_START_PENDING. If initialization fails, call - // ReportSvcStatus with SERVICE_STOPPED. - - ZEN_UNUSED(lpszArgv, dwArgc); - - // Create an event. The control handler function, SvcCtrlHandler, - // signals this event when it receives the stop control code. - - ghSvcStopEvent = CreateEvent(NULL, // default security attributes - TRUE, // manual reset event - FALSE, // not signaled - NULL); // no name - - if (ghSvcStopEvent == NULL) - { - ReportSvcStatus(SERVICE_STOPPED, GetLastError(), 0); - return; - } - - // Report running status when initialization is complete. - - ReportSvcStatus(SERVICE_RUNNING, NO_ERROR, 0); - - // TO_DO: Perform work until service stops. - - while (1) - { - // Check whether to stop the service. - - WaitForSingleObject(ghSvcStopEvent, INFINITE); - - ReportSvcStatus(SERVICE_STOPPED, NO_ERROR, 0); - return; - } -} - -// -// Purpose: // Sets the current service status and reports it to the SCM. // // Parameters: @@ -565,21 +556,13 @@ ReportSvcStatus(DWORD dwCurrentState, DWORD dwWin32ExitCode, DWORD dwWaitHint) SetServiceStatus(gSvcStatusHandle, &gSvcStatus); } -// -// Purpose: -// Called by SCM whenever a control code is sent to the service -// using the ControlService function. -// -// Parameters: -// dwCtrl - control code -// -// Return value: -// None -// -VOID WINAPI -SvcCtrlHandler(DWORD dwCtrl) +void +WindowsService::SvcCtrlHandler(DWORD dwCtrl) { // Handle the requested control code. + // + // Called by SCM whenever a control code is sent to the service + // using the ControlService function. switch (dwCtrl) { @@ -589,8 +572,9 @@ SvcCtrlHandler(DWORD dwCtrl) // Signal the service to stop. SetEvent(ghSvcStopEvent); - ReportSvcStatus(gSvcStatus.dwCurrentState, NO_ERROR, 0); + zen::RequestApplicationExit(0); + ReportSvcStatus(gSvcStatus.dwCurrentState, NO_ERROR, 0); return; case SERVICE_CONTROL_INTERROGATE: @@ -645,11 +629,3 @@ SvcReportEvent(LPTSTR szFunction) // DeregisterEventSource(hEventSource); //} } - -WindowsServiceBase::WindowsServiceBase() -{ -} - -WindowsServiceBase::~WindowsServiceBase() -{ -} |