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