mirror of
https://github.com/TrinityCore/TrinityCore.git
synced 2026-01-26 20:02:25 +01:00
Core/Common: Compile ServiceWin32 as part of common project instead of directly adding its source files to both server executables
(cherry picked from commit 052f2d0a81)
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -15,50 +15,50 @@
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
#include "Common.h"
|
||||
#include "Log.h"
|
||||
#include "ServiceWin32.h"
|
||||
#include <array> // for std::size
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <tchar.h>
|
||||
#include <windows.h>
|
||||
#include <winsvc.h>
|
||||
|
||||
#if !defined(WINADVAPI)
|
||||
#if !defined(_ADVAPI32_)
|
||||
#define WINADVAPI DECLSPEC_IMPORT
|
||||
#else
|
||||
#define WINADVAPI
|
||||
#endif
|
||||
#endif
|
||||
namespace
|
||||
{
|
||||
_TCHAR* ServiceLongName;
|
||||
_TCHAR* ServiceName;
|
||||
_TCHAR* ServiceDescription;
|
||||
int(*ServiceEntryPoint)(int argc, char** argv);
|
||||
int* ServiceStatusPtr;
|
||||
|
||||
extern int main(int argc, char ** argv);
|
||||
extern TCHAR serviceLongName[];
|
||||
extern TCHAR serviceName[];
|
||||
extern TCHAR serviceDescription[];
|
||||
SERVICE_STATUS ServiceStatus;
|
||||
SERVICE_STATUS_HANDLE ServiceStatusHandle = nullptr;
|
||||
}
|
||||
|
||||
extern int m_ServiceStatus;
|
||||
typedef BOOL (WINAPI *CSD_T)(SC_HANDLE, DWORD, LPCVOID);
|
||||
|
||||
SERVICE_STATUS serviceStatus;
|
||||
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;
|
||||
}
|
||||
|
||||
SERVICE_STATUS_HANDLE serviceStatusHandle = 0;
|
||||
|
||||
typedef WINADVAPI BOOL (WINAPI *CSD_T)(SC_HANDLE, DWORD, LPCVOID);
|
||||
|
||||
bool WinServiceInstall()
|
||||
int32 Trinity::Service::Install()
|
||||
{
|
||||
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)
|
||||
if (GetModuleFileName(nullptr, path, std::size(path)) > 0)
|
||||
{
|
||||
SC_HANDLE service;
|
||||
_tcscat(path, _T(" --service run"));
|
||||
service = CreateService(serviceControlManager,
|
||||
serviceName, // name of service
|
||||
serviceLongName, // service name to display
|
||||
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,
|
||||
@@ -72,25 +72,9 @@ bool WinServiceInstall()
|
||||
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(
|
||||
sdBuf.lpDescription = ServiceDescription;
|
||||
ChangeServiceConfig2(
|
||||
service, // handle to service
|
||||
SERVICE_CONFIG_DESCRIPTION, // change: description
|
||||
&sdBuf); // new data
|
||||
@@ -102,8 +86,8 @@ bool WinServiceInstall()
|
||||
ZeroMemory(&sfa, sizeof(SERVICE_FAILURE_ACTIONS));
|
||||
sfa.lpsaActions = _action;
|
||||
sfa.cActions = 1;
|
||||
sfa.dwResetPeriod =INFINITE;
|
||||
ChangeService_Config2(
|
||||
sfa.dwResetPeriod = INFINITE;
|
||||
ChangeServiceConfig2(
|
||||
service, // handle to service
|
||||
SERVICE_CONFIG_FAILURE_ACTIONS, // information level
|
||||
&sfa); // new data
|
||||
@@ -116,17 +100,17 @@ bool WinServiceInstall()
|
||||
}
|
||||
|
||||
printf("Service installed\n");
|
||||
return true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool WinServiceUninstall()
|
||||
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);
|
||||
ServiceName, SERVICE_QUERY_STATUS | DELETE);
|
||||
if (service)
|
||||
{
|
||||
SERVICE_STATUS serviceStatus2;
|
||||
@@ -142,7 +126,7 @@ bool WinServiceUninstall()
|
||||
}
|
||||
|
||||
printf("Service uninstalled\n");
|
||||
return true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void WINAPI ServiceControlHandler(DWORD controlCode)
|
||||
@@ -154,26 +138,26 @@ void WINAPI ServiceControlHandler(DWORD controlCode)
|
||||
|
||||
case SERVICE_CONTROL_SHUTDOWN:
|
||||
case SERVICE_CONTROL_STOP:
|
||||
serviceStatus.dwCurrentState = SERVICE_STOP_PENDING;
|
||||
SetServiceStatus(serviceStatusHandle, &serviceStatus);
|
||||
ServiceStatus.dwCurrentState = SERVICE_STOP_PENDING;
|
||||
SetServiceStatus(ServiceStatusHandle, &ServiceStatus);
|
||||
|
||||
m_ServiceStatus = 0;
|
||||
*ServiceStatusPtr = 0;
|
||||
return;
|
||||
|
||||
case SERVICE_CONTROL_PAUSE:
|
||||
m_ServiceStatus = 2;
|
||||
serviceStatus.dwCurrentState = SERVICE_PAUSED;
|
||||
SetServiceStatus(serviceStatusHandle, &serviceStatus);
|
||||
*ServiceStatusPtr = 2;
|
||||
ServiceStatus.dwCurrentState = SERVICE_PAUSED;
|
||||
SetServiceStatus(ServiceStatusHandle, &ServiceStatus);
|
||||
break;
|
||||
|
||||
case SERVICE_CONTROL_CONTINUE:
|
||||
serviceStatus.dwCurrentState = SERVICE_RUNNING;
|
||||
SetServiceStatus(serviceStatusHandle, &serviceStatus);
|
||||
m_ServiceStatus = 1;
|
||||
ServiceStatus.dwCurrentState = SERVICE_RUNNING;
|
||||
SetServiceStatus(ServiceStatusHandle, &ServiceStatus);
|
||||
*ServiceStatusPtr = 1;
|
||||
break;
|
||||
|
||||
default:
|
||||
if ( controlCode >= 128 && controlCode <= 255 )
|
||||
if (controlCode >= 128 && controlCode <= 255)
|
||||
// user defined control code
|
||||
break;
|
||||
else
|
||||
@@ -181,7 +165,7 @@ void WINAPI ServiceControlHandler(DWORD controlCode)
|
||||
break;
|
||||
}
|
||||
|
||||
SetServiceStatus(serviceStatusHandle, &serviceStatus);
|
||||
SetServiceStatus(ServiceStatusHandle, &ServiceStatus);
|
||||
}
|
||||
|
||||
template<size_t size>
|
||||
@@ -196,81 +180,77 @@ void TCharToChar(TCHAR const* src, char(&dst)[size])
|
||||
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;
|
||||
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);
|
||||
ServiceStatusHandle = RegisterServiceCtrlHandler(ServiceName, ServiceControlHandler);
|
||||
|
||||
if ( serviceStatusHandle )
|
||||
if (ServiceStatusHandle)
|
||||
{
|
||||
TCHAR path[_MAX_PATH + 1];
|
||||
unsigned int i, last_slash = 0;
|
||||
size_t 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;
|
||||
}
|
||||
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);
|
||||
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 );
|
||||
ServiceStatus.dwControlsAccepted |= (SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN);
|
||||
ServiceStatus.dwCurrentState = SERVICE_RUNNING;
|
||||
SetServiceStatus(ServiceStatusHandle, &ServiceStatus);
|
||||
|
||||
////////////////////////
|
||||
// service main cycle //
|
||||
////////////////////////
|
||||
|
||||
m_ServiceStatus = 1;
|
||||
*ServiceStatusPtr = 1;
|
||||
|
||||
char cArg[_MAX_PATH + 1];
|
||||
TCharToChar(argv[0], cArg);
|
||||
char* cArgv[] = { cArg };
|
||||
|
||||
main(1, cArgv);
|
||||
ServiceEntryPoint(1, cArgv);
|
||||
|
||||
// service was stopped
|
||||
serviceStatus.dwCurrentState = SERVICE_STOP_PENDING;
|
||||
SetServiceStatus(serviceStatusHandle, &serviceStatus);
|
||||
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);
|
||||
ServiceStatus.dwControlsAccepted &= ~(SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN);
|
||||
ServiceStatus.dwCurrentState = SERVICE_STOPPED;
|
||||
SetServiceStatus(ServiceStatusHandle, &ServiceStatus);
|
||||
}
|
||||
}
|
||||
|
||||
bool WinServiceRun()
|
||||
int32 Trinity::Service::Run()
|
||||
{
|
||||
SERVICE_TABLE_ENTRY serviceTable[] =
|
||||
{
|
||||
{ serviceName, ServiceMain },
|
||||
{ ServiceName, ServiceMain },
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
if (!StartServiceCtrlDispatcher(serviceTable))
|
||||
{
|
||||
TC_LOG_ERROR("server.worldserver", "StartService Failed. Error [{}]", uint32(::GetLastError()));
|
||||
return false;
|
||||
printf("StartService Failed. Error [%u]", uint32(::GetLastError()));
|
||||
return 1;
|
||||
}
|
||||
return true;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
@@ -15,13 +15,19 @@
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifdef _WIN32
|
||||
#ifndef _WIN32_SERVICE_
|
||||
#define _WIN32_SERVICE_
|
||||
#ifndef TRINITYCORE_WIN32_SERVICE
|
||||
#define TRINITYCORE_WIN32_SERVICE
|
||||
|
||||
bool WinServiceInstall();
|
||||
bool WinServiceUninstall();
|
||||
bool WinServiceRun();
|
||||
#include "Define.h"
|
||||
#include <tchar.h>
|
||||
|
||||
#endif // _WIN32_SERVICE_
|
||||
#endif // _WIN32
|
||||
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
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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.h>
|
||||
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<UINT> newTimerResolution;
|
||||
boost::system::error_code dllError;
|
||||
|
||||
Reference in New Issue
Block a user