summaryrefslogtreecommitdiff
path: root/ace/NT_Service.h
diff options
context:
space:
mode:
authorcoryan <coryan@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>2000-11-01 22:17:39 +0000
committercoryan <coryan@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>2000-11-01 22:17:39 +0000
commit4cdff4b3e2dbc73b00e671ef638d71d6d854e0ac (patch)
tree97236ece363cff48fd287c780db4290da39b02cb /ace/NT_Service.h
parent7b6368ec78831d127f38eb7b630c21f98faf6a83 (diff)
downloadATCD-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.h342
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_;