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