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>
11 /* INCLUDES *****************************************************************/
20 int WINAPI
RegisterServicesProcess(DWORD ServicesProcessId
);
22 /* GLOBALS ******************************************************************/
24 /* Defined in include/reactos/services/services.h */
25 // #define SCM_START_EVENT L"SvcctrlStartEvent_A3752DX"
26 #define SCM_AUTOSTARTCOMPLETE_EVENT L"SC_AutoStartComplete"
28 BOOL ScmInitialize
= FALSE
;
29 BOOL ScmShutdown
= FALSE
;
30 BOOL ScmLiveSetup
= FALSE
;
31 BOOL ScmSetupInProgress
= FALSE
;
32 static HANDLE hScmShutdownEvent
= NULL
;
33 static HANDLE hScmSecurityServicesEvent
= NULL
;
36 /* FUNCTIONS *****************************************************************/
39 PrintString(LPCSTR fmt
, ...)
46 vsprintf(buffer
, fmt
, ap
);
49 OutputDebugStringA(buffer
);
56 WCHAR CommandLine
[MAX_PATH
];
59 DWORD dwSetupInProgress
;
64 DPRINT1("CheckSetup()\n");
66 /* Open the Setup key */
67 dwError
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
72 if (dwError
!= ERROR_SUCCESS
)
75 /* Read the SetupType value */
76 dwSize
= sizeof(DWORD
);
77 dwError
= RegQueryValueExW(hSetupKey
,
84 if (dwError
!= ERROR_SUCCESS
||
85 dwType
!= REG_DWORD
||
86 dwSize
!= sizeof(DWORD
) ||
90 /* Read the CmdLine value */
91 dwSize
= sizeof(CommandLine
);
92 dwError
= RegQueryValueExW(hSetupKey
,
99 if (dwError
!= ERROR_SUCCESS
||
101 dwType
!= REG_EXPAND_SZ
&&
102 dwType
!= REG_MULTI_SZ
))
105 /* Check for the '-mini' option */
106 if (wcsstr(CommandLine
, L
" -mini") != NULL
)
108 DPRINT1("Running on LiveCD\n");
112 /* Read the SystemSetupInProgress value */
113 dwSize
= sizeof(DWORD
);
114 dwError
= RegQueryValueExW(hSetupKey
,
115 L
"SystemSetupInProgress",
118 (LPBYTE
)&dwSetupInProgress
,
120 if (dwError
!= ERROR_SUCCESS
||
121 dwType
!= REG_DWORD
||
122 dwSize
!= sizeof(DWORD
) ||
128 if (dwSetupInProgress
== 1)
130 DPRINT1("ReactOS Setup currently in progress!\n");
131 ScmSetupInProgress
= TRUE
;
135 RegCloseKey(hSetupKey
);
142 SetSecurityServicesEvent(VOID
)
146 if (hScmSecurityServicesEvent
!= NULL
)
147 return ERROR_SUCCESS
;
149 /* Create or open the SECURITY_SERVICES_STARTED event */
150 hScmSecurityServicesEvent
= CreateEventW(NULL
,
153 L
"SECURITY_SERVICES_STARTED");
154 if (hScmSecurityServicesEvent
== NULL
)
156 dwError
= GetLastError();
157 if (dwError
!= ERROR_ALREADY_EXISTS
)
160 hScmSecurityServicesEvent
= OpenEventW(EVENT_MODIFY_STATE
,
162 L
"SECURITY_SERVICES_STARTED");
163 if (hScmSecurityServicesEvent
== NULL
)
164 return GetLastError();
167 SetEvent(hScmSecurityServicesEvent
);
169 return ERROR_SUCCESS
;
174 ScmLogEvent(DWORD dwEventId
,
181 hLog
= RegisterEventSourceW(NULL
,
182 L
"Service Control Manager");
185 DPRINT1("ScmLogEvent: RegisterEventSourceW failed %lu\n", GetLastError());
189 if (!ReportEventW(hLog
,
199 DPRINT1("ScmLogEvent: ReportEventW failed %lu\n", GetLastError());
202 DeregisterEventSource(hLog
);
209 HANDLE hEvent
= CreateEventW(NULL
, TRUE
, FALSE
, L
"LSA_RPC_SERVER_ACTIVE");
212 DPRINT1("Failed to create or open the notification event (Error %lu)\n", GetLastError());
216 DPRINT("Wait for the LSA server\n");
217 WaitForSingleObject(hEvent
, INFINITE
);
218 DPRINT("LSA server running\n");
222 DPRINT("ScmWaitForLsa() done\n");
227 ShutdownHandlerRoutine(DWORD dwCtrlType
)
229 DPRINT1("ShutdownHandlerRoutine() called\n");
231 if (dwCtrlType
& (CTRL_SHUTDOWN_EVENT
| CTRL_LOGOFF_EVENT
))
233 DPRINT1("Shutdown event received\n");
236 ScmAutoShutdownServices();
237 ScmShutdownServiceDatabase();
239 /* Set the shutdown event */
240 SetEvent(hScmShutdownEvent
);
248 wWinMain(HINSTANCE hInstance
,
249 HINSTANCE hPrevInstance
,
253 HANDLE hScmStartEvent
= NULL
;
254 HANDLE hScmAutoStartCompleteEvent
= NULL
;
255 SC_RPC_LOCK Lock
= NULL
;
256 BOOL bCanDeleteNamedPipeCriticalSection
= FALSE
;
259 DPRINT("SERVICES: Service Control Manager\n");
261 dwError
= CheckForLiveCD();
262 if (dwError
!= ERROR_SUCCESS
)
264 DPRINT1("SERVICES: Failed to check for LiveCD (Error %lu)\n", dwError
);
268 /* Make us critical */
269 RtlSetProcessIsCritical(TRUE
, NULL
, TRUE
);
271 /* We are initializing ourselves */
272 ScmInitialize
= TRUE
;
274 /* Create the start event */
275 hScmStartEvent
= CreateEventW(NULL
, TRUE
, FALSE
, SCM_START_EVENT
);
276 if (hScmStartEvent
== NULL
)
278 DPRINT1("SERVICES: Failed to create the start event\n");
281 DPRINT("SERVICES: Created start event with handle %p\n", hScmStartEvent
);
283 /* Create the auto-start complete event */
284 hScmAutoStartCompleteEvent
= CreateEventW(NULL
, TRUE
, FALSE
, SCM_AUTOSTARTCOMPLETE_EVENT
);
285 if (hScmAutoStartCompleteEvent
== NULL
)
287 DPRINT1("SERVICES: Failed to create the auto-start complete event\n");
290 DPRINT("SERVICES: created auto-start complete event with handle %p\n", hScmAutoStartCompleteEvent
);
292 /* Create the shutdown event */
293 hScmShutdownEvent
= CreateEventW(NULL
, TRUE
, FALSE
, NULL
);
294 if (hScmShutdownEvent
== NULL
)
296 DPRINT1("SERVICES: Failed to create the shutdown event\n");
300 /* Initialize our communication named pipe's critical section */
301 ScmInitNamedPipeCriticalSection();
302 bCanDeleteNamedPipeCriticalSection
= TRUE
;
304 // ScmInitThreadManager();
306 ScmInitializeSecurity();
308 /* FIXME: more initialization */
310 /* Create the 'Last Known Good' control set */
311 dwError
= ScmCreateLastKnownGoodControlSet();
312 if (dwError
!= ERROR_SUCCESS
)
314 DPRINT1("SERVICES: Failed to create the 'Last Known Good' control set (Error %lu)\n", dwError
);
318 /* Create the services database */
319 dwError
= ScmCreateServiceDatabase();
320 if (dwError
!= ERROR_SUCCESS
)
322 DPRINT1("SERVICES: Failed to create SCM database (Error %lu)\n", dwError
);
326 /* Update the services database */
327 ScmGetBootAndSystemDriverState();
329 /* Register the Service Control Manager process with the ReactOS Subsystem */
330 if (!RegisterServicesProcess(GetCurrentProcessId()))
332 DPRINT1("SERVICES: Could not register SCM process\n");
337 * Acquire the user service start lock until
338 * auto-start services have been started.
340 dwError
= ScmAcquireServiceStartLock(TRUE
, &Lock
);
341 if (dwError
!= ERROR_SUCCESS
)
343 DPRINT1("SERVICES: Failed to acquire service start lock (Error %lu)\n", dwError
);
347 /* Start the RPC server */
350 /* Signal start event */
351 SetEvent(hScmStartEvent
);
353 DPRINT("SERVICES: Initialized\n");
355 /* Register event handler (used for system shutdown) */
356 SetConsoleCtrlHandler(ShutdownHandlerRoutine
, TRUE
);
359 * Set our shutdown parameters: we want to shutdown after the maintained
360 * services (that inherit the default shutdown level of 640).
362 SetProcessShutdownParameters(480, SHUTDOWN_NORETRY
);
364 /* Start auto-start services */
365 ScmAutoStartServices();
367 /* Signal auto-start complete event */
368 SetEvent(hScmAutoStartCompleteEvent
);
370 /* FIXME: more to do ? */
372 /* Release the service start lock */
373 ScmReleaseServiceStartLock(&Lock
);
375 /* Initialization finished */
376 ScmInitialize
= FALSE
;
378 DPRINT("SERVICES: Running\n");
380 /* Wait until the shutdown event gets signaled */
381 WaitForSingleObject(hScmShutdownEvent
, INFINITE
);
384 ScmShutdownSecurity();
386 /* Delete our communication named pipe's critical section */
387 if (bCanDeleteNamedPipeCriticalSection
!= FALSE
)
388 ScmDeleteNamedPipeCriticalSection();
390 if (hScmSecurityServicesEvent
!= NULL
)
391 CloseHandle(hScmSecurityServicesEvent
);
393 /* Close the shutdown event */
394 if (hScmShutdownEvent
!= NULL
)
395 CloseHandle(hScmShutdownEvent
);
397 /* Close the auto-start complete event */
398 if (hScmAutoStartCompleteEvent
!= NULL
)
399 CloseHandle(hScmAutoStartCompleteEvent
);
401 /* Close the start event */
402 if (hScmStartEvent
!= NULL
)
403 CloseHandle(hScmStartEvent
);
405 DPRINT("SERVICES: Finished\n");