-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathCservice.h
165 lines (137 loc) · 5.15 KB
/
Cservice.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
#if !defined(SERVICE_H)
#define SERVICE_H
#define STATE_NO_CHANGE 0xffffffff
#define NUMEVENTS 4
#define MAX_SERVICE_LEN 256
#include <winsvc.h>
#include <process.h>
///////////////////////////////////////////////////////
// CService Class
///////////////////////////////////////////////////////
/* Each service derives from this to do its own
work. The application must instantiate the derived
service class one and only one time. */
///////////////////////////////////////////////////////
class CService
{
public:
BOOL ControlHandler(DWORD dwCtrlType);
CService(LPCTSTR szName, LPCTSTR szDisplay, DWORD dwType);
~CService();
DWORD GetStatus() { return m_dwState; }
DWORD GetControls() { return m_dwControlsAccepted; }
LPCTSTR GetName() { return m_szName; }
LPCTSTR GetDisplayName() { return m_szDisplay; }
// All derived class static ServiceMain functions are delegated to me
void ServiceMainMember(DWORD argc, LPTSTR* argv,
LPHANDLER_FUNCTION pf, LPTHREAD_START_ROUTINE pfnWTP);
void DebugMainMember(DWORD argc, LPTSTR* argv, LPTHREAD_START_ROUTINE pfnWTP);
// All derived class static handler functions are delegated to me
void HandlerMember(DWORD dwControl);
BOOL bDebug;
protected:
bool SetupHandlerInside(LPHANDLER_FUNCTION lpHandlerProc);
// Launches a thread to look for control requests
virtual void LaunchWatcherThread(LPTHREAD_START_ROUTINE pfnWTP);
virtual DWORD WatcherThreadMemberProc();
void SetStatus(DWORD dwNewState,
DWORD dwNewCheckpoint = STATE_NO_CHANGE,
DWORD dwNewHint = STATE_NO_CHANGE,
DWORD dwNewControls = STATE_NO_CHANGE,
DWORD dwExitCode = NO_ERROR,
DWORD dwSpecificExit = 0);
DWORD ErrorHandler(const TCHAR* pszFcn,
bool bPrintEvent = true,
bool bRaiseException = true,
DWORD dwErr = 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);
virtual void Run() = 0;
virtual void OnStop() = 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_hEvents[NUMEVENTS];
HANDLE m_hWatcherThread;
TCHAR m_szName[MAX_SERVICE_LEN + 1];
TCHAR m_szDisplay[MAX_SERVICE_LEN + 1];
DWORD m_dwType;
enum EVENTS { STOP, PAUSE, CONTINUE, SHUTDOWN };
};
// Implements static thread functions for derived classes
#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); \
static BOOL WINAPI service_name##ControlHandler(DWORD dwCtrlType);
#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(); \
} \
BOOL WINAPI class_name::service_name##ControlHandler( DWORD dwCtrlType ) \
{ \
return(m_pThis->ControlHandler(dwCtrlType)); \
}
// For implementing a service process
#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);
#ifdef UNICODE
#define BEGIN_DEBUG_SERVICE(class_name, service_name, argc, argv) \
{ \
printf( "Start Console Mode\n" ); \
DWORD dwArgc; \
LPTSTR *lpszArgv; \
lpszArgv = CommandLineToArgvW(GetCommandLineW(), &(dwArgc) ); \
::SetConsoleCtrlHandler(class_name::service_name##ControlHandler, TRUE); \
}
#else
#define BEGIN_DEBUG_SERVICE(class_name, service_name, argc, argv) \
{ \
printf( "Start Console Mode\n" ); \
service_name.bDebug = true; \
DWORD dwArgc; \
LPTSTR *lpszArgv; \
dwArgc = (DWORD) argc; \
lpszArgv = argv; \
::SetConsoleCtrlHandler(class_name::service_name##ControlHandler, TRUE); \
service_name.DebugMainMember(argc, argv, (LPTHREAD_START_ROUTINE)service_name.service_name##WatcherThreadProc); \
return(0); \
}
#endif
#endif