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