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