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

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

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2