Fixed bug in StartupDelay handling
[public/netxms.git] / src / agent / core / service.cpp
CommitLineData
e7474978
VK
1/*
2** NetXMS multiplatform core agent
3** Copyright (C) 2003, 2004 Victor Kirhenshtein
4**
5** This program is free software; you can redistribute it and/or modify
6** it under the terms of the GNU General Public License as published by
7** the Free Software Foundation; either version 2 of the License, or
8** (at your option) any later version.
9**
10** This program is distributed in the hope that it will be useful,
11** but WITHOUT ANY WARRANTY; without even the implied warranty of
12** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13** GNU General Public License for more details.
14**
15** You should have received a copy of the GNU General Public License
16** along with this program; if not, write to the Free Software
17** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18**
19** $module: service.cpp
20**
21**/
22
23#include "nxagentd.h"
24
25
26//
27// Static data
28//
29
30static SERVICE_STATUS_HANDLE serviceHandle;
31
32
33//
34// Service control handler
35//
36
37static VOID WINAPI ServiceCtrlHandler(DWORD ctrlCode)
38{
39 SERVICE_STATUS status;
40
41 status.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
42 status.dwCurrentState = SERVICE_RUNNING;
43 status.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN;
44 status.dwWin32ExitCode = 0;
45 status.dwServiceSpecificExitCode = 0;
46 status.dwCheckPoint = 0;
47 status.dwWaitHint = 0;
48
49 switch(ctrlCode)
50 {
51 case SERVICE_CONTROL_STOP:
52 case SERVICE_CONTROL_SHUTDOWN:
53 status.dwCurrentState = SERVICE_STOP_PENDING;
54 status.dwWaitHint = 4000;
55 SetServiceStatus(serviceHandle, &status);
56
57 Shutdown();
58
59 status.dwCurrentState = SERVICE_STOPPED;
60 status.dwWaitHint = 0;
61 break;
62 default:
63 break;
64 }
65
66 SetServiceStatus(serviceHandle, &status);
67}
68
69
70//
71// Service main
72//
73
74static VOID WINAPI AgentServiceMain(DWORD argc, LPTSTR *argv)
75{
76 SERVICE_STATUS status;
77
78 serviceHandle = RegisterServiceCtrlHandler(AGENT_SERVICE_NAME, ServiceCtrlHandler);
79
80 // Now we start service initialization
81 status.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
82 status.dwCurrentState = SERVICE_START_PENDING;
83 status.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN;
84 status.dwWin32ExitCode = 0;
85 status.dwServiceSpecificExitCode = 0;
86 status.dwCheckPoint = 0;
d231de5d 87 status.dwWaitHint = 3000 + g_dwStartupDelay * 1000;
e7474978
VK
88 SetServiceStatus(serviceHandle, &status);
89
90 // Actual initialization
91 if (!Initialize())
92 {
93 Shutdown();
94
95 // Now service is stopped
96 status.dwCurrentState = SERVICE_STOPPED;
97 status.dwWaitHint = 0;
98 SetServiceStatus(serviceHandle, &status);
99 return;
100 }
101
102 // Now service is running
103 status.dwCurrentState = SERVICE_RUNNING;
104 status.dwWaitHint = 0;
105 SetServiceStatus(serviceHandle, &status);
106
107 Main();
108}
109
110
111//
112// Initialize service
113//
114
115void InitService(void)
116{
117 static SERVICE_TABLE_ENTRY serviceTable[2]={ { AGENT_SERVICE_NAME, AgentServiceMain }, { NULL, NULL } };
e9580fef 118 char szErrorText[256];
e7474978
VK
119
120 if (!StartServiceCtrlDispatcher(serviceTable))
e9580fef
VK
121 printf("StartServiceCtrlDispatcher() failed: %s\n",
122 GetSystemErrorText(GetLastError(), szErrorText, 256));
e7474978
VK
123}
124
125
126//
127// Create service
128//
129
130void InstallService(char *execName, char *confFile)
131{
132 SC_HANDLE mgr, service;
e9580fef 133 char cmdLine[MAX_PATH*2], szErrorText[256];
e7474978
VK
134
135 mgr = OpenSCManager(NULL, NULL, GENERIC_WRITE);
136 if (mgr == NULL)
137 {
e9580fef
VK
138 printf("ERROR: Cannot connect to Service Manager (%s)\n",
139 GetSystemErrorText(GetLastError(), szErrorText, 256));
e7474978
VK
140 return;
141 }
142
143 sprintf(cmdLine,"\"%s\" -d -c \"%s\"", execName, confFile);
144 service=CreateService(mgr, AGENT_SERVICE_NAME, "NetXMS Agent", GENERIC_READ,SERVICE_WIN32_OWN_PROCESS,
145 SERVICE_AUTO_START,SERVICE_ERROR_NORMAL,cmdLine,NULL,NULL,NULL,NULL,NULL);
146 if (service == NULL)
147 {
148 DWORD code = GetLastError();
149
150 if (code == ERROR_SERVICE_EXISTS)
151 printf("ERROR: Service named '" AGENT_SERVICE_NAME "' already exist\n");
152 else
e9580fef 153 printf("ERROR: Cannot create service (%s)\n", GetSystemErrorText(code, szErrorText, 256));
e7474978
VK
154 }
155 else
156 {
157 printf("Win32 Agent service created successfully\n");
158 CloseServiceHandle(service);
159 }
160
161 CloseServiceHandle(mgr);
162
163 InstallEventSource(execName);
164}
165
166
167//
168// Remove service
169//
170
171void RemoveService(void)
172{
173 SC_HANDLE mgr, service;
e9580fef 174 char szErrorText[256];
e7474978
VK
175
176 mgr = OpenSCManager(NULL,NULL,GENERIC_WRITE);
177 if (mgr==NULL)
178 {
e9580fef
VK
179 printf("ERROR: Cannot connect to Service Manager (%s)\n",
180 GetSystemErrorText(GetLastError(), szErrorText, 256));
e7474978
VK
181 return;
182 }
183
184 service=OpenService(mgr, AGENT_SERVICE_NAME, DELETE);
185 if (service==NULL)
186 {
187 printf("ERROR: Cannot open service named '" AGENT_SERVICE_NAME "' (%s)\n",
e9580fef 188 GetSystemErrorText(GetLastError(), szErrorText, 256));
e7474978
VK
189 }
190 else
191 {
192 if (DeleteService(service))
193 printf("Win32 Agent service deleted successfully\n");
194 else
195 printf("ERROR: Cannot remove service named '" AGENT_SERVICE_NAME "' (%s)\n",
e9580fef 196 GetSystemErrorText(GetLastError(), szErrorText, 256));
e7474978
VK
197
198 CloseServiceHandle(service);
199 }
200
201 CloseServiceHandle(mgr);
202
203 RemoveEventSource();
204}
205
206
207//
208// Start service
209//
210
211void StartAgentService(void)
212{
213 SC_HANDLE mgr, service;
e9580fef 214 char szErrorText[256];
e7474978
VK
215
216 mgr = OpenSCManager(NULL, NULL, GENERIC_WRITE);
217 if (mgr == NULL)
218 {
e9580fef
VK
219 printf("ERROR: Cannot connect to Service Manager (%s)\n",
220 GetSystemErrorText(GetLastError(), szErrorText, 256));
e7474978
VK
221 return;
222 }
223
224 service = OpenService(mgr, AGENT_SERVICE_NAME, SERVICE_START);
225 if (service == NULL)
226 {
227 printf("ERROR: Cannot open service named '" AGENT_SERVICE_NAME "' (%s)\n",
e9580fef 228 GetSystemErrorText(GetLastError(), szErrorText, 256));
e7474978
VK
229 }
230 else
231 {
232 if (StartService(service, 0, NULL))
233 printf("Win32 Agent service started successfully\n");
234 else
235 printf("ERROR: Cannot start service named '" AGENT_SERVICE_NAME "' (%s)\n",
e9580fef 236 GetSystemErrorText(GetLastError(), szErrorText, 256));
e7474978
VK
237
238 CloseServiceHandle(service);
239 }
240
241 CloseServiceHandle(mgr);
242}
243
244
245//
246// Stop service
247//
248
249void StopAgentService(void)
250{
251 SC_HANDLE mgr, service;
e9580fef 252 char szErrorText[256];
e7474978
VK
253
254 mgr = OpenSCManager(NULL, NULL, GENERIC_WRITE);
255 if (mgr == NULL)
256 {
e9580fef
VK
257 printf("ERROR: Cannot connect to Service Manager (%s)\n",
258 GetSystemErrorText(GetLastError(), szErrorText, 256));
e7474978
VK
259 return;
260 }
261
262 service = OpenService(mgr, AGENT_SERVICE_NAME, SERVICE_STOP);
263 if (service == NULL)
264 {
265 printf("ERROR: Cannot open service named '" AGENT_SERVICE_NAME "' (%s)\n",
e9580fef 266 GetSystemErrorText(GetLastError(), szErrorText, 256));
e7474978
VK
267 }
268 else
269 {
270 SERVICE_STATUS status;
271
272 if (ControlService(service,SERVICE_CONTROL_STOP,&status))
273 printf("Win32 Agent service stopped successfully\n");
274 else
275 printf("ERROR: Cannot stop service named '" AGENT_SERVICE_NAME "' (%s)\n",
e9580fef 276 GetSystemErrorText(GetLastError(), szErrorText, 256));
e7474978
VK
277
278 CloseServiceHandle(service);
279 }
280
281 CloseServiceHandle(mgr);
282}
283
284
285//
286// Install event source
287//
288
289void InstallEventSource(char *path)
290{
291 HKEY hKey;
292 DWORD dwTypes = EVENTLOG_ERROR_TYPE | EVENTLOG_WARNING_TYPE | EVENTLOG_INFORMATION_TYPE;
e9580fef 293 char szErrorText[256];
e7474978
VK
294
295 if (ERROR_SUCCESS != RegCreateKeyEx(HKEY_LOCAL_MACHINE,
296 "System\\CurrentControlSet\\Services\\EventLog\\System\\" AGENT_EVENT_SOURCE,
297 0,NULL,REG_OPTION_NON_VOLATILE,KEY_SET_VALUE,NULL,&hKey,NULL))
298 {
e9580fef
VK
299 printf("Unable to create registry key: %s\n",
300 GetSystemErrorText(GetLastError(), szErrorText, 256));
e7474978
VK
301 return;
302 }
303
304 RegSetValueEx(hKey, "TypesSupported", 0, REG_DWORD, (BYTE *)&dwTypes, sizeof(DWORD));
305 RegSetValueEx(hKey, "EventMessageFile", 0, REG_EXPAND_SZ, (BYTE *)path, strlen(path) + 1);
306
307 RegCloseKey(hKey);
308 printf("Event source \"" AGENT_EVENT_SOURCE "\" installed successfully\n");
309}
310
311
312//
313// Remove event source
314//
315
316void RemoveEventSource(void)
317{
e9580fef
VK
318 char szErrorText[256];
319
e7474978
VK
320 if (ERROR_SUCCESS == RegDeleteKey(HKEY_LOCAL_MACHINE,
321 "System\\CurrentControlSet\\Services\\EventLog\\System\\" AGENT_EVENT_SOURCE))
322 {
323 printf("Event source \"" AGENT_EVENT_SOURCE "\" uninstalled successfully\n");
324 }
325 else
326 {
327 printf("Unable to uninstall event source \"" AGENT_EVENT_SOURCE "\": %s\n",
e9580fef 328 GetSystemErrorText(GetLastError(), szErrorText, 256));
e7474978
VK
329 }
330}