1 /*
2 * ReactOS Services
3 * Copyright (C) 2015 ReactOS Team
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 */
19 /*
20 * COPYRIGHT: See COPYING in the top level directory
21 * PROJECT: ReactOS Services
22 * FILE: base/services/srvsvc/srvsvc.c
23 * PURPOSE: Server service
24 * PROGRAMMER: Eric Kohl
25 */
26
27 /* INCLUDES *****************************************************************/
28
29 #include "precomp.h"
30
31 WINE_DEFAULT_DEBUG_CHANNEL(srvsvc);
32
33 /* GLOBALS ******************************************************************/
34
35 static WCHAR ServiceName[] = L"Lanmanserver";
36
37 static SERVICE_STATUS_HANDLE ServiceStatusHandle;
38 static SERVICE_STATUS ServiceStatus;
39
40 DWORD dwServiceBits = 0;
41
42
43 /* FUNCTIONS *****************************************************************/
44
45 static VOID
UpdateServiceStatus(DWORD dwState)46 UpdateServiceStatus(DWORD dwState)
47 {
48 ServiceStatus.dwServiceType = SERVICE_WIN32_SHARE_PROCESS;
49 ServiceStatus.dwCurrentState = dwState;
50 ServiceStatus.dwControlsAccepted = 0;
51 ServiceStatus.dwWin32ExitCode = 0;
52 ServiceStatus.dwServiceSpecificExitCode = 0;
53 ServiceStatus.dwCheckPoint = 0;
54
55 if (dwState == SERVICE_START_PENDING ||
56 dwState == SERVICE_STOP_PENDING ||
57 dwState == SERVICE_PAUSE_PENDING ||
58 dwState == SERVICE_CONTINUE_PENDING)
59 ServiceStatus.dwWaitHint = 10000;
60 else
61 ServiceStatus.dwWaitHint = 0;
62
63 if (dwState == SERVICE_RUNNING)
64 ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN;
65
66 SetServiceStatus(ServiceStatusHandle,
67 &ServiceStatus);
68 }
69
70 static DWORD WINAPI
ServiceControlHandler(DWORD dwControl,DWORD dwEventType,LPVOID lpEventData,LPVOID lpContext)71 ServiceControlHandler(DWORD dwControl,
72 DWORD dwEventType,
73 LPVOID lpEventData,
74 LPVOID lpContext)
75 {
76 TRACE("ServiceControlHandler() called\n");
77
78 switch (dwControl)
79 {
80 case SERVICE_CONTROL_STOP:
81 TRACE(" SERVICE_CONTROL_STOP received\n");
82 UpdateServiceStatus(SERVICE_STOP_PENDING);
83 /* Stop listening to incoming RPC messages */
84 RpcMgmtStopServerListening(NULL);
85 UpdateServiceStatus(SERVICE_STOPPED);
86 return ERROR_SUCCESS;
87
88 case SERVICE_CONTROL_PAUSE:
89 TRACE(" SERVICE_CONTROL_PAUSE received\n");
90 UpdateServiceStatus(SERVICE_PAUSED);
91 return ERROR_SUCCESS;
92
93 case SERVICE_CONTROL_CONTINUE:
94 TRACE(" SERVICE_CONTROL_CONTINUE received\n");
95 UpdateServiceStatus(SERVICE_RUNNING);
96 return ERROR_SUCCESS;
97
98 case SERVICE_CONTROL_INTERROGATE:
99 TRACE(" SERVICE_CONTROL_INTERROGATE received\n");
100 SetServiceStatus(ServiceStatusHandle,
101 &ServiceStatus);
102 return ERROR_SUCCESS;
103
104 case SERVICE_CONTROL_SHUTDOWN:
105 TRACE(" SERVICE_CONTROL_SHUTDOWN received\n");
106 UpdateServiceStatus(SERVICE_STOP_PENDING);
107 /* Stop listening to incoming RPC messages */
108 RpcMgmtStopServerListening(NULL);
109 UpdateServiceStatus(SERVICE_STOPPED);
110 return ERROR_SUCCESS;
111
112 default :
113 TRACE(" Control %lu received\n", dwControl);
114 return ERROR_CALL_NOT_IMPLEMENTED;
115 }
116 }
117
118
119 static
120 DWORD
ServiceInit(VOID)121 ServiceInit(VOID)
122 {
123 HANDLE hThread;
124
125 hThread = CreateThread(NULL,
126 0,
127 (LPTHREAD_START_ROUTINE)RpcThreadRoutine,
128 NULL,
129 0,
130 NULL);
131
132 if (!hThread)
133 {
134 ERR("Can't create PortThread\n");
135 return GetLastError();
136 }
137 else
138 CloseHandle(hThread);
139
140 /* Report a running server service */
141 SetServiceBits(ServiceStatusHandle,
142 SV_TYPE_SERVER,
143 TRUE,
144 TRUE);
145
146 return ERROR_SUCCESS;
147 }
148
149
150 VOID
151 WINAPI
ServiceMain(DWORD argc,LPTSTR * argv)152 ServiceMain(DWORD argc, LPTSTR *argv)
153 {
154 DWORD dwError;
155
156 UNREFERENCED_PARAMETER(argc);
157 UNREFERENCED_PARAMETER(argv);
158
159 TRACE("ServiceMain() called\n");
160
161 ServiceStatusHandle = RegisterServiceCtrlHandlerExW(ServiceName,
162 ServiceControlHandler,
163 NULL);
164 if (!ServiceStatusHandle)
165 {
166 ERR("RegisterServiceCtrlHandlerExW() failed! (Error %lu)\n", GetLastError());
167 return;
168 }
169
170 UpdateServiceStatus(SERVICE_START_PENDING);
171
172 dwError = ServiceInit();
173 if (dwError != ERROR_SUCCESS)
174 {
175 ERR("Service stopped (dwError: %lu\n", dwError);
176 UpdateServiceStatus(SERVICE_STOPPED);
177 return;
178 }
179
180 UpdateServiceStatus(SERVICE_RUNNING);
181 }
182
183
184 BOOL WINAPI
DllMain(HINSTANCE hinstDLL,DWORD fdwReason,LPVOID lpvReserved)185 DllMain(HINSTANCE hinstDLL,
186 DWORD fdwReason,
187 LPVOID lpvReserved)
188 {
189 switch (fdwReason)
190 {
191 case DLL_PROCESS_ATTACH:
192 DisableThreadLibraryCalls(hinstDLL);
193 break;
194
195 case DLL_PROCESS_DETACH:
196 break;
197 }
198
199 return TRUE;
200 }
201