ReactOS 0.4.16-dev-340-g0540c21
services.c
Go to the documentation of this file.
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
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
34
35
36/* FUNCTIONS *****************************************************************/
37
38VOID
40{
41#if DBG
42 CHAR buffer[512];
43 va_list ap;
44
45 va_start(ap, fmt);
47 va_end(ap);
48
50#endif
51}
52
55{
56 WCHAR CommandLine[MAX_PATH];
57 HKEY hSetupKey;
58 DWORD dwSetupType;
59 DWORD dwSetupInProgress;
60 DWORD dwType;
62 DWORD dwError;
63
64 DPRINT1("CheckSetup()\n");
65
66 /* Open the Setup key */
68 L"SYSTEM\\Setup",
69 0,
71 &hSetupKey);
72 if (dwError != ERROR_SUCCESS)
73 return dwError;
74
75 /* Read the SetupType value */
76 dwSize = sizeof(DWORD);
77 dwError = RegQueryValueExW(hSetupKey,
78 L"SetupType",
79 NULL,
80 &dwType,
81 (LPBYTE)&dwSetupType,
82 &dwSize);
83
84 if (dwError != ERROR_SUCCESS ||
85 dwType != REG_DWORD ||
86 dwSize != sizeof(DWORD) ||
87 dwSetupType == 0)
88 goto done;
89
90 /* Read the CmdLine value */
91 dwSize = sizeof(CommandLine);
92 dwError = RegQueryValueExW(hSetupKey,
93 L"CmdLine",
94 NULL,
95 &dwType,
96 (LPBYTE)CommandLine,
97 &dwSize);
98
99 if (dwError != ERROR_SUCCESS ||
100 (dwType != REG_SZ &&
101 dwType != REG_EXPAND_SZ &&
102 dwType != REG_MULTI_SZ))
103 goto done;
104
105 /* Check for the '-mini' option */
106 if (wcsstr(CommandLine, L" -mini") != NULL)
107 {
108 DPRINT1("Running on LiveCD\n");
110 }
111
112 /* Read the SystemSetupInProgress value */
113 dwSize = sizeof(DWORD);
114 dwError = RegQueryValueExW(hSetupKey,
115 L"SystemSetupInProgress",
116 NULL,
117 &dwType,
118 (LPBYTE)&dwSetupInProgress,
119 &dwSize);
120 if (dwError != ERROR_SUCCESS ||
121 dwType != REG_DWORD ||
122 dwSize != sizeof(DWORD) ||
123 dwSetupType == 0)
124 {
125 goto done;
126 }
127
128 if (dwSetupInProgress == 1)
129 {
130 DPRINT1("ReactOS Setup currently in progress!\n");
132 }
133
134done:
135 RegCloseKey(hSetupKey);
136
137 return dwError;
138}
139
140
141DWORD
143{
144 DWORD dwError;
145
147 return ERROR_SUCCESS;
148
149 /* Create or open the SECURITY_SERVICES_STARTED event */
151 TRUE,
152 FALSE,
153 L"SECURITY_SERVICES_STARTED");
155 {
156 dwError = GetLastError();
157 if (dwError != ERROR_ALREADY_EXISTS)
158 return dwError;
159
161 FALSE,
162 L"SECURITY_SERVICES_STARTED");
164 return GetLastError();
165 }
166
168
169 return ERROR_SUCCESS;
170}
171
172
173VOID
175 WORD wType,
176 WORD wStrings,
177 LPCWSTR *lpStrings)
178{
179 HANDLE hLog;
180
182 L"Service Control Manager");
183 if (hLog == NULL)
184 {
185 DPRINT1("ScmLogEvent: RegisterEventSourceW failed %lu\n", GetLastError());
186 return;
187 }
188
189 if (!ReportEventW(hLog,
190 wType,
191 0,
192 dwEventId,
193 NULL,
194 wStrings,
195 0,
196 lpStrings,
197 NULL))
198 {
199 DPRINT1("ScmLogEvent: ReportEventW failed %lu\n", GetLastError());
200 }
201
203}
204
205
206VOID
208{
209 HANDLE hEvent = CreateEventW(NULL, TRUE, FALSE, L"LSA_RPC_SERVER_ACTIVE");
210 if (hEvent == NULL)
211 {
212 DPRINT1("Failed to create or open the notification event (Error %lu)\n", GetLastError());
213 }
214 else
215 {
216 DPRINT("Wait for the LSA server\n");
218 DPRINT("LSA server running\n");
220 }
221
222 DPRINT("ScmWaitForLsa() done\n");
223}
224
225
228{
229 DPRINT1("ShutdownHandlerRoutine() called\n");
230
231 if (dwCtrlType & (CTRL_SHUTDOWN_EVENT | CTRL_LOGOFF_EVENT))
232 {
233 DPRINT1("Shutdown event received\n");
235
238
239 /* Set the shutdown event */
241 }
242
243 return TRUE;
244}
245
246
247int WINAPI
249 HINSTANCE hPrevInstance,
250 LPWSTR lpCmdLine,
251 int nShowCmd)
252{
253 HANDLE hScmStartEvent = NULL;
254 HANDLE hScmAutoStartCompleteEvent = NULL;
256 BOOL bCanDeleteNamedPipeCriticalSection = FALSE;
257 DWORD dwError;
258
259 DPRINT("SERVICES: Service Control Manager\n");
260
261 dwError = CheckForLiveCD();
262 if (dwError != ERROR_SUCCESS)
263 {
264 DPRINT1("SERVICES: Failed to check for LiveCD (Error %lu)\n", dwError);
265 goto done;
266 }
267
268 /* Make us critical */
270
271 /* We are initializing ourselves */
273
274 /* Create the start event */
275 hScmStartEvent = CreateEventW(NULL, TRUE, FALSE, SCM_START_EVENT);
276 if (hScmStartEvent == NULL)
277 {
278 DPRINT1("SERVICES: Failed to create the start event\n");
279 goto done;
280 }
281 DPRINT("SERVICES: Created start event with handle %p\n", hScmStartEvent);
282
283 /* Create the auto-start complete event */
284 hScmAutoStartCompleteEvent = CreateEventW(NULL, TRUE, FALSE, SCM_AUTOSTARTCOMPLETE_EVENT);
285 if (hScmAutoStartCompleteEvent == NULL)
286 {
287 DPRINT1("SERVICES: Failed to create the auto-start complete event\n");
288 goto done;
289 }
290 DPRINT("SERVICES: created auto-start complete event with handle %p\n", hScmAutoStartCompleteEvent);
291
292 /* Create the shutdown event */
294 if (hScmShutdownEvent == NULL)
295 {
296 DPRINT1("SERVICES: Failed to create the shutdown event\n");
297 goto done;
298 }
299
300 /* Initialize our communication named pipe's critical section */
302 bCanDeleteNamedPipeCriticalSection = TRUE;
303
304// ScmInitThreadManager();
305
307
308 /* FIXME: more initialization */
309
310 /* Create the 'Last Known Good' control set */
312 if (dwError != ERROR_SUCCESS)
313 {
314 DPRINT1("SERVICES: Failed to create the 'Last Known Good' control set (Error %lu)\n", dwError);
315 goto done;
316 }
317
318 /* Create the services database */
319 dwError = ScmCreateServiceDatabase();
320 if (dwError != ERROR_SUCCESS)
321 {
322 DPRINT1("SERVICES: Failed to create SCM database (Error %lu)\n", dwError);
323 goto done;
324 }
325
326 /* Update the services database */
328
329 /* Register the Service Control Manager process with the ReactOS Subsystem */
331 {
332 DPRINT1("SERVICES: Could not register SCM process\n");
333 goto done;
334 }
335
336 /*
337 * Acquire the user service start lock until
338 * auto-start services have been started.
339 */
341 if (dwError != ERROR_SUCCESS)
342 {
343 DPRINT1("SERVICES: Failed to acquire service start lock (Error %lu)\n", dwError);
344 goto done;
345 }
346
347 /* Start the RPC server */
349
350 /* Signal start event */
351 SetEvent(hScmStartEvent);
352
353 DPRINT("SERVICES: Initialized\n");
354
355 /* Register event handler (used for system shutdown) */
357
358 /*
359 * Set our shutdown parameters: we want to shutdown after the maintained
360 * services (that inherit the default shutdown level of 640).
361 */
363
364 /* Start auto-start services */
366
367 /* Signal auto-start complete event */
368 SetEvent(hScmAutoStartCompleteEvent);
369
370 /* FIXME: more to do ? */
371
372 /* Release the service start lock */
374
375 /* Initialization finished */
377
378 DPRINT("SERVICES: Running\n");
379
380 /* Wait until the shutdown event gets signaled */
382
383done:
385
386 /* Delete our communication named pipe's critical section */
387 if (bCanDeleteNamedPipeCriticalSection != FALSE)
389
392
393 /* Close the shutdown event */
394 if (hScmShutdownEvent != NULL)
396
397 /* Close the auto-start complete event */
398 if (hScmAutoStartCompleteEvent != NULL)
399 CloseHandle(hScmAutoStartCompleteEvent);
400
401 /* Close the start event */
402 if (hScmStartEvent != NULL)
403 CloseHandle(hScmStartEvent);
404
405 DPRINT("SERVICES: Finished\n");
406
407 ExitThread(0);
408 return 0;
409}
410
411/* EOF */
char * va_list
Definition: acmsvcex.h:78
#define va_end(ap)
Definition: acmsvcex.h:90
#define va_start(ap, A)
Definition: acmsvcex.h:91
static HANDLE hLog
Definition: misc.cpp:13
#define DPRINT1
Definition: precomp.h:8
VOID ScmAutoStartServices(VOID)
Definition: database.c:2065
VOID ScmInitNamedPipeCriticalSection(VOID)
Definition: database.c:2335
DWORD ScmCreateServiceDatabase(VOID)
Definition: database.c:1187
VOID ScmAutoShutdownServices(VOID)
Definition: database.c:2276
VOID ScmGetBootAndSystemDriverState(VOID)
Definition: database.c:1384
VOID ScmDeleteNamedPipeCriticalSection(VOID)
Definition: database.c:2363
VOID ScmShutdownServiceDatabase(VOID)
Definition: database.c:1274
DWORD ScmAcquireServiceStartLock(IN BOOL IsServiceController, OUT LPSC_RPC_LOCK lpLock)
Definition: lock.c:31
DWORD ScmReleaseServiceStartLock(IN OUT LPSC_RPC_LOCK lpLock)
Definition: lock.c:82
VOID ScmStartRpcServer(VOID)
Definition: rpcserver.c:107
VOID ScmShutdownSecurity(VOID)
Definition: security.c:398
DWORD ScmInitializeSecurity(VOID)
Definition: security.c:373
DWORD CheckForLiveCD(VOID)
Definition: services.c:54
VOID PrintString(LPCSTR fmt,...)
Definition: services.c:39
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nShowCmd)
Definition: services.c:248
VOID ScmWaitForLsa(VOID)
Definition: services.c:207
BOOL ScmShutdown
Definition: services.c:29
BOOL ScmInitialize
Definition: services.c:28
static HANDLE hScmShutdownEvent
Definition: services.c:32
#define SCM_AUTOSTARTCOMPLETE_EVENT
Definition: services.c:26
static HANDLE hScmSecurityServicesEvent
Definition: services.c:33
DWORD SetSecurityServicesEvent(VOID)
Definition: services.c:142
BOOL ScmLiveSetup
Definition: services.c:30
BOOL ScmSetupInProgress
Definition: services.c:31
BOOL WINAPI ShutdownHandlerRoutine(DWORD dwCtrlType)
Definition: services.c:227
int WINAPI RegisterServicesProcess(DWORD ServicesProcessId)
Definition: logon.c:18
VOID ScmLogEvent(DWORD dwEventId, WORD wType, WORD wStrings, LPCWSTR *lpStrings)
Definition: services.c:174
#define RegCloseKey(hKey)
Definition: registry.h:49
HINSTANCE hInstance
Definition: charmap.c:19
DWORD ScmCreateLastKnownGoodControlSet(VOID)
Definition: controlset.c:275
#define ERROR_SUCCESS
Definition: deptool.c:10
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
LONG WINAPI RegOpenKeyExW(HKEY hKey, LPCWSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult)
Definition: reg.c:3333
LONG WINAPI RegQueryValueExW(_In_ HKEY hkeyorg, _In_ LPCWSTR name, _In_ LPDWORD reserved, _In_ LPDWORD type, _In_ LPBYTE data, _In_ LPDWORD count)
Definition: reg.c:4103
BOOL WINAPI ReportEventW(IN HANDLE hEventLog, IN WORD wType, IN WORD wCategory, IN DWORD dwEventID, IN PSID lpUserSid, IN WORD wNumStrings, IN DWORD dwDataSize, IN LPCWSTR *lpStrings, IN LPVOID lpRawData)
Definition: eventlog.c:1516
BOOL WINAPI DeregisterEventSource(IN HANDLE hEventLog)
Definition: eventlog.c:473
HANDLE WINAPI RegisterEventSourceW(IN LPCWSTR lpUNCServerName, IN LPCWSTR lpSourceName)
Definition: eventlog.c:1295
#define CloseHandle
Definition: compat.h:739
#define MAX_PATH
Definition: compat.h:34
BOOL WINAPI DECLSPEC_HOTPATCH SetConsoleCtrlHandler(PHANDLER_ROUTINE HandlerRoutine, BOOL Add)
Definition: console.c:2109
BOOL WINAPI SetProcessShutdownParameters(IN DWORD dwLevel, IN DWORD dwFlags)
Definition: proc.c:949
VOID WINAPI ExitThread(IN DWORD uExitCode)
Definition: thread.c:365
#define INFINITE
Definition: serial.h:102
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
unsigned short WORD
Definition: ntddk_ex.h:93
GLuint buffer
Definition: glext.h:5915
void WINAPI SHIM_OBJ_NAME() OutputDebugStringA(LPCSTR lpOutputString)
Definition: ignoredbgout.c:18
int __cdecl vsprintf(char *_Dest, const char *_Format, va_list _Args)
Definition: sprintf.c:733
_CONST_RETURN wchar_t *__cdecl wcsstr(_In_z_ const wchar_t *_Str, _In_z_ const wchar_t *_SubStr)
#define REG_SZ
Definition: layer.c:22
#define ERROR_ALREADY_EXISTS
Definition: disk.h:80
PSDBQUERYRESULT_VISTA PVOID DWORD * dwSize
Definition: env.c:56
static HANDLE hEvent
Definition: comm.c:54
NTSYSAPI NTSTATUS __cdecl RtlSetProcessIsCritical(_In_ BOOLEAN NewValue, _Out_opt_ PBOOLEAN OldValue, _In_ BOOLEAN NeedBreaks)
#define KEY_QUERY_VALUE
Definition: nt_native.h:1016
#define REG_MULTI_SZ
Definition: nt_native.h:1501
#define DWORD
Definition: nt_native.h:44
#define REG_EXPAND_SZ
Definition: nt_native.h:1494
#define L(x)
Definition: ntvdm.h:50
#define REG_DWORD
Definition: sdbapi.c:596
#define SCM_START_EVENT
Definition: services.h:26
#define DPRINT
Definition: sndvol32.h:73
Definition: dsound.c:943
HANDLE WINAPI DECLSPEC_HOTPATCH OpenEventW(IN DWORD dwDesiredAccess, IN BOOL bInheritHandle, IN LPCWSTR lpName)
Definition: synch.c:682
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82
HANDLE WINAPI DECLSPEC_HOTPATCH CreateEventW(IN LPSECURITY_ATTRIBUTES lpEventAttributes OPTIONAL, IN BOOL bManualReset, IN BOOL bInitialState, IN LPCWSTR lpName OPTIONAL)
Definition: synch.c:651
BOOL WINAPI DECLSPEC_HOTPATCH SetEvent(IN HANDLE hEvent)
Definition: synch.c:733
unsigned char * LPBYTE
Definition: typedefs.h:53
_Must_inspect_result_ _In_opt_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFWAITLOCK * Lock
Definition: wdfsync.h:127
ULONG_PTR ServicesProcessId
Definition: register.c:20
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
#define SHUTDOWN_NORETRY
Definition: winbase.h:474
#define EVENT_MODIFY_STATE
Definition: winbase.h:164
DWORD WINAPI GetCurrentProcessId(void)
Definition: proc.c:1158
#define CTRL_SHUTDOWN_EVENT
Definition: wincon.h:73
#define CTRL_LOGOFF_EVENT
Definition: wincon.h:72
#define WINAPI
Definition: msvc.h:6
void int int ULONGLONG int va_list * ap
Definition: winesup.h:36
#define HKEY_LOCAL_MACHINE
Definition: winreg.h:12
const char * LPCSTR
Definition: xmlstorage.h:183
__wchar_t WCHAR
Definition: xmlstorage.h:180
WCHAR * LPWSTR
Definition: xmlstorage.h:184
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
char CHAR
Definition: xmlstorage.h:175