ReactOS  0.4.15-dev-5146-g069b08d
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 
38 VOID
40 {
41 #if DBG
42  CHAR buffer[512];
43  va_list ap;
44 
45  va_start(ap, fmt);
46  vsprintf(buffer, fmt, ap);
47  va_end(ap);
48 
50 #endif
51 }
52 
53 DWORD
55 {
56  WCHAR CommandLine[MAX_PATH];
57  HKEY hSetupKey;
58  DWORD dwSetupType;
59  DWORD dwSetupInProgress;
60  DWORD dwType;
61  DWORD dwSize;
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");
109  ScmLiveSetup = TRUE;
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 
134 done:
135  RegCloseKey(hSetupKey);
136 
137  return dwError;
138 }
139 
140 
141 DWORD
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 
173 VOID
174 ScmLogEvent(DWORD dwEventId,
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 
206 VOID
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 
226 BOOL WINAPI
228 {
229  DPRINT1("ShutdownHandlerRoutine() called\n");
230 
231  if (dwCtrlType & (CTRL_SHUTDOWN_EVENT | CTRL_LOGOFF_EVENT))
232  {
233  DPRINT1("Shutdown event received\n");
234  ScmShutdown = TRUE;
235 
238 
239  /* Set the shutdown event */
241  }
242 
243  return TRUE;
244 }
245 
246 
247 int 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  */
340  dwError = ScmAcquireServiceStartLock(TRUE, &Lock);
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 
383 done:
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 */
VOID PrintString(LPCSTR fmt,...)
Definition: services.c:39
ULONG_PTR ServicesProcessId
Definition: register.c:20
VOID ScmAutoStartServices(VOID)
Definition: database.c:2171
#define CloseHandle
Definition: compat.h:598
BOOL ScmLiveSetup
Definition: services.c:30
#define ERROR_SUCCESS
Definition: deptool.c:10
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
static HANDLE hScmShutdownEvent
Definition: services.c:32
#define TRUE
Definition: types.h:120
_CONST_RETURN wchar_t *__cdecl wcsstr(_In_z_ const wchar_t *_Str, _In_z_ const wchar_t *_SubStr)
BOOL ScmInitialize
Definition: services.c:28
VOID ScmAutoShutdownServices(VOID)
Definition: database.c:2382
char CHAR
Definition: xmlstorage.h:175
VOID ScmWaitForLsa(VOID)
Definition: services.c:207
DWORD ScmCreateLastKnownGoodControlSet(VOID)
Definition: controlset.c:614
BOOL WINAPI DECLSPEC_HOTPATCH SetEvent(IN HANDLE hEvent)
Definition: synch.c:733
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1040
DWORD SetSecurityServicesEvent(VOID)
Definition: services.c:142
GLuint buffer
Definition: glext.h:5915
DWORD ScmInitializeSecurity(VOID)
Definition: security.c:373
#define DWORD
Definition: nt_native.h:44
HANDLE WINAPI DECLSPEC_HOTPATCH CreateEventW(IN LPSECURITY_ATTRIBUTES lpEventAttributes OPTIONAL, IN BOOL bManualReset, IN BOOL bInitialState, IN LPCWSTR lpName OPTIONAL)
Definition: synch.c:651
HANDLE WINAPI DECLSPEC_HOTPATCH OpenEventW(IN DWORD dwDesiredAccess, IN BOOL bInheritHandle, IN LPCWSTR lpName)
Definition: synch.c:682
static HANDLE hEvent
Definition: comm.c:54
BOOL WINAPI SetProcessShutdownParameters(IN DWORD dwLevel, IN DWORD dwFlags)
Definition: proc.c:949
VOID ScmGetBootAndSystemDriverState(VOID)
Definition: database.c:1285
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82
HINSTANCE hInstance
Definition: charmap.c:20
#define L(x)
Definition: ntvdm.h:50
unsigned char * LPBYTE
Definition: typedefs.h:53
#define va_end(ap)
Definition: acmsvcex.h:90
#define FALSE
Definition: types.h:117
DWORD ScmAcquireServiceStartLock(IN BOOL IsServiceController, OUT LPSC_RPC_LOCK lpLock)
Definition: lock.c:31
unsigned int BOOL
Definition: ntddk_ex.h:94
#define REG_MULTI_SZ
Definition: nt_native.h:1501
BOOL WINAPI DECLSPEC_HOTPATCH SetConsoleCtrlHandler(PHANDLER_ROUTINE HandlerRoutine, BOOL Add)
Definition: console.c:2109
char * va_list
Definition: acmsvcex.h:78
VOID WINAPI ExitThread(IN DWORD uExitCode)
Definition: thread.c:365
const char * LPCSTR
Definition: xmlstorage.h:183
VOID ScmLogEvent(DWORD dwEventId, WORD wType, WORD wStrings, LPCWSTR *lpStrings)
Definition: services.c:174
LONG WINAPI RegQueryValueExW(_In_ HKEY hkeyorg, _In_ LPCWSTR name, _In_ LPDWORD reserved, _In_ LPDWORD type, _In_ LPBYTE data, _In_ LPDWORD count)
Definition: reg.c:4120
BOOL ScmShutdown
Definition: services.c:29
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define MAX_PATH
Definition: compat.h:34
#define WINAPI
Definition: msvc.h:6
static HANDLE hLog
Definition: misc.cpp:13
unsigned short WORD
Definition: ntddk_ex.h:93
unsigned long DWORD
Definition: ntddk_ex.h:95
VOID ScmStartRpcServer(VOID)
Definition: rpcserver.c:107
va_start(ap, x)
BOOL ScmSetupInProgress
Definition: services.c:31
#define CTRL_LOGOFF_EVENT
Definition: wincon.h:72
DWORD ScmReleaseServiceStartLock(IN OUT LPSC_RPC_LOCK lpLock)
Definition: lock.c:82
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nShowCmd)
Definition: services.c:248
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
VOID ScmInitNamedPipeCriticalSection(VOID)
Definition: database.c:2441
VOID ScmDeleteNamedPipeCriticalSection(VOID)
Definition: database.c:2469
static HANDLE hScmSecurityServicesEvent
Definition: services.c:33
#define CTRL_SHUTDOWN_EVENT
Definition: wincon.h:73
#define SHUTDOWN_NORETRY
Definition: winbase.h:445
BOOL WINAPI ShutdownHandlerRoutine(DWORD dwCtrlType)
Definition: services.c:227
#define KEY_QUERY_VALUE
Definition: nt_native.h:1016
#define REG_EXPAND_SZ
Definition: nt_native.h:1494
int __cdecl vsprintf(char *_Dest, const char *_Format, va_list _Args)
Definition: sprintf.c:733
DWORD ScmCreateServiceDatabase(VOID)
Definition: database.c:1088
#define NULL
Definition: types.h:112
BOOL WINAPI DeregisterEventSource(IN HANDLE hEventLog)
Definition: eventlog.c:473
#define DPRINT1
Definition: precomp.h:8
NTSYSAPI NTSTATUS __cdecl RtlSetProcessIsCritical(_In_ BOOLEAN NewValue, _Out_opt_ PBOOLEAN OldValue, _In_ BOOLEAN NeedBreaks)
void int int ULONGLONG int va_list * ap
Definition: winesup.h:32
_Must_inspect_result_ _In_opt_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFWAITLOCK * Lock
Definition: wdfsync.h:124
LONG WINAPI RegOpenKeyExW(HKEY hKey, LPCWSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult)
Definition: reg.c:3356
#define EVENT_MODIFY_STATE
Definition: winbase.h:163
DWORD CheckForLiveCD(VOID)
Definition: services.c:54
#define ERROR_ALREADY_EXISTS
Definition: disk.h:80
#define DPRINT
Definition: sndvol32.h:71
WCHAR * LPWSTR
Definition: xmlstorage.h:184
#define SCM_AUTOSTARTCOMPLETE_EVENT
Definition: services.c:26
#define INFINITE
Definition: serial.h:102
#define SCM_START_EVENT
Definition: services.h:26
HANDLE WINAPI RegisterEventSourceW(IN LPCWSTR lpUNCServerName, IN LPCWSTR lpSourceName)
Definition: eventlog.c:1295
#define REG_DWORD
Definition: sdbapi.c:596
VOID ScmShutdownServiceDatabase(VOID)
Definition: database.c:1175
Definition: dsound.c:943
void WINAPI SHIM_OBJ_NAME() OutputDebugStringA(LPCSTR lpOutputString)
Definition: ignoredbgout.c:18
VOID ScmShutdownSecurity(VOID)
Definition: security.c:398
#define RegCloseKey(hKey)
Definition: registry.h:47
PSDBQUERYRESULT_VISTA PVOID DWORD * dwSize
Definition: env.c:56
int WINAPI RegisterServicesProcess(DWORD ServicesProcessId)
Definition: logon.c:18
DWORD WINAPI GetCurrentProcessId(VOID)
Definition: proc.c:1158
#define HKEY_LOCAL_MACHINE
Definition: winreg.h:12
#define REG_SZ
Definition: layer.c:22