xref: /reactos/base/services/netlogon/netlogon.c (revision 8a978a17)
1 /*
2  * PROJECT:     ReactOS NetLogon Service
3  * LICENSE:     GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
4  * PURPOSE:     NetLogon service RPC server
5  * COPYRIGHT:   Eric Kohl 2019 <eric.kohl@reactos.org>
6  */
7 
8 /* INCLUDES *****************************************************************/
9 
10 #include "precomp.h"
11 
12 WINE_DEFAULT_DEBUG_CHANNEL(netlogon);
13 
14 
15 /* GLOBALS ******************************************************************/
16 
17 HINSTANCE hDllInstance;
18 
19 static WCHAR ServiceName[] = L"netlogon";
20 
21 static SERVICE_STATUS_HANDLE ServiceStatusHandle;
22 static SERVICE_STATUS ServiceStatus;
23 
24 
25 /* FUNCTIONS *****************************************************************/
26 
27 static
28 VOID
29 UpdateServiceStatus(
30     DWORD dwState)
31 {
32     ServiceStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
33     ServiceStatus.dwCurrentState = dwState;
34     ServiceStatus.dwControlsAccepted = 0;
35     ServiceStatus.dwWin32ExitCode = 0;
36     ServiceStatus.dwServiceSpecificExitCode = 0;
37     ServiceStatus.dwCheckPoint = 0;
38 
39     if (dwState == SERVICE_START_PENDING ||
40         dwState == SERVICE_STOP_PENDING ||
41         dwState == SERVICE_PAUSE_PENDING ||
42         dwState == SERVICE_CONTINUE_PENDING)
43         ServiceStatus.dwWaitHint = 10000;
44     else
45         ServiceStatus.dwWaitHint = 0;
46 
47     SetServiceStatus(ServiceStatusHandle,
48                      &ServiceStatus);
49 }
50 
51 
52 static
53 DWORD
54 WINAPI
55 ServiceControlHandler(
56     DWORD dwControl,
57     DWORD dwEventType,
58     LPVOID lpEventData,
59     LPVOID lpContext)
60 {
61     TRACE("ServiceControlHandler()\n");
62 
63     switch (dwControl)
64     {
65         case SERVICE_CONTROL_STOP:
66             TRACE("  SERVICE_CONTROL_STOP received\n");
67             /* Stop listening to incoming RPC messages */
68             RpcMgmtStopServerListening(NULL);
69             UpdateServiceStatus(SERVICE_STOPPED);
70             return ERROR_SUCCESS;
71 
72         case SERVICE_CONTROL_PAUSE:
73             TRACE("  SERVICE_CONTROL_PAUSE received\n");
74             UpdateServiceStatus(SERVICE_PAUSED);
75             return ERROR_SUCCESS;
76 
77         case SERVICE_CONTROL_CONTINUE:
78             TRACE("  SERVICE_CONTROL_CONTINUE received\n");
79             UpdateServiceStatus(SERVICE_RUNNING);
80             return ERROR_SUCCESS;
81 
82         case SERVICE_CONTROL_INTERROGATE:
83             TRACE("  SERVICE_CONTROL_INTERROGATE received\n");
84             SetServiceStatus(ServiceStatusHandle,
85                              &ServiceStatus);
86             return ERROR_SUCCESS;
87 
88         case SERVICE_CONTROL_SHUTDOWN:
89             TRACE("  SERVICE_CONTROL_SHUTDOWN received\n");
90             UpdateServiceStatus(SERVICE_STOPPED);
91             return ERROR_SUCCESS;
92 
93         default :
94             TRACE("  Control %lu received\n", dwControl);
95             return ERROR_CALL_NOT_IMPLEMENTED;
96     }
97 }
98 
99 
100 static
101 DWORD
102 ServiceInit(VOID)
103 {
104     HANDLE hThread;
105 
106     hThread = CreateThread(NULL,
107                            0,
108                            (LPTHREAD_START_ROUTINE)RpcThreadRoutine,
109                            NULL,
110                            0,
111                            NULL);
112 
113     if (!hThread)
114     {
115         ERR("Can't create PortThread\n");
116         return GetLastError();
117     }
118     else
119         CloseHandle(hThread);
120 
121     return ERROR_SUCCESS;
122 }
123 
124 
125 VOID WINAPI
126 NlNetlogonMain(
127     _In_ INT ArgCount,
128     _In_ PWSTR *ArgVector)
129 {
130     DWORD dwError;
131 
132     UNREFERENCED_PARAMETER(ArgCount);
133     UNREFERENCED_PARAMETER(ArgVector);
134 
135     TRACE("NlNetlogonMain(%d %p)\n", ArgCount, ArgVector);
136 
137     ServiceStatusHandle = RegisterServiceCtrlHandlerExW(ServiceName,
138                                                         ServiceControlHandler,
139                                                         NULL);
140     if (!ServiceStatusHandle)
141     {
142         ERR("RegisterServiceCtrlHandlerExW() failed! (Error %lu)\n", GetLastError());
143         return;
144     }
145 
146     UpdateServiceStatus(SERVICE_START_PENDING);
147 
148     dwError = ServiceInit();
149     if (dwError != ERROR_SUCCESS)
150     {
151         ERR("Service stopped (dwError: %lu\n", dwError);
152         UpdateServiceStatus(SERVICE_STOPPED);
153         return;
154     }
155 
156     UpdateServiceStatus(SERVICE_RUNNING);
157 }
158 
159 
160 BOOL
161 WINAPI
162 DllMain(
163     _In_ HINSTANCE hinstDLL,
164     _In_ DWORD fdwReason,
165     _In_ PVOID pvReserved)
166 {
167     UNREFERENCED_PARAMETER(pvReserved);
168 
169     switch (fdwReason)
170     {
171         case DLL_PROCESS_ATTACH:
172             DisableThreadLibraryCalls(hinstDLL);
173             hDllInstance = hinstDLL;
174             break;
175 
176         case DLL_PROCESS_DETACH:
177             break;
178     }
179 
180     return TRUE;
181 }
182 
183 /* EOF */
184