2 * Empire - A multi-player, client/server Internet based war game.
3 * Copyright (C) 1986-2009, Dave Pare, Jeff Bailey, Thomas Ruschak,
4 * Ken Stevens, Steve McClure
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 * See files README, COPYING and CREDITS in the root of the source
23 * tree for related information and legal notices. It is expected
24 * that future projects/authors will amend these files as needed.
28 * service.c: Windows services support
30 * Known contributors to this file:
31 * Ron Koenderink, 2004-2009
37 * For WIN32 in empthread.h, winsock2.h is included which interferes
38 * with including windows.h, use sys/socket.h instead to prevent a
41 #include <sys/socket.h>
44 #include "empthread.h"
45 #include "prototypes.h"
48 install_service(char *program_name, char *service_name, char *config_file)
50 HANDLE schSCManager,schService;
51 SERVICE_DESCRIPTION sdBuf;
53 if (config_file != NULL)
54 snprintf(&program_name[strlen(program_name)], _MAX_PATH-strlen(program_name), " -e %s",
57 if (service_name == NULL)
58 service_name = DEFAULT_SERVICE_NAME;
59 else if (service_name[0] == '\0')
60 service_name = DEFAULT_SERVICE_NAME;
62 schSCManager = OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS);
64 if (schSCManager == NULL) {
65 fprintf(stderr, "install_service failed to open Service Control Manager\n");
69 schService = CreateService(schSCManager,
71 service_name, /* service name to display */
72 SERVICE_ALL_ACCESS, /* desired access */
73 SERVICE_WIN32_OWN_PROCESS, /* service type */
74 SERVICE_AUTO_START, /* start type */
75 SERVICE_ERROR_NORMAL, /* error control type */
76 program_name, /* service's binary */
77 NULL, /* no load ordering group */
78 NULL, /* no tag identifier */
79 NULL, /* database service dependency */
80 NULL, /* LocalSystem account */
81 NULL); /* no password */
83 if (schService == NULL) {
84 fprintf(stderr, "install_service failed to create service %s\n", service_name);
87 sdBuf.lpDescription = "Server for Empire game";
89 if(!ChangeServiceConfig2(
90 schService, /* handle to service */
91 SERVICE_CONFIG_DESCRIPTION, /* change: description */
92 &sdBuf)) { /* value: new description */
93 fprintf(stderr, "install_service failed to set the description\n");
96 printf("Service %s installed.\n", service_name);
97 CloseServiceHandle(schService);
102 remove_service(char *service_name)
107 if (service_name == NULL)
108 service_name = DEFAULT_SERVICE_NAME;
109 else if (service_name[0] == '\0')
110 service_name = DEFAULT_SERVICE_NAME;
112 schSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
114 if (schSCManager == NULL) {
115 fprintf(stderr, "remove_service failed to open Service Control Manager\n");
119 hService = OpenService(schSCManager, service_name, SERVICE_ALL_ACCESS);
121 if (hService == NULL) {
122 fprintf(stderr, "remove_service failed to open service %s\n", service_name);
126 if (DeleteService(hService) == 0) {
127 fprintf(stderr, "remove_service failed to remove service %s\n", service_name);
131 if (CloseServiceHandle(hService) == 0) {
132 fprintf(stderr, "remove_service failed to close service %s\n", service_name);
135 printf("Service %s removed.\n", service_name);
140 static SERVICE_STATUS service_status;
141 static SERVICE_STATUS_HANDLE service_status_handle;
144 service_ctrl_handler(DWORD Opcode)
147 case SERVICE_CONTROL_PAUSE:
148 service_status.dwCurrentState = SERVICE_PAUSED;
149 logerror("Pausing the service not supported");
152 case SERVICE_CONTROL_CONTINUE:
153 logerror("Continuing the service not supported");
154 service_status.dwCurrentState = SERVICE_RUNNING;
157 case SERVICE_CONTROL_STOP:
158 logerror("Service stopping");
159 empth_request_shutdown();
162 case SERVICE_CONTROL_INTERROGATE:
163 /* Fall through to send current status. */
167 logerror("Unrecognized opcode %ld in ServiceCtrlHandler",
171 /* Send current status. */
172 if (!SetServiceStatus (service_status_handle, &service_status))
173 logerror("SetServiceStatus error %ld",GetLastError());
178 service_main(DWORD argc, LPTSTR *argv)
182 service_status.dwServiceType = SERVICE_WIN32;
183 service_status.dwCurrentState = SERVICE_START_PENDING;
184 service_status.dwControlsAccepted = SERVICE_ACCEPT_STOP;
185 service_status.dwWin32ExitCode = 0;
186 service_status.dwServiceSpecificExitCode = 0;
187 service_status.dwCheckPoint = 0;
188 service_status.dwWaitHint = 0;
190 service_status_handle = RegisterServiceCtrlHandler(
191 DEFAULT_SERVICE_NAME, service_ctrl_handler);
193 if (service_status_handle == (SERVICE_STATUS_HANDLE)0) {
194 logerror("RegisterServiceCtrlHandler failed %lu\n", GetLastError());
201 /* Initialization complete - report running status. */
202 service_status.dwCurrentState = SERVICE_RUNNING;
203 service_status.dwCheckPoint = 0;
204 service_status.dwWaitHint = 0;
206 if (!SetServiceStatus (service_status_handle, &service_status)) {
207 logerror("SetServiceStatus error %ld\n", GetLastError());
210 sig = empth_wait_for_signal();
221 logerror("Service stopped");
222 service_status.dwWin32ExitCode = 0;
223 service_status.dwCurrentState = SERVICE_STOPPED;
224 service_status.dwCheckPoint = 0;
225 service_status.dwWaitHint = 0;
227 if (!SetServiceStatus (service_status_handle, &service_status))
228 logerror("Error while stopping service SetServiceStatus"
229 " error %ld", GetLastError());