bd7f24ccc0ea85ff0cfc9e3d5ef2012efe6ed7e6
[reactos.git] / base / system / services / services.c
1 /*
2 * PROJECT: ReactOS Service Control Manager
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: base/system/services/services.c
5 * PURPOSE: Main SCM controller
6 * COPYRIGHT: Copyright 2001-2005 Eric Kohl
7 * Copyright 2007 Ged Murphy <gedmurphy@reactos.org>
8 *
9 */
10
11 /* INCLUDES *****************************************************************/
12
13 #include "services.h"
14
15 #include <wincon.h>
16
17 #define NDEBUG
18 #include <debug.h>
19
20 int WINAPI RegisterServicesProcess(DWORD ServicesProcessId);
21
22 /* GLOBALS ******************************************************************/
23
24 /* Defined in include/reactos/services/services.h */
25 // #define SCM_START_EVENT L"SvcctrlStartEvent_A3752DX"
26 #define SCM_AUTOSTARTCOMPLETE_EVENT L"SC_AutoStartComplete"
27
28 BOOL ScmInitialize = FALSE;
29 BOOL ScmShutdown = FALSE;
30 static HANDLE hScmShutdownEvent = NULL;
31
32
33 /* FUNCTIONS *****************************************************************/
34
35 VOID
36 PrintString(LPCSTR fmt, ...)
37 {
38 #if DBG
39 CHAR buffer[512];
40 va_list ap;
41
42 va_start(ap, fmt);
43 vsprintf(buffer, fmt, ap);
44 va_end(ap);
45
46 OutputDebugStringA(buffer);
47 #endif
48 }
49
50
51 VOID
52 ScmLogEvent(DWORD dwEventId,
53 WORD wType,
54 WORD wStrings,
55 LPCWSTR *lpStrings)
56 {
57 HANDLE hLog;
58
59 hLog = RegisterEventSourceW(NULL,
60 L"Service Control Manager");
61 if (hLog == NULL)
62 {
63 DPRINT1("ScmLogEvent: RegisterEventSourceW failed %lu\n", GetLastError());
64 return;
65 }
66
67 if (!ReportEventW(hLog,
68 wType,
69 0,
70 dwEventId,
71 NULL,
72 wStrings,
73 0,
74 lpStrings,
75 NULL))
76 {
77 DPRINT1("ScmLogEvent: ReportEventW failed %lu\n", GetLastError());
78 }
79
80 DeregisterEventSource(hLog);
81 }
82
83
84 VOID
85 ScmWaitForLsa(VOID)
86 {
87 HANDLE hEvent = CreateEventW(NULL, TRUE, FALSE, L"LSA_RPC_SERVER_ACTIVE");
88 if (hEvent == NULL)
89 {
90 DPRINT1("Failed to create or open the notification event (Error %lu)\n", GetLastError());
91 }
92 else
93 {
94 DPRINT("Wait for the LSA server!\n");
95 WaitForSingleObject(hEvent, INFINITE);
96 DPRINT("LSA server running!\n");
97 CloseHandle(hEvent);
98 }
99
100 DPRINT("ScmWaitForLsa() done\n");
101 }
102
103
104 BOOL WINAPI
105 ShutdownHandlerRoutine(DWORD dwCtrlType)
106 {
107 DPRINT1("ShutdownHandlerRoutine() called\n");
108
109 if (dwCtrlType & (CTRL_SHUTDOWN_EVENT | CTRL_LOGOFF_EVENT))
110 {
111 DPRINT1("Shutdown event received!\n");
112 ScmShutdown = TRUE;
113
114 ScmAutoShutdownServices();
115 ScmShutdownServiceDatabase();
116
117 /* Set the shutdown event */
118 SetEvent(hScmShutdownEvent);
119 }
120
121 return TRUE;
122 }
123
124
125 int WINAPI
126 wWinMain(HINSTANCE hInstance,
127 HINSTANCE hPrevInstance,
128 LPWSTR lpCmdLine,
129 int nShowCmd)
130 {
131 HANDLE hScmStartEvent = NULL;
132 HANDLE hScmAutoStartCompleteEvent = NULL;
133 SC_RPC_LOCK Lock = NULL;
134 BOOL bCanDeleteNamedPipeCriticalSection = FALSE;
135 DWORD dwError;
136
137 DPRINT("SERVICES: Service Control Manager\n");
138
139 /* Make us critical */
140 RtlSetProcessIsCritical(TRUE, NULL, TRUE);
141
142 /* We are initializing ourselves */
143 ScmInitialize = TRUE;
144
145 /* Create the start event */
146 hScmStartEvent = CreateEventW(NULL, TRUE, FALSE, SCM_START_EVENT);
147 if (hScmStartEvent == NULL)
148 {
149 DPRINT1("SERVICES: Failed to create the start event\n");
150 goto done;
151 }
152 DPRINT("SERVICES: Created start event with handle %p.\n", hScmStartEvent);
153
154 /* Create the auto-start complete event */
155 hScmAutoStartCompleteEvent = CreateEventW(NULL, TRUE, FALSE, SCM_AUTOSTARTCOMPLETE_EVENT);
156 if (hScmAutoStartCompleteEvent == NULL)
157 {
158 DPRINT1("SERVICES: Failed to create the auto-start complete event\n");
159 goto done;
160 }
161 DPRINT("SERVICES: created auto-start complete event with handle %p.\n", hScmAutoStartCompleteEvent);
162
163 /* Create the shutdown event */
164 hScmShutdownEvent = CreateEventW(NULL, TRUE, FALSE, NULL);
165 if (hScmShutdownEvent == NULL)
166 {
167 DPRINT1("SERVICES: Failed to create the shutdown event\n");
168 goto done;
169 }
170
171 /* Initialize our communication named pipe's critical section */
172 ScmInitNamedPipeCriticalSection();
173 bCanDeleteNamedPipeCriticalSection = TRUE;
174
175 // ScmInitThreadManager();
176
177 ScmInitializeSecurity();
178
179 /* FIXME: more initialization */
180
181 /* Read the control set values */
182 if (!ScmGetControlSetValues())
183 {
184 DPRINT1("SERVICES: Failed to read the control set values\n");
185 goto done;
186 }
187
188 /* Create the services database */
189 dwError = ScmCreateServiceDatabase();
190 if (dwError != ERROR_SUCCESS)
191 {
192 DPRINT1("SERVICES: Failed to create SCM database (Error %lu)\n", dwError);
193 goto done;
194 }
195
196 /* Update the services database */
197 ScmGetBootAndSystemDriverState();
198
199 /* Register the Service Control Manager process with the ReactOS Subsystem */
200 if (!RegisterServicesProcess(GetCurrentProcessId()))
201 {
202 DPRINT1("SERVICES: Could not register SCM process\n");
203 goto done;
204 }
205
206 /*
207 * Acquire the user service start lock until
208 * auto-start services have been started.
209 */
210 dwError = ScmAcquireServiceStartLock(TRUE, &Lock);
211 if (dwError != ERROR_SUCCESS)
212 {
213 DPRINT1("SERVICES: Failed to acquire the service start lock (Error %lu)\n", dwError);
214 goto done;
215 }
216
217 /* Start the RPC server */
218 ScmStartRpcServer();
219
220 /* Signal start event */
221 SetEvent(hScmStartEvent);
222
223 DPRINT("SERVICES: Initialized.\n");
224
225 /* Register event handler (used for system shutdown) */
226 SetConsoleCtrlHandler(ShutdownHandlerRoutine, TRUE);
227
228 /*
229 * Set our shutdown parameters: we want to shutdown after the maintained
230 * services (that inherit the default shutdown level of 640).
231 */
232 SetProcessShutdownParameters(480, SHUTDOWN_NORETRY);
233
234 /* Start auto-start services */
235 ScmAutoStartServices();
236
237 /* Signal auto-start complete event */
238 SetEvent(hScmAutoStartCompleteEvent);
239
240 /* FIXME: more to do ? */
241
242 /* Release the service start lock */
243 ScmReleaseServiceStartLock(&Lock);
244
245 /* Initialization finished */
246 ScmInitialize = FALSE;
247
248 DPRINT("SERVICES: Running.\n");
249
250 /* Wait until the shutdown event gets signaled */
251 WaitForSingleObject(hScmShutdownEvent, INFINITE);
252
253 done:
254 ScmShutdownSecurity();
255
256 /* Delete our communication named pipe's critical section */
257 if (bCanDeleteNamedPipeCriticalSection != FALSE)
258 ScmDeleteNamedPipeCriticalSection();
259
260 /* Close the shutdown event */
261 if (hScmShutdownEvent != NULL)
262 CloseHandle(hScmShutdownEvent);
263
264 /* Close the auto-start complete event */
265 if (hScmAutoStartCompleteEvent != NULL)
266 CloseHandle(hScmAutoStartCompleteEvent);
267
268 /* Close the start event */
269 if (hScmStartEvent != NULL)
270 CloseHandle(hScmStartEvent);
271
272 DPRINT("SERVICES: Finished.\n");
273
274 ExitThread(0);
275 return 0;
276 }
277
278 /* EOF */