1 mike 1.7 //%/////////////////////////////////////////////////////////////////////////////
2 //
|
3 kumpf 1.16 // Copyright (c) 2000, 2001, 2002 BMC Software, Hewlett-Packard Company, IBM,
4 // The Open Group, Tivoli Systems
|
5 mike 1.7 //
6 // Permission is hereby granted, free of charge, to any person obtaining a copy
|
7 kumpf 1.16 // of this software and associated documentation files (the "Software"), to
8 // deal in the Software without restriction, including without limitation the
9 // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
10 mike 1.7 // sell copies of the Software, and to permit persons to whom the Software is
11 // furnished to do so, subject to the following conditions:
12 //
|
13 kumpf 1.16 // THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN
|
14 mike 1.7 // ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED
15 // "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
|
16 kumpf 1.16 // LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
17 // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
18 // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
19 mike 1.7 // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 //
22 //==============================================================================
23 //
24 // Author: Mike Day (mdday@us.ibm.com)
25 //
|
26 mary 1.11 // Modified By: Mary Hinton (m.hinton@verizon.net)
|
27 kumpf 1.12 // Sushma Fernandes (sushma_fernandes@hp.com)
|
28 tony 1.22 // Yi Zhou, Hewlett-Packard Company (yi_zhou@hp.com)
29 // Tony Fiorentino (fiorentino_tony@emc.com)
|
30 kumpf 1.23 // Roger Kumpf, Hewlett-Packard Company (roger_kumpf@hp.com)
|
31 mike 1.7 //
32 //%/////////////////////////////////////////////////////////////////////////////
33
34 #include <windows.h>
35 #include <process.h> /* _beginthread, _endthread */
36 #include <tchar.h>
37 #include <direct.h>
38
|
39 tony 1.22 #include "service.cpp"
|
40 mike 1.7
41 PEGASUS_USING_PEGASUS;
42 PEGASUS_USING_STD;
43
|
44 tony 1.22 //-------------------------------------------------------------------------
45 // DEFINES
46 //-------------------------------------------------------------------------
47 #define PEGASUS_SERVICE_NAME "cimserver"
48 #define PEGASUS_DISPLAY_NAME "Pegasus CIM Object Manager"
49 #define PEGASUS_DESCRIPTION "Pegasus CIM Object Manager Service"
50
51 //-------------------------------------------------------------------------
52 // GLOBALS
53 //-------------------------------------------------------------------------
|
54 mike 1.7 CIMServer *server_windows;
|
55 tony 1.22 static Service pegasus_service(PEGASUS_SERVICE_NAME);
56 static HANDLE pegasus_service_event;
|
57 tony 1.26 static LPCSTR g_cimservice_key = TEXT("SYSTEM\\CurrentControlSet\\Services\\%s");
|
58 tony 1.22 static LPCSTR g_cimservice_home = TEXT("home");
59
60 //-------------------------------------------------------------------------
61 // PROTOTYPES
62 //-------------------------------------------------------------------------
63 int cimserver_windows_main(int flag, int argc, char **argv);
64 extern void GetOptions(ConfigManager *cm,
65 int &argc,
66 char **argv,
67 const String &pegasusHome);
68 static bool _getRegInfo(const char *lpchKeyword, char *lpchRetValue);
69 static bool _setRegInfo(const char *lpchKeyword, const char *lpchValue);
70 void setHome(String & home);
71
72 //-------------------------------------------------------------------------
73 // NO-OPs for windows platform
74 //-------------------------------------------------------------------------
75 int cimserver_fork(void) { return(0); }
76 int cimserver_kill(void) { return(0); }
|
77 konrad.r 1.28 void notify_parent(int id) { return(id); }
|
78 tony 1.22
79 //-------------------------------------------------------------------------
80 // START MONITOR Asynchronously
81 //-------------------------------------------------------------------------
82 static void __cdecl cimserver_windows_thread(void *parm)
83 {
84
85 // Get options (from command line and from configuration file); this
86 // removes corresponding options and their arguments fromt he command
87 // line.
|
88 mike 1.7
|
89 tony 1.22 String pegasusHome;
|
90 mike 1.7
|
91 tony 1.22 // Windows way to set home
92 setHome(pegasusHome);
|
93 mike 1.7
|
94 tony 1.22 ConfigManager::setPegasusHome(pegasusHome);
|
95 mike 1.7
|
96 tony 1.22 ConfigManager* configManager = ConfigManager::getInstance();
97 int dummy = 0;
|
98 mike 1.8
|
99 tony 1.22 try
|
100 mike 1.7 {
|
101 tony 1.22 GetOptions(configManager, dummy, NULL, pegasusHome);
|
102 mike 1.7 }
|
103 tony 1.22 catch (Exception&)
|
104 mike 1.7 {
105 exit(1);
106 }
107
|
108 kumpf 1.25 Boolean enableHttpConnection = String::equal(
109 configManager->getCurrentValue("enableHttpConnection"), "true");
110 Boolean enableHttpsConnection = String::equal(
111 configManager->getCurrentValue("enableHttpsConnection"), "true");
|
112 tony 1.22
|
113 kumpf 1.23 if (!enableHttpConnection && !enableHttpsConnection)
114 {
115 Logger::put(Logger::STANDARD_LOG, "CIMServer", Logger::WARNING,
116 "Neither HTTP nor HTTPS connection is enabled. "
117 "CIMServer will not be started.");
118 cerr << "Neither HTTP nor HTTPS connection is enabled. "
119 "CIMServer will not be started." << endl;
120 exit(1);
121 }
|
122 mike 1.8
|
123 kumpf 1.23 // Get the connection port configurations
|
124 tony 1.22
|
125 kumpf 1.23 Uint32 portNumberHttps;
126 Uint32 portNumberHttp;
|
127 tony 1.22
|
128 kumpf 1.23 if (enableHttpsConnection)
|
129 tony 1.22 {
|
130 kumpf 1.23 String httpsPort = configManager->getCurrentValue("httpsPort");
131 CString portString = httpsPort.getCString();
132 char* end = 0;
133 Uint32 port = strtol(portString, &end, 10);
134 assert(end != 0 && *end == '\0');
135
136 //
137 // Look up the WBEM-HTTPS port number
138 //
139 portNumberHttps = System::lookupPort(WBEM_HTTPS_SERVICE_NAME, port);
|
140 tony 1.22 }
|
141 kumpf 1.23
142 if (enableHttpConnection)
|
143 tony 1.22 {
|
144 kumpf 1.23 String httpPort = configManager->getCurrentValue("httpPort");
145 CString portString = httpPort.getCString();
146 char* end = 0;
147 Uint32 port = strtol(portString, &end, 10);
148 assert(end != 0 && *end == '\0');
149
150 //
151 // Look up the WBEM-HTTP port number
152 //
153 portNumberHttp = System::lookupPort(WBEM_HTTP_SERVICE_NAME, port);
|
154 tony 1.22 }
155
156 // Set up the Logger
157 String logsDirectory = String::EMPTY;
158 logsDirectory = configManager->getCurrentValue("logdir");
159 logsDirectory = ConfigManager::getHomedPath(configManager->getCurrentValue("logdir"));
160
161 Logger::setHomeDirectory(logsDirectory);
162
163 // Put server start message to the logger
164 Logger::put(Logger::STANDARD_LOG, PEGASUS_SERVICE_NAME, Logger::INFORMATION,
|
165 kumpf 1.25 "Started $0 version $1.", PEGASUS_NAME, PEGASUS_VERSION);
|
166 kumpf 1.23
|
167 tony 1.22 // try loop to bind the address, and run the server
168 try
169 {
170 Monitor monitor(true);
171
|
172 kumpf 1.23 CIMServer server(&monitor);
|
173 tony 1.22 server_windows = &server;
174
|
175 kumpf 1.23 if (enableHttpConnection)
176 {
177 server_windows->addAcceptor(false, portNumberHttp, false);
178 Logger::put(Logger::STANDARD_LOG, "CIMServer", Logger::INFORMATION,
179 "Listening on HTTP port $0.", portNumberHttp);
180 }
181 if (enableHttpsConnection)
182 {
183 server_windows->addAcceptor(false, portNumberHttps, true);
184 Logger::put(Logger::STANDARD_LOG, "CIMServer", Logger::INFORMATION,
185 "Listening on HTTPS port $0.", portNumberHttps);
186 }
|
187 tony 1.22
|
188 kumpf 1.23 server_windows->bind();
|
189 tony 1.22
190 while(!server_windows->terminated())
191 {
192 server_windows->runForever();
193 }
194 }
195 catch(Exception& e)
196 {
197 PEGASUS_STD(cerr) << "Error: " << e.getMessage() << PEGASUS_STD(endl);
198 }
199
200 _endthreadex(NULL);
201 }
|
202 mary 1.13
|
203 mike 1.7
|
204 tony 1.22 //-------------------------------------------------------------------------
205 // Windows NT Service Control Code
206 //-------------------------------------------------------------------------
|
207 kumpf 1.14
|
208 tony 1.22 //-------------------------------------------------------------------------
209 // SERVICE (no parameters)
210 //-------------------------------------------------------------------------
211 void cim_server_service(int argc, char **argv)
212 {
213 Service::ReturnCode status = Service::SERVICE_RETURN_SUCCESS;
214 char console_title[_MAX_PATH] = {0};
|
215 mike 1.7
|
216 tony 1.22 // Check if running from a console window
217 if (GetConsoleTitle(console_title, _MAX_PATH) > 0)
218 return;
|
219 mike 1.7
|
220 tony 1.22 pegasus_service_event = CreateEvent(NULL, FALSE, FALSE, NULL);
|
221 mike 1.8
|
222 tony 1.22 // Run should exit the process if a service
223 status = pegasus_service.Run(cimserver_windows_main);
|
224 mike 1.8
|
225 tony 1.22 // If we made it here there was a problem starting this process as a service
226 // Log the problem to the log file
|
227 mike 1.7
|
228 tony 1.22 // TODO: log or echo something here
|
229 mike 1.7 }
230
|
231 tony 1.22 //-------------------------------------------------------------------------
232 // START/STOP handler
233 //-------------------------------------------------------------------------
234 int cimserver_windows_main(int flag, int argc, char *argv[])
235 {
236 switch (flag)
237 {
238 case Service::STARTUP_FLAG:
239 if (_beginthread(cimserver_windows_thread, 0, NULL))
240 WaitForSingleObject(pegasus_service_event, INFINITE);
241 break;
|
242 mike 1.7
|
243 tony 1.22 case Service::SHUTDOWN_FLAG:
244 SetEvent(pegasus_service_event);
245 break;
246
247 default:
248 break;
249 }
|
250 mike 1.7
|
251 tony 1.22 return 0;
252 }
|
253 mike 1.7
|
254 tony 1.22 //-------------------------------------------------------------------------
255 // IS RUNNING?
256 //-------------------------------------------------------------------------
257 Boolean isCIMServerRunning(void)
258 {
259 Service::State state;
260 pegasus_service.GetState(&state);
|
261 mike 1.7
|
262 tony 1.22 return (state == Service::SERVICE_STATE_RUNNING) ? true : false;
263 }
|
264 mike 1.7
|
265 tony 1.22 //-------------------------------------------------------------------------
266 // INSTALL
267 //-------------------------------------------------------------------------
|
268 tony 1.26 bool cimserver_install_nt_service(char *service_name)
|
269 mike 1.7 {
|
270 tony 1.22 Service::ReturnCode status = Service::SERVICE_RETURN_SUCCESS;
|
271 tony 1.26 char filename[_MAX_PATH] = {0};
272 char displayname[_MAX_PATH] = {0};
273
274 // If service name is specified, override default
275 if (service_name == NULL)
276 {
277 strcpy(displayname, PEGASUS_DISPLAY_NAME);
278 }
279 else
280 {
281 pegasus_service.SetServiceName(service_name);
282 sprintf(displayname, "%s - %s", PEGASUS_DISPLAY_NAME, service_name);
283 }
|
284 tony 1.22
285 GetModuleFileName(NULL, filename, sizeof(filename));
|
286 tony 1.26 status = pegasus_service.Install(displayname, PEGASUS_DESCRIPTION, filename);
|
287 mike 1.7
|
288 tony 1.22 // Upon success, set home in registry
289 if (status == Service::SERVICE_RETURN_SUCCESS)
|
290 mike 1.7 {
|
291 tony 1.22 char pegasus_homepath[_MAX_PATH];
292 System::extract_file_path(filename, pegasus_homepath);
293 pegasus_homepath[strlen(pegasus_homepath)-1] = '\0';
294 strcpy(filename, pegasus_homepath);
295 System::extract_file_path(filename, pegasus_homepath);
296 pegasus_homepath[strlen(pegasus_homepath)-1] = '\0';
297 _setRegInfo(g_cimservice_home, pegasus_homepath);
|
298 mike 1.7 }
|
299 tony 1.22
300 return (status == Service::SERVICE_RETURN_SUCCESS) ? true : false;
301 }
302
303 //-------------------------------------------------------------------------
304 // REMOVE
305 //-------------------------------------------------------------------------
|
306 tony 1.26 bool cimserver_remove_nt_service(char *service_name)
|
307 tony 1.22 {
308 Service::ReturnCode status = Service::SERVICE_RETURN_SUCCESS;
309
|
310 tony 1.26 // If service name is specified, override default
311 if (service_name != NULL)
312 {
313 pegasus_service.SetServiceName(service_name);
314 }
315
|
316 tony 1.22 status = pegasus_service.Remove();
317
318 return (status == Service::SERVICE_RETURN_SUCCESS) ? true : false;
|
319 mike 1.7 }
320
|
321 tony 1.22 //-------------------------------------------------------------------------
322 // START
323 //-------------------------------------------------------------------------
|
324 tony 1.26 bool cimserver_start_nt_service(char *service_name)
|
325 tony 1.22 {
326 Service::ReturnCode status = Service::SERVICE_RETURN_SUCCESS;
327
|
328 tony 1.26 // If service name is specified, override default
329 if (service_name != NULL)
330 {
331 pegasus_service.SetServiceName(service_name);
332 }
333
|
334 tony 1.22 status = pegasus_service.Start(5);
335
336 return (status == Service::SERVICE_RETURN_SUCCESS) ? true : false;
337 }
|
338 mike 1.7
|
339 tony 1.22 //-------------------------------------------------------------------------
340 // STOP
341 //-------------------------------------------------------------------------
|
342 tony 1.26 bool cimserver_stop_nt_service(char *service_name)
|
343 mike 1.7 {
|
344 tony 1.22 Service::ReturnCode status = Service::SERVICE_RETURN_SUCCESS;
|
345 mike 1.7
|
346 tony 1.26 // If service name is specified, override default
347 if (service_name != NULL)
348 {
349 pegasus_service.SetServiceName(service_name);
350 }
351
|
352 tony 1.22 status = pegasus_service.Stop(5);
353
354 return (status == Service::SERVICE_RETURN_SUCCESS) ? true : false;
355 }
|
356 mike 1.7
|
357 tony 1.22 //-------------------------------------------------------------------------
358 // HELPER Utilities
359 //-------------------------------------------------------------------------
360 static bool _getRegInfo(const char *lpchKeyword, char *lpchRetValue)
361 {
362 HKEY hKey;
363 DWORD dw = _MAX_PATH;
|
364 tony 1.26 char subKey[_MAX_PATH] = {0};
365
366 sprintf(subKey, g_cimservice_key, pegasus_service.GetServiceName());
|
367 mike 1.7
|
368 tony 1.22 if ((RegOpenKeyEx(HKEY_LOCAL_MACHINE,
|
369 tony 1.26 subKey,
|
370 tony 1.22 0,
371 KEY_READ,
372 &hKey)) != ERROR_SUCCESS)
|
373 mike 1.7 {
|
374 tony 1.22 return false;
|
375 mike 1.7 }
376
|
377 tony 1.22 if ((RegQueryValueEx(hKey,
378 lpchKeyword,
379 NULL,
380 NULL,
381 (LPBYTE)lpchRetValue,
382 &dw)) != ERROR_SUCCESS)
|
383 mike 1.7 {
|
384 tony 1.22 RegCloseKey(hKey);
385 return false;
|
386 mike 1.7 }
387
|
388 tony 1.22 RegCloseKey(hKey);
389
390 return true;
|
391 mike 1.7 }
392
|
393 tony 1.22 static bool _setRegInfo(const char *lpchKeyword, const char *lpchValue)
|
394 mike 1.7 {
|
395 tony 1.22 HKEY hKey;
396 DWORD dw = _MAX_PATH;
397 char home_key[_MAX_PATH] = {0};
|
398 tony 1.26 char subKey[_MAX_PATH] = {0};
|
399 tony 1.22
400 if (lpchKeyword == NULL || lpchValue == NULL)
401 return false;
402
|
403 tony 1.26 sprintf(subKey, g_cimservice_key, pegasus_service.GetServiceName());
404
405 if ((RegCreateKeyEx (HKEY_LOCAL_MACHINE,
406 subKey,
|
407 tony 1.22 0,
408 NULL,
409 0,
410 KEY_ALL_ACCESS,
411 NULL,
412 &hKey,
413 NULL) != ERROR_SUCCESS))
414 {
415 return false;
416 }
417
418 if ((RegSetValueEx(hKey,
419 lpchKeyword,
420 0,
421 REG_SZ,
422 (CONST BYTE *)lpchValue,
423 (DWORD)(strlen(lpchValue)+1))) != ERROR_SUCCESS)
424 {
425 RegCloseKey(hKey);
426 return false;
427 }
|
428 mike 1.7
|
429 tony 1.22 RegCloseKey(hKey);
430
431 return true;
|
432 mike 1.7 }
433
|
434 tony 1.22 void setHome(String & home)
|
435 mike 1.7 {
|
436 tony 1.22 // Determine the absolute path to the running program
|
437 tony 1.27 char exe_pathname[_MAX_PATH] = {0};
438 char home_pathname[_MAX_PATH] = {0};
|
439 tony 1.22 GetModuleFileName(NULL, exe_pathname, sizeof(exe_pathname));
440
441 // Pegasus home search rules:
442 // - look in registry (if set)
443 // - if not found, look in PEGASUS_HOME (if set)
444 // - if not found, use exe directory minus one level
445
|
446 tony 1.27 bool found_reg = _getRegInfo("home", home_pathname);
447 if (found_reg == true)
|
448 tony 1.22 {
|
449 tony 1.27 // Make sure home matches
450 String current_home(home_pathname);
451 String current_exe(exe_pathname);
452 current_home.toLower();
453 current_exe.toLower();
454
455 Uint32 pos = current_exe.find(current_home);
456 if (pos != PEG_NOT_FOUND)
457 {
458 home = home_pathname;
459 }
460 else
461 {
462 found_reg = false;
463 }
|
464 tony 1.22 }
|
465 tony 1.27 if (found_reg == false)
|
466 tony 1.22 {
467 const char* tmp = getenv("PEGASUS_HOME");
468 if (tmp)
469 {
470 home = tmp;
471 }
472 else
473 {
474 // ASSUMPTION: At a minimum, the cimserver program is running
475 // from a "bin" directory
476 home = FileSystem::extractFilePath(exe_pathname);
477 home.remove(home.size()-1, 1);
478 home = FileSystem::extractFilePath(home);
479 home.remove(home.size()-1, 1);
480 }
|
481 mike 1.7 }
482 }
483
484
|
485 tony 1.22
|