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 dj.gorey 1.6 #ifdef PEGASUS_USE_23HTTPMONITOR_CLIENT
|
205 kumpf 1.3 Monitor monitor(true);
|
206 dj.gorey 1.5 #else
207 monitor_2 monitor();
208 #endif
|
209 kumpf 1.3
210 CIMServer server(&monitor);
211 server_windows = &server;
|
212 kumpf 1.2
|
213 kumpf 1.3 if (enableHttpConnection)
|
214 kumpf 1.1 {
|
215 kumpf 1.7 server_windows->addAcceptor(false, portNumberHttp, false, false);
|
216 kumpf 1.3 Logger::put(Logger::STANDARD_LOG, "CIMServer", Logger::INFORMATION,
217 "Listening on HTTP port $0.", portNumberHttp);
|
218 kumpf 1.1 }
|
219 kumpf 1.2 if (enableHttpsConnection)
|
220 kumpf 1.1 {
|
221 kumpf 1.7 server_windows->addAcceptor(false, portNumberHttps, true, false);
|
222 kumpf 1.3 Logger::put(Logger::STANDARD_LOG, "CIMServer", Logger::INFORMATION,
223 "Listening on HTTPS port $0.", portNumberHttps);
|
224 kumpf 1.1 }
|
225 kumpf 1.7 if (enableSSLExportClientVerification)
226 {
227 server_windows->addAcceptor(false, portNumberExportHttps, true, true);
228 Logger::put(Logger::STANDARD_LOG, "CIMServer", Logger::INFORMATION,
229 "Listening on HTTPS port $0.", portNumberExportHttps);
230 }
|
231 kumpf 1.2
|
232 kumpf 1.3 server_windows->bind();
233
234 while(!server_windows->terminated())
|
235 kumpf 1.1 {
|
236 kumpf 1.3 server_windows->runForever();
|
237 kumpf 1.1 }
|
238 kumpf 1.3 }
239 catch(Exception& e)
240 {
241 PEGASUS_STD(cerr) << "Error: " << e.getMessage() << PEGASUS_STD(endl);
242 }
|
243 kumpf 1.1
|
244 kumpf 1.3 _endthreadex(NULL);
|
245 kumpf 1.1 }
246
247
|
248 kumpf 1.3 //-------------------------------------------------------------------------
|
249 kumpf 1.1 // Windows NT Service Control Code
|
250 kumpf 1.3 //-------------------------------------------------------------------------
251
252 //-------------------------------------------------------------------------
253 // SERVICE (no parameters)
254 //-------------------------------------------------------------------------
255 void cim_server_service(int argc, char **argv)
|
256 kumpf 1.2 {
|
257 kumpf 1.3 Service::ReturnCode status = Service::SERVICE_RETURN_SUCCESS;
258 char console_title[_MAX_PATH] = {0};
259
260 // Check if running from a console window
261 if (GetConsoleTitle(console_title, _MAX_PATH) > 0)
262 return;
263
264 pegasus_service_event = CreateEvent(NULL, FALSE, FALSE, NULL);
265
266 // Run should exit the process if a service
267 status = pegasus_service.Run(cimserver_windows_main);
|
268 kumpf 1.1
|
269 kumpf 1.3 // If we made it here there was a problem starting this process as a service
270 // Log the problem to the log file
|
271 kumpf 1.1
|
272 kumpf 1.3 // TODO: log or echo something here
|
273 kumpf 1.1 }
274
|
275 kumpf 1.3 //-------------------------------------------------------------------------
276 // START/STOP handler
277 //-------------------------------------------------------------------------
278 int cimserver_windows_main(int flag, int argc, char *argv[])
|
279 kumpf 1.1 {
|
280 kumpf 1.3 switch (flag)
281 {
282 case Service::STARTUP_FLAG:
283 if (_beginthread(cimserver_windows_thread, 0, NULL))
284 WaitForSingleObject(pegasus_service_event, INFINITE);
285 break;
286
287 case Service::SHUTDOWN_FLAG:
288 SetEvent(pegasus_service_event);
289 break;
290
291 default:
292 break;
293 }
|
294 kumpf 1.1
|
295 kumpf 1.3 return 0;
296 }
|
297 kumpf 1.2
|
298 kumpf 1.3 //-------------------------------------------------------------------------
299 // IS RUNNING?
300 //-------------------------------------------------------------------------
301 Boolean isCIMServerRunning(void)
302 {
303 Service::State state;
304 pegasus_service.GetState(&state);
|
305 kumpf 1.1
|
306 kumpf 1.3 return (state == Service::SERVICE_STATE_RUNNING) ? true : false;
307 }
|
308 kumpf 1.1
|
309 kumpf 1.3 //-------------------------------------------------------------------------
310 // INSTALL
311 //-------------------------------------------------------------------------
312 bool cimserver_install_nt_service(char *service_name)
313 {
314 Service::ReturnCode status = Service::SERVICE_RETURN_SUCCESS;
315 char filename[_MAX_PATH] = {0};
316 char displayname[_MAX_PATH] = {0};
|
317 kumpf 1.2
|
318 kumpf 1.3 // If service name is specified, override default
319 if (service_name == NULL)
320 {
321 strcpy(displayname, PEGASUS_DISPLAY_NAME);
322 }
323 else
324 {
325 pegasus_service.SetServiceName(service_name);
326 sprintf(displayname, "%s - %s", PEGASUS_DISPLAY_NAME, service_name);
327 }
|
328 kumpf 1.2
|
329 kumpf 1.3 GetModuleFileName(NULL, filename, sizeof(filename));
330 status = pegasus_service.Install(displayname, PEGASUS_DESCRIPTION, filename);
|
331 kumpf 1.1
|
332 kumpf 1.3 // Upon success, set home in registry
333 if (status == Service::SERVICE_RETURN_SUCCESS)
|
334 kumpf 1.1 {
|
335 kumpf 1.3 char pegasus_homepath[_MAX_PATH];
336 System::extract_file_path(filename, pegasus_homepath);
337 pegasus_homepath[strlen(pegasus_homepath)-1] = '\0';
338 strcpy(filename, pegasus_homepath);
339 System::extract_file_path(filename, pegasus_homepath);
340 pegasus_homepath[strlen(pegasus_homepath)-1] = '\0';
341 _setRegInfo(g_cimservice_home, pegasus_homepath);
342 }
343
344 return (status == Service::SERVICE_RETURN_SUCCESS) ? true : false;
345 }
346
347 //-------------------------------------------------------------------------
348 // REMOVE
349 //-------------------------------------------------------------------------
350 bool cimserver_remove_nt_service(char *service_name)
351 {
352 Service::ReturnCode status = Service::SERVICE_RETURN_SUCCESS;
|
353 kumpf 1.1
|
354 kumpf 1.3 // If service name is specified, override default
355 if (service_name != NULL)
356 {
357 pegasus_service.SetServiceName(service_name);
358 }
|
359 kumpf 1.1
|
360 kumpf 1.3 status = pegasus_service.Remove();
|
361 kumpf 1.1
|
362 kumpf 1.3 return (status == Service::SERVICE_RETURN_SUCCESS) ? true : false;
|
363 kumpf 1.1 }
364
|
365 kumpf 1.3 //-------------------------------------------------------------------------
366 // START
367 //-------------------------------------------------------------------------
368 bool cimserver_start_nt_service(char *service_name)
|
369 kumpf 1.1 {
|
370 kumpf 1.3 Service::ReturnCode status = Service::SERVICE_RETURN_SUCCESS;
371
372 // If service name is specified, override default
373 if (service_name != NULL)
374 {
375 pegasus_service.SetServiceName(service_name);
376 }
377
378 status = pegasus_service.Start(5);
|
379 kumpf 1.1
|
380 kumpf 1.3 return (status == Service::SERVICE_RETURN_SUCCESS) ? true : false;
|
381 kumpf 1.1 }
382
|
383 kumpf 1.3 //-------------------------------------------------------------------------
384 // STOP
385 //-------------------------------------------------------------------------
386 bool cimserver_stop_nt_service(char *service_name)
|
387 kumpf 1.1 {
|
388 kumpf 1.3 Service::ReturnCode status = Service::SERVICE_RETURN_SUCCESS;
389
390 // If service name is specified, override default
391 if (service_name != NULL)
392 {
393 pegasus_service.SetServiceName(service_name);
394 }
395
396 status = pegasus_service.Stop(5);
397
398 return (status == Service::SERVICE_RETURN_SUCCESS) ? true : false;
|
399 kumpf 1.1 }
|
400 kumpf 1.3
401 //-------------------------------------------------------------------------
402 // HELPER Utilities
403 //-------------------------------------------------------------------------
404 static bool _getRegInfo(const char *lpchKeyword, char *lpchRetValue)
|
405 kumpf 1.2 {
|
406 kumpf 1.3 HKEY hKey;
407 DWORD dw = _MAX_PATH;
408 char subKey[_MAX_PATH] = {0};
|
409 kumpf 1.1
|
410 kumpf 1.3 sprintf(subKey, g_cimservice_key, pegasus_service.GetServiceName());
411
412 if ((RegOpenKeyEx(HKEY_LOCAL_MACHINE,
413 subKey,
414 0,
415 KEY_READ,
416 &hKey)) != ERROR_SUCCESS)
417 {
418 return false;
419 }
420
421 if ((RegQueryValueEx(hKey,
422 lpchKeyword,
423 NULL,
424 NULL,
425 (LPBYTE)lpchRetValue,
426 &dw)) != ERROR_SUCCESS)
427 {
428 RegCloseKey(hKey);
429 return false;
430 }
431 kumpf 1.3
432 RegCloseKey(hKey);
433
434 return true;
|
435 kumpf 1.1 }
436
|
437 kumpf 1.3 static bool _setRegInfo(const char *lpchKeyword, const char *lpchValue)
|
438 kumpf 1.1 {
|
439 kumpf 1.3 HKEY hKey;
440 DWORD dw = _MAX_PATH;
441 char home_key[_MAX_PATH] = {0};
442 char subKey[_MAX_PATH] = {0};
443
444 if (lpchKeyword == NULL || lpchValue == NULL)
445 return false;
446
447 sprintf(subKey, g_cimservice_key, pegasus_service.GetServiceName());
448
449 if ((RegCreateKeyEx (HKEY_LOCAL_MACHINE,
450 subKey,
451 0,
452 NULL,
453 0,
454 KEY_ALL_ACCESS,
455 NULL,
456 &hKey,
457 NULL) != ERROR_SUCCESS))
458 {
459 return false;
460 kumpf 1.3 }
461
462 if ((RegSetValueEx(hKey,
463 lpchKeyword,
464 0,
465 REG_SZ,
466 (CONST BYTE *)lpchValue,
467 (DWORD)(strlen(lpchValue)+1))) != ERROR_SUCCESS)
468 {
469 RegCloseKey(hKey);
470 return false;
471 }
|
472 kumpf 1.1
|
473 kumpf 1.3 RegCloseKey(hKey);
|
474 kumpf 1.2
|
475 kumpf 1.3 return true;
|
476 kumpf 1.1 }
|
477 kumpf 1.3
478 void setHome(String & home)
479 {
480 // Determine the absolute path to the running program
481 char exe_pathname[_MAX_PATH] = {0};
482 char home_pathname[_MAX_PATH] = {0};
483 GetModuleFileName(NULL, exe_pathname, sizeof(exe_pathname));
484
485 // Pegasus home search rules:
486 // - look in registry (if set)
487 // - if not found, look in PEGASUS_HOME (if set)
488 // - if not found, use exe directory minus one level
489
490 bool found_reg = _getRegInfo("home", home_pathname);
491 if (found_reg == true)
492 {
493 // Make sure home matches
494 String current_home(home_pathname);
495 String current_exe(exe_pathname);
496 current_home.toLower();
497 current_exe.toLower();
498 kumpf 1.3
499 Uint32 pos = current_exe.find(current_home);
500 if (pos != PEG_NOT_FOUND)
501 {
502 home = home_pathname;
503 }
504 else
505 {
506 found_reg = false;
507 }
508 }
509 if (found_reg == false)
510 {
511 const char* tmp = getenv("PEGASUS_HOME");
512 if (tmp)
513 {
514 home = tmp;
515 }
516 else
517 {
518 // ASSUMPTION: At a minimum, the cimserver program is running
519 kumpf 1.3 // from a "bin" directory
520 home = FileSystem::extractFilePath(exe_pathname);
521 home.remove(home.size()-1, 1);
522 home = FileSystem::extractFilePath(home);
523 home.remove(home.size()-1, 1);
524 }
525 }
|
526 karl 1.4 }
527
|