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