Main Page | Namespace List | Class Hierarchy | Class List | Directories | File List | Namespace Members | Class Members | File Members

Omniifr::Service Class Reference

Singleton class that contains various methods for running a Windows service. More...

#include <daemon_windows.h>

List of all members.

Public Member Functions

 Service ()
 ~Service ()
void start (int &argc, char **&argv)
void tracefile (const char *val)
 Set _tracefile.
void pidfile (const char *val)
 Set _pidfile.
void foreground (bool val)
 Set _foreground.
void daemonize ()
 Redirects output streams to tracefile.
void runningOk ()
 Called to signal that all startup operations have completed OK.
void shutdown ()
 Exit handler set with ::on_exit() - shuts down the service.

Static Public Member Functions

static void log (const char *message)
 Callback, used as a parameter to omniORB::setLogFunction().
static void ctrlHandler (DWORD controlCode)
 Handles control codes from the Service Control Manager.

Private Member Functions

void Service::setArgcArgv (int &argc, char **&argv)
void install (int argc, char **argv) const
void uninstall () const
void readParameters ()
 Populates _parameters from the Registry.
void writeParameters (int argc, char **argv) const
 Writes args 2+ to the Registry.
bool Service::setServiceStatus (DWORD currentState, DWORD win32ExitCode, DWORD serviceSpecificExitCode, DWORD checkPoint, DWORD waitHint)

Private Attributes

char * _tracefile
 The tracefile name (if any).
const char * _regSubKey
bool _serviceRunning
int _callCount
char * _parameters
 Stores parameters read from the registry.
char ** _argv
 Replacement argv array, read from registry.
std::ostream * _logstream
SERVICE_STATUS_HANDLE _serviceStatusHandle
 Windows thing.


Detailed Description

Singleton class that contains various methods for running a Windows service.

Definition at line 40 of file daemon_windows.h.


Constructor & Destructor Documentation

Omniifr::Service::Service  ) 
 

Definition at line 180 of file daemon_windows.cc.

References PACKAGE_NAME.

00180                 :
00181   _tracefile(NULL),
00182   _regSubKey("SYSTEM\\CurrentControlSet\\Services\\" PACKAGE_NAME),
00183   _serviceRunning(false),
00184   _callCount(0),
00185   _parameters(NULL),
00186   _argv(NULL),
00187   _logstream(&cerr),
00188   _serviceStatusHandle()
00189 {}

Omniifr::Service::~Service  ) 
 

Definition at line 192 of file daemon_windows.cc.

References _argv, _logstream, _parameters, and _tracefile.

00193 {
00194   delete[] _tracefile;
00195   delete[] _parameters;
00196   delete[] _argv;
00197   if(_logstream!=&cerr)
00198       delete _logstream;
00199 }


Member Function Documentation

void Omniifr::Service::ctrlHandler DWORD  controlCode  )  [static]
 

Handles control codes from the Service Control Manager.

Definition at line 340 of file daemon_windows.cc.

References Omniifr::service.

00341 {
00342   switch(controlCode)
00343   {  
00344   case SERVICE_CONTROL_SHUTDOWN:
00345   case SERVICE_CONTROL_STOP:
00346       ::Omniifr_Orb_shutdown(controlCode);
00347       service.setServiceStatus(SERVICE_STOP_PENDING,NO_ERROR,0,1,6000);
00348       break;
00349   case 128: // User defined code.
00350       ::Omniifr_Orb_bumpTraceLevel(controlCode);
00351       break;
00352   default:
00353       break;
00354   }
00355 }

void Omniifr::Service::daemonize  ) 
 

Redirects output streams to tracefile.

Definition at line 292 of file daemon_windows.cc.

References _logstream, _tracefile, omniORB::setLogFunction(), and Omniifr::shutdown0().

00293 {
00294   if(_tracefile && _tracefile[0]!='\0')
00295   {
00296     _logstream=new ofstream(_tracefile,ios::out|ios::app);
00297     omniORB::setLogFunction(Service::log);
00298   }
00299 
00300   // Register the shutdown function.
00301   if( ::atexit(shutdown0) <0) // Windows has atexit()
00302   {
00303     Service::log("Failed to set exit handler.");
00304     ::exit(-1);
00305   }
00306 }

void Omniifr::Service::foreground bool  val  ) 
 

Set _foreground.

Definition at line 216 of file daemon_windows.cc.

00217 {
00218   Service::log("Option -f not supported on windows.\n");
00219   ::exit(1);
00220 }

void Omniifr::Service::install int  argc,
char **  argv
const [private]
 

Definition at line 383 of file daemon_windows.cc.

References _regSubKey, HERE, PACKAGE_NAME, Omniifr::service, Omniifr::RegistryKey::setValueStr(), and writeParameters().

Referenced by start().

00384 {
00385   //
00386   // Install service
00387   char exe_file_name[MAX_PATH];
00388   if(0== ::GetModuleFileName(0, exe_file_name, MAX_PATH) )
00389   {
00390     Win::perror(HERE);
00391     ::exit(1);
00392   }
00393 
00394   string command =string(exe_file_name)+" service";
00395 
00396   SC_HANDLE scmanager =::OpenSCManager(0,0,SC_MANAGER_CREATE_SERVICE);
00397   if(!scmanager)
00398   {
00399     Win::perror(HERE);
00400     ::exit(1);
00401   }
00402   SC_HANDLE service =
00403     ::CreateService(
00404       scmanager,
00405       PACKAGE_NAME,
00406       "CORBA Event Daemon",
00407       SERVICE_ALL_ACCESS,
00408       SERVICE_WIN32_OWN_PROCESS,
00409       SERVICE_AUTO_START,
00410       SERVICE_ERROR_NORMAL,
00411       command.c_str(),
00412       0,0,0,0,0
00413     );
00414   if(!service)
00415   {
00416     Win::perror(HERE);
00417     ::exit(1);
00418   }
00419   if(0== ::CloseServiceHandle(service) )
00420   {
00421     Win::perror(HERE);
00422     ::exit(1);
00423   }
00424   if(0== ::CloseServiceHandle(scmanager) )
00425   {
00426     Win::perror(HERE);
00427     ::exit(1);
00428   }
00429 
00430   //
00431   // Set the service's parameters & description.
00432   writeParameters(argc,argv);
00433   RegistryKey rkey(HKEY_LOCAL_MACHINE,_regSubKey,KEY_SET_VALUE);
00434   if(!rkey)
00435   {
00436     Win::perror("Can't open registry key at " HERE);
00437     ::exit(1);
00438   }
00439   if(0!= rkey.setValueStr("Description",
00440            "Asynchronous broadcast channels for CORBA applications.") )
00441   {
00442     Win::perror("Can't set registry value 'Description' at " HERE);
00443     ::exit(1);
00444   }
00445 }

void Omniifr::Service::log const char *  message  )  [static]
 

Callback, used as a parameter to omniORB::setLogFunction().

Definition at line 334 of file daemon_windows.cc.

References _logstream, and Omniifr::service.

00335 {
00336   (*service._logstream)<<message<<flush;
00337 }

void Omniifr::Service::pidfile const char *  val  ) 
 

Set _pidfile.

Definition at line 209 of file daemon_windows.cc.

00210 {
00211   Service::log("Option -P not supported on windows.\n");
00212   ::exit(1);
00213 }

void Omniifr::Service::readParameters  )  [private]
 

Populates _parameters from the Registry.

Definition at line 485 of file daemon_windows.cc.

References _parameters, _regSubKey, HERE, and Omniifr::RegistryKey::queryValueStr().

Referenced by start().

00486 {
00487   RegistryKey rkey(HKEY_LOCAL_MACHINE,_regSubKey);
00488   if(!rkey)
00489   {
00490     Win::perror("Can't open registry key at " HERE);
00491     ::exit(1);
00492   }
00493   _parameters=rkey.queryValueStr("Parameters"); // deleted by ~Service()
00494   if(_parameters==NULL)
00495   {
00496     Win::perror("Can't get Parameters at " HERE);
00497     ::exit(1);
00498   }
00499 }

void Omniifr::Service::runningOk  ) 
 

Called to signal that all startup operations have completed OK.

Definition at line 309 of file daemon_windows.cc.

References _serviceRunning.

00310 {
00311   if(_serviceRunning)
00312   {
00313     if(! setServiceStatus(SERVICE_RUNNING,NO_ERROR,0,0,0) )
00314         ::exit(1);
00315   }
00316 }

void Omniifr::Service::Service::setArgcArgv int &  argc,
char **&  argv
[private]
 

bool Omniifr::Service::Service::setServiceStatus DWORD  currentState,
DWORD  win32ExitCode,
DWORD  serviceSpecificExitCode,
DWORD  checkPoint,
DWORD  waitHint
[private]
 

void Omniifr::Service::shutdown  ) 
 

Exit handler set with ::on_exit() - shuts down the service.

Definition at line 319 of file daemon_windows.cc.

References _logstream, and _serviceRunning.

00320 {
00321   if(_logstream!=&cerr)
00322   {
00323     delete _logstream;
00324     _logstream=&cerr;
00325   }
00326   if(_serviceRunning)
00327   {
00328     setServiceStatus(SERVICE_STOPPED,NO_ERROR,0,0,0);
00329     _serviceRunning=false;
00330   }
00331 }

void Omniifr::Service::start int &  argc,
char **&  argv
 

Definition at line 223 of file daemon_windows.cc.

References _callCount, _parameters, _serviceRunning, _serviceStatusHandle, HERE, install(), PACKAGE_NAME, readParameters(), uninstall(), and writeParameters().

00224 {
00225   ++_callCount;
00226   if(_callCount>1)
00227   {
00228     // This is a re-entrant call. We are inside 'ServiceMain()'.
00229     setArgcArgv(argc,argv); // Set argv & argc from the registry.
00230     _serviceStatusHandle=
00231       ::RegisterServiceCtrlHandler(
00232         PACKAGE_NAME,
00233         (LPHANDLER_FUNCTION)Service::ctrlHandler
00234       );
00235     if(!_serviceStatusHandle)
00236         ::exit(1);
00237     if(! setServiceStatus(SERVICE_START_PENDING,NO_ERROR,0,1,3000) )
00238         ::exit(1);
00239     _serviceRunning=true;
00240     // ...and return to main().
00241   }
00242   else if(argc>=2 && 0==::strcmp(argv[1],"service"))
00243   {
00244     // Start service.
00245     char* name =::strdup(PACKAGE_NAME);
00246     SERVICE_TABLE_ENTRY servicetable[]=
00247     {
00248       {name,(LPSERVICE_MAIN_FUNCTION)::main},
00249       {NULL,NULL}
00250     };
00251     if(! ::StartServiceCtrlDispatcher(servicetable) )
00252     {
00253       Win::perror(HERE);
00254       ::exit(1);
00255     }
00256     ::exit(0);
00257   }
00258   else if(argc>=2 && 0==::strcmp(argv[1],"install"))
00259   {
00260     install(argc,argv);
00261     cout<<"Service '" PACKAGE_NAME "' installed OK."<<endl;
00262     ::exit(0);
00263   }
00264   else if(argc>=2 && 0==::strcmp(argv[1],"uninstall"))
00265   {
00266     uninstall();
00267     cout<<"Service '" PACKAGE_NAME "' removed."<<endl;
00268     ::exit(0);
00269   }
00270   else if(argc>=2 && 0==::strcmp(argv[1],"getoptions"))
00271   {
00272     readParameters();
00273     cout<<_parameters<<endl;
00274     ::exit(0);
00275   }
00276   else if(argc>=2 && 0==::strcmp(argv[1],"setoptions"))
00277   {
00278     writeParameters(argc,argv);
00279     ::exit(0);
00280   }
00281   else if(argc>=2 && 0==::strcmp(argv[1],"run"))
00282   {
00283     setArgcArgv(argc,argv); // Set argv & argc from the registry.
00284   }
00285   else
00286   {
00287     ; // Just run the program in the foreground.
00288   }
00289 }

void Omniifr::Service::tracefile const char *  val  ) 
 

Set _tracefile.

Definition at line 202 of file daemon_windows.cc.

References _tracefile.

00203 {
00204   delete[] _tracefile;
00205   _tracefile=::strdup(val);
00206 }

void Omniifr::Service::uninstall  )  const [private]
 

Definition at line 448 of file daemon_windows.cc.

References HERE, PACKAGE_NAME, and Omniifr::service.

Referenced by start().

00449 {
00450   SC_HANDLE scmanager =::OpenSCManager(0,0,SC_MANAGER_CREATE_SERVICE);
00451   if(!scmanager)
00452   {
00453     Win::perror(HERE);
00454     ::exit(1);
00455   }
00456   SC_HANDLE service =
00457     ::OpenService(
00458       scmanager,
00459       PACKAGE_NAME,
00460       SC_MANAGER_ALL_ACCESS
00461     );
00462   if(!service)
00463   {
00464     Win::perror(HERE);
00465     ::exit(1);
00466   }
00467   if(0== ::DeleteService(service) )
00468   {
00469     Win::perror(HERE);
00470     ::exit(1);
00471   }
00472   if(0== ::CloseServiceHandle(service) )
00473   {
00474     Win::perror(HERE);
00475     ::exit(1);
00476   }
00477   if(0== ::CloseServiceHandle(scmanager) )
00478   {
00479     Win::perror(HERE);
00480     ::exit(1);
00481   }
00482 }

void Omniifr::Service::writeParameters int  argc,
char **  argv
const [private]
 

Writes args 2+ to the Registry.

Definition at line 502 of file daemon_windows.cc.

References _regSubKey, HERE, and Omniifr::RegistryKey::setValueStr().

Referenced by install(), and start().

00503 {
00504   RegistryKey rkey(HKEY_LOCAL_MACHINE,_regSubKey,KEY_SET_VALUE);
00505   if(!rkey)
00506   {
00507     Win::perror("Can't open registry key at " HERE);
00508     ::exit(1);
00509   }
00510   string parameters ="";
00511   for(int i=2; i<argc; ++i)
00512   {
00513     if(!parameters.empty())
00514         parameters+=" ";
00515     parameters+=argv[i];
00516   }
00517   if(0!= rkey.setValueStr("Parameters",parameters.c_str()) )
00518   {
00519     Win::perror("Can't set registry value 'Parameters' at " HERE);
00520     ::exit(1);
00521   }
00522 }


Member Data Documentation

char** Omniifr::Service::_argv [private]
 

Replacement argv array, read from registry.

Definition at line 75 of file daemon_windows.h.

Referenced by ~Service().

int Omniifr::Service::_callCount [private]
 

Definition at line 73 of file daemon_windows.h.

Referenced by start().

std::ostream* Omniifr::Service::_logstream [private]
 

Definition at line 76 of file daemon_windows.h.

Referenced by daemonize(), log(), shutdown(), and ~Service().

char* Omniifr::Service::_parameters [private]
 

Stores parameters read from the registry.

Definition at line 74 of file daemon_windows.h.

Referenced by readParameters(), start(), and ~Service().

const char* Omniifr::Service::_regSubKey [private]
 

Definition at line 71 of file daemon_windows.h.

Referenced by install(), readParameters(), and writeParameters().

bool Omniifr::Service::_serviceRunning [private]
 

Definition at line 72 of file daemon_windows.h.

Referenced by runningOk(), shutdown(), and start().

SERVICE_STATUS_HANDLE Omniifr::Service::_serviceStatusHandle [private]
 

Windows thing.

Definition at line 77 of file daemon_windows.h.

Referenced by start().

char* Omniifr::Service::_tracefile [private]
 

The tracefile name (if any).

Definition at line 70 of file daemon_windows.h.

Referenced by daemonize(), tracefile(), and ~Service().


The documentation for this class was generated from the following files:
Generated on Fri Mar 4 13:03:58 2005 for OmniIFR by  doxygen 1.4.1