diff options
author | coryan <coryan@ae88bc3d-4319-0410-8dbf-d08b4c9d3795> | 2000-11-01 22:17:39 +0000 |
---|---|---|
committer | coryan <coryan@ae88bc3d-4319-0410-8dbf-d08b4c9d3795> | 2000-11-01 22:17:39 +0000 |
commit | 4cdff4b3e2dbc73b00e671ef638d71d6d854e0ac (patch) | |
tree | 97236ece363cff48fd287c780db4290da39b02cb /ace/NT_Service.h | |
parent | 7b6368ec78831d127f38eb7b630c21f98faf6a83 (diff) | |
download | ATCD-4cdff4b3e2dbc73b00e671ef638d71d6d854e0ac.tar.gz |
ChangeLogTag:Wed Nov 1 14:11:48 2000 Carlos O'Ryan <coryan@uci.edu>
Diffstat (limited to 'ace/NT_Service.h')
-rw-r--r-- | ace/NT_Service.h | 342 |
1 files changed, 182 insertions, 160 deletions
diff --git a/ace/NT_Service.h b/ace/NT_Service.h index 9f01164c623..0a17c04aed6 100644 --- a/ace/NT_Service.h +++ b/ace/NT_Service.h @@ -1,18 +1,15 @@ /* -*- C++ -*- */ -// $Id$ -// ============================================================================ -// -// = LIBRARY -// ace -// -// = FILENAME -// NT_Service.h -// -// = AUTHOR -// Steve Huston <shuston@riverace.com> -// -// ============================================================================ +//============================================================================= +/** + * @file NT_Service.h + * + * $Id$ + * + * @author Steve Huston <shuston@riverace.com> + */ +//============================================================================= + #ifndef ACE_NT_SERVICE_H #define ACE_NT_SERVICE_H @@ -38,129 +35,145 @@ #define ACE_NT_SERVICE_START_TIMEOUT 5000 #endif /* ACE_NT_SERVICE_TIMEOUT */ +/** + * @class ACE_NT_Service + * + * @brief 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: + * + * - The main program defines an array of entries describing the + * services offered. The ACE_NT_SERVICE_ENTRY macro can help with + * this. + * - For each service, a separate ServiceMain and Handler function + * need to be defined. These are taken care of by the + * ACE_NT_SERVICE_DEFINE macro. + * - When the main program/thread calls + * StartServiceCtrlDispatcher, NT creates a thread for each + * service, and runs the ServiceMain function for the service in + * that new thread. When that thread exits, the service is gone. + * + * 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. + */ class ACE_Export ACE_NT_Service : public ACE_Task<ACE_MT_SYNCH> { - // = TITLE - // Provide the base class which defines the interface for controlling - // an NT service. - // - // = DESCRIPTION - // 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: - - // - The main program defines an array of entries describing the - // services offered. The ACE_NT_SERVICE_ENTRY macro can help with - // this. - // - For each service, a separate ServiceMain and Handler function - // need to be defined. These are taken care of by the - // ACE_NT_SERVICE_DEFINE macro. - // - When the main program/thread calls - // StartServiceCtrlDispatcher, NT creates a thread for each - // service, and runs the ServiceMain function for the service in - // that new thread. When that thread exits, the service is gone. - // - // 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. + public: // = Initialization and termination methods. + /// Constructor primarily for use when running the 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. + /// Constructor primarily for use when inserting/removing/controlling + /// the 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. virtual ~ACE_NT_Service (void); // = Functions to operate the service + /** + * Hook called to open the service. By default, will set the status + * to <START>_PENDING, <svc>, <wait>, then set the status to + * STOPPED. + */ virtual int open (void *args = 0); - // Hook called to open the service. By default, will set the status - // to <START>_PENDING, <svc>, <wait>, then set the status to - // STOPPED. + /** + * 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. + */ virtual int svc (void); - // 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. + /** + * 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. + */ virtual void handle_control (DWORD control_code); - // 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. + /// Set the svc_handle_ member. This is only a public function because + /// the macro-generated service function calls it. 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. // = Methods which can be used to do SCP-like functions. The first group // are used to register/insert and remove the service's definition in the // SCM registry. + /// Sets the name and description for the service. + /// If desc is 0, it takes the same value as name. 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. + /// Get the service name. const ACE_TCHAR *name (void) const; - // Get the service name. + /// Get the service description. const ACE_TCHAR *desc (void) const; - // Get the service description. + /// Sets the host machine void host (const ACE_TCHAR *host); - // Sets the host machine + /// Get the host machine. const ACE_TCHAR *host (void) const; - // Get the host machine. + /** + * 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. + */ int insert (DWORD start_type = SERVICE_DEMAND_START, DWORD error_control = SERVICE_ERROR_IGNORE, const ACE_TCHAR *exe_path = 0, @@ -169,22 +182,19 @@ public: 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. + /** + * 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. + */ int 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. + /// Sets the startup type for the service. Returns -1 on error, 0 on success. int startup (DWORD startup); - // Sets the startup type for the service. Returns -1 on error, 0 on success. + /// Returns the current startup type. DWORD startup (void); - // Returns the current startup type. // = Methods which control the service's execution. @@ -215,98 +225,110 @@ public: // not configured to receive the request (this is most likely to // happen in the case of pause and continue). + /** + * 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. + */ int 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. + /** + * 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. + */ int 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. + /// Pause the service. int pause_svc (ACE_Time_Value *wait_time = 0, DWORD *svc_state = 0); - // Pause the service. + /// Continue the service. int continue_svc (ACE_Time_Value *wait_time = 0, DWORD *svc_state = 0); - // Continue the service. + /** + * 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. + */ DWORD 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. + /// A version of <state> that returns -1 for failure, 0 for success. + /// The DWORD pointed to by pstate receives the state value. 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. + /** + * 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. + */ int 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. + /// Declare the dynamic allocation hooks. ACE_ALLOC_HOOK_DECLARE; - // Declare the dynamic allocation hooks. protected: int report_status (DWORD new_status, DWORD time_hint = 0); + /** + * Return the svc_sc_handle_ member. If the member is null, it + * retrieves the handle from the Service Control Manager and caches + * it. + */ SC_HANDLE svc_sc_handle (void); - // Return the svc_sc_handle_ member. If the member is null, it - // retrieves the handle from the Service Control Manager and caches - // it. + /** + * 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. NOTE - the + * timeout doesn't currently work - it always acts like + * ACE_Time_Value::zero is passed - it checks the state once but + * doesn't wait after that. + */ void wait_for_service_state (DWORD desired_state, ACE_Time_Value *wait_time); - // 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. NOTE - the - // timeout doesn't currently work - it always acts like - // ACE_Time_Value::zero is passed - it checks the state once but - // doesn't wait after that. + /// Called by <handle_control> when a stop/shutdown was requested. virtual void stop_requested (DWORD control_code); - // Called by <handle_control> when a stop/shutdown was requested. + /// Called by <handle_control> when a pause was requested. virtual void pause_requested (DWORD control_code); - // Called by <handle_control> when a pause was requested. + /// Called by <handle_control> when a continue was requested. virtual void continue_requested (DWORD control_code); - // Called by <handle_control> when a continue was requested. + /// Called by <handle_control> when a interrogate was requested. virtual void interrogate_requested (DWORD control_code); - // Called by <handle_control> when a interrogate was requested. protected: - DWORD start_time_; - // Estimate of init time needed - SERVICE_STATUS_HANDLE svc_handle_; - // Service handle - doesn't need close. + /// Estimate of init time needed + /// Service handle - doesn't need close. + DWORD start_time_; + SERVICE_STATUS_HANDLE svc_handle_; SERVICE_STATUS svc_status_; + /// Service's SCM handle SC_HANDLE svc_sc_handle_; - // Service's SCM handle ACE_TCHAR *name_; ACE_TCHAR *desc_; ACE_TCHAR *host_; |