(file) Return to cimserver_windows.cpp CVS log (file) (dir) Up to [Pegasus] / pegasus / src / Server

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

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2