Revert "[SHELL32] SHChangeNotify: Use tree for CDirectoryList (#6784)" (#6800)
[reactos.git] / dll / win32 / lsasrv / service.c
1 /*
2 * PROJECT: Local Security Authority Server DLL
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: dll/win32/lsasrv/service.c
5 * PURPOSE: Security service
6 * COPYRIGHT: Copyright 2016, 2019 Eric Kohl <eric.kohl@reactos.org>
7 */
8
9 /* INCLUDES ****************************************************************/
10
11 #include "lsasrv.h"
12 #include <winsvc.h>
13
14 typedef VOID (WINAPI *PNETLOGONMAIN)(INT ArgCount, PWSTR *ArgVector);
15
16 VOID WINAPI I_ScIsSecurityProcess(VOID);
17
18 static VOID WINAPI NetlogonServiceMain(DWORD dwArgc, PWSTR *pszArgv);
19 static VOID WINAPI SamSsServiceMain(DWORD dwArgc, PWSTR *pszArgv);
20
21 SERVICE_TABLE_ENTRYW ServiceTable[] =
22 {
23 {L"NETLOGON", NetlogonServiceMain},
24 {L"SAMSS", SamSsServiceMain},
25 {NULL, NULL}
26 };
27
28
29 /* FUNCTIONS ***************************************************************/
30
31 static
32 VOID
33 WINAPI
34 NetlogonServiceMain(
35 _In_ DWORD dwArgc,
36 _In_ PWSTR *pszArgv)
37 {
38 HINSTANCE hNetlogon = NULL;
39 PNETLOGONMAIN pNetlogonMain = NULL;
40
41 TRACE("NetlogonServiceMain(%lu %p)\n", dwArgc, pszArgv);
42
43 hNetlogon = LoadLibraryW(L"Netlogon.dll");
44 if (hNetlogon == NULL)
45 {
46 ERR("LoadLibrary() failed!\n");
47 return;
48 }
49
50 pNetlogonMain = (PNETLOGONMAIN)GetProcAddress(hNetlogon, "NlNetlogonMain");
51 if (pNetlogonMain == NULL)
52 {
53 ERR("GetProcAddress(NlNetlogonMain) failed!\n");
54 FreeLibrary(hNetlogon);
55 return;
56 }
57
58 TRACE("NlNetlogonMain %p\n", pNetlogonMain);
59
60 pNetlogonMain(dwArgc, pszArgv);
61 }
62
63
64 static
65 VOID
66 WINAPI
67 SamSsControlHandler(
68 _In_ DWORD fdwControl)
69 {
70 TRACE("SamSsControlHandler(%lu)\n", fdwControl);
71 }
72
73
74 static
75 VOID
76 WINAPI
77 SamSsServiceMain(
78 _In_ DWORD dwArgc,
79 _In_ PWSTR *pszArgv)
80 {
81 SERVICE_STATUS_HANDLE hStatus;
82 SERVICE_STATUS ServiceStatus;
83
84 TRACE("SamSsServiceMain(%lu %p)\n", dwArgc, pszArgv);
85
86 hStatus = RegisterServiceCtrlHandlerW(L"SAMSS",
87 SamSsControlHandler);
88 if (hStatus == NULL)
89 return;
90
91 ServiceStatus.dwServiceType = SERVICE_WIN32_SHARE_PROCESS;
92 ServiceStatus.dwCurrentState = SERVICE_START_PENDING;
93 ServiceStatus.dwControlsAccepted = 0;
94 ServiceStatus.dwWin32ExitCode = ERROR_SUCCESS;
95 ServiceStatus.dwServiceSpecificExitCode = ERROR_SUCCESS;
96 ServiceStatus.dwCheckPoint = 1;
97 ServiceStatus.dwWaitHint = 0x7530;
98
99 SetServiceStatus(hStatus, &ServiceStatus);
100
101 ServiceStatus.dwCurrentState = SERVICE_RUNNING;
102 ServiceStatus.dwCheckPoint = 0;
103 ServiceStatus.dwWaitHint = 0;
104
105 SetServiceStatus(hStatus, &ServiceStatus);
106 }
107
108
109 static
110 DWORD
111 WINAPI
112 DispatcherThread(
113 _In_ PVOID pParameter)
114 {
115 HANDLE hEvent;
116 DWORD dwError;
117
118 TRACE("DispatcherThread(%p)\n", pParameter);
119
120 /* Create or open the SECURITY_SERVICES_STARTED event */
121 hEvent = CreateEventW(NULL,
122 TRUE,
123 FALSE,
124 L"SECURITY_SERVICES_STARTED");
125 if (hEvent == NULL)
126 {
127 dwError = GetLastError();
128 if (dwError != ERROR_ALREADY_EXISTS)
129 return dwError;
130
131 hEvent = OpenEventW(SYNCHRONIZE,
132 FALSE,
133 L"SECURITY_SERVICES_STARTED");
134 if (hEvent == NULL)
135 return GetLastError();
136 }
137
138 /* Wait for the SECURITY_SERVICES_STARTED event to be signaled */
139 TRACE("Waiting for the SECURITY_SERVICES_STARTED event!\n");
140 dwError = WaitForSingleObject(hEvent, INFINITE);
141 TRACE("WaitForSingleObject returned %lu\n", dwError);
142
143 /* Close the event handle */
144 CloseHandle(hEvent);
145
146 /* Fail, if the event was not signaled */
147 if (dwError != WAIT_OBJECT_0)
148 {
149 ERR("Wait failed!\n");
150 return dwError;
151 }
152
153 /* This is the security process */
154 I_ScIsSecurityProcess();
155
156 /* Start the services */
157 TRACE("Start the security services!\n");
158 if (!StartServiceCtrlDispatcherW(ServiceTable))
159 return GetLastError();
160
161 TRACE("Done!\n");
162
163 return ERROR_SUCCESS;
164 }
165
166
167 NTSTATUS
168 WINAPI
169 ServiceInit(VOID)
170 {
171 HANDLE hThread;
172 DWORD dwThreadId;
173
174 TRACE("ServiceInit()\n");
175
176 hThread = CreateThread(NULL,
177 0,
178 DispatcherThread,
179 NULL,
180 0,
181 &dwThreadId);
182 if (hThread == NULL)
183 return (NTSTATUS)GetLastError();
184
185 return STATUS_SUCCESS;
186 }
187
188 /* EOF */