-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathBaseSrv.cpp
129 lines (103 loc) · 3.52 KB
/
BaseSrv.cpp
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
/* Copyright (C) 2016-2020 Thomas Hauck - All Rights Reserved.
Distributed under MIT license.
See file LICENSE for detail or copy at https://opensource.org/licenses/MIT
The author would be happy if changes and
improvements were reported back to him.
Author: Thomas Hauck
Email: Thomas@fam-hauck.de
*/
#if defined(_WIN32) || defined(_WIN64)
#include "BaseSrv.h"
wstring CBaseSrv::s_strSrvName;
SERVICE_STATUS CBaseSrv::s_stSrvStatus;
SERVICE_STATUS_HANDLE CBaseSrv::s_hSrvStatus;
CBaseSrv* CBaseSrv::s_This;
CBaseSrv::CBaseSrv(const wchar_t* szSrvName)
{
s_strSrvName = szSrvName;
s_This = this;
}
CBaseSrv::~CBaseSrv(void)
{
}
int CBaseSrv::Run(void) noexcept
{
SERVICE_TABLE_ENTRY DispatchTable[2];
DispatchTable[0].lpServiceName = &s_strSrvName[0];
DispatchTable[0].lpServiceProc = ServiceStartCB;
DispatchTable[1].lpServiceName = nullptr;
DispatchTable[1].lpServiceProc = nullptr;
if (StartServiceCtrlDispatcher(&DispatchTable[0]) == FALSE)
{
return GetLastError();
}
return 0;
}
void WINAPI CBaseSrv::ServiceStartCB(DWORD /*argc*/, LPTSTR *argv)
{
s_stSrvStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
s_stSrvStatus.dwCurrentState = SERVICE_START_PENDING;
s_stSrvStatus.dwControlsAccepted = 0;
s_stSrvStatus.dwWin32ExitCode = NO_ERROR;
s_stSrvStatus.dwServiceSpecificExitCode = 0;
s_stSrvStatus.dwCheckPoint = 0;
s_stSrvStatus.dwWaitHint = 0;
s_hSrvStatus = RegisterServiceCtrlHandler(*argv, ServiceCtrlHandler);
if (s_hSrvStatus == static_cast<SERVICE_STATUS_HANDLE>(nullptr))
return;
// The Installation of the User-Programm is called
// Should only take a few seconds
if (s_This->Init() != 0)
{
// Initialization complete - report running status.
s_stSrvStatus.dwCurrentState = SERVICE_RUNNING;
s_stSrvStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN | SERVICE_ACCEPT_PAUSE_CONTINUE;
if (!SetServiceStatus (s_hSrvStatus, &s_stSrvStatus))
{
// SvcDebugOut(" [MY_SERVICE] SetServiceStatus error %ld\n",GetLastError());
}
// Run the service, until it comes back, when it is finished
s_This->Start();
}
s_stSrvStatus.dwCurrentState = SERVICE_STOPPED;
if (!SetServiceStatus (s_hSrvStatus, &s_stSrvStatus))
{
}
}
void WINAPI CBaseSrv::ServiceCtrlHandler(DWORD Opcode)
{
switch(Opcode)
{
case SERVICE_CONTROL_PAUSE:
// Do whatever it takes to pause here.
s_This->Pause();
s_stSrvStatus.dwCurrentState = SERVICE_PAUSED;
break;
case SERVICE_CONTROL_CONTINUE:
// Do whatever it takes to continue here.
s_This->Continue();
s_stSrvStatus.dwCurrentState = SERVICE_RUNNING;
break;
case SERVICE_CONTROL_STOP:
case SERVICE_CONTROL_SHUTDOWN:
// Do whatever it takes to stop here.
s_This->Stop();
s_stSrvStatus.dwCurrentState = SERVICE_STOP_PENDING;
s_stSrvStatus.dwWaitHint = 5000;
break;
case SERVICE_CONTROL_INTERROGATE:
// Fall through to send current status.
break;
default:
;
// SvcDebugOut(" [MY_SERVICE] Unrecognized opcode %ld\n", Opcode);
}
s_stSrvStatus.dwCheckPoint++;
// Send current status.
if (!SetServiceStatus (s_hSrvStatus, &s_stSrvStatus))
{
// SvcDebugOut(" [MY_SERVICE] SetServiceStatus error %ld\n", GetLastError());
}
return;
}
#endif