ReactOS  0.4.15-dev-1207-g698a8e6
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 
33 
34 
35 /* FUNCTIONS *****************************************************************/
36 
37 VOID
39 {
40 #if DBG
41  CHAR buffer[512];
42  va_list ap;
43 
44  va_start(ap, fmt);
45  vsprintf(buffer, fmt, ap);
46  va_end(ap);
47 
49 #endif
50 }
51 
52 DWORD
54 {
55  WCHAR CommandLine[MAX_PATH];
56  HKEY hSetupKey;
57  DWORD dwSetupType;
58  DWORD dwType;
59  DWORD dwSize;
60  DWORD dwError;
61 
62  DPRINT1("CheckSetup()\n");
63 
64  /* Open the Setup key */
66  L"SYSTEM\\Setup",
67  0,
69  &hSetupKey);
70  if (dwError != ERROR_SUCCESS)
71  return dwError;
72 
73  /* Read the SetupType value */
74  dwSize = sizeof(DWORD);
75  dwError = RegQueryValueExW(hSetupKey,
76  L"SetupType",
77  NULL,
78  &dwType,
79  (LPBYTE)&dwSetupType,
80  &dwSize);
81 
82  if (dwError != ERROR_SUCCESS ||
83  dwType != REG_DWORD ||
84  dwSize != sizeof(DWORD) ||
85  dwSetupType == 0)
86  goto done;
87 
88  /* Read the CmdLine value */
89  dwSize = sizeof(CommandLine);
90  dwError = RegQueryValueExW(hSetupKey,
91  L"CmdLine",
92  NULL,
93  &dwType,
94  (LPBYTE)CommandLine,
95  &dwSize);
96 
97  if (dwError != ERROR_SUCCESS ||
98  (dwType != REG_SZ &&
99  dwType != REG_EXPAND_SZ &&
100  dwType != REG_MULTI_SZ))
101  goto done;
102 
103  /* Check for the '-mini' option */
104  if (wcsstr(CommandLine, L" -mini") != NULL)
105  {
106  DPRINT1("Running on LiveCD!\n");
107  ScmLiveSetup = TRUE;
108  }
109 
110 done:
111  RegCloseKey(hSetupKey);
112 
113  return dwError;
114 }
115 
116 
117 DWORD
119 {
120  DWORD dwError;
121 
123  return ERROR_SUCCESS;
124 
125  /* Create or open the SECURITY_SERVICES_STARTED event */
127  TRUE,
128  FALSE,
129  L"SECURITY_SERVICES_STARTED");
131  {
132  dwError = GetLastError();
133  if (dwError != ERROR_ALREADY_EXISTS)
134  return dwError;
135 
137  FALSE,
138  L"SECURITY_SERVICES_STARTED");
140  return GetLastError();
141  }
142 
144 
145  return ERROR_SUCCESS;
146 }
147 
148 
149 VOID
150 ScmLogEvent(DWORD dwEventId,
151  WORD wType,
152  WORD wStrings,
153  LPCWSTR *lpStrings)
154 {
155  HANDLE hLog;
156 
158  L"Service Control Manager");
159  if (hLog == NULL)
160  {
161  DPRINT1("ScmLogEvent: RegisterEventSourceW failed %lu\n", GetLastError());
162  return;
163  }
164 
165  if (!ReportEventW(hLog,
166  wType,
167  0,
168  dwEventId,
169  NULL,
170  wStrings,
171  0,
172  lpStrings,
173  NULL))
174  {
175  DPRINT1("ScmLogEvent: ReportEventW failed %lu\n", GetLastError());
176  }
177 
179 }
180 
181 
182 VOID
184 {
185  HANDLE hEvent = CreateEventW(NULL, TRUE, FALSE, L"LSA_RPC_SERVER_ACTIVE");
186  if (hEvent == NULL)
187  {
188  DPRINT1("Failed to create or open the notification event (Error %lu)\n", GetLastError());
189  }
190  else
191  {
192  DPRINT("Wait for the LSA server!\n");
194  DPRINT("LSA server running!\n");
196  }
197 
198  DPRINT("ScmWaitForLsa() done\n");
199 }
200 
201 
202 BOOL WINAPI
204 {
205  DPRINT1("ShutdownHandlerRoutine() called\n");
206 
207  if (dwCtrlType & (CTRL_SHUTDOWN_EVENT | CTRL_LOGOFF_EVENT))
208  {
209  DPRINT1("Shutdown event received!\n");
210  ScmShutdown = TRUE;
211 
214 
215  /* Set the shutdown event */
217  }
218 
219  return TRUE;
220 }
221 
222 
223 int WINAPI
225  HINSTANCE hPrevInstance,
226  LPWSTR lpCmdLine,
227  int nShowCmd)
228 {
229  HANDLE hScmStartEvent = NULL;
230  HANDLE hScmAutoStartCompleteEvent = NULL;
232  BOOL bCanDeleteNamedPipeCriticalSection = FALSE;
233  DWORD dwError;
234 
235  DPRINT("SERVICES: Service Control Manager\n");
236 
237  dwError = CheckForLiveCD();
238  if (dwError != ERROR_SUCCESS)
239  {
240  DPRINT1("SERVICES: Failed to check for LiveCD (Error %lu)\n", dwError);
241  goto done;
242  }
243 
244  /* Make us critical */
246 
247  /* We are initializing ourselves */
249 
250  /* Create the start event */
251  hScmStartEvent = CreateEventW(NULL, TRUE, FALSE, SCM_START_EVENT);
252  if (hScmStartEvent == NULL)
253  {
254  DPRINT1("SERVICES: Failed to create the start event\n");
255  goto done;
256  }
257  DPRINT("SERVICES: Created start event with handle %p.\n", hScmStartEvent);
258 
259  /* Create the auto-start complete event */
260  hScmAutoStartCompleteEvent = CreateEventW(NULL, TRUE, FALSE, SCM_AUTOSTARTCOMPLETE_EVENT);
261  if (hScmAutoStartCompleteEvent == NULL)
262  {
263  DPRINT1("SERVICES: Failed to create the auto-start complete event\n");
264  goto done;
265  }
266  DPRINT("SERVICES: created auto-start complete event with handle %p.\n", hScmAutoStartCompleteEvent);
267 
268  /* Create the shutdown event */
270  if (hScmShutdownEvent == NULL)
271  {
272  DPRINT1("SERVICES: Failed to create the shutdown event\n");
273  goto done;
274  }
275 
276  /* Initialize our communication named pipe's critical section */
278  bCanDeleteNamedPipeCriticalSection = TRUE;
279 
280 // ScmInitThreadManager();
281 
283 
284  /* FIXME: more initialization */
285 
286  /* Create the 'Last Known Good' control set */
288  if (dwError != ERROR_SUCCESS)
289  {
290  DPRINT1("SERVICES: Failed to create the 'Last Known Good' control set (Error %lu)\n", dwError);
291  goto done;
292  }
293 
294  /* Create the services database */
295  dwError = ScmCreateServiceDatabase();
296  if (dwError != ERROR_SUCCESS)
297  {
298  DPRINT1("SERVICES: Failed to create SCM database (Error %lu)\n", dwError);
299  goto done;
300  }
301 
302  /* Update the services database */
304 
305  /* Register the Service Control Manager process with the ReactOS Subsystem */
307  {
308  DPRINT1("SERVICES: Could not register SCM process\n");
309  goto done;
310  }
311 
312  /*
313  * Acquire the user service start lock until
314  * auto-start services have been started.
315  */
316  dwError = ScmAcquireServiceStartLock(TRUE, &Lock);
317  if (dwError != ERROR_SUCCESS)
318  {
319  DPRINT1("SERVICES: Failed to acquire the service start lock (Error %lu)\n", dwError);
320  goto done;
321  }
322 
323  /* Start the RPC server */
325 
326  /* Signal start event */
327  SetEvent(hScmStartEvent);
328 
329  DPRINT("SERVICES: Initialized.\n");
330 
331  /* Register event handler (used for system shutdown) */
333 
334  /*
335  * Set our shutdown parameters: we want to shutdown after the maintained
336  * services (that inherit the default shutdown level of 640).
337  */
339 
340  /* Start auto-start services */
342 
343  /* Signal auto-start complete event */
344  SetEvent(hScmAutoStartCompleteEvent);
345 
346  /* FIXME: more to do ? */
347 
348  /* Release the service start lock */
350 
351  /* Initialization finished */
353 
354  DPRINT("SERVICES: Running.\n");
355 
356  /* Wait until the shutdown event gets signaled */
358 
359 done:
361 
362  /* Delete our communication named pipe's critical section */
363  if (bCanDeleteNamedPipeCriticalSection != FALSE)
365 
368 
369  /* Close the shutdown event */
370  if (hScmShutdownEvent != NULL)
372 
373  /* Close the auto-start complete event */
374  if (hScmAutoStartCompleteEvent != NULL)
375  CloseHandle(hScmAutoStartCompleteEvent);
376 
377  /* Close the start event */
378  if (hScmStartEvent != NULL)
379  CloseHandle(hScmStartEvent);
380 
381  DPRINT("SERVICES: Finished.\n");
382 
383  ExitThread(0);
384  return 0;
385 }
386 
387 /* EOF */
VOID PrintString(LPCSTR fmt,...)
Definition: services.c:38
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:31
#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:183
DWORD ScmCreateLastKnownGoodControlSet(VOID)
Definition: controlset.c:613
BOOL WINAPI DECLSPEC_HOTPATCH SetEvent(IN HANDLE hEvent)
Definition: synch.c:733
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1044
DWORD SetSecurityServicesEvent(VOID)
Definition: services.c:118
GLuint buffer
Definition: glext.h:5915
DWORD ScmInitializeSecurity(VOID)
Definition: security.c:372
#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
LONG WINAPI RegCloseKey(HKEY hKey)
Definition: reg.c:423
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:2111
smooth NULL
Definition: ftsmooth.c:416
char * va_list
Definition: acmsvcex.h:78
void DPRINT(...)
Definition: polytest.cpp:61
VOID WINAPI ExitThread(IN DWORD uExitCode)
Definition: thread.c:364
const char * LPCSTR
Definition: xmlstorage.h:183
VOID ScmLogEvent(DWORD dwEventId, WORD wType, WORD wStrings, LPCWSTR *lpStrings)
Definition: services.c:150
LONG WINAPI RegQueryValueExW(_In_ HKEY hkeyorg, _In_ LPCWSTR name, _In_ LPDWORD reserved, _In_ LPDWORD type, _In_ LPBYTE data, _In_ LPDWORD count)
Definition: reg.c:4116
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:105
#define CTRL_LOGOFF_EVENT
Definition: wincon.h:72
DWORD ScmReleaseServiceStartLock(IN OUT LPSC_RPC_LOCK lpLock)
Definition: lock.c:82
static const WCHAR L[]
Definition: oid.c:1250
IN OUT PLONG IN OUT PLONG Addend IN OUT PLONG IN LONG IN OUT PLONG IN LONG Increment IN PNDIS_RW_LOCK Lock
Definition: CrNtStubs.h:75
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nShowCmd)
Definition: services.c:224
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:32
#define CTRL_SHUTDOWN_EVENT
Definition: wincon.h:73
#define SHUTDOWN_NORETRY
Definition: winbase.h:429
BOOL WINAPI ShutdownHandlerRoutine(DWORD dwCtrlType)
Definition: services.c:203
#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
#define va_start(ap, A)
Definition: acmsvcex.h:91
DWORD ScmCreateServiceDatabase(VOID)
Definition: database.c:1088
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
LONG WINAPI RegOpenKeyExW(HKEY hKey, LPCWSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult)
Definition: reg.c:3366
#define EVENT_MODIFY_STATE
Definition: winbase.h:163
DWORD CheckForLiveCD(VOID)
Definition: services.c:53
#define ERROR_ALREADY_EXISTS
Definition: disk.h:80
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:397
PSDBQUERYRESULT_VISTA PVOID DWORD * dwSize
Definition: env.c:54
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