2 * Empire - A multi-player, client/server Internet based war game.
3 * Copyright (C) 1986-2004, 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 the "LEGAL", "LICENSE", "CREDITS" and "README" files for all the
23 * related information and legal notices. It is expected that any future
24 * projects/authors will amend these files as needed.
28 * service.c: Windows services support
30 * Known contributors to this file:
31 * Ron Koenderink, 2004
37 #include "prototypes.h"
39 #include "../gen/getopt.h"
43 install_service(char *program_name, char *service_name, int datadir_set, char *config_file)
46 HANDLE schSCManager,schService;
47 LPCTSTR lpszBinaryPathName;
48 SERVICE_DESCRIPTION sdBuf;
50 if (strrchr(program_name,'\\') == NULL) {
51 GetCurrentDirectory(sizeof(strDir), strDir);
53 strcat(strDir, program_name);
55 strcpy(strDir, program_name);
58 strcat(strDir, " -D ");
59 strcat(strDir, datadir);
61 if (config_file != NULL) {
62 strcat(strDir, " -e ");
63 strcat(strDir, config_file);
66 if (service_name == NULL)
67 service_name = DEFAULT_SERVICE_NAME;
68 else if (service_name[0] == '\0')
69 service_name = DEFAULT_SERVICE_NAME;
71 schSCManager = OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS);
73 if (schSCManager == NULL) {
74 logerror("install_service failed to open Service Control Manager");
75 printf("Install service: failed to open Service Control Manager.\n");
79 lpszBinaryPathName = strDir;
81 schService = CreateService(schSCManager,
83 service_name, /* service name to display */
84 SERVICE_ALL_ACCESS, /* desired access */
85 SERVICE_WIN32_OWN_PROCESS, /* service type */
86 SERVICE_AUTO_START, /* start type */
87 SERVICE_ERROR_NORMAL, /* error control type */
88 lpszBinaryPathName, /* service's binary */
89 NULL, /* no load ordering group */
90 NULL, /* no tag identifier */
91 NULL, /* database service dependency */
92 NULL, /* LocalSystem account */
93 NULL); /* no password */
95 if (schService == NULL) {
96 logerror("install_service failed to create service %s", service_name);
97 printf("Install service: failed to create service %s.\n", service_name);
100 sdBuf.lpDescription = "Server for Empire game";
102 if(!ChangeServiceConfig2(
103 schService, /* handle to service */
104 SERVICE_CONFIG_DESCRIPTION, /* change: description */
105 &sdBuf)) { /* value: new description */
106 logerror("install_service failed to set the description");
107 printf("Install service: failed to set the description.\n");
110 logerror("install_service successfully created the service %s", service_name);
111 printf("Service %s installed.\n", service_name);
112 CloseServiceHandle(schService);
117 remove_service(char *service_name)
122 if (service_name == NULL)
123 service_name = DEFAULT_SERVICE_NAME;
124 else if (service_name[0] == '\0')
125 service_name = DEFAULT_SERVICE_NAME;
127 schSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
129 if (schSCManager == NULL) {
130 logerror("remove_service failed to open Service Control Manager");
131 printf("remove service: failed to open Service Control Manager.\n");
135 hService = OpenService(schSCManager, service_name, SERVICE_ALL_ACCESS);
137 if (hService == NULL) {
138 logerror("remove_service failed to open service %s", service_name);
139 printf("Remove service: failed to open service %s.\n", service_name);
143 if (DeleteService(hService) == 0) {
144 logerror("remove_service failed to remove service %s", service_name);
145 printf("Remove service: failed to remove service %s.\n", service_name);
149 if (CloseServiceHandle(hService) == 0) {
150 logerror("remove_service failed to close service %s", service_name);
151 printf("Remove service: failed to close service %s.\n", service_name);
154 logerror("remove_service successfully removed service %s", service_name);
155 printf("Service %s removed.\n", service_name);
160 static SERVICE_STATUS service_status;
161 static SERVICE_STATUS_HANDLE service_status_handle;
164 service_ctrl_handler(DWORD Opcode)
170 case SERVICE_CONTROL_PAUSE:
171 service_status.dwCurrentState = SERVICE_PAUSED;
172 logerror("Pausing the service not supported");
175 case SERVICE_CONTROL_CONTINUE:
176 logerror("Continuing the service not supported");
177 service_status.dwCurrentState = SERVICE_RUNNING;
180 case SERVICE_CONTROL_STOP:
181 service_status.dwWin32ExitCode = 0;
182 service_status.dwCurrentState = SERVICE_STOPPED;
183 service_status.dwCheckPoint = 0;
184 service_status.dwWaitHint = 0;
186 if (!SetServiceStatus (service_status_handle,
188 status = GetLastError();
189 logerror("Error while stopping service SetServiceStatus"
190 " error %ld", status);
193 logerror("Service stopped");
196 case SERVICE_CONTROL_INTERROGATE:
197 /* Fall through to send current status. */
201 logerror("Unrecognized opcode %ld in ServiceCtrlHandler",
205 /* Send current status. */
206 if (!SetServiceStatus (service_status_handle, &service_status)) {
207 status = GetLastError();
208 logerror("SetServiceStatus error %ld",status);
214 service_main(DWORD argc, LPTSTR *argv)
219 char *config_file = NULL;
223 while ((op = getopt(argc, argv, "D:e:")) != EOF) {
229 config_file = optarg;
234 if (config_file == NULL) {
235 sprintf(tbuf, "%s/econfig", datadir);
238 emp_config(config_file);
240 service_status.dwServiceType = SERVICE_WIN32;
241 service_status.dwCurrentState = SERVICE_START_PENDING;
242 service_status.dwControlsAccepted = SERVICE_ACCEPT_STOP;
243 service_status.dwWin32ExitCode = 0;
244 service_status.dwServiceSpecificExitCode = 0;
245 service_status.dwCheckPoint = 0;
246 service_status.dwWaitHint = 0;
248 service_status_handle = RegisterServiceCtrlHandler(
249 DEFAULT_SERVICE_NAME, service_ctrl_handler);
251 if (service_status_handle == (SERVICE_STATUS_HANDLE)0) {
252 logerror("RegisterServiceCtrlHandler failed %d\n", GetLastError());
256 /* Initialization code goes here. */
260 /* Initialization complete - report running status. */
261 service_status.dwCurrentState = SERVICE_RUNNING;
262 service_status.dwCheckPoint = 0;
263 service_status.dwWaitHint = 0;
265 if (!SetServiceStatus (service_status_handle, &service_status)) {
266 status = GetLastError();
267 logerror("SetServiceStatus error %ld\n",status);
272 /* We should never get here. But, just in case... */
277 // This is where the service does its work.
278 logerror("Returning the Main Thread \n",0);
283 service_stopped(void)
285 if (service_status.dwCurrentState == SERVICE_STOPPED)