summaryrefslogtreecommitdiff
path: root/ace/NT_Service.h
diff options
context:
space:
mode:
Diffstat (limited to 'ace/NT_Service.h')
-rw-r--r--ace/NT_Service.h435
1 files changed, 0 insertions, 435 deletions
diff --git a/ace/NT_Service.h b/ace/NT_Service.h
deleted file mode 100644
index e3675b6fa57..00000000000
--- a/ace/NT_Service.h
+++ /dev/null
@@ -1,435 +0,0 @@
-// -*- C++ -*-
-
-//==========================================================================
-/**
- * @file NT_Service.h
- *
- * $Id$
- *
- * @author Steve Huston <shuston@riverace.com>
- */
-//==========================================================================
-
-#ifndef ACE_NT_SERVICE_H
-#define ACE_NT_SERVICE_H
-
-#include "ace/pre.h"
-
-#include "ace/config-all.h"
-
-#if !defined (ACE_LACKS_PRAGMA_ONCE)
-# pragma once
-#endif /* ACE_LACKS_PRAGMA_ONCE */
-
-#if defined (ACE_WIN32) && !defined (ACE_HAS_PHARLAP) && \
- !defined (ACE_HAS_WINCE)
-
-#include "ace/ACE.h"
-#include "ace/OS_Log_Msg_Attributes.h"
-#include "ace/Service_Object.h"
-#include "ace/Synch.h"
-#include "ace/Task.h"
-
-// ACE_NT_SERVICE_START_TIMEOUT is an estimate of the number of
-// milliseconds your service will take to start. Default is 5
-// seconds; you can pass a different value (or set one) when you
-// create the ACE_NT_Service object for your service.
-#if !defined ACE_NT_SERVICE_START_TIMEOUT
-#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>
-{
-
-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 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);
-
- virtual ~ACE_NT_Service (void);
-
- // = Functions to operate the service
-
- /**
- * Hook called to open the service. By default, sets the service
- * status to SERVICE_START_PENDING, calls the @c svc() method,
- * interprets and sets the service status, and returns.
- */
- virtual int open (void *args = 0);
-
- /**
- * Hook called when terminating the service. Inherited from
- * ACE_Shared_Object. Default implementation sets the service status
- * to SERVICE_STOPPED.
- */
- virtual int fini (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.
- */
- virtual int svc (void);
-
- /**
- * 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);
-
- /// 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);
-
-
- // = 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);
-
- /// Get the service name.
- const ACE_TCHAR *name (void) const;
-
- /// Get the service description.
- const ACE_TCHAR *desc (void) const;
-
- /// Sets the host machine
- void host (const ACE_TCHAR *host);
-
- /// Get the host machine.
- const ACE_TCHAR *host (void) const;
-
- /**
- * 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,
- 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);
-
- /**
- * 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);
-
- /// Sets the startup type for the service. Returns -1 on error, 0 on success.
- int startup (DWORD startup);
-
- /// Returns the current startup type.
- DWORD startup (void);
-
- // = Methods to control ACE_Log_Msg behavior in the service.
-
- /**
- * 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.
- */
- void capture_log_msg_attributes (void);
-
- /**
- * Set the ACE_Log_Msg attributes in the current thread to those saved
- * in the most recent call to @c 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.
- */
- void inherit_log_msg_attributes (void);
-
- // = Methods which control the service's execution.
-
- // These methods to start/pause/resume/stop/check the service all
- // have the following common behavior with respect to <wait_time>
- // and return value. <wait_time> is a pointer to an ACE_Time_Value
- // object. If not supplied (a zero pointer) the function will wait
- // indefinitely for the action to be finalized (service reach
- // running state, completely shut down, etc.) or get "stuck" before
- // returning. If the time is supplied, it specifies how long to
- // wait for the service to reach a steady state, and on return, it
- // is updated to the service's last reported wait hint. So, if you
- // want to control the waiting yourself (for example, you want to
- // react to UI events during the wait) specify a <wait_time> of (0,
- // 0) and use the updated time to know when to check the service's
- // state again. NOTE!!!! The wait_time things don't work yet. The
- // calls always check status once, and do not wait for it to change.
- //
- // The return value from start_svc, stop_svc, pause_svc,
- // continue_svc is 0 if the request to NT to effect the change was
- // made successfully. The service may refuse to change, or not do
- // what you wanted; so if you need to know, supply a <svc_state>
- // pointer to receive the service's reported last state on return
- // and check it to see if it's what you want. The functions only
- // return -1 when the actual request to the service is refused -
- // this would include privilege restrictions and if the service is
- // 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);
-
- /**
- * 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);
-
- /// Pause the service.
- int pause_svc (ACE_Time_Value *wait_time = 0, DWORD *svc_state = 0);
-
- /// Continue the service.
- int continue_svc (ACE_Time_Value *wait_time = 0, DWORD *svc_state = 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.
- */
- DWORD state (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.
- int state (DWORD *pstate, ACE_Time_Value *wait_hint = 0);
-
- /**
- * 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);
-
- /// Declare the dynamic allocation hooks.
- ACE_ALLOC_HOOK_DECLARE;
-
-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);
-
- /**
- * 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.
- */
- void wait_for_service_state (DWORD desired_state,
- ACE_Time_Value *wait_time);
-
- /// Called by <handle_control> when a stop/shutdown was requested.
- virtual void stop_requested (DWORD control_code);
-
- /// Called by <handle_control> when a pause was requested.
- virtual void pause_requested (DWORD control_code);
-
- /// Called by <handle_control> when a continue was requested.
- virtual void continue_requested (DWORD control_code);
-
- /// Called by <handle_control> when a interrogate was requested.
- virtual void interrogate_requested (DWORD control_code);
-
-protected:
- /// Estimate of init time needed
- DWORD start_time_;
- /// Service handle - doesn't need close.
- SERVICE_STATUS_HANDLE svc_handle_;
- SERVICE_STATUS svc_status_;
-
- /// Service's SCM handle
- SC_HANDLE svc_sc_handle_;
- ACE_TCHAR *name_;
- ACE_TCHAR *desc_;
- ACE_TCHAR *host_;
-
- /// ACE_Log_Msg attributes to inherit from the starting thread.
- ACE_OS_Log_Msg_Attributes log_msg_attributes_;
-};
-
-// These macros help to get things set up correctly at compile time
-// and to take most of the grudge work out of creating the proper
-// functions and doing the registrations.
-//
-// ACE_NT_SERVICE_DEFINE - defines the 'ServiceMain' function which NT will
-// call in its own thread when the service control
-// dispatcher starts.
-
-#define ACE_NT_SERVICE_DEFINE(SVCNAME, SVCCLASS, SVCDESC) \
- ACE_NT_Service * _ace_nt_svc_obj_##SVCNAME = 0; \
- VOID WINAPI ace_nt_svc_handler_##SVCNAME (DWORD fdwControl) { \
- _ace_nt_svc_obj_##SVCNAME->handle_control(fdwControl); \
- } \
- VOID WINAPI ace_nt_svc_main_##SVCNAME (DWORD dwArgc, \
- ACE_TCHAR **lpszArgv) { \
- int delete_svc_obj = 0; \
- if (_ace_nt_svc_obj_##SVCNAME == 0) { \
- ACE_NEW (_ace_nt_svc_obj_##SVCNAME, SVCCLASS); \
- if (_ace_nt_svc_obj_##SVCNAME == 0) \
- return; \
- delete_svc_obj = 1; \
- } \
- else \
- _ace_nt_svc_obj_##SVCNAME->inherit_log_msg_attributes (); \
- _ace_nt_svc_obj_##SVCNAME->init(dwArgc, lpszArgv); \
- _ace_nt_svc_obj_##SVCNAME->svc_handle( \
- ACE_TEXT_RegisterServiceCtrlHandler(SVCDESC, \
- &ace_nt_svc_handler_##SVCNAME)); \
- _ace_nt_svc_obj_##SVCNAME->open(); \
- _ace_nt_svc_obj_##SVCNAME->wait(); \
- _ace_nt_svc_obj_##SVCNAME->fini(); \
- if (delete_svc_obj) { \
- delete _ace_nt_svc_obj_##SVCNAME; \
- _ace_nt_svc_obj_##SVCNAME = 0; \
- } \
- return; \
- }
-
-#define ACE_NT_SERVICE_REFERENCE(SVCNAME) \
-extern ACE_NT_Service * _ace_nt_svc_obj_##SVCNAME; \
-extern VOID WINAPI ace_nt_svc_main_##SVCNAME (DWORD dwArgc, \
- ACE_TCHAR **lpszArgv);
-
-#define ACE_NT_SERVICE_ENTRY(SVCDESC, SVCNAME) \
- { SVCDESC, &ace_nt_svc_main_##SVCNAME }
-
-#define ACE_NT_SERVICE_RUN(SVCNAME, SVCINSTANCE, RET) \
- ACE_TEXT_SERVICE_TABLE_ENTRY _ace_nt_svc_table[2] = \
- { \
- ACE_NT_SERVICE_ENTRY(ACE_TEXT (#SVCNAME), SVCNAME), \
- { 0, 0 } \
- }; \
- _ace_nt_svc_obj_##SVCNAME = SVCINSTANCE; \
- _ace_nt_svc_obj_##SVCNAME->capture_log_msg_attributes (); \
- ACE_OS::last_error (0); \
- int RET = ACE_TEXT_StartServiceCtrlDispatcher(_ace_nt_svc_table);
-
-#if defined (__ACE_INLINE__)
-#include "ace/NT_Service.i"
-#endif /* __ACE_INLINE__ */
-
-#endif /* ACE_WIN32 && !ACE_HAS_PHARLAP && !ACE_HAS_WINCE */
-
-#include "ace/post.h"
-
-#endif /* ACE_SERVICE_OBJECT_H */