Something went wrong. Try again.
Reactos
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412/* * PROJECT: ReactOS Service Control Manager * LICENSE: GPL - See COPYING in the top level directory * FILE: base/system/services/services.c * PURPOSE: Main SCM controller * COPYRIGHT: Copyright 2001-2005 Eric Kohl * Copyright 2007 Ged Murphy <gedmurphy@reactos.org> * */
/* INCLUDES *****************************************************************/
#include "services.h"
#include <wincon.h>
#define NDEBUG#include <debug.h>
int WINAPI RegisterServicesProcess(DWORD ServicesProcessId);
/* GLOBALS ******************************************************************/
/* Defined in include/reactos/services/services.h */// #define SCM_START_EVENT L"SvcctrlStartEvent_A3752DX"#define SCM_AUTOSTARTCOMPLETE_EVENT L"SC_AutoStartComplete"
BOOL ScmInitialize = FALSE;BOOL ScmShutdown = FALSE;BOOL ScmLiveSetup = FALSE;BOOL ScmSetupInProgress = FALSE;static HANDLE hScmShutdownEvent = NULL;static HANDLE hScmSecurityServicesEvent = NULL;
/* FUNCTIONS *****************************************************************/
VOIDPrintString(LPCSTR fmt, ...){#if DBG CHAR buffer[512]; va_list ap;
va_start(ap, fmt); vsprintf(buffer, fmt, ap); va_end(ap);
OutputDebugStringA(buffer);#endif}
DWORDCheckForLiveCD(VOID){ WCHAR CommandLine[MAX_PATH]; HKEY hSetupKey; DWORD dwSetupType; DWORD dwSetupInProgress; DWORD dwType; DWORD dwSize; DWORD dwError;
DPRINT1("CheckSetup()\n");
/* Open the Setup key */ dwError = RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"SYSTEM\\Setup", 0, KEY_QUERY_VALUE, &hSetupKey); if (dwError != ERROR_SUCCESS) return dwError;
/* Read the SetupType value */ dwSize = sizeof(DWORD); dwError = RegQueryValueExW(hSetupKey, L"SetupType", NULL, &dwType, (LPBYTE)&dwSetupType, &dwSize);
if (dwError != ERROR_SUCCESS || dwType != REG_DWORD || dwSize != sizeof(DWORD) || dwSetupType == 0) goto done;
/* Read the CmdLine value */ dwSize = sizeof(CommandLine); dwError = RegQueryValueExW(hSetupKey, L"CmdLine", NULL, &dwType, (LPBYTE)CommandLine, &dwSize);
if (dwError != ERROR_SUCCESS || (dwType != REG_SZ && dwType != REG_EXPAND_SZ && dwType != REG_MULTI_SZ)) goto done;
/* Check for the '-mini' option */ if (wcsstr(CommandLine, L" -mini") != NULL) { DPRINT1("Running on LiveCD\n"); ScmLiveSetup = TRUE; }
/* Read the SystemSetupInProgress value */ dwSize = sizeof(DWORD); dwError = RegQueryValueExW(hSetupKey, L"SystemSetupInProgress", NULL, &dwType, (LPBYTE)&dwSetupInProgress, &dwSize); if (dwError != ERROR_SUCCESS || dwType != REG_DWORD || dwSize != sizeof(DWORD) || dwSetupType == 0) { goto done; }
if (dwSetupInProgress == 1) { DPRINT1("ReactOS Setup currently in progress!\n"); ScmSetupInProgress = TRUE; }
done: RegCloseKey(hSetupKey);
return dwError;}
DWORDSetSecurityServicesEvent(VOID){ DWORD dwError;
if (hScmSecurityServicesEvent != NULL) return ERROR_SUCCESS;
/* Create or open the SECURITY_SERVICES_STARTED event */ hScmSecurityServicesEvent = CreateEventW(NULL, TRUE, FALSE, L"SECURITY_SERVICES_STARTED"); if (hScmSecurityServicesEvent == NULL) { dwError = GetLastError(); if (dwError != ERROR_ALREADY_EXISTS) return dwError;
hScmSecurityServicesEvent = OpenEventW(EVENT_MODIFY_STATE, FALSE, L"SECURITY_SERVICES_STARTED"); if (hScmSecurityServicesEvent == NULL) return GetLastError(); }
SetEvent(hScmSecurityServicesEvent);
return ERROR_SUCCESS;}
VOIDScmLogEvent(DWORD dwEventId, WORD wType, WORD wStrings, LPCWSTR *lpStrings){ HANDLE hLog;
hLog = RegisterEventSourceW(NULL, L"Service Control Manager"); if (hLog == NULL) { DPRINT1("ScmLogEvent: RegisterEventSourceW failed %lu\n", GetLastError()); return; }
if (!ReportEventW(hLog, wType, 0, dwEventId, NULL, wStrings, 0, lpStrings, NULL)) { DPRINT1("ScmLogEvent: ReportEventW failed %lu\n", GetLastError()); }
DeregisterEventSource(hLog);}
VOIDScmWaitForLsa(VOID){ HANDLE hEvent = CreateEventW(NULL, TRUE, FALSE, L"LSA_RPC_SERVER_ACTIVE"); if (hEvent == NULL) { DPRINT1("Failed to create or open the notification event (Error %lu)\n", GetLastError()); } else { DPRINT("Wait for the LSA server\n"); WaitForSingleObject(hEvent, INFINITE); DPRINT("LSA server running\n"); CloseHandle(hEvent); }
DPRINT("ScmWaitForLsa() done\n");}
BOOL WINAPIShutdownHandlerRoutine(DWORD dwCtrlType){ DPRINT1("ShutdownHandlerRoutine() called\n");
if (dwCtrlType & (CTRL_SHUTDOWN_EVENT | CTRL_LOGOFF_EVENT)) { DPRINT1("Shutdown event received\n"); ScmShutdown = TRUE;
ScmAutoShutdownServices(); ScmShutdownServiceDatabase();
/* Set the shutdown event */ SetEvent(hScmShutdownEvent); }
return TRUE;}
int WINAPIwWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nShowCmd){ HANDLE hScmStartEvent = NULL; HANDLE hScmAutoStartCompleteEvent = NULL; SC_RPC_LOCK Lock = NULL; BOOL bCanDeleteNamedPipeCriticalSection = FALSE; DWORD dwError;
DPRINT("SERVICES: Service Control Manager\n");
dwError = CheckForLiveCD(); if (dwError != ERROR_SUCCESS) { DPRINT1("SERVICES: Failed to check for LiveCD (Error %lu)\n", dwError); goto done; }
/* Make us critical */ RtlSetProcessIsCritical(TRUE, NULL, TRUE);
/* We are initializing ourselves */ ScmInitialize = TRUE;
/* Create the start event */ hScmStartEvent = CreateEventW(NULL, TRUE, FALSE, SCM_START_EVENT); if (hScmStartEvent == NULL) { DPRINT1("SERVICES: Failed to create the start event\n"); goto done; } DPRINT("SERVICES: Created start event with handle %p\n", hScmStartEvent);
/* Create the auto-start complete event */ hScmAutoStartCompleteEvent = CreateEventW(NULL, TRUE, FALSE, SCM_AUTOSTARTCOMPLETE_EVENT); if (hScmAutoStartCompleteEvent == NULL) { DPRINT1("SERVICES: Failed to create the auto-start complete event\n"); goto done; } DPRINT("SERVICES: created auto-start complete event with handle %p\n", hScmAutoStartCompleteEvent);
/* Create the shutdown event */ hScmShutdownEvent = CreateEventW(NULL, TRUE, FALSE, NULL); if (hScmShutdownEvent == NULL) { DPRINT1("SERVICES: Failed to create the shutdown event\n"); goto done; }
/* Initialize our communication named pipe's critical section */ ScmInitNamedPipeCriticalSection(); bCanDeleteNamedPipeCriticalSection = TRUE;
// ScmInitThreadManager();
ScmInitializeSecurity();
/* FIXME: more initialization */
/* Create the 'Last Known Good' control set */ dwError = ScmCreateLastKnownGoodControlSet(); if (dwError != ERROR_SUCCESS) { DPRINT1("SERVICES: Failed to create the 'Last Known Good' control set (Error %lu)\n", dwError); goto done; }
/* Create the services database */ dwError = ScmCreateServiceDatabase(); if (dwError != ERROR_SUCCESS) { DPRINT1("SERVICES: Failed to create SCM database (Error %lu)\n", dwError); goto done; }
/* Update the services database */ ScmGetBootAndSystemDriverState();
/* Register the Service Control Manager process with the ReactOS Subsystem */ if (!RegisterServicesProcess(GetCurrentProcessId())) { DPRINT1("SERVICES: Could not register SCM process\n"); goto done; }
/* * Acquire the user service start lock until * auto-start services have been started. */ dwError = ScmAcquireServiceStartLock(TRUE, &Lock); if (dwError != ERROR_SUCCESS) { DPRINT1("SERVICES: Failed to acquire service start lock (Error %lu)\n", dwError); goto done; }
/* Start the RPC server */ ScmStartRpcServer();
/* Signal start event */ SetEvent(hScmStartEvent);
DPRINT("SERVICES: Initialized\n");
/* Register event handler (used for system shutdown) */ SetConsoleCtrlHandler(ShutdownHandlerRoutine, TRUE);
/* * Set our shutdown parameters: we want to shutdown after the maintained * services (that inherit the default shutdown level of 640). */ SetProcessShutdownParameters(480, SHUTDOWN_NORETRY);
/* Start auto-start services */ ScmAutoStartServices();
/* Signal auto-start complete event */ SetEvent(hScmAutoStartCompleteEvent);
/* FIXME: more to do ? */
/* Release the service start lock */ ScmReleaseServiceStartLock(&Lock);
/* Initialization finished */ ScmInitialize = FALSE;
DPRINT("SERVICES: Running\n");
/* Wait until the shutdown event gets signaled */ WaitForSingleObject(hScmShutdownEvent, INFINITE);
done: ScmShutdownSecurity();
/* Delete our communication named pipe's critical section */ if (bCanDeleteNamedPipeCriticalSection != FALSE) ScmDeleteNamedPipeCriticalSection();
if (hScmSecurityServicesEvent != NULL) CloseHandle(hScmSecurityServicesEvent);
/* Close the shutdown event */ if (hScmShutdownEvent != NULL) CloseHandle(hScmShutdownEvent);
/* Close the auto-start complete event */ if (hScmAutoStartCompleteEvent != NULL) CloseHandle(hScmAutoStartCompleteEvent);
/* Close the start event */ if (hScmStartEvent != NULL) CloseHandle(hScmStartEvent);
DPRINT("SERVICES: Finished\n");
ExitThread(0); return 0;}
/* EOF */