From 7e1e441dfadc157fbba8c05539fad6a5b9525ea4 Mon Sep 17 00:00:00 2001 From: Shauren Date: Sun, 15 Sep 2024 12:40:54 +0200 Subject: Core/Common: Compile ServiceWin32 as part of common project instead of directly adding its source files to both server executables (cherry picked from commit 052f2d0a81460ba484c27d05fe34673cf467c75e) --- src/common/CMakeLists.txt | 5 + src/common/Platform/ServiceWin32.cpp | 276 --------------------------- src/common/Platform/ServiceWin32.h | 27 --- src/common/Platform/Windows/ServiceWin32.cpp | 256 +++++++++++++++++++++++++ src/common/Platform/Windows/ServiceWin32.h | 33 ++++ src/server/CMakeLists.txt | 7 - src/server/authserver/Main.cpp | 7 +- src/server/worldserver/Main.cpp | 11 +- 8 files changed, 304 insertions(+), 318 deletions(-) delete mode 100644 src/common/Platform/ServiceWin32.cpp delete mode 100644 src/common/Platform/ServiceWin32.h create mode 100644 src/common/Platform/Windows/ServiceWin32.cpp create mode 100644 src/common/Platform/Windows/ServiceWin32.h diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt index c839bcf54cf..c2098260917 100644 --- a/src/common/CMakeLists.txt +++ b/src/common/CMakeLists.txt @@ -22,6 +22,11 @@ if(WIN32) WINDOWS_DEBUGGING_SOURCES) list(APPEND PRIVATE_SOURCES ${WINDOWS_DEBUGGING_SOURCES}) + CollectSourceFiles( + ${CMAKE_CURRENT_SOURCE_DIR}/Platform/Windows + WINDOWS_PLATFORM_SOURCES) + list(APPEND PRIVATE_SOURCES + ${WINDOWS_PLATFORM_SOURCES}) endif() if(USE_COREPCH) diff --git a/src/common/Platform/ServiceWin32.cpp b/src/common/Platform/ServiceWin32.cpp deleted file mode 100644 index 970bd5fbeeb..00000000000 --- a/src/common/Platform/ServiceWin32.cpp +++ /dev/null @@ -1,276 +0,0 @@ -/* - * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -#ifdef _WIN32 - -#include "Common.h" -#include "Log.h" -#include -#include -#include -#include - -#if !defined(WINADVAPI) -#if !defined(_ADVAPI32_) -#define WINADVAPI DECLSPEC_IMPORT -#else -#define WINADVAPI -#endif -#endif - -extern int main(int argc, char ** argv); -extern TCHAR serviceLongName[]; -extern TCHAR serviceName[]; -extern TCHAR serviceDescription[]; - -extern int m_ServiceStatus; - -SERVICE_STATUS serviceStatus; - -SERVICE_STATUS_HANDLE serviceStatusHandle = 0; - -typedef WINADVAPI BOOL (WINAPI *CSD_T)(SC_HANDLE, DWORD, LPCVOID); - -bool WinServiceInstall() -{ - SC_HANDLE serviceControlManager = OpenSCManager(0, 0, SC_MANAGER_CREATE_SERVICE); - - if (serviceControlManager) - { - TCHAR path[_MAX_PATH + 10]; - if (GetModuleFileName( 0, path, sizeof(path)/sizeof(path[0]) ) > 0) - { - SC_HANDLE service; - _tcscat(path, _T(" --service run")); - service = CreateService(serviceControlManager, - serviceName, // name of service - serviceLongName, // service name to display - SERVICE_ALL_ACCESS, // desired access - // service type - SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS, - SERVICE_AUTO_START, // start type - SERVICE_ERROR_IGNORE, // error control type - path, // service's binary - 0, // no load ordering group - 0, // no tag identifier - 0, // no dependencies - 0, // LocalSystem account - 0); // no password - if (service) - { - HMODULE advapi32 = GetModuleHandle(_T("ADVAPI32.DLL")); - if (!advapi32) - { - CloseServiceHandle(service); - CloseServiceHandle(serviceControlManager); - return false; - } - - CSD_T ChangeService_Config2 = (CSD_T) GetProcAddress(advapi32, "ChangeServiceConfig2A"); - if (!ChangeService_Config2) - { - CloseServiceHandle(service); - CloseServiceHandle(serviceControlManager); - return false; - } - - SERVICE_DESCRIPTION sdBuf; - sdBuf.lpDescription = serviceDescription; - ChangeService_Config2( - service, // handle to service - SERVICE_CONFIG_DESCRIPTION, // change: description - &sdBuf); // new data - - SC_ACTION _action[1]; - _action[0].Type = SC_ACTION_RESTART; - _action[0].Delay = 10000; - SERVICE_FAILURE_ACTIONS sfa; - ZeroMemory(&sfa, sizeof(SERVICE_FAILURE_ACTIONS)); - sfa.lpsaActions = _action; - sfa.cActions = 1; - sfa.dwResetPeriod =INFINITE; - ChangeService_Config2( - service, // handle to service - SERVICE_CONFIG_FAILURE_ACTIONS, // information level - &sfa); // new data - - CloseServiceHandle(service); - - } - } - CloseServiceHandle(serviceControlManager); - } - - printf("Service installed\n"); - return true; -} - -bool WinServiceUninstall() -{ - SC_HANDLE serviceControlManager = OpenSCManager(0, 0, SC_MANAGER_CONNECT); - - if (serviceControlManager) - { - SC_HANDLE service = OpenService(serviceControlManager, - serviceName, SERVICE_QUERY_STATUS | DELETE); - if (service) - { - SERVICE_STATUS serviceStatus2; - if (QueryServiceStatus(service, &serviceStatus2)) - { - if (serviceStatus2.dwCurrentState == SERVICE_STOPPED) - DeleteService(service); - } - CloseServiceHandle(service); - } - - CloseServiceHandle(serviceControlManager); - } - - printf("Service uninstalled\n"); - return true; -} - -void WINAPI ServiceControlHandler(DWORD controlCode) -{ - switch (controlCode) - { - case SERVICE_CONTROL_INTERROGATE: - break; - - case SERVICE_CONTROL_SHUTDOWN: - case SERVICE_CONTROL_STOP: - serviceStatus.dwCurrentState = SERVICE_STOP_PENDING; - SetServiceStatus(serviceStatusHandle, &serviceStatus); - - m_ServiceStatus = 0; - return; - - case SERVICE_CONTROL_PAUSE: - m_ServiceStatus = 2; - serviceStatus.dwCurrentState = SERVICE_PAUSED; - SetServiceStatus(serviceStatusHandle, &serviceStatus); - break; - - case SERVICE_CONTROL_CONTINUE: - serviceStatus.dwCurrentState = SERVICE_RUNNING; - SetServiceStatus(serviceStatusHandle, &serviceStatus); - m_ServiceStatus = 1; - break; - - default: - if ( controlCode >= 128 && controlCode <= 255 ) - // user defined control code - break; - else - // unrecognized control code - break; - } - - SetServiceStatus(serviceStatusHandle, &serviceStatus); -} - -template -void TCharToChar(TCHAR const* src, char(&dst)[size]) -{ - if constexpr (std::is_same_v) - ::strcpy_s(dst, src); - else - ::wcstombs_s(nullptr, dst, src, _TRUNCATE); -} - -void WINAPI ServiceMain(DWORD /*argc*/, TCHAR *argv[]) -{ - // initialise service status - serviceStatus.dwServiceType = SERVICE_WIN32; - serviceStatus.dwCurrentState = SERVICE_START_PENDING; - serviceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_PAUSE_CONTINUE; - serviceStatus.dwWin32ExitCode = NO_ERROR; - serviceStatus.dwServiceSpecificExitCode = NO_ERROR; - serviceStatus.dwCheckPoint = 0; - serviceStatus.dwWaitHint = 0; - - serviceStatusHandle = RegisterServiceCtrlHandler(serviceName, ServiceControlHandler); - - if ( serviceStatusHandle ) - { - TCHAR path[_MAX_PATH + 1]; - unsigned int i, last_slash = 0; - - GetModuleFileName(0, path, sizeof(path)/sizeof(path[0])); - - size_t pathLen = _tcslen(path); - for (i = 0; i < pathLen; i++) - { - if (path[i] == '\\') last_slash = i; - } - - path[last_slash] = 0; - - // service is starting - serviceStatus.dwCurrentState = SERVICE_START_PENDING; - SetServiceStatus(serviceStatusHandle, &serviceStatus); - - // do initialisation here - SetCurrentDirectory(path); - - // running - serviceStatus.dwControlsAccepted |= (SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN); - serviceStatus.dwCurrentState = SERVICE_RUNNING; - SetServiceStatus( serviceStatusHandle, &serviceStatus ); - - //////////////////////// - // service main cycle // - //////////////////////// - - m_ServiceStatus = 1; - - char cArg[_MAX_PATH + 1]; - TCharToChar(argv[0], cArg); - char* cArgv[] = { cArg }; - - main(1, cArgv); - - // service was stopped - serviceStatus.dwCurrentState = SERVICE_STOP_PENDING; - SetServiceStatus(serviceStatusHandle, &serviceStatus); - - // do cleanup here - - // service is now stopped - serviceStatus.dwControlsAccepted &= ~(SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN); - serviceStatus.dwCurrentState = SERVICE_STOPPED; - SetServiceStatus(serviceStatusHandle, &serviceStatus); - } -} - -bool WinServiceRun() -{ - SERVICE_TABLE_ENTRY serviceTable[] = - { - { serviceName, ServiceMain }, - { 0, 0 } - }; - - if (!StartServiceCtrlDispatcher(serviceTable)) - { - TC_LOG_ERROR("server.worldserver", "StartService Failed. Error [{}]", uint32(::GetLastError())); - return false; - } - return true; -} -#endif diff --git a/src/common/Platform/ServiceWin32.h b/src/common/Platform/ServiceWin32.h deleted file mode 100644 index baa983f8f6f..00000000000 --- a/src/common/Platform/ServiceWin32.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -#ifdef _WIN32 -#ifndef _WIN32_SERVICE_ -#define _WIN32_SERVICE_ - -bool WinServiceInstall(); -bool WinServiceUninstall(); -bool WinServiceRun(); - -#endif // _WIN32_SERVICE_ -#endif // _WIN32 diff --git a/src/common/Platform/Windows/ServiceWin32.cpp b/src/common/Platform/Windows/ServiceWin32.cpp new file mode 100644 index 00000000000..7cb2575e5bd --- /dev/null +++ b/src/common/Platform/Windows/ServiceWin32.cpp @@ -0,0 +1,256 @@ +/* + * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +#include "ServiceWin32.h" +#include // for std::size +#include +#include +#include +#include +#include + +namespace +{ +_TCHAR* ServiceLongName; +_TCHAR* ServiceName; +_TCHAR* ServiceDescription; +int(*ServiceEntryPoint)(int argc, char** argv); +int* ServiceStatusPtr; + +SERVICE_STATUS ServiceStatus; +SERVICE_STATUS_HANDLE ServiceStatusHandle = nullptr; +} + +typedef BOOL (WINAPI *CSD_T)(SC_HANDLE, DWORD, LPCVOID); + +void Trinity::Service::Init(_TCHAR* serviceLongName, _TCHAR* serviceName, _TCHAR* serviceDescription, int(* entryPoint)(int argc, char** argv), int* status) +{ + ServiceLongName = serviceLongName; + ServiceName = serviceName; + ServiceDescription = serviceDescription; + ServiceEntryPoint = entryPoint; + ServiceStatusPtr = status; +} + +int32 Trinity::Service::Install() +{ + SC_HANDLE serviceControlManager = OpenSCManager(0, 0, SC_MANAGER_CREATE_SERVICE); + + if (serviceControlManager) + { + TCHAR path[_MAX_PATH + 10]; + if (GetModuleFileName(nullptr, path, std::size(path)) > 0) + { + _tcscat(path, _T(" --service run")); + SC_HANDLE service = CreateService(serviceControlManager, + ServiceName, // name of service + ServiceLongName, // service name to display + SERVICE_ALL_ACCESS, // desired access + // service type + SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS, + SERVICE_AUTO_START, // start type + SERVICE_ERROR_IGNORE, // error control type + path, // service's binary + 0, // no load ordering group + 0, // no tag identifier + 0, // no dependencies + 0, // LocalSystem account + 0); // no password + if (service) + { + SERVICE_DESCRIPTION sdBuf; + sdBuf.lpDescription = ServiceDescription; + ChangeServiceConfig2( + service, // handle to service + SERVICE_CONFIG_DESCRIPTION, // change: description + &sdBuf); // new data + + SC_ACTION _action[1]; + _action[0].Type = SC_ACTION_RESTART; + _action[0].Delay = 10000; + SERVICE_FAILURE_ACTIONS sfa; + ZeroMemory(&sfa, sizeof(SERVICE_FAILURE_ACTIONS)); + sfa.lpsaActions = _action; + sfa.cActions = 1; + sfa.dwResetPeriod = INFINITE; + ChangeServiceConfig2( + service, // handle to service + SERVICE_CONFIG_FAILURE_ACTIONS, // information level + &sfa); // new data + + CloseServiceHandle(service); + + } + } + CloseServiceHandle(serviceControlManager); + } + + printf("Service installed\n"); + return 0; +} + +int32 Trinity::Service::Uninstall() +{ + SC_HANDLE serviceControlManager = OpenSCManager(0, 0, SC_MANAGER_CONNECT); + + if (serviceControlManager) + { + SC_HANDLE service = OpenService(serviceControlManager, + ServiceName, SERVICE_QUERY_STATUS | DELETE); + if (service) + { + SERVICE_STATUS serviceStatus2; + if (QueryServiceStatus(service, &serviceStatus2)) + { + if (serviceStatus2.dwCurrentState == SERVICE_STOPPED) + DeleteService(service); + } + CloseServiceHandle(service); + } + + CloseServiceHandle(serviceControlManager); + } + + printf("Service uninstalled\n"); + return 0; +} + +void WINAPI ServiceControlHandler(DWORD controlCode) +{ + switch (controlCode) + { + case SERVICE_CONTROL_INTERROGATE: + break; + + case SERVICE_CONTROL_SHUTDOWN: + case SERVICE_CONTROL_STOP: + ServiceStatus.dwCurrentState = SERVICE_STOP_PENDING; + SetServiceStatus(ServiceStatusHandle, &ServiceStatus); + + *ServiceStatusPtr = 0; + return; + + case SERVICE_CONTROL_PAUSE: + *ServiceStatusPtr = 2; + ServiceStatus.dwCurrentState = SERVICE_PAUSED; + SetServiceStatus(ServiceStatusHandle, &ServiceStatus); + break; + + case SERVICE_CONTROL_CONTINUE: + ServiceStatus.dwCurrentState = SERVICE_RUNNING; + SetServiceStatus(ServiceStatusHandle, &ServiceStatus); + *ServiceStatusPtr = 1; + break; + + default: + if (controlCode >= 128 && controlCode <= 255) + // user defined control code + break; + else + // unrecognized control code + break; + } + + SetServiceStatus(ServiceStatusHandle, &ServiceStatus); +} + +template +void TCharToChar(TCHAR const* src, char(&dst)[size]) +{ + if constexpr (std::is_same_v) + ::strcpy_s(dst, src); + else + ::wcstombs_s(nullptr, dst, src, _TRUNCATE); +} + +void WINAPI ServiceMain(DWORD /*argc*/, TCHAR *argv[]) +{ + // initialise service status + ServiceStatus.dwServiceType = SERVICE_WIN32; + ServiceStatus.dwCurrentState = SERVICE_START_PENDING; + ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_PAUSE_CONTINUE; + ServiceStatus.dwWin32ExitCode = NO_ERROR; + ServiceStatus.dwServiceSpecificExitCode = NO_ERROR; + ServiceStatus.dwCheckPoint = 0; + ServiceStatus.dwWaitHint = 0; + + ServiceStatusHandle = RegisterServiceCtrlHandler(ServiceName, ServiceControlHandler); + + if (ServiceStatusHandle) + { + TCHAR path[_MAX_PATH + 1]; + size_t last_slash = 0; + + size_t pathLen = GetModuleFileName(nullptr, path, std::size(path)); + for (size_t i = 0; i < pathLen; i++) + if (path[i] == '\\') + last_slash = i; + + path[last_slash] = 0; + + // service is starting + ServiceStatus.dwCurrentState = SERVICE_START_PENDING; + SetServiceStatus(ServiceStatusHandle, &ServiceStatus); + + // do initialisation here + SetCurrentDirectory(path); + + // running + ServiceStatus.dwControlsAccepted |= (SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN); + ServiceStatus.dwCurrentState = SERVICE_RUNNING; + SetServiceStatus(ServiceStatusHandle, &ServiceStatus); + + //////////////////////// + // service main cycle // + //////////////////////// + + *ServiceStatusPtr = 1; + + char cArg[_MAX_PATH + 1]; + TCharToChar(argv[0], cArg); + char* cArgv[] = { cArg }; + + ServiceEntryPoint(1, cArgv); + + // service was stopped + ServiceStatus.dwCurrentState = SERVICE_STOP_PENDING; + SetServiceStatus(ServiceStatusHandle, &ServiceStatus); + + // do cleanup here + + // service is now stopped + ServiceStatus.dwControlsAccepted &= ~(SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN); + ServiceStatus.dwCurrentState = SERVICE_STOPPED; + SetServiceStatus(ServiceStatusHandle, &ServiceStatus); + } +} + +int32 Trinity::Service::Run() +{ + SERVICE_TABLE_ENTRY serviceTable[] = + { + { ServiceName, ServiceMain }, + { 0, 0 } + }; + + if (!StartServiceCtrlDispatcher(serviceTable)) + { + printf("StartService Failed. Error [%u]", uint32(::GetLastError())); + return 1; + } + return 0; +} diff --git a/src/common/Platform/Windows/ServiceWin32.h b/src/common/Platform/Windows/ServiceWin32.h new file mode 100644 index 00000000000..8602c12fedf --- /dev/null +++ b/src/common/Platform/Windows/ServiceWin32.h @@ -0,0 +1,33 @@ +/* + * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +#ifndef TRINITYCORE_WIN32_SERVICE +#define TRINITYCORE_WIN32_SERVICE + +#include "Define.h" +#include + +namespace Trinity::Service +{ + TC_COMMON_API void Init(_TCHAR* serviceLongName, _TCHAR* serviceName, _TCHAR* serviceDescription, + int(*entryPoint)(int argc, char** argv), int* status); + TC_COMMON_API int32 Install(); + TC_COMMON_API int32 Uninstall(); + TC_COMMON_API int32 Run(); +} + +#endif // TRINITYCORE_WIN32_SERVICE diff --git a/src/server/CMakeLists.txt b/src/server/CMakeLists.txt index e4e795ba8a1..75dbc1d57ae 100644 --- a/src/server/CMakeLists.txt +++ b/src/server/CMakeLists.txt @@ -8,13 +8,6 @@ # WITHOUT ANY WARRANTY, to the extent permitted by law; without even the # implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -if(WIN32) - list(APPEND sources_windows - ${CMAKE_SOURCE_DIR}/src/common/Platform/ServiceWin32.cpp - ${CMAKE_SOURCE_DIR}/src/common/Platform/ServiceWin32.h - ) -endif(WIN32) - add_subdirectory(database) add_subdirectory(shared) add_subdirectory(game) diff --git a/src/server/authserver/Main.cpp b/src/server/authserver/Main.cpp index fa735217fca..6474b15429e 100644 --- a/src/server/authserver/Main.cpp +++ b/src/server/authserver/Main.cpp @@ -103,12 +103,13 @@ int main(int argc, char** argv) return 0; #if TRINITY_PLATFORM == TRINITY_PLATFORM_WINDOWS + Trinity::Service::Init(serviceLongName, serviceName, serviceDescription, &main, &m_ServiceStatus); if (winServiceAction == "install") - return WinServiceInstall() == true ? 0 : 1; + return Trinity::Service::Install(); if (winServiceAction == "uninstall") - return WinServiceUninstall() == true ? 0 : 1; + return Trinity::Service::Uninstall(); if (winServiceAction == "run") - return WinServiceRun() ? 0 : 1; + return Trinity::Service::Run(); #endif std::string configError; diff --git a/src/server/worldserver/Main.cpp b/src/server/worldserver/Main.cpp index 2b05c996ce3..b78a45fd3ae 100644 --- a/src/server/worldserver/Main.cpp +++ b/src/server/worldserver/Main.cpp @@ -74,7 +74,7 @@ namespace fs = boost::filesystem; #define _TRINITY_CORE_CONFIG_DIR "worldserver.conf.d" #endif -#ifdef _WIN32 +#if TRINITY_PLATFORM == TRINITY_PLATFORM_WINDOWS #include "ServiceWin32.h" #include TCHAR serviceName[] = _T("worldserver"); @@ -127,7 +127,7 @@ bool LoadRealmInfo(Trinity::Asio::IoContext& ioContext); variables_map GetConsoleArguments(int argc, char** argv, fs::path& configFile, fs::path& configDir, std::string& winServiceAction); /// Launch the Trinity server -extern int main(int argc, char** argv) +int main(int argc, char** argv) { Trinity::Impl::CurrentServerProcessHolder::_type = SERVER_PROCESS_WORLDSERVER; signal(SIGABRT, &Trinity::AbortHandler); @@ -146,12 +146,13 @@ extern int main(int argc, char** argv) return 0; #ifdef _WIN32 + Trinity::Service::Init(serviceLongName, serviceName, serviceDescription, &main, &m_ServiceStatus); if (winServiceAction == "install") - return WinServiceInstall() ? 0 : 1; + return Trinity::Service::Install(); if (winServiceAction == "uninstall") - return WinServiceUninstall() ? 0 : 1; + return Trinity::Service::Uninstall(); if (winServiceAction == "run") - return WinServiceRun() ? 0 : 1; + return Trinity::Service::Run(); Optional newTimerResolution; boost::system::error_code dllError; -- cgit v1.2.3