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