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