]> rtime.felk.cvut.cz Git - orte.git/blob - orte/manager/service.c
Reformat the sources with orte/uncrustify script
[orte.git] / orte / manager / service.c
1 #include "orte_all.h"
2
3 HANDLE                         killServiceEvent = NULL;
4 static SERVICE_STATUS          ssStatus;       // current status of the service
5 static SERVICE_STATUS_HANDLE   sshStatusHandle;
6 static DWORD                   dwErr = 0;
7 static char                    szErr[1024] = "";
8
9 char                           *name_service = "ortemanager";
10 char                           *name_service_disp = "ortemanager";
11
12 int
13 managerInit(void);             //forward declaration
14 int
15 managerStart(void);            //forward declaration
16 int
17 managerStop(void);             //forward declaration
18
19 static void
20 AddToMessageLog(char *lpszMsg)
21 {
22   char    szMsg[2048];
23   HANDLE  hEventSource;
24   char *lpszStrings[2];
25
26   dwErr = GetLastError();
27   hEventSource = RegisterEventSource(NULL, name_service);
28   sprintf(szMsg, "%s error: %li", name_service, dwErr);
29   lpszStrings[0] = szMsg;
30   lpszStrings[1] = lpszMsg;
31   if (hEventSource != NULL) {
32     ReportEvent(hEventSource, // handle of event source
33                 EVENTLOG_ERROR_TYPE,  // event type
34                 0,                    // event category
35                 0,                    // event ID
36                 NULL,                 // current user's SID
37                 2,                    // strings in lpszStrings
38                 0,                    // no bytes of raw data
39                 (LPCSTR *)lpszStrings, // array of error strings
40                 NULL);                // no raw data
41     DeregisterEventSource(hEventSource);
42   }
43 }
44
45 BOOL
46 ReportStatusToSCMgr(DWORD dwCurrentState, DWORD dwWin32ExitCode,
47                     DWORD dwWaitHint)
48 {
49   static DWORD dwCheckPoint = 1;
50   BOOL fResult = TRUE;
51
52   if (dwCurrentState == SERVICE_START_PENDING)
53     ssStatus.dwControlsAccepted = 0;
54   else
55     ssStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP;
56   ssStatus.dwCurrentState = dwCurrentState;
57   ssStatus.dwWin32ExitCode = dwWin32ExitCode;
58   ssStatus.dwWaitHint = dwWaitHint;
59   if ((dwCurrentState == SERVICE_RUNNING) || (dwCurrentState == SERVICE_STOPPED))
60     ssStatus.dwCheckPoint = 0;
61   else
62     ssStatus.dwCheckPoint = dwCheckPoint++;
63   if (!(fResult = SetServiceStatus(sshStatusHandle, &ssStatus))) {
64     AddToMessageLog("SetServiceStatus");
65   }
66   return fResult;
67 }
68
69 void WINAPI
70 service_ctrl(DWORD dwCtrlCode)
71 {
72   switch (dwCtrlCode) {
73     case SERVICE_CONTROL_STOP:
74       ssStatus.dwCurrentState = SERVICE_STOP_PENDING;
75       managerStop();
76       SetEvent(killServiceEvent);
77       break;
78     case SERVICE_CONTROL_INTERROGATE:
79       break;
80     default:
81       break;
82   }
83   ReportStatusToSCMgr(ssStatus.dwCurrentState, NO_ERROR, 0);
84 }
85
86 void WINAPI
87 service_main(DWORD dwArgc, char **lpszArgv)
88 {
89   int       err;
90
91   sshStatusHandle = RegisterServiceCtrlHandler(name_service, service_ctrl);
92   if (sshStatusHandle) {
93     ssStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
94     ssStatus.dwServiceSpecificExitCode = 0;
95     killServiceEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
96     if (!killServiceEvent)
97       goto cleanup;
98     if (!ReportStatusToSCMgr(SERVICE_START_PENDING, NO_ERROR, 3000))
99       goto cleanup;
100     err = managerInit();
101     if (err < 0) {
102       AddToMessageLog("Starting communication");
103       dwErr = NO_ERROR;
104       goto cleanup;
105     }
106     managerStart();
107     if (!ReportStatusToSCMgr(SERVICE_RUNNING, NO_ERROR, 0))
108       goto cleanup;
109     WaitForSingleObject(killServiceEvent, INFINITE);
110     CloseHandle(killServiceEvent);
111   }
112 cleanup:
113   if (sshStatusHandle) {
114     ReportStatusToSCMgr(SERVICE_STOP_PENDING, dwErr, 0);
115     ReportStatusToSCMgr(SERVICE_STOPPED, dwErr, 0);
116   }
117 }
118
119 void
120 serviceDispatchTable(void)
121 {
122   SERVICE_TABLE_ENTRY dispatchTable[] = {
123     { name_service, (LPSERVICE_MAIN_FUNCTION)service_main },
124     { NULL, NULL }
125   };
126
127   if (!StartServiceCtrlDispatcher(dispatchTable)) {
128     AddToMessageLog("StartServiceCtrlDispatcher failed.");
129   }
130 }
131
132 char *
133 GetLastErrorText(char *lpszBuf, DWORD dwSize)
134 {
135   DWORD dwRet;
136   char *lpszTemp = NULL;
137
138   dwRet = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |FORMAT_MESSAGE_ARGUMENT_ARRAY,
139                         NULL,
140                         GetLastError(),
141                         LANG_NEUTRAL,
142                         (char *)&lpszTemp,
143                         0,
144                         NULL);
145   // supplied buffer is not long enough
146   if (!dwRet || ((long)dwSize < (long)dwRet+14)) {
147     lpszBuf[0] = '\0';
148   } else {
149     lpszTemp[lstrlen(lpszTemp)-2] = '\0';  //remove cr and newline character
150     sprintf(lpszBuf, "%s (%li)", lpszTemp, GetLastError());
151   }
152   if (lpszTemp)
153     LocalFree((HLOCAL)lpszTemp);
154   return lpszBuf;
155 }
156
157 void
158 installService(void)
159 {
160   SC_HANDLE   schService;
161   SC_HANDLE   schSCManager;
162   TCHAR       szPath[512];
163
164   if (GetModuleFileName(NULL, szPath, sizeof(szPath) - 1) == 0) {
165     printf("Unable to install %s - %s\n",
166            name_service,
167            GetLastErrorText(szErr, sizeof(szErr)));
168     return;
169   }
170   strcat(szPath, " -s");
171   schSCManager = OpenSCManager(NULL,  // machine (NULL == local)
172                                NULL,  // database (NULL == default)
173                                SC_MANAGER_ALL_ACCESS);   // access required
174   if (schSCManager) {
175     schService = CreateService(schSCManager,               // SCManager database
176                                name_service,               // name of service
177                                name_service_disp,          // name to display
178                                SERVICE_ALL_ACCESS,         // desired access
179                                SERVICE_WIN32_OWN_PROCESS,  // service type
180                                SERVICE_AUTO_START,         // start type
181                                SERVICE_ERROR_NORMAL,       // error control type
182                                szPath,                     // service's binary
183                                NULL,                       // no load ordering group
184                                NULL,                       // no tag identifier
185                                NULL,                       // dependencies
186                                NULL,                       // LocalSystem account
187                                NULL);                      // no password
188     if (schService) {
189       CloseServiceHandle(schSCManager);
190       printf("Service name (%s) instaled!\n", name_service);
191     } else {
192       printf("OpenSCManager failed - %s\n", GetLastErrorText(szErr, sizeof(szErr)));
193     }
194   }
195 }
196
197 void
198 removeService(void)
199 {
200   SC_HANDLE   schService;
201   SC_HANDLE   schSCManager;
202
203   schSCManager = OpenSCManager(NULL,          // machine (NULL == local)
204                                NULL,          // database (NULL == default)
205                                SC_MANAGER_ALL_ACCESS);   // access required
206   if (schSCManager) {
207     schService = OpenService(schSCManager, name_service, SERVICE_ALL_ACCESS);
208     if (schService) {
209       // try to stop the service
210       if (ControlService(schService, SERVICE_CONTROL_STOP, &ssStatus)) {
211         printf("Stopping %s.", name_service);
212         Sleep(100);
213         while (QueryServiceStatus(schService, &ssStatus)) {
214           if (ssStatus.dwCurrentState == SERVICE_STOP_PENDING) {
215             printf(".");
216             Sleep(100);
217           } else {
218             break;
219           }
220         }
221         if (ssStatus.dwCurrentState == SERVICE_STOPPED) {
222           printf("\n%s stopped.\n", name_service);
223         } else {
224           printf("\n%s failed to stop.\n", name_service);
225         }
226       }
227       // now remove the service
228       if (DeleteService(schService)) {
229         printf("%s removed.\n", name_service);
230       } else {
231         printf("DeleteService failed - %s\n", GetLastErrorText(szErr, sizeof(szErr)));
232       }
233       CloseServiceHandle(schService);
234     } else {
235       printf("OpenService failed - %s\n", GetLastErrorText(szErr, sizeof(szErr)));
236     }
237     CloseServiceHandle(schSCManager);
238   } else {
239     printf("OpenSCManager failed - %s\n", GetLastErrorText(szErr, sizeof(szErr)));
240   }
241 }