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"
27 #define LSA_RPC_SERVER_ACTIVE L"LSA_RPC_SERVER_ACTIVE"
29 BOOL ScmInitialize
= FALSE
;
30 BOOL ScmShutdown
= FALSE
;
31 static HANDLE hScmShutdownEvent
= NULL
;
34 /* FUNCTIONS *****************************************************************/
37 PrintString(LPCSTR fmt
, ...)
44 vsprintf(buffer
, fmt
, ap
);
47 OutputDebugStringA(buffer
);
53 ScmLogEvent(DWORD dwEventId
,
60 hLog
= RegisterEventSourceW(NULL
,
61 L
"Service Control Manager");
64 DPRINT1("ScmLogEvent: RegisterEventSourceW failed %lu\n", GetLastError());
68 if (!ReportEventW(hLog
,
78 DPRINT1("ScmLogEvent: ReportEventW failed %lu\n", GetLastError());
81 DeregisterEventSource(hLog
);
88 HANDLE hEvent
= CreateEventW(NULL
, TRUE
, FALSE
, LSA_RPC_SERVER_ACTIVE
);
91 DPRINT1("Failed to create the notification event (Error %lu)\n", GetLastError());
95 DPRINT("Wait for the LSA server!\n");
96 WaitForSingleObject(hEvent
, INFINITE
);
97 DPRINT("LSA server running!\n");
101 DPRINT("ScmWaitForLsa() done\n");
106 ShutdownHandlerRoutine(DWORD dwCtrlType
)
108 DPRINT1("ShutdownHandlerRoutine() called\n");
110 if (dwCtrlType
& (CTRL_SHUTDOWN_EVENT
| CTRL_LOGOFF_EVENT
))
112 DPRINT1("Shutdown event received!\n");
115 ScmAutoShutdownServices();
116 ScmShutdownServiceDatabase();
118 /* Set the shutdown event */
119 SetEvent(hScmShutdownEvent
);
127 wWinMain(HINSTANCE hInstance
,
128 HINSTANCE hPrevInstance
,
132 HANDLE hScmStartEvent
= NULL
;
133 HANDLE hScmAutoStartCompleteEvent
= NULL
;
134 SC_RPC_LOCK Lock
= NULL
;
135 BOOL bCanDeleteNamedPipeCriticalSection
= FALSE
;
138 DPRINT("SERVICES: Service Control Manager\n");
140 /* Make us critical */
141 RtlSetProcessIsCritical(TRUE
, NULL
, TRUE
);
143 /* We are initializing ourselves */
144 ScmInitialize
= TRUE
;
146 /* Create the start event */
147 hScmStartEvent
= CreateEventW(NULL
, TRUE
, FALSE
, SCM_START_EVENT
);
148 if (hScmStartEvent
== NULL
)
150 DPRINT1("SERVICES: Failed to create the start event\n");
153 DPRINT("SERVICES: Created start event with handle %p.\n", hScmStartEvent
);
155 /* Create the auto-start complete event */
156 hScmAutoStartCompleteEvent
= CreateEventW(NULL
, TRUE
, FALSE
, SCM_AUTOSTARTCOMPLETE_EVENT
);
157 if (hScmAutoStartCompleteEvent
== NULL
)
159 DPRINT1("SERVICES: Failed to create the auto-start complete event\n");
162 DPRINT("SERVICES: created auto-start complete event with handle %p.\n", hScmAutoStartCompleteEvent
);
164 /* Create the shutdown event */
165 hScmShutdownEvent
= CreateEventW(NULL
, TRUE
, FALSE
, NULL
);
166 if (hScmShutdownEvent
== NULL
)
168 DPRINT1("SERVICES: Failed to create the shutdown event\n");
172 /* Initialize our communication named pipe's critical section */
173 ScmInitNamedPipeCriticalSection();
174 bCanDeleteNamedPipeCriticalSection
= TRUE
;
176 // ScmInitThreadManager();
178 ScmInitializeSecurity();
180 /* FIXME: more initialization */
182 /* Read the control set values */
183 if (!ScmGetControlSetValues())
185 DPRINT1("SERVICES: Failed to read the control set values\n");
189 /* Create the services database */
190 dwError
= ScmCreateServiceDatabase();
191 if (dwError
!= ERROR_SUCCESS
)
193 DPRINT1("SERVICES: Failed to create SCM database (Error %lu)\n", dwError
);
197 /* Wait for the LSA server */
200 /* Update the services database */
201 ScmGetBootAndSystemDriverState();
203 /* Register the Service Control Manager process with the ReactOS Subsystem */
204 if (!RegisterServicesProcess(GetCurrentProcessId()))
206 DPRINT1("SERVICES: Could not register SCM process\n");
211 * Acquire the user service start lock until
212 * auto-start services have been started.
214 dwError
= ScmAcquireServiceStartLock(TRUE
, &Lock
);
215 if (dwError
!= ERROR_SUCCESS
)
217 DPRINT1("SERVICES: Failed to acquire the service start lock (Error %lu)\n", dwError
);
221 /* Start the RPC server */
224 /* Signal start event */
225 SetEvent(hScmStartEvent
);
227 DPRINT("SERVICES: Initialized.\n");
229 /* Register event handler (used for system shutdown) */
230 SetConsoleCtrlHandler(ShutdownHandlerRoutine
, TRUE
);
233 * Set our shutdown parameters: we want to shutdown after the maintained
234 * services (that inherit the default shutdown level of 640).
236 SetProcessShutdownParameters(480, SHUTDOWN_NORETRY
);
238 /* Start auto-start services */
239 ScmAutoStartServices();
241 /* Signal auto-start complete event */
242 SetEvent(hScmAutoStartCompleteEvent
);
244 /* FIXME: more to do ? */
246 /* Release the service start lock */
247 ScmReleaseServiceStartLock(&Lock
);
249 /* Initialization finished */
250 ScmInitialize
= FALSE
;
252 DPRINT("SERVICES: Running.\n");
254 /* Wait until the shutdown event gets signaled */
255 WaitForSingleObject(hScmShutdownEvent
, INFINITE
);
258 ScmShutdownSecurity();
260 /* Delete our communication named pipe's critical section */
261 if (bCanDeleteNamedPipeCriticalSection
== TRUE
)
262 ScmDeleteNamedPipeCriticalSection();
264 /* Close the shutdown event */
265 if (hScmShutdownEvent
!= NULL
)
266 CloseHandle(hScmShutdownEvent
);
268 /* Close the auto-start complete event */
269 if (hScmAutoStartCompleteEvent
!= NULL
)
270 CloseHandle(hScmAutoStartCompleteEvent
);
272 /* Close the start event */
273 if (hScmStartEvent
!= NULL
)
274 CloseHandle(hScmStartEvent
);
276 DPRINT("SERVICES: Finished.\n");