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 kumpf 1.1 //
40 //%/////////////////////////////////////////////////////////////////////////////
41
42 #include <windows.h>
43 #include <process.h> /* _beginthread, _endthread */
44 #include <tchar.h>
45 #include <direct.h>
46
|
47 kumpf 1.3 #include "service.cpp"
48
|
49 kumpf 1.1 PEGASUS_USING_PEGASUS;
50 PEGASUS_USING_STD;
51
|
52 kumpf 1.3 //-------------------------------------------------------------------------
53 // DEFINES
54 //-------------------------------------------------------------------------
55 #define PEGASUS_SERVICE_NAME "wmiserver"
56 #define PEGASUS_DISPLAY_NAME "Pegasus WMI Mapper"
57 #define PEGASUS_DESCRIPTION "Pegasus WBEM to WMI Mapper Manager Service"
58
59 //-------------------------------------------------------------------------
60 // GLOBALS
61 //-------------------------------------------------------------------------
|
62 kumpf 1.1 CIMServer *server_windows;
|
63 kumpf 1.3 static Service pegasus_service(PEGASUS_SERVICE_NAME);
64 static HANDLE pegasus_service_event;
65 static LPCSTR g_cimservice_key = TEXT("SYSTEM\\CurrentControlSet\\Services\\%s");
66 static LPCSTR g_cimservice_home = TEXT("home");
67
68 //-------------------------------------------------------------------------
69 // PROTOTYPES
70 //-------------------------------------------------------------------------
71 int cimserver_windows_main(int flag, int argc, char **argv);
72 extern void GetOptions(ConfigManager *cm,
73 int &argc,
74 char **argv,
75 const String &pegasusHome);
76 static bool _getRegInfo(const char *lpchKeyword, char *lpchRetValue);
77 static bool _setRegInfo(const char *lpchKeyword, const char *lpchValue);
78 void setHome(String & home);
79
80 //-------------------------------------------------------------------------
81 // NO-OPs for windows platform
82 //-------------------------------------------------------------------------
83 int cimserver_fork(void) { return(0); }
84 kumpf 1.3 int cimserver_kill(void) { return(0); }
85 void notify_parent(int id) { return; }
86
87 //-------------------------------------------------------------------------
88 // START MONITOR Asynchronously
89 //-------------------------------------------------------------------------
90 static void __cdecl cimserver_windows_thread(void *parm)
91 {
|
92 kumpf 1.1
|
93 kumpf 1.3 // Get options (from command line and from configuration file); this
94 // removes corresponding options and their arguments fromt he command
95 // line.
96
97 String pegasusHome;
|
98 kumpf 1.2
|
99 kumpf 1.3 // Windows way to set home
100 setHome(pegasusHome);
|
101 kumpf 1.1
|
102 kumpf 1.3 ConfigManager::setPegasusHome(pegasusHome);
|
103 kumpf 1.1
|
104 kumpf 1.3 ConfigManager* configManager = ConfigManager::getInstance();
105 int dummy = 0;
|
106 kumpf 1.1
|
107 kumpf 1.3 try
|
108 kumpf 1.1 {
|
109 kumpf 1.3 GetOptions(configManager, dummy, NULL, pegasusHome);
|
110 kumpf 1.1 }
|
111 kumpf 1.3 catch (Exception&)
|
112 kumpf 1.1 {
|
113 kumpf 1.3 exit(1);
|
114 kumpf 1.1 }
115
|
116 kumpf 1.3 Boolean enableHttpConnection = String::equal(
117 configManager->getCurrentValue("enableHttpConnection"), "true");
118 Boolean enableHttpsConnection = String::equal(
119 configManager->getCurrentValue("enableHttpsConnection"), "true");
|
120 kumpf 1.7 Boolean enableSSLExportClientVerification = String::equal(
121 configManager->getCurrentValue("enableSSLExportClientVerification"), "true");
|
122 kumpf 1.3
123 if (!enableHttpConnection && !enableHttpsConnection)
124 {
125 Logger::put(Logger::STANDARD_LOG, "CIMServer", Logger::WARNING,
126 "Neither HTTP nor HTTPS connection is enabled. "
127 "CIMServer will not be started.");
128 cerr << "Neither HTTP nor HTTPS connection is enabled. "
129 "CIMServer will not be started." << endl;
130 exit(1);
131 }
132
133 // Get the connection port configurations
134
135 Uint32 portNumberHttps;
136 Uint32 portNumberHttp;
|
137 kumpf 1.7 Uint32 portNumberExportHttps;
|
138 kumpf 1.3
139 if (enableHttpsConnection)
140 {
141 String httpsPort = configManager->getCurrentValue("httpsPort");
142 CString portString = httpsPort.getCString();
143 char* end = 0;
144 Uint32 port = strtol(portString, &end, 10);
145 assert(end != 0 && *end == '\0');
146
147 //
148 // Look up the WBEM-HTTPS port number
|
149 kumpf 1.1 //
|
150 kumpf 1.3 portNumberHttps = System::lookupPort(WBEM_HTTPS_SERVICE_NAME, port);
151 }
|
152 kumpf 1.1
|
153 kumpf 1.3 if (enableHttpConnection)
154 {
155 String httpPort = configManager->getCurrentValue("httpPort");
156 CString portString = httpPort.getCString();
157 char* end = 0;
158 Uint32 port = strtol(portString, &end, 10);
159 assert(end != 0 && *end == '\0');
|
160 kumpf 1.1
161 //
|
162 kumpf 1.3 // Look up the WBEM-HTTP port number
163 //
164 portNumberHttp = System::lookupPort(WBEM_HTTP_SERVICE_NAME, port);
165 }
|
166 kumpf 1.1
|
167 kumpf 1.7 if (enableSSLExportClientVerification)
168 {
169 //
170 // No config property is looked up to get the default port number.
171 // Lookup the port defined in /etc/services for the service name
172 // wbem-exp-https and bind to that port. If the service is not defined
173 // then log a warning message and do not start the cimserver.
174 //
175 Uint32 port = 0;
176
177 portNumberExportHttps = System::lookupPort(WBEM_EXPORT_HTTPS_SERVICE_NAME, port);
178
179 if (portNumberExportHttps == 0)
180 {
181 Logger::put_l(Logger::STANDARD_LOG, System::CIMSERVER, Logger::WARNING,
182 "src.Server.cimserver.EXPORT_HTTPS_PORT_NOT_DEFINED",
183 "Port not defined for the service wbem-exp-https. CIMServer will not be started.");
184
185 MessageLoaderParms parms("src.Server.cimserver.EXPORT_HTTPS_PORT_NOT_DEFINED",
186 "Port not defined for the service wbem-exp-https. CIMServer will not be started.");
187
188 kumpf 1.7 cerr << MessageLoader::getMessage(parms) << endl;
189 }
190 }
191
|
192 kumpf 1.3 // Set up the Logger
193 String logsDirectory = String::EMPTY;
194 logsDirectory = configManager->getCurrentValue("logdir");
195 logsDirectory = ConfigManager::getHomedPath(configManager->getCurrentValue("logdir"));
196
197 Logger::setHomeDirectory(logsDirectory);
198
199 // Put server start message to the logger
200 Logger::put(Logger::STANDARD_LOG, PEGASUS_SERVICE_NAME, Logger::INFORMATION,
|
201 kumpf 1.9 "Started $0 version $1.", PEGASUS_PRODUCT_NAME, PEGASUS_PRODUCT_VERSION);
|
202 kumpf 1.3
203 // try loop to bind the address, and run the server
204 try
205 {
206 Monitor monitor(true);
207
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
|