Windows2003-3790/inetsrv/pop3/service/pop3svc/service.h
2020-09-30 16:53:55 +02:00

184 lines
8.0 KiB
C++

/************************************************************************************************
Copyright (c) 2001 Microsoft Corporation
Module Name: Service.h
Abstract: Defines the CService class and related macros. See description below.
Notes:
History: 01/25/2001 - created, Luciano Passuello (lucianop).
************************************************************************************************/
#pragma once
// global constants
const int nMaxServiceLen = 256;
const int nMaxServiceDescLen = 1024;
/************************************************************************************************
Class: CService
Purpose: Abstract class that implements the service-related code, such as
threads creating, SCM registering, status retrieval, etc..
Notes: (1) Class design based on the CService class described in the book:
Professional NT Services, by Kevin Miller.
(2) Each derived class must be instantiated one and only time.
History: 01/25/2001 - created, Luciano Passuello (lucianop)
************************************************************************************************/
class CService
{
protected:
// actions that services respond to
const static DWORD dwStateNoChange;
enum SERVICE_NUMBER_EVENTS { nNumServiceEvents = 4 };
enum SERVICE_EVENTS {STOP, PAUSE, CONTINUE, SHUTDOWN};
DWORD m_dwDefaultEventID;
WORD m_wDefaultCategory;
public:
CService(LPCTSTR szName, LPCTSTR szDisplay, DWORD dwType);
virtual ~CService();
DWORD GetStatus() { return m_dwState; }
DWORD GetControls() { return m_dwControlsAccepted; }
LPCTSTR GetName() { return m_szName; }
LPCTSTR GetDisplayName() { return m_szDisplay; }
protected:
void ServiceMainMember(DWORD argc, LPTSTR* argv, LPHANDLER_FUNCTION pf, LPTHREAD_START_ROUTINE pfnWTP);
void HandlerMember(DWORD dwControl);
virtual void LaunchWatcherThread(LPTHREAD_START_ROUTINE pfnWTP);
virtual DWORD WatcherThreadMemberProc();
bool SetupHandlerInside(LPHANDLER_FUNCTION lpHandlerProc);
void SetStatus(DWORD dwNewState, DWORD dwNewCheckpoint = dwStateNoChange, DWORD dwNewHint = dwStateNoChange,
DWORD dwNewControls = dwStateNoChange, DWORD dwExitCode = NO_ERROR, DWORD dwSpecificExit = 0);
void AbortService(DWORD dwErrorNum = GetLastError());
// Overrideables
protected:
virtual void PreInit(); // if you override, call the base class version
virtual void Init();
virtual void DeInit(); // If you override, call the base class version
virtual void ParseArgs(DWORD argc, LPTSTR* argv);
virtual void OnPause();
virtual void OnContinue();
virtual void OnShutdown();
virtual void HandleUserDefined(DWORD dwControl);
// service events handling
virtual void OnStopRequest();
virtual void OnPauseRequest();
virtual void OnContinueRequest();
virtual void OnShutdownRequest();
virtual void OnBeforeStart();
virtual void OnAfterStart();
virtual void Run() = 0;
virtual void OnStop(DWORD dwErrorCode) = 0;
// Attributes
protected:
CRITICAL_SECTION m_cs;
// Status info
SERVICE_STATUS_HANDLE m_hServiceStatus;
DWORD m_dwState;
DWORD m_dwControlsAccepted;
DWORD m_dwCheckpoint;
DWORD m_dwWaitHint;
// Tracks state currently being worked on in Handler
DWORD m_dwRequestedControl;
// Control Events
HANDLE m_hServiceEvent[nNumServiceEvents];
HANDLE m_hWatcherThread;
TCHAR m_szName[nMaxServiceLen + 1];
TCHAR m_szDisplay[nMaxServiceLen + 1];
DWORD m_dwType;
};
/************************************************************************************************
Macro: DECLARE_SERVICE
Synopsis: declares the static functions that will be used as thread-entry points.
Effects: These functions need to be static because they will be used as thread
entry-points. Since static functions don't have access to the this pointer, it
have to be explicitly passed to them (m_pThis). That's why this code need to be
put in derived classes, otherwise we could have just one CService around at a
time. We can only have one specific CService-derived class at a time.
Arguments: [class_name] - the name of the CService-derived class.
[service_name] - the SCM short service name.
Notes: to be used in CService-derived class declaration.
History: 01/25/2001 - created, Luciano Passuello (lucianop).
************************************************************************************************/
#define DECLARE_SERVICE(class_name, service_name) \
public: \
static class_name##* m_pThis; \
static void WINAPI service_name##Main(DWORD argc, LPTSTR* argv); \
static void WINAPI service_name##Handler(DWORD dwControl); \
static DWORD WINAPI service_name##WatcherThreadProc(LPVOID lpParameter);
/************************************************************************************************
Macro: IMPLEMENT_SERVICE
Synopsis: implements the static functions that will be used as thread-entry points.
Effects: Using the explicit "this" pointer, it just delegates the work to the member
functions.
Arguments: [class_name] - the name of the CService-derived class.
[service_name] - the SCM short service name.
Notes: to be used in CService-derived class implementation.
History: 01/25/2001 - created, Luciano Passuello (lucianop).
************************************************************************************************/
#define IMPLEMENT_SERVICE(class_name, service_name) \
class_name##* class_name::m_pThis = NULL; \
void WINAPI class_name::service_name##Main(DWORD argc, LPTSTR* argv) \
{ \
m_pThis->ServiceMainMember(argc, argv, (LPHANDLER_FUNCTION)service_name##Handler, \
(LPTHREAD_START_ROUTINE)service_name##WatcherThreadProc); \
} \
void WINAPI class_name::service_name##Handler(DWORD dwControl) \
{ \
m_pThis->HandlerMember(dwControl); \
} \
DWORD WINAPI class_name::service_name##WatcherThreadProc(LPVOID /*lpParameter*/) \
{ \
return m_pThis->WatcherThreadMemberProc(); \
}
/************************************************************************************************
Macro: BEGIN_SERVICE_MAP, SERVICE_MAP_ENTRY, END_SERVICE_MAP
Synopsis: creates the service map and registers it with the SCM.
Effects: Using the explicit "this" pointer, it just delegates the work to the member
functions.
Arguments: [class_name] - the name of the CService-derived class.
[service_name] - the SCM short service name.
Notes: to be used in the entry-point where the CService-derived class is used.
History: 01/25/2001 - created, Luciano Passuello (lucianop).
************************************************************************************************/
#define BEGIN_SERVICE_MAP \
SERVICE_TABLE_ENTRY svcTable[] = {
#define SERVICE_MAP_ENTRY(class_name, service_name) \
{_T(#service_name), (LPSERVICE_MAIN_FUNCTION)class_name::service_name##Main},
#define END_SERVICE_MAP \
{NULL, NULL}}; \
StartServiceCtrlDispatcher(svcTable);
/************************************************************************************************
Macro: IMPLEMENT_STATIC_REFERENCE()
Synopsis: assigns the "this" pointer to an explicit m_pThis member.
Effects: makes the static member functions know explicitly about the data in the class,
since static functions don't have access to the "this" pointer.
Notes: to be used in CService-derived constructors.
History: 01/25/2001 - created, Luciano Passuello (lucianop).
************************************************************************************************/
#define IMPLEMENT_STATIC_REFERENCE() m_pThis = this
// End of file Service.h.