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

  1 h.sterling 1.1 //%2005////////////////////////////////////////////////////////////////////////
  2                //
  3                // 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                // Copyright (c) 2004 BMC Software; Hewlett-Packard Development Company, L.P.;
  8                // IBM Corp.; EMC Corporation; VERITAS Software Corporation; The Open Group.
  9                // Copyright (c) 2005 Hewlett-Packard Development Company, L.P.; IBM Corp.;
 10                // EMC Corporation; VERITAS Software Corporation; The Open Group.
 11                //
 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 h.sterling 1.1 // 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                // Modified By: Mary Hinton (m.hinton@verizon.net)
 33                //              Sushma Fernandes (sushma_fernandes@hp.com)
 34                //              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                //              Steve Hills (steve.hills@ncr.com)
 38 joyce.j    1.3 //              Josephine Eskaline Joyce, IBM (jojustin@in.ibm.com) - Bug#2032, 2031
 39 h.sterling 1.1 //
 40                //%/////////////////////////////////////////////////////////////////////////////
 41                
 42                #include <windows.h>
 43                #include <process.h>    /* _beginthread, _endthread */
 44                #include <tchar.h>
 45                #include <direct.h>
 46                #include <Pegasus/Common/MessageLoader.h> //l10n
 47                #include <Pegasus/Common/Thread.h>  // l10n
 48                #include <Pegasus/Server/CIMServer.h>
 49                
 50                #include "Service.cpp"
 51                
 52                PEGASUS_USING_PEGASUS;
 53                PEGASUS_USING_STD;
 54                
 55                static const char* _ALREADY_RUNNING_NAME = 0;
 56                
 57                //-------------------------------------------------------------------------
 58                // GLOBALS
 59                //-------------------------------------------------------------------------
 60 h.sterling 1.1 static Mutex _cimserverLock;
 61                static ServerProcess* _server_proc = 0;
 62                static bool _shutdown = false;
 63                static Service pegasus_service;
 64                static HANDLE pegasus_service_event = NULL;
 65                static LPCSTR g_cimservice_key  = TEXT("SYSTEM\\CurrentControlSet\\Services\\%s");
 66                static LPCSTR g_cimservice_home = TEXT("home");
 67                static int g_argc = 0;
 68                static char **g_argv = 0;
 69                
 70                //  Constants representing the command line options.
 71                static const char OPTION_INSTALL[] = "install";
 72                static const char OPTION_REMOVE[]  = "remove";
 73                static const char OPTION_START[]   = "start";
 74                static const char OPTION_STOP[]    = "stop";
 75                
 76                //-------------------------------------------------------------------------
 77                // PROTOTYPES
 78                //-------------------------------------------------------------------------
 79                int cimserver_windows_main(int flag, int argc, char **argv);
 80                static bool _getRegInfo(const char *lpchKeyword, char *lpchRetValue);
 81 h.sterling 1.1 static bool _setRegInfo(const char *lpchKeyword, const char *lpchValue);
 82                
 83                //-------------------------------------------------------------------------
 84                // NO-OPs for windows platform
 85                //-------------------------------------------------------------------------
 86                int ServerProcess::cimserver_fork(void) { return(0); }
 87                void ServerProcess::notify_parent(int id) { return; }
 88                long ServerProcess::get_server_pid(void) { return 0; }
 89 h.sterling 1.2 void ServerProcess::set_parent_pid(int pid) {}
 90 h.sterling 1.1 int ServerProcess::get_proc(int pid) { return 0; }
 91                int ServerProcess::cimserver_kill(int id) { return(0); }
 92                void cimserver_exitRC(int rc) {}
 93                int ServerProcess::cimserver_initialize(void) { return 0; }
 94                int ServerProcess::cimserver_wait(void) { return 0; }
 95                
 96                
 97                //-------------------------------------------------------------------------
 98                // Helper for platform specific handling
 99                //-------------------------------------------------------------------------
100                
101                ServerProcess::ServerProcess()
102                {
103                    //be sure to call cimserver_set_process right after instantiating this in order for everything to work
104                }
105                
106                ServerProcess::~ServerProcess()
107                {
108                }
109                
110                void ServerProcess::cimserver_set_process(void* p)
111 h.sterling 1.1 {
112                    AutoMutex am( _cimserverLock );
113                    _server_proc = static_cast<ServerProcess *>(p);
114                    if(_server_proc && _shutdown)
115                        _server_proc->cimserver_stop();
116                
117                    pegasus_service = Service(getProcessName());
118                    _ALREADY_RUNNING_NAME = getProcessName();
119                }
120                
121                void signal_shutdown()
122                {
123                    AutoMutex am( _cimserverLock );
124                    _shutdown = true;
125                    if( _server_proc )
126                        _server_proc->cimserver_stop(); 
127                }
128                
129                //-------------------------------------------------------------------------
130                // Run main server asynchronously
131                //-------------------------------------------------------------------------
132 h.sterling 1.1 static unsigned __stdcall cimserver_windows_thread( void* parm )
133                {
134                    int argc = 0;
135 kumpf      1.5     int rc = _server_proc->cimserver_run( g_argc, g_argv, false, false );
136 h.sterling 1.1     SetEvent(pegasus_service_event);
137                    _endthreadex( rc );
138                    return rc;
139                }
140                
141                //-------------------------------------------------------------------------
142                //  Windows NT Service Control Code 
143                //-------------------------------------------------------------------------
144                
145                //-------------------------------------------------------------------------
146                // START/STOP handler 
147                //-------------------------------------------------------------------------
148                int cimserver_windows_main(int flag, int argc, char *argv[])
149                {
150                    switch( flag )
151                    {
152                    case Service::STARTUP_FLAG:
153                    {
154                        //
155                        // Start up main run in a separate thread and wait for it to finish.
156                        //
157 h.sterling 1.1 
158                        unsigned threadid = 0;
159                        g_argc = argc;
160                        g_argv = argv;
161                        HANDLE hThread = (HANDLE)_beginthreadex( NULL, 0, cimserver_windows_thread, NULL, 0, &threadid );
162                        if( hThread == NULL )
163                            return 1;
164                
165                        WaitForSingleObject( pegasus_service_event, INFINITE );
166                
167                        //
168                        // Shutdown the cimserver.
169                        //
170                
171                        signal_shutdown();
172                
173                        //
174                        // Make sure we upate the SCM that our stop is pending.
175                        // Wait for the main run thread to exit.
176                        //
177                
178 h.sterling 1.1         DWORD dwCheckPoint = 1; // service code should have already started at 0
179                
180                        while( WaitForSingleObject( hThread, 3000 ) == WAIT_TIMEOUT )
181                        {
182                            pegasus_service.report_status( 
183                                SERVICE_STOP_PENDING, NO_ERROR, dwCheckPoint++, 5000 );
184                        }
185                
186                        CloseHandle( hThread );
187                
188                        break;
189                    }
190                    case Service::SHUTDOWN_FLAG:
191                        SetEvent(pegasus_service_event);
192                        break;
193                
194                    default:
195                        break;
196                    }
197                
198                    return 0;
199 h.sterling 1.1 }
200                
201                //-------------------------------------------------------------------------
202                // IS RUNNING?
203                //-------------------------------------------------------------------------
204                
205                class AlreadyRunning
206                {
207                public:
208                    AlreadyRunning(): alreadyRunning( true ), event( NULL )
209                    {
210                    }
211                    ~AlreadyRunning()
212                    {
213                        if( event != NULL )
214                            CloseHandle( event );
215                    }
216                
217                    void Init()
218                    {
219                        if( event == NULL )
220 h.sterling 1.1         {
221                            event = CreateEvent( NULL, TRUE, TRUE, _ALREADY_RUNNING_NAME );
222                            if( event != NULL && GetLastError() != ERROR_ALREADY_EXISTS )
223                                alreadyRunning = false;
224                        }
225                    }
226                
227                    bool IsAlreadyRunning()
228                    {
229                        return alreadyRunning;
230                    }
231                
232                    bool alreadyRunning;
233                    HANDLE event;
234                };
235                
236                AlreadyRunning _alreadyRunning;
237                
238                
239                Boolean ServerProcess::isCIMServerRunning(void)
240                {
241 h.sterling 1.1     //Service::State state;
242                    //pegasus_service.GetState(&state);
243                    //return (state == Service::SERVICE_STATE_RUNNING) ? true : false;
244                
245                    // We do it this way so this will work when run as a 
246                    // console process and a Windows service.
247                    AlreadyRunning ar;
248                    ar.Init();
249                    return ar.IsAlreadyRunning();
250                }
251                
252                //-------------------------------------------------------------------------
253                // INSTALL
254                //-------------------------------------------------------------------------
255                bool cimserver_install_nt_service(char *service_name)
256                {
257                  Service::ReturnCode status = Service::SERVICE_RETURN_SUCCESS;
258                  char filename[_MAX_PATH] = {0};
259                  char displayname[_MAX_PATH] = {0};
260                  char descriptionname[_MAX_PATH] = {0};
261                
262 h.sterling 1.1   // If service name is specified, override default
263                  if (service_name == NULL)
264                    {
265                      strcpy(displayname, _server_proc->getExtendedName());
266                    }
267                  else
268                    {
269                      pegasus_service.SetServiceName(service_name);
270                      sprintf(displayname, "%s - %s", _server_proc->getExtendedName(), service_name);
271                    }
272                
273                  strcpy(descriptionname, _server_proc->getDescription());
274                
275 joyce.j    1.3   if(0 != GetModuleFileName(NULL, filename, sizeof(filename)))
276                  {
277                     status = pegasus_service.Install(displayname, descriptionname, filename);
278 h.sterling 1.1 
279 joyce.j    1.3      // Upon success, set home in registry
280                     if (status == Service::SERVICE_RETURN_SUCCESS)
281                     {
282 h.sterling 1.1       char pegasus_homepath[_MAX_PATH];
283                      System::extract_file_path(filename, pegasus_homepath);
284                      pegasus_homepath[strlen(pegasus_homepath)-1] = '\0';
285                      strcpy(filename, pegasus_homepath);
286                      System::extract_file_path(filename, pegasus_homepath);
287                      pegasus_homepath[strlen(pegasus_homepath)-1] = '\0';
288                      _setRegInfo(g_cimservice_home, pegasus_homepath);
289 joyce.j    1.3      }
290                  }
291                  else
292                  {
293                    status = (Service::ReturnCode) GetLastError();
294                  }
295 h.sterling 1.1   return (status == Service::SERVICE_RETURN_SUCCESS) ? true : false;
296                }
297                
298                //-------------------------------------------------------------------------
299                // REMOVE
300                //-------------------------------------------------------------------------
301                bool cimserver_remove_nt_service(char *service_name) 
302                {
303                  Service::ReturnCode status = Service::SERVICE_RETURN_SUCCESS;
304                
305                  // If service name is specified, override default
306                  if (service_name != NULL)
307                    {
308                      pegasus_service.SetServiceName(service_name);
309                    }
310                
311                  status = pegasus_service.Remove();
312                
313                  return (status == Service::SERVICE_RETURN_SUCCESS) ? true : false;
314                }
315                
316 h.sterling 1.1 //-------------------------------------------------------------------------
317                // START
318                //-------------------------------------------------------------------------
319                bool cimserver_start_nt_service(char *service_name, int num_args, char **service_args) 
320                {
321                  Service::ReturnCode status = Service::SERVICE_RETURN_SUCCESS;
322                
323                  // If service name is specified, override default
324                  if (service_name != NULL)
325                    {
326                      pegasus_service.SetServiceName(service_name);
327                    }
328                
329                  if(num_args > 0 && service_args != NULL)
330                  {
331                      pegasus_service.SetServiceArgs(num_args, service_args);
332                  }
333                
334                  status = pegasus_service.Start(5);
335                
336                  return (status == Service::SERVICE_RETURN_SUCCESS) ? true : false;
337 h.sterling 1.1 }
338                
339                //-------------------------------------------------------------------------
340                // STOP
341                //-------------------------------------------------------------------------
342                bool cimserver_stop_nt_service(char *service_name) 
343                {
344                  Service::ReturnCode status = Service::SERVICE_RETURN_SUCCESS;
345                
346                  // If service name is specified, override default
347                  if (service_name != NULL)
348                    {
349                      pegasus_service.SetServiceName(service_name);
350                    }
351                
352                  status = pegasus_service.Stop(5);
353                
354                  return (status == Service::SERVICE_RETURN_SUCCESS) ? true : false;
355                }
356                
357                //-------------------------------------------------------------------------
358 h.sterling 1.1 // HELPER Utilities
359                //-------------------------------------------------------------------------
360                static bool _getRegInfo(const char *lpchKeyword, char *lpchRetValue)
361                {
362                  HKEY   hKey;
363                  DWORD  dw                   = _MAX_PATH;
364                  char   subKey[_MAX_PATH]    = {0};
365                  
366                  sprintf(subKey, g_cimservice_key, pegasus_service.GetServiceName());
367                
368                  if ((RegOpenKeyEx(HKEY_LOCAL_MACHINE,
369                                    subKey, 
370                                    0,
371                                    KEY_READ, 
372                                    &hKey)) != ERROR_SUCCESS)
373                    {
374                      return false;
375                    }
376                
377                  if ((RegQueryValueEx(hKey, 
378                                       lpchKeyword, 
379 h.sterling 1.1                        NULL, 
380                                       NULL, 
381                                       (LPBYTE)lpchRetValue,
382                                       &dw)) != ERROR_SUCCESS)
383                    {
384                      RegCloseKey(hKey);
385                      return false;
386                    }
387                
388                  RegCloseKey(hKey);
389                
390                  return true;
391                }
392                
393                static bool _setRegInfo(const char *lpchKeyword, const char *lpchValue)
394                {
395                  HKEY   hKey;
396                  DWORD  dw                   = _MAX_PATH;
397                  char   home_key[_MAX_PATH]  = {0};
398                  char   subKey[_MAX_PATH]    = {0};
399                
400 h.sterling 1.1   if (lpchKeyword == NULL || lpchValue == NULL)
401                    return false;
402                
403                  sprintf(subKey, g_cimservice_key, pegasus_service.GetServiceName());
404                
405                  if ((RegCreateKeyEx (HKEY_LOCAL_MACHINE,
406                                      subKey,
407                                      0,
408                                      NULL,
409                                      0,
410                                      KEY_ALL_ACCESS,
411                                      NULL,
412                                      &hKey,
413                                      NULL) != ERROR_SUCCESS))
414                    {
415                      return false;
416                    }
417                
418                  if ((RegSetValueEx(hKey, 
419                                     lpchKeyword, 
420                                     0, 
421 h.sterling 1.1                      REG_SZ, 
422                                     (CONST BYTE *)lpchValue,
423                                     (DWORD)(strlen(lpchValue)+1))) != ERROR_SUCCESS)
424                    {
425                      RegCloseKey(hKey);
426                      return false;
427                    }
428                
429                  RegCloseKey(hKey);
430                
431                  return true;
432                }
433                
434                //void ServerProcess::setHome(const String& home)
435                String ServerProcess::getHome(void)
436                {
437                    String home = String::EMPTY;
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 joyce.j    1.3   if(0 != GetModuleFileName(NULL, exe_pathname, sizeof(exe_pathname)))
443                  {
444 h.sterling 1.1 
445 joyce.j    1.3     // Pegasus home search rules:
446                    // - look in registry (if set)
447                    // - if not found, look in PEGASUS_HOME (if set)
448                    // - if not found, use exe directory minus one level
449                
450                    bool found_reg = _getRegInfo("home", home_pathname);
451                    if (found_reg == true)
452                      {
453                        // Make sure home matches
454                        String current_home(home_pathname);
455                        String current_exe(exe_pathname);
456                        current_home.toLower();
457                        current_exe.toLower();
458                
459                        Uint32 pos = current_exe.find(current_home);
460                        if (pos != PEG_NOT_FOUND)
461                          {
462                            home = home_pathname;
463                          }
464                        else
465                          {
466 joyce.j    1.3             found_reg = false;
467                          }
468                      }
469                    if (found_reg == false)
470                      {
471                        const char* tmp = getenv("PEGASUS_HOME");
472                        if (tmp)
473                          {
474                            home = tmp;
475                          }
476                        else
477                          {
478                            // ASSUMPTION: At a minimum, the cimserver program is running
479                            // from a "bin" directory
480                            home = FileSystem::extractFilePath(exe_pathname);
481                            home.remove(home.size()-1, 1);
482                            home = FileSystem::extractFilePath(home);
483                            home.remove(home.size()-1, 1);
484                          }
485                      }
486                  }
487 h.sterling 1.1     return home;
488                }
489                
490                //
491                // Our console control handler
492                //
493                
494                static BOOL WINAPI ControlHandler( DWORD dwCtrlType )
495                {
496                    switch( dwCtrlType )
497                    {
498                    case CTRL_BREAK_EVENT:  // use Ctrl+C or Ctrl+Break to simulate
499                    case CTRL_C_EVENT:      // SERVICE_CONTROL_STOP in debug mode
500                    {
501                        signal_shutdown();
502                        return TRUE;
503                    }
504                    }
505                    return FALSE;
506                }
507                
508 h.sterling 1.1 //
509                // Platform specific run
510                //
511                
512 kumpf      1.4 int ServerProcess::platform_run(
513                    int argc,
514                    char** argv,
515                    Boolean shutdownOption,
516                    Boolean debugOutputOption)
517 h.sterling 1.1 {
518                    //
519                    // Check for my command line options
520                    //
521                
522                    for( int i = 1; i < argc; )
523                    {
524                        const char* arg = argv[i];
525                
526                        // Check for -option
527                        if (*arg == '-')
528                        {
529                            // Get the option
530                            const char* option = arg + 1;
531                
532                            if (strcmp(option, OPTION_INSTALL) == 0)
533                            {
534                                //
535                                // Install as a NT service
536                                //
537                                char *opt_arg = NULL;
538 h.sterling 1.1                 if (i+1 < argc)
539                                {
540                                    opt_arg = argv[i+1];
541                
542                                }
543                                if(cimserver_install_nt_service(opt_arg))
544                                {
545                                    //l10n
546                                    //cout << "\nPegasus installed as NT Service";
547                                    MessageLoaderParms parms(
548                                        "src.Server.cimserver.INSTALLED_NT_SERVICE",
549                                        "\nPegasus installed as a Windows service");
550                                    cout << MessageLoader::getMessage(parms) << endl;
551                                    exit(0);
552                                }
553                                else
554                                {
555                                    exit(0);
556                                }
557                            }
558                            else if (strcmp(option, OPTION_REMOVE) == 0)
559 h.sterling 1.1             {
560                                //
561                                // Remove Pegasus as an NT service
562                                //
563                                char *opt_arg = NULL;
564                                if (i+1 < argc)
565                                {
566                                    opt_arg = argv[i+1];                    
567                                }
568                                if(cimserver_remove_nt_service(opt_arg))
569                                {
570                                    //l10n
571                                    //cout << "\nPegasus removed as NT Service";
572                                    MessageLoaderParms parms(
573                                        "src.Server.cimserver.REMOVED_NT_SERVICE",
574                                        "\nPegasus removed as a Windows service");
575                                    cout << MessageLoader::getMessage(parms) << endl;
576                                    exit(0);
577                                }
578                                else
579                                {
580 h.sterling 1.1                     exit(0);
581                                }
582                
583                            }
584                            else if (strcmp(option, OPTION_START) == 0)
585                            {
586                                //
587                                // Start as a NT service
588                                //
589                                char *opt_arg = NULL;
590                                int num_args = 0;
591                                if (i+1 < argc)
592                                {
593                                    opt_arg = argv[i+1];                    
594                                    num_args = argc - 3;
595                                }
596                                else
597                                {
598                                    num_args = argc - 2;
599                                }
600                
601 h.sterling 1.1                 char **service_args = &argv[1];
602                                if(cimserver_start_nt_service(opt_arg, num_args, service_args))
603                                {
604                                    //l10n
605                                    //cout << "\nPegasus started as NT Service";
606                                    MessageLoaderParms parms(
607                                        "src.Server.cimserver.STARTED_NT_SERVICE",
608                                        "\nPegasus started as a Windows service");
609                                    cout << MessageLoader::getMessage(parms) << endl;
610                                    exit(0);
611                                }
612                                else
613                                {
614                                    exit(0);
615                                }
616                            }
617                            else if (strcmp(option, OPTION_STOP) == 0)
618                            {
619                                //
620                                // Stop as a NT service
621                                //
622 h.sterling 1.1                 char *opt_arg = NULL;
623                                if (i+1 < argc)
624                                {
625                                    opt_arg = argv[i+1];                    
626                                }
627                                if(cimserver_stop_nt_service(opt_arg))
628                                {
629                                    //l10n
630                                    //cout << "\nPegasus stopped as NT Service";
631                                    MessageLoaderParms parms(
632                                        "src.Server.cimserver.STOPPED_NT_SERVICE",
633                                        "\nPegasus stopped as a Windows service");
634                                    cout << MessageLoader::getMessage(parms) << endl;
635                                    exit(0);
636                                }
637                                else
638                                {
639                                    exit(0);
640                                }
641                            }
642                            else
643 h.sterling 1.1                 i++;
644                        }
645                        else
646                            i++;
647                    }
648                
649                    //
650                    // Signal ourself as running
651                    //
652                
653                    if( !shutdownOption )
654                        _alreadyRunning.Init();
655                
656                    //
657                    // Check if already running
658                    //
659                    // Hmm, when starting as a service, should we do this here (before
660                    // starting the control dispatcher)?  If we do then the SCM reports
661                    // a dumb message to the user.  If we don't, and it in the serviceProc 
662                    // then the service will start up then die silently.
663                    //
664 h.sterling 1.1 
665                    if( !shutdownOption && _alreadyRunning.IsAlreadyRunning() )
666                    {
667                        MessageLoaderParms parms(
668                            "src.Server.cimserver.UNABLE_TO_START_SERVER_ALREADY_RUNNING",
669                            "Unable to start CIMServer.\nCIMServer is already running." );
670                        Logger::put(
671                            Logger::ERROR_LOG, "CIMServer", Logger::SEVERE,
672                            MessageLoader::getMessage(parms) );
673                        PEGASUS_STD(cerr) << MessageLoader::getMessage(parms) << PEGASUS_STD(endl);
674                        return 1;
675                    }
676                
677                    //
678                    // Check if running from a console window. If so then just run
679                    // as a console process.
680                    //
681                
682                    char console_title[ _MAX_PATH ] = {0};
683                    if( GetConsoleTitle( console_title, _MAX_PATH ) > 0 )
684                    {
685 h.sterling 1.1         SetConsoleCtrlHandler( ControlHandler, TRUE );
686                
687 kumpf      1.4         return cimserver_run(argc, argv, shutdownOption, debugOutputOption);
688 h.sterling 1.1     }
689                
690                    //
691                    // Run as a service
692                    //
693                
694                    pegasus_service_event = CreateEvent( NULL, FALSE, FALSE, NULL );
695                
696                    Service::ReturnCode status;
697                    status = pegasus_service.Run( cimserver_windows_main );
698                
699                    if( status != Service::SERVICE_RETURN_SUCCESS )
700                    {
701                        // todo: put into localized messages when messages unfreezes.
702                        Logger::put_l(
703                            Logger::ERROR_LOG, "CIMServer", Logger::SEVERE,
704                            "src.Server.cimserver_windows.LISTENING_ON_HTTP_PORT",
705                            "Error during service run: code = $0.", status );
706                        return 1;
707                    }
708                
709 h.sterling 1.1     return 0;
710                }

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2