#include <NT_Service.h>
Inheritance diagram for ACE_NT_Service:


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_TCHAR * | name (void) const |
| Get the service name. More... | |
| const ACE_TCHAR * | desc (void) const |
| Get the service description. More... | |
| void | host (const ACE_TCHAR *host) |
| Sets the host machine. More... | |
| const ACE_TCHAR * | host (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_TCHAR * | name_ |
| ACE_TCHAR * | desc_ |
| ACE_TCHAR * | host_ |
| ACE_OS_Log_Msg_Attributes | log_msg_attributes_ |
| ACE_Log_Msg attributes to inherit from the starting thread. More... | |
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:
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 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 } |
|
||||||||||||||||||||||||
|
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 } |
|
|
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 }
|
|
|
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 }
|
|
|
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 }
|
|
||||||||||||
|
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 }
|
|
|
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 }
|
|
|
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 }
|
|
|
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 }
|
|
|
Get the host machine.
Definition at line 69 of file NT_Service.i. References host_.
00070 {
00071 return host_;
00072 }
|
|
|
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 }
|
|
|
Set the ACE_Log_Msg attributes in the current thread to those saved in the most recent call to 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 }
|
|
||||||||||||||||||||||||||||||||||||
|
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 }
|
|
|
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 }
|
|
|
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 }
|
|
||||||||||||
|
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.
|
|
|
Hook called to open the service. By default, sets the service status to SERVICE_START_PENDING, calls the 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 }
|
|
|
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 }
|
|
||||||||||||
|
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 }
|
|
|
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 }
|
|
||||||||||||
|
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 }
|
|
||||||||||||||||||||
|
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 }
|
|
|
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 }
|
|
|
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 }
|
|
||||||||||||
|
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 }
|
|
|
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 }
|
|
|
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 }
|
|
||||||||||||
|
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 }
|
|
|
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 }
|
|
|
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 }
|
|
|
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 }
|
|
|
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 }
|
|
||||||||||||
|
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 }
|
|
|
Declare the dynamic allocation hooks.
Reimplemented from ACE_Task< ACE_MT_SYNCH >. Definition at line 318 of file NT_Service.h. |
|
|
Definition at line 363 of file NT_Service.h. Referenced by desc, name, and ~ACE_NT_Service. |
|
|
Definition at line 364 of file NT_Service.h. Referenced by host, and ~ACE_NT_Service. |
|
|
ACE_Log_Msg attributes to inherit from the starting thread.
Definition at line 367 of file NT_Service.h. |
|
|
Definition at line 362 of file NT_Service.h. Referenced by name, and ~ACE_NT_Service. |
|
|
Estimate of init time needed.
Definition at line 355 of file NT_Service.h. Referenced by report_status. |
|
|
Service handle - doesn't need close.
Definition at line 357 of file NT_Service.h. Referenced by svc_handle. |
|
|
Service's SCM handle.
Definition at line 361 of file NT_Service.h. Referenced by host, insert, svc_sc_handle, and ~ACE_NT_Service. |
|
|
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. |
1.2.14 written by Dimitri van Heesch,
© 1997-2002