Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members   Related Pages  

ACE_NT_Service Class Reference

Provide the base class which defines the interface for controlling an NT service. More...

#include <NT_Service.h>

Inheritance diagram for ACE_NT_Service:

Inheritance graph
[legend]
Collaboration diagram for ACE_NT_Service:

Collaboration graph
[legend]
List of all members.

Public Methods

 ACE_NT_Service (DWORD start_timeout=ACE_NT_SERVICE_START_TIMEOUT, DWORD service_type=SERVICE_WIN32_OWN_PROCESS, DWORD controls_mask=SERVICE_ACCEPT_STOP)
 Constructor primarily for use when running the service. More...

 ACE_NT_Service (const ACE_TCHAR *name, const ACE_TCHAR *desc=0, DWORD start_timeout=ACE_NT_SERVICE_START_TIMEOUT, DWORD service_type=SERVICE_WIN32_OWN_PROCESS, DWORD controls_mask=SERVICE_ACCEPT_STOP)
 Constructor primarily for use when inserting/removing/controlling the service. More...

virtual ~ACE_NT_Service (void)
virtual int open (void *args=0)
virtual int fini (void)
virtual int svc (void)
virtual void handle_control (DWORD control_code)
void svc_handle (const SERVICE_STATUS_HANDLE new_svc_handle)
 Set the svc_handle_ member. This is only a public function because the macro-generated service function calls it. More...

void name (const ACE_TCHAR *name, const ACE_TCHAR *desc=0)
 Sets the name and description for the service. If desc is 0, it takes the same value as name. More...

const ACE_TCHARname (void) const
 Get the service name. More...

const ACE_TCHARdesc (void) const
 Get the service description. More...

void host (const ACE_TCHAR *host)
 Sets the host machine. More...

const ACE_TCHARhost (void) const
 Get the host machine. More...

int insert (DWORD start_type=SERVICE_DEMAND_START, DWORD error_control=SERVICE_ERROR_IGNORE, const ACE_TCHAR *exe_path=0, const ACE_TCHAR *group_name=0, LPDWORD tag_id=0, const ACE_TCHAR *dependencies=0, const ACE_TCHAR *account_name=0, const ACE_TCHAR *password=0)
int remove (void)
int startup (DWORD startup)
 Sets the startup type for the service. Returns -1 on error, 0 on success. More...

DWORD startup (void)
 Returns the current startup type. More...

void capture_log_msg_attributes (void)
void inherit_log_msg_attributes (void)
int start_svc (ACE_Time_Value *wait_time=0, DWORD *svc_state=0, DWORD argc=0, const ACE_TCHAR **argv=0)
int stop_svc (ACE_Time_Value *wait_time=0, DWORD *svc_state=0)
int pause_svc (ACE_Time_Value *wait_time=0, DWORD *svc_state=0)
 Pause the service. More...

int continue_svc (ACE_Time_Value *wait_time=0, DWORD *svc_state=0)
 Continue the service. More...

DWORD state (ACE_Time_Value *wait_hint=0)
int state (DWORD *pstate, ACE_Time_Value *wait_hint=0)
 A version of <state> that returns -1 for failure, 0 for success. The DWORD pointed to by pstate receives the state value. More...

int test_access (DWORD desired_access=SERVICE_ALL_ACCESS)

Public Attributes

 ACE_ALLOC_HOOK_DECLARE
 Declare the dynamic allocation hooks. More...


Protected Methods

int report_status (DWORD new_status, DWORD time_hint=0)
SC_HANDLE svc_sc_handle (void)
void wait_for_service_state (DWORD desired_state, ACE_Time_Value *wait_time)
virtual void stop_requested (DWORD control_code)
 Called by <handle_control> when a stop/shutdown was requested. More...

virtual void pause_requested (DWORD control_code)
 Called by <handle_control> when a pause was requested. More...

virtual void continue_requested (DWORD control_code)
 Called by <handle_control> when a continue was requested. More...

virtual void interrogate_requested (DWORD control_code)
 Called by <handle_control> when a interrogate was requested. More...


Protected Attributes

DWORD start_time_
 Estimate of init time needed. More...

SERVICE_STATUS_HANDLE svc_handle_
 Service handle - doesn't need close. More...

SERVICE_STATUS svc_status_
SC_HANDLE svc_sc_handle_
 Service's SCM handle. More...

ACE_TCHARname_
ACE_TCHARdesc_
ACE_TCHARhost_
ACE_OS_Log_Msg_Attributes log_msg_attributes_
 ACE_Log_Msg attributes to inherit from the starting thread. More...


Detailed Description

Provide the base class which defines the interface for controlling an NT service.

NT Services can be implemented using the framework defined by the ACE_NT_Service class, and the macros defined in this file. Some quick refresher notes on NT Services:

To use this facility, you could derive a class from ACE_Service_Object (if you want to start via ACE's service configurator), or use any other class to run when the image starts (assuming that NT runs the image). You must set up an NT SERVICE_TABLE_ENTRY array to define your service(s). You can use the ACE_NT_SERVICE_... macros defined below for this.

A SERVICE_TABLE might look like this: ACE_NT_SERVICE_REFERENCE(Svc1); // If service is in another file SERVICE_TABLE_ENTRY myServices[] = { ACE_NT_SERVICE_ENTRY ("MyNeatService", Svc1), { 0, 0 } };

In the file where your service(s) are implemented, use the ACE_NT_SERVICE_DEFINE macro to set up the following: 1. A pointer to the service's implementation object (must be derived from ACE_NT_Service). 2. The service's Handler function (forwards all requests to the ACE_NT_Service-derived object's handle_control function). 3. The service's ServiceMain function. Creates a new instance of the ACE_NT_Service-derived class SVCCLASS, unless one has been created already.

If you are using all the default constructor values, you can let the generated ServiceMain function create the object, else you need to create it by hand before calling StartServiceCtrlDispatcher. Set the pointer so ServiceMain won't create another one. Another reason you may want to do the object creation yourself is if you want to also implement suspend and resume functions (the ones inherited from ACE_Service_Object) to do something intelligent to the services which are running, like call their handle_control functions to request suspend and resume actions, similar to what NT would do if a Services control panel applet would do if the user clicks on Suspend.

Definition at line 98 of file NT_Service.h.


Constructor & Destructor Documentation

ACE_INLINE ACE_NT_Service::ACE_NT_Service DWORD    start_timeout = ACE_NT_SERVICE_START_TIMEOUT,
DWORD    service_type = SERVICE_WIN32_OWN_PROCESS,
DWORD    controls_mask = SERVICE_ACCEPT_STOP
 

Constructor primarily for use when running the service.

Definition at line 5 of file NT_Service.i.

References svc_status_.

00007                                                      :
00008                                  start_time_(start_timeout),
00009                                  svc_handle_(0),
00010                                  svc_sc_handle_(0),
00011                                  name_(0),
00012                                  desc_(0),
00013                                  host_(0)
00014 {
00015   svc_status_.dwServiceType = service_type;
00016   svc_status_.dwCurrentState = 0;
00017   svc_status_.dwControlsAccepted = controls_mask;
00018   svc_status_.dwWin32ExitCode = NO_ERROR;
00019   svc_status_.dwServiceSpecificExitCode = 0;
00020   svc_status_.dwCheckPoint = 0;
00021 }

ACE_INLINE ACE_NT_Service::ACE_NT_Service const ACE_TCHAR   name,
const ACE_TCHAR   desc = 0,
DWORD    start_timeout = ACE_NT_SERVICE_START_TIMEOUT,
DWORD    service_type = SERVICE_WIN32_OWN_PROCESS,
DWORD    controls_mask = SERVICE_ACCEPT_STOP
 

Constructor primarily for use when inserting/removing/controlling the service.

Definition at line 25 of file NT_Service.i.

References ACE_TCHAR, and svc_status_.

00029                                                      :
00030                                  start_time_(start_timeout),
00031                                  svc_handle_(0),
00032                                  svc_sc_handle_(0),
00033                                  name_(ACE::strnew(name)),
00034                                  desc_(ACE::strnew(desc)),
00035                                  host_(0)
00036 {
00037   svc_status_.dwServiceType = service_type;
00038   svc_status_.dwCurrentState = 0;
00039   svc_status_.dwControlsAccepted = controls_mask;
00040   svc_status_.dwWin32ExitCode = NO_ERROR;
00041   svc_status_.dwServiceSpecificExitCode = 0;
00042   svc_status_.dwCheckPoint = 0;
00043 }

ACE_NT_Service::~ACE_NT_Service void    [virtual]
 

Definition at line 22 of file NT_Service.cpp.

References desc_, host_, name_, and svc_sc_handle_.

00023 {
00024   if (this->svc_sc_handle_ != 0)
00025     {
00026       CloseServiceHandle (this->svc_sc_handle_);
00027       this->svc_sc_handle_ = 0;
00028     }
00029   delete [] this->desc_;
00030   delete [] this->name_;
00031   delete [] this->host_;
00032 }


Member Function Documentation

void ACE_NT_Service::capture_log_msg_attributes void   
 

Set the ACE_Log_Msg attributes that the service thread will use to initialize its ACE_Log_Msg instance. This is how the initiating thread's logging ostream, etc. get into the service thread. The logging attributes in effect when this function is called are what the service thread will have at its disposal when it starts; therefore, the main thread should set up logging options for the process, and call this function just before calling the StartServiceCtrlDispatcher function.

Definition at line 306 of file NT_Service.cpp.

References ACE_Log_Msg::init_hook.

00307 {
00308   ACE_Log_Msg::init_hook (this->log_msg_attributes_);
00309 }

void ACE_NT_Service::continue_requested DWORD    control_code [protected, virtual]
 

Called by <handle_control> when a continue was requested.

Definition at line 130 of file NT_Service.cpp.

References report_status, and ACE_Task_Base::resume.

Referenced by handle_control.

00131 {
00132   this->report_status (SERVICE_CONTINUE_PENDING);
00133   this->resume ();
00134   this->report_status (SERVICE_RUNNING);
00135 }

int ACE_NT_Service::continue_svc ACE_Time_Value   wait_time = 0,
DWORD *    svc_state = 0
 

Continue the service.

Definition at line 382 of file NT_Service.cpp.

References svc, svc_sc_handle, svc_status_, and wait_for_service_state.

00384 {
00385   SC_HANDLE svc = this->svc_sc_handle ();
00386   if (svc == 0)
00387     return -1;
00388 
00389   if (!ControlService (svc,
00390                        SERVICE_CONTROL_CONTINUE,
00391                        &this->svc_status_))
00392     return -1;
00393 
00394   this->wait_for_service_state (SERVICE_RUNNING,
00395                                 wait_time);
00396   if (svc_state != 0)
00397     *svc_state = this->svc_status_.dwCurrentState;
00398 
00399   return 0;
00400 }

ACE_INLINE const ACE_TCHAR * ACE_NT_Service::desc void    const
 

Get the service description.

Definition at line 62 of file NT_Service.i.

References desc_.

Referenced by insert, and name.

00063 {
00064   return desc_;
00065 }

int ACE_NT_Service::fini void    [virtual]
 

Hook called when terminating the service. Inherited from ACE_Shared_Object. Default implementation sets the service status to SERVICE_STOPPED.

Reimplemented from ACE_Shared_Object.

Definition at line 84 of file NT_Service.cpp.

References report_status.

00085 {
00086   return this->report_status (SERVICE_STOPPED, 0);
00087 }

void ACE_NT_Service::handle_control DWORD    control_code [virtual]
 

This function is called in response to a request from the Service Dispatcher. It must interact with the <svc> function to effect the requested control operation. The default implementation handles all requests as follows: SERVICE_CONTROL_STOP: set stop pending, set cancel flag SERVICE_CONTROL_PAUSE: set pause pending, <suspend>, set paused SERVICE_CONTROL_CONTINUE: set continue pending, <resume>, set running SERVICE_CONTROL_INTERROGATE: reports current status SERVICE_CONTROL_SHUTDOWN: same as SERVICE_CONTROL_STOP.

Definition at line 91 of file NT_Service.cpp.

References continue_requested, interrogate_requested, pause_requested, and stop_requested.

00092 {
00093   switch (control_code)
00094     {
00095     case SERVICE_CONTROL_SHUTDOWN:
00096     case SERVICE_CONTROL_STOP:
00097       this->stop_requested (control_code);
00098       break;
00099 
00100     case SERVICE_CONTROL_PAUSE:
00101       this->pause_requested (control_code);
00102       break;
00103 
00104     case SERVICE_CONTROL_CONTINUE:
00105       this->continue_requested (control_code);
00106       break;
00107 
00108     case SERVICE_CONTROL_INTERROGATE:
00109       this->interrogate_requested (control_code);
00110       break;
00111     }
00112 }

ACE_INLINE const ACE_TCHAR * ACE_NT_Service::host void    const
 

Get the host machine.

Definition at line 69 of file NT_Service.i.

References host_.

00070 {
00071   return host_;
00072 }

void ACE_NT_Service::host const ACE_TCHAR   host
 

Sets the host machine.

Definition at line 157 of file NT_Service.cpp.

References ACE_TCHAR, host, host_, ACE::strnew, and svc_sc_handle_.

Referenced by host.

00158 {
00159   delete [] this->host_;
00160 
00161   if (this->svc_sc_handle_ != 0)
00162     {
00163       CloseServiceHandle (this->svc_sc_handle_);
00164       this->svc_sc_handle_ = 0;
00165     }
00166 
00167   if (host == 0)
00168     {
00169       this->host_ = 0;
00170     }
00171   else
00172     {
00173       this->host_ = ACE::strnew (host);
00174     }
00175 }

void ACE_NT_Service::inherit_log_msg_attributes void   
 

Set the ACE_Log_Msg attributes in the current thread to those saved in the most recent call to capture_log_msg_attributes(). This function should be called from the service's service thread. Ideally, it is the first method called to be sure that any logging done is incorporated correctly into the process's established logging setup.

Definition at line 312 of file NT_Service.cpp.

References ACE_Log_Msg::inherit_hook.

00313 {
00314   // There's no thread descriptor involved with a NT-started
00315   // thread, so the first arg is 0.
00316   ACE_Log_Msg::inherit_hook (0, this->log_msg_attributes_);
00317 }

int ACE_NT_Service::insert DWORD    start_type = SERVICE_DEMAND_START,
DWORD    error_control = SERVICE_ERROR_IGNORE,
const ACE_TCHAR   exe_path = 0,
const ACE_TCHAR   group_name = 0,
LPDWORD    tag_id = 0,
const ACE_TCHAR   dependencies = 0,
const ACE_TCHAR   account_name = 0,
const ACE_TCHAR   password = 0
 

Insert (create) the service in the NT Service Control Manager, with the given creation values. exe_path defaults to the path name of the program that calls the function. All other 0-defaulted arguments pass 0 into the service creation, taking NT_specified defaults. Returns -1 on error, 0 on success.

Definition at line 178 of file NT_Service.cpp.

References ACE_TCHAR, desc, MAXPATHLEN, ACE_OS::set_errno_to_last_error, svc_sc_handle_, and svc_status_.

00186 {
00187   ACE_TCHAR this_exe[MAXPATHLEN];
00188 
00189   // Insure ACE_OS::last_error finds GetLastError unless we set errno.
00190   errno = 0;
00191 
00192   if (exe_path == 0)
00193     {
00194       if (ACE_TEXT_GetModuleFileName (0, this_exe, sizeof this_exe) == 0)
00195         return -1;
00196       exe_path = this_exe;
00197     }
00198 
00199   SC_HANDLE sc_mgr = ACE_TEXT_OpenSCManager (this->host (),
00200                                              0,
00201                                              SC_MANAGER_ALL_ACCESS);
00202   if (sc_mgr == 0)
00203     return -1;
00204 
00205   SC_HANDLE sh = ACE_TEXT_CreateService (sc_mgr,
00206                                          this->name (),
00207                                          this->desc (),
00208                                          SERVICE_ALL_ACCESS,
00209                                          this->svc_status_.dwServiceType,
00210                                          start_type,
00211                                          error_control,
00212                                          exe_path,
00213                                          group_name,
00214                                          tag_id,
00215                                          dependencies,
00216                                          account_name,
00217                                          password);
00218   // If there was an error, stash GetLastError before CloseServiceHandle
00219   // smashes it. ACE_OS::last_error will find the saved error value.
00220   if (sh == 0)
00221     ACE_OS::set_errno_to_last_error ();
00222 
00223   CloseServiceHandle (sc_mgr);
00224 
00225   if (sh == 0)
00226     return -1;
00227 
00228   if (this->svc_sc_handle_ != 0)
00229     CloseServiceHandle (this->svc_sc_handle_);
00230   this->svc_sc_handle_ = sh;
00231 
00232   return 0;
00233 
00234 }

void ACE_NT_Service::interrogate_requested DWORD    control_code [protected, virtual]
 

Called by <handle_control> when a interrogate was requested.

Definition at line 138 of file NT_Service.cpp.

References report_status.

Referenced by handle_control.

00139 {
00140   this->report_status (0);
00141 }

ACE_INLINE const ACE_TCHAR * ACE_NT_Service::name void    const
 

Get the service name.

Reimplemented from ACE_Task< ACE_MT_SYNCH >.

Definition at line 55 of file NT_Service.i.

References name_.

00056 {
00057   return name_;
00058 }

void ACE_NT_Service::name const ACE_TCHAR   name,
const ACE_TCHAR   desc = 0
 

Sets the name and description for the service. If desc is 0, it takes the same value as name.

Definition at line 144 of file NT_Service.cpp.

References ACE_TCHAR, desc, desc_, name, name_, and ACE::strnew.

Referenced by name.

00145 {
00146   delete [] this->desc_;
00147   delete [] this->name_;
00148 
00149   if (desc == 0)
00150     desc = name;
00151 
00152   this->name_ = ACE::strnew (name);
00153   this->desc_ = ACE::strnew (desc);
00154 }

int ACE_NT_Service::open void *    args = 0 [virtual]
 

Hook called to open the service. By default, sets the service status to SERVICE_START_PENDING, calls the svc() method, interprets and sets the service status, and returns.

Reimplemented from ACE_Task_Base.

Definition at line 55 of file NT_Service.cpp.

References report_status, svc, and svc_status_.

00056 {
00057   ACE_UNUSED_ARG (args);
00058   this->report_status (SERVICE_START_PENDING, 0);
00059 
00060   int svc_return = this->svc ();
00061   if (svc_return == 0)
00062     {
00063       this->svc_status_.dwWin32ExitCode = NO_ERROR;
00064       this->svc_status_.dwServiceSpecificExitCode = 0;
00065     }
00066   else
00067     {
00068       if (errno == 0)
00069         {
00070           this->svc_status_.dwWin32ExitCode = GetLastError ();
00071         }
00072       else
00073         {
00074           this->svc_status_.dwWin32ExitCode = ERROR_SERVICE_SPECIFIC_ERROR;
00075           this->svc_status_.dwServiceSpecificExitCode = errno;
00076         }
00077     }
00078 
00079   return svc_return;
00080 
00081 }

void ACE_NT_Service::pause_requested DWORD    control_code [protected, virtual]
 

Called by <handle_control> when a pause was requested.

Definition at line 122 of file NT_Service.cpp.

References report_status, and ACE_Task_Base::suspend.

Referenced by handle_control.

00123 {
00124   this->report_status (SERVICE_PAUSE_PENDING);
00125   this->suspend ();
00126   this->report_status (SERVICE_PAUSED);
00127 }

int ACE_NT_Service::pause_svc ACE_Time_Value   wait_time = 0,
DWORD *    svc_state = 0
 

Pause the service.

Definition at line 361 of file NT_Service.cpp.

References svc, svc_sc_handle, svc_status_, and wait_for_service_state.

00363 {
00364   SC_HANDLE svc = this->svc_sc_handle ();
00365   if (svc == 0)
00366     return -1;
00367 
00368   if (!ControlService (svc,
00369                        SERVICE_CONTROL_PAUSE,
00370                        &this->svc_status_))
00371     return -1;
00372 
00373   this->wait_for_service_state (SERVICE_PAUSED,
00374                                 wait_time);
00375   if (svc_state != 0)
00376     *svc_state = this->svc_status_.dwCurrentState;
00377 
00378   return 0;
00379 }

int ACE_NT_Service::remove void   
 

Remove the service from the NT Service Control Manager. Returns -1 on error, 0 on success. This just affects the SCM and registry - the can and will keep running fine if it is already running.

Definition at line 237 of file NT_Service.cpp.

References svc_sc_handle.

00238 {
00239   if (this->svc_sc_handle () == 0)
00240     return -1;
00241 
00242   if (DeleteService (this->svc_sc_handle()) == 0
00243       && GetLastError () != ERROR_SERVICE_MARKED_FOR_DELETE)
00244     return -1;
00245 
00246   return 0;
00247 }

int ACE_NT_Service::report_status DWORD    new_status,
DWORD    time_hint = 0
[protected]
 

Definition at line 481 of file NT_Service.cpp.

References start_time_, and svc_status_.

Referenced by continue_requested, fini, interrogate_requested, open, pause_requested, and stop_requested.

00483 {
00484   int bump_checkpoint = 0;
00485   int retval = 0;
00486   DWORD save_controls = 0;
00487 
00488   if (new_status != 0)
00489     this->svc_status_.dwCurrentState = new_status;
00490   switch (this->svc_status_.dwCurrentState)
00491     {
00492   case SERVICE_START_PENDING:
00493     save_controls = this->svc_status_.dwControlsAccepted;
00494     this->svc_status_.dwControlsAccepted = 0;
00495     /* Fall through */
00496   case SERVICE_STOP_PENDING:
00497   case SERVICE_CONTINUE_PENDING:
00498   case SERVICE_PAUSE_PENDING:
00499     this->svc_status_.dwWaitHint = time_hint ? time_hint : this->start_time_;
00500     bump_checkpoint = 1;
00501     break;
00502 
00503   default:
00504     this->svc_status_.dwCheckPoint = 0;
00505   }
00506 
00507   retval = SetServiceStatus (this->svc_handle_,
00508                              &this->svc_status_) ? 0 : -1;
00509 
00510   if (save_controls != 0)
00511     this->svc_status_.dwControlsAccepted = save_controls;
00512 
00513   if (bump_checkpoint)
00514     ++this->svc_status_.dwCheckPoint;
00515 
00516   return retval;
00517 }

int ACE_NT_Service::start_svc ACE_Time_Value   wait_time = 0,
DWORD *    svc_state = 0,
DWORD    argc = 0,
const ACE_TCHAR **    argv = 0
 

Start the service (must have been inserted before). wait_time is the time to wait for the service to reach a steady state before returning. If it is 0, the function waits as long as it takes for the service to reach the 'running' state, or gets stuck in some other state, or exits. If <wait_time> is supplied, it is updated on return to hold the service's last reported wait hint. svc_state can be used to receive the state which the service settled in. If the value is 0, the service never ran. argc/argv are passed to the service's ServiceMain function when it starts. Returns 0 for success, -1 for error.

Definition at line 321 of file NT_Service.cpp.

References ACE_TCHAR, svc, svc_sc_handle, svc_status_, and wait_for_service_state.

00324 {
00325   SC_HANDLE svc = this->svc_sc_handle ();
00326   if (svc == 0)
00327     return -1;
00328 
00329   if (!ACE_TEXT_StartService (svc, argc, argv))
00330     return -1;
00331 
00332   this->wait_for_service_state (SERVICE_RUNNING, wait_time);
00333   if (svc_state != 0)
00334     *svc_state = this->svc_status_.dwCurrentState;
00335 
00336   return 0;
00337 }

DWORD ACE_NT_Service::startup void   
 

Returns the current startup type.

Definition at line 276 of file NT_Service.cpp.

References svc, and svc_sc_handle.

00277 {
00278   // The query buffer will hold strings as well as the defined struct.
00279   // The string pointers in the struct point to other areas in the
00280   // passed memory area, so it has to be large enough to hold the
00281   // struct plus all the strings.
00282   char cfgbuff[1024];
00283   LPQUERY_SERVICE_CONFIG cfg;
00284   DWORD cfgsize, needed_size;
00285 
00286   SC_HANDLE svc = this->svc_sc_handle ();
00287   if (svc == 0)
00288   {
00289     // To distinguish this error from the QueryServiceConfig failure
00290     // below, return the DWORD equivalent of -2, rather than -1.
00291     return MAXDWORD - 1;
00292   }
00293   cfgsize = sizeof cfgbuff;
00294   cfg = (LPQUERY_SERVICE_CONFIG) cfgbuff;
00295   BOOL ok = QueryServiceConfig (svc, cfg, cfgsize, &needed_size);
00296   if (ok)
00297     return cfg->dwStartType;
00298   // Zero is a valid return value for QueryServiceConfig, so if
00299   // QueryServiceConfig fails, return the DWORD equivalent of -1.
00300   return MAXDWORD;
00301 
00302 }

int ACE_NT_Service::startup DWORD    startup
 

Sets the startup type for the service. Returns -1 on error, 0 on success.

Definition at line 252 of file NT_Service.cpp.

References startup, svc, and svc_sc_handle.

Referenced by startup.

00253 {
00254   SC_HANDLE svc = this->svc_sc_handle ();
00255   if (svc == 0)
00256     return -1;
00257 
00258   BOOL ok =
00259     ChangeServiceConfig (svc,
00260                          (DWORD) SERVICE_NO_CHANGE,// No change to service type
00261                          startup,                  // New startup type
00262                          (DWORD) SERVICE_NO_CHANGE,// No change to error ctrl
00263                          0,                        // No change to pathname
00264                          0,                        // No change to load group
00265                          0,                        // No change to tag
00266                          0,                        // No change to dependencies
00267                          0, 0,                     // No change to acct/passwd
00268                          0);                       // No change to name
00269 
00270   return ok ? 0 : -1;
00271 }

int ACE_NT_Service::state DWORD *    pstate,
ACE_Time_Value   wait_hint = 0
 

A version of <state> that returns -1 for failure, 0 for success. The DWORD pointed to by pstate receives the state value.

Definition at line 414 of file NT_Service.cpp.

References ACE_Time_Value::msec, svc, svc_sc_handle, and svc_status_.

00416 {
00417   SC_HANDLE svc = this->svc_sc_handle ();
00418 
00419   if (svc == 0)
00420     return -1;
00421 
00422   // Need to create a temporary copy of this variable since the
00423   // QueryServiceStatus call will modify the setting depending on the
00424   // current state of the Service.  If the service is currently
00425   // STOPPED, the value will be cleared.
00426   DWORD controls_accepted = this->svc_status_.dwControlsAccepted;
00427 
00428   if (QueryServiceStatus (svc,
00429                           &this->svc_status_) == 0)
00430     return -1;
00431 
00432   if (wait_hint != 0)
00433     wait_hint->msec (this->svc_status_.dwWaitHint);
00434 
00435   *pstate = this->svc_status_.dwCurrentState;
00436   this->svc_status_.dwControlsAccepted = controls_accepted;
00437   return 0;
00438 }

DWORD ACE_NT_Service::state ACE_Time_Value   wait_hint = 0
 

Get the current state for the service. If <wait_hint> is not 0, it receives the service's reported wait hint. Note that this function returns 0 on failure (not -1 as is usual in ACE). A zero return would (probably) only be returned if there is either no service with the given name in the SCM database, or the caller does not have sufficient rights to access the service state. The set of valid service state values are all greater than 0.

Definition at line 403 of file NT_Service.cpp.

00404 {
00405   DWORD curr_state;
00406 
00407   if (this->state (&curr_state,
00408                    wait_hint) == -1)
00409     return 0;
00410   return curr_state;
00411 }

void ACE_NT_Service::stop_requested DWORD    control_code [protected, virtual]
 

Called by <handle_control> when a stop/shutdown was requested.

Definition at line 115 of file NT_Service.cpp.

References report_status.

Referenced by handle_control.

00116 {
00117   this->report_status (SERVICE_STOP_PENDING);
00118   /* how to cancel? */
00119 }

int ACE_NT_Service::stop_svc ACE_Time_Value   wait_time = 0,
DWORD *    svc_state = 0
 

Requests the service to stop. Will wait up to <wait_time> for the service to actually stop. If not specified, the function waits until the service either stops or gets stuck in some other state before it stops. If <svc_state> is specified, it receives the last reported state of the service. Returns 0 if the request was made successfully, -1 if not.

Definition at line 340 of file NT_Service.cpp.

References svc, svc_sc_handle, svc_status_, and wait_for_service_state.

00342 {
00343   SC_HANDLE svc = this->svc_sc_handle ();
00344   if (svc == 0)
00345     return -1;
00346 
00347   if (!ControlService (svc,
00348                        SERVICE_CONTROL_STOP,
00349                        &this->svc_status_))
00350     return -1;
00351 
00352   this->wait_for_service_state (SERVICE_STOPPED,
00353                                 wait_time);
00354   if (svc_state != 0)
00355     *svc_state = this->svc_status_.dwCurrentState;
00356 
00357   return 0;
00358 }

ACE_INLINE int ACE_NT_Service::svc void    [virtual]
 

The actual service implementation. This function need not be overridden by applications that are just using SCM capabilities, but must be by subclasses when actually running the service. It is expected that this function will set the status to RUNNING.

Reimplemented from ACE_Task_Base.

Definition at line 47 of file NT_Service.i.

Referenced by continue_svc, open, pause_svc, start_svc, startup, state, and stop_svc.

00048 {
00049   return -1;
00050 }

ACE_INLINE void ACE_NT_Service::svc_handle const SERVICE_STATUS_HANDLE    new_svc_handle
 

Set the svc_handle_ member. This is only a public function because the macro-generated service function calls it.

Definition at line 75 of file NT_Service.i.

References svc_handle_.

00076 {
00077   this->svc_handle_ = new_svc_handle;
00078   return;
00079 }

SC_HANDLE ACE_NT_Service::svc_sc_handle void    [protected]
 

Return the svc_sc_handle_ member. If the member is null, it retrieves the handle from the Service Control Manager and caches it.

Definition at line 520 of file NT_Service.cpp.

References ACE_OS::set_errno_to_last_error, and svc_sc_handle_.

Referenced by continue_svc, pause_svc, remove, start_svc, startup, state, and stop_svc.

00521 {
00522   if (this->svc_sc_handle_ == 0)
00523     {
00524       SC_HANDLE sc_mgr = ACE_TEXT_OpenSCManager (this->host (),
00525                                                  0,
00526                                                  SC_MANAGER_ALL_ACCESS);
00527       if (sc_mgr != 0)
00528         {
00529           this->svc_sc_handle_ = ACE_TEXT_OpenService (sc_mgr,
00530                                                        this->name (),
00531                                                        SERVICE_ALL_ACCESS);
00532           if (this->svc_sc_handle_ == 0)
00533             ACE_OS::set_errno_to_last_error ();
00534           CloseServiceHandle (sc_mgr);
00535         }
00536       else
00537         ACE_OS::set_errno_to_last_error ();
00538     }
00539 
00540   return this->svc_sc_handle_;
00541 }

int ACE_NT_Service::test_access DWORD    desired_access = SERVICE_ALL_ACCESS
 

Test access to the object's service in the SCM. The service must already have been inserted in the SCM database. This function has no affect on the service itself. Returns 0 if the specified access is allowed, -1 otherwise (either the access is denied, or there is a problem with the service's definition - check ACE_OS::last_error to get the specific error indication.

Definition at line 447 of file NT_Service.cpp.

00448 {
00449   int status = -1;     // Guilty until proven innocent
00450 
00451   SC_HANDLE sc_mgr = ACE_TEXT_OpenSCManager (this->host (),
00452                                              0,
00453                                              GENERIC_READ);
00454   if (sc_mgr != 0)
00455     {
00456       SC_HANDLE handle = ACE_TEXT_OpenService (sc_mgr,
00457                                                this->name (),
00458                                                desired_access);
00459       CloseServiceHandle (sc_mgr);
00460       if (handle != 0)
00461         {
00462           status = 0;
00463           CloseServiceHandle (handle);
00464         }
00465     }
00466 
00467   return status;
00468 }

void ACE_NT_Service::wait_for_service_state DWORD    desired_state,
ACE_Time_Value   wait_time
[protected]
 

Waits for the service to reach <desired_state> or get (apparently) stuck before it reaches that state. Will wait at most <wait_time> to get to the desired state. If <wait_time> is 0, then the function keeps waiting until the desired state is reached or the service doesn't update its state any further. The svc_status_ class member is updated upon return.

Definition at line 544 of file NT_Service.cpp.

References ETIME, ACE_OS::gettimeofday, and svc_status_.

Referenced by continue_svc, pause_svc, start_svc, and stop_svc.

00546 {
00547   DWORD last_state, last_check_point;
00548   int first_time = 1;
00549   int service_ok;
00550     
00551   ACE_Time_Value time_out = ACE_OS::gettimeofday ();
00552   if (wait_time != 0)
00553     time_out += *wait_time;
00554     
00555   // Poll until the service reaches the desired state.
00556   for (;;)
00557     {
00558       service_ok = 0 != QueryServiceStatus (this->svc_sc_handle_,
00559                                             &this->svc_status_);
00560        
00561       // If we cannot query the service, we are done.
00562       if (!service_ok)
00563         break;
00564         
00565       // If the service has the desired state, we are done.
00566       if (desired_state == this->svc_status_.dwCurrentState)
00567         break;
00568         
00569       // If we time-out, we are done
00570       if (wait_time != 0 && ACE_OS::gettimeofday () > time_out )
00571         {
00572           errno = ETIME;
00573           break;
00574         }
00575         
00576       if (first_time)
00577         {
00578           // remember the service state, the first time we wait
00579           last_state       = this->svc_status_.dwCurrentState;
00580           last_check_point = this->svc_status_.dwCheckPoint;
00581           first_time = 0;
00582         }
00583       else
00584         {
00585           // update the state change.
00586           if (last_state != this->svc_status_.dwCurrentState)
00587             {
00588               last_state       = this->svc_status_.dwCurrentState;
00589               last_check_point = this->svc_status_.dwCheckPoint;
00590             }
00591           else
00592             {
00593               // The check-point should have increased
00594               if (this->svc_status_.dwCheckPoint > last_check_point)
00595                 last_check_point = this->svc_status_.dwCheckPoint;
00596               else
00597                 {
00598                   // Service control failure, we are done.
00599                   service_ok = 0;
00600                   break;
00601                 }
00602             }
00603         }
00604         
00605       ::Sleep (this->svc_status_.dwWaitHint);
00606     }
00607     
00608   return;
00609 }


Member Data Documentation

ACE_NT_Service::ACE_ALLOC_HOOK_DECLARE
 

Declare the dynamic allocation hooks.

Reimplemented from ACE_Task< ACE_MT_SYNCH >.

Definition at line 318 of file NT_Service.h.

ACE_TCHAR* ACE_NT_Service::desc_ [protected]
 

Definition at line 363 of file NT_Service.h.

Referenced by desc, name, and ~ACE_NT_Service.

ACE_TCHAR* ACE_NT_Service::host_ [protected]
 

Definition at line 364 of file NT_Service.h.

Referenced by host, and ~ACE_NT_Service.

ACE_OS_Log_Msg_Attributes ACE_NT_Service::log_msg_attributes_ [protected]
 

ACE_Log_Msg attributes to inherit from the starting thread.

Definition at line 367 of file NT_Service.h.

ACE_TCHAR* ACE_NT_Service::name_ [protected]
 

Definition at line 362 of file NT_Service.h.

Referenced by name, and ~ACE_NT_Service.

DWORD ACE_NT_Service::start_time_ [protected]
 

Estimate of init time needed.

Definition at line 355 of file NT_Service.h.

Referenced by report_status.

SERVICE_STATUS_HANDLE ACE_NT_Service::svc_handle_ [protected]
 

Service handle - doesn't need close.

Definition at line 357 of file NT_Service.h.

Referenced by svc_handle.

SC_HANDLE ACE_NT_Service::svc_sc_handle_ [protected]
 

Service's SCM handle.

Definition at line 361 of file NT_Service.h.

Referenced by host, insert, svc_sc_handle, and ~ACE_NT_Service.

SERVICE_STATUS ACE_NT_Service::svc_status_ [protected]
 

Definition at line 358 of file NT_Service.h.

Referenced by ACE_NT_Service, continue_svc, insert, open, pause_svc, report_status, start_svc, state, stop_svc, and wait_for_service_state.


The documentation for this class was generated from the following files:
Generated on Mon Jun 16 12:51:10 2003 for ACE by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002