00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034 #include <config.h>
00035
00036 #include <windows.h>
00037
00038 #include "service.h"
00039 #include "empthread.h"
00040 #include "prototypes.h"
00041
00042 int
00043 install_service(char *program_name, char *service_name, char *config_file)
00044 {
00045 HANDLE schSCManager,schService;
00046 SERVICE_DESCRIPTION sdBuf;
00047
00048 if (config_file != NULL)
00049 snprintf(&program_name[strlen(program_name)], _MAX_PATH-strlen(program_name), " -e %s",
00050 config_file);
00051
00052 if (service_name == NULL)
00053 service_name = DEFAULT_SERVICE_NAME;
00054 else if (service_name[0] == '\0')
00055 service_name = DEFAULT_SERVICE_NAME;
00056
00057 schSCManager = OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS);
00058
00059 if (schSCManager == NULL) {
00060 fprintf(stderr, "install_service failed to open Service Control Manager\n");
00061 return EXIT_FAILURE;
00062 }
00063
00064 schService = CreateService(schSCManager,
00065 service_name,
00066 service_name,
00067 SERVICE_ALL_ACCESS,
00068 SERVICE_WIN32_OWN_PROCESS,
00069 SERVICE_AUTO_START,
00070 SERVICE_ERROR_NORMAL,
00071 program_name,
00072 NULL,
00073 NULL,
00074 NULL,
00075 NULL,
00076 NULL);
00077
00078 if (schService == NULL) {
00079 fprintf(stderr, "install_service failed to create service %s\n", service_name);
00080 return EXIT_FAILURE;
00081 }
00082 sdBuf.lpDescription = "Server for Empire game";
00083
00084 if(!ChangeServiceConfig2(
00085 schService,
00086 SERVICE_CONFIG_DESCRIPTION,
00087 &sdBuf)) {
00088 fprintf(stderr, "install_service failed to set the description\n");
00089 }
00090
00091 printf("Service %s installed.\n", service_name);
00092 CloseServiceHandle(schService);
00093 return EXIT_SUCCESS;
00094 }
00095
00096 int
00097 remove_service(char *service_name)
00098 {
00099 HANDLE schSCManager;
00100 SC_HANDLE hService;
00101
00102 if (service_name == NULL)
00103 service_name = DEFAULT_SERVICE_NAME;
00104 else if (service_name[0] == '\0')
00105 service_name = DEFAULT_SERVICE_NAME;
00106
00107 schSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
00108
00109 if (schSCManager == NULL) {
00110 fprintf(stderr, "remove_service failed to open Service Control Manager\n");
00111 return EXIT_FAILURE;
00112 }
00113
00114 hService = OpenService(schSCManager, service_name, SERVICE_ALL_ACCESS);
00115
00116 if (hService == NULL) {
00117 fprintf(stderr, "remove_service failed to open service %s\n", service_name);
00118 return EXIT_FAILURE;
00119 }
00120
00121 if (DeleteService(hService) == 0) {
00122 fprintf(stderr, "remove_service failed to remove service %s\n", service_name);
00123 return EXIT_FAILURE;
00124 }
00125
00126 if (CloseServiceHandle(hService) == 0) {
00127 fprintf(stderr, "remove_service failed to close service %s\n", service_name);
00128 return EXIT_FAILURE;
00129 } else {
00130 printf("Service %s removed.\n", service_name);
00131 return EXIT_SUCCESS;
00132 }
00133 }
00134
00135 static SERVICE_STATUS service_status;
00136 static SERVICE_STATUS_HANDLE service_status_handle;
00137
00138 static void WINAPI
00139 service_ctrl_handler(DWORD Opcode)
00140 {
00141 switch(Opcode) {
00142 case SERVICE_CONTROL_PAUSE:
00143 service_status.dwCurrentState = SERVICE_PAUSED;
00144 logerror("Pausing the service not supported");
00145 break;
00146
00147 case SERVICE_CONTROL_CONTINUE:
00148 logerror("Continuing the service not supported");
00149 service_status.dwCurrentState = SERVICE_RUNNING;
00150 break;
00151
00152 case SERVICE_CONTROL_STOP:
00153 logerror("Service stopping");
00154 empth_request_shutdown();
00155 return;
00156
00157 case SERVICE_CONTROL_INTERROGATE:
00158
00159 break;
00160
00161 default:
00162 logerror("Unrecognized opcode %ld in ServiceCtrlHandler",
00163 Opcode);
00164 }
00165
00166
00167 if (!SetServiceStatus (service_status_handle, &service_status))
00168 logerror("SetServiceStatus error %ld",GetLastError());
00169 return;
00170 }
00171
00172 void WINAPI
00173 service_main(DWORD argc, LPTSTR *argv)
00174 {
00175 int sig;
00176
00177 service_status.dwServiceType = SERVICE_WIN32;
00178 service_status.dwCurrentState = SERVICE_START_PENDING;
00179 service_status.dwControlsAccepted = SERVICE_ACCEPT_STOP;
00180 service_status.dwWin32ExitCode = 0;
00181 service_status.dwServiceSpecificExitCode = 0;
00182 service_status.dwCheckPoint = 0;
00183 service_status.dwWaitHint = 0;
00184
00185 service_status_handle = RegisterServiceCtrlHandler(
00186 DEFAULT_SERVICE_NAME, service_ctrl_handler);
00187
00188 if (service_status_handle == (SERVICE_STATUS_HANDLE)0) {
00189 logerror("RegisterServiceCtrlHandler failed %lu\n", GetLastError());
00190 finish_server();
00191 return;
00192 }
00193
00194 start_server(0);
00195
00196
00197 service_status.dwCurrentState = SERVICE_RUNNING;
00198 service_status.dwCheckPoint = 0;
00199 service_status.dwWaitHint = 0;
00200
00201 if (!SetServiceStatus (service_status_handle, &service_status)) {
00202 logerror("SetServiceStatus error %ld\n", GetLastError());
00203 }
00204
00205 sig = empth_wait_for_signal();
00206
00207 shutdwn(sig);
00208
00209 CANT_REACH();
00210 finish_server();
00211 }
00212
00213 void
00214 stop_service(void)
00215 {
00216 logerror("Service stopped");
00217 service_status.dwWin32ExitCode = 0;
00218 service_status.dwCurrentState = SERVICE_STOPPED;
00219 service_status.dwCheckPoint = 0;
00220 service_status.dwWaitHint = 0;
00221
00222 if (!SetServiceStatus (service_status_handle, &service_status))
00223 logerror("Error while stopping service SetServiceStatus"
00224 " error %ld", GetLastError());
00225 }