mirror of
https://github.com/ApfelTeeSaft/reactos.git
synced 2026-09-02 04:13:34 +00:00
[SERVICES]
- It seems (after testing) that services report now correctly their state to the SCM. So we can start them in SERVICE_START_PENDING state (see revisions r45626 and r45640). - Add some informative comments. - Use a helper function to create start events at initialization time. - When autostart services are up, signal an event. (see revisions r45633 and r45658). - Wait for LSASS just after having created the services database, and before calling ScmGetBootAndSystemDriverState (conform to Windows Internals 4th, page 224). --------- - When starting auto-start services, hold a lock during all the operation in such a way that, if an external program wants to start a service, it is obliged to wait till all the auto-start services have been started (usual service starting also uses that lock). CORE-7001 #resolve #comment Should be fixed by r58534. Do not hesitate to reopen this bug-report if the problem reappears. svn path=/trunk/; revision=58534
This commit is contained in:
@@ -19,9 +19,9 @@
|
||||
|
||||
/*
|
||||
* Uncomment the line below to start services
|
||||
* using the SERVICE_START_PENDING state
|
||||
* using the SERVICE_START_PENDING state.
|
||||
*/
|
||||
// #define USE_SERVICE_START_PENDING
|
||||
#define USE_SERVICE_START_PENDING
|
||||
|
||||
/*
|
||||
* Uncomment the line below to use asynchronous IO operations
|
||||
@@ -38,6 +38,7 @@ LIST_ENTRY ServiceListHead;
|
||||
static RTL_RESOURCE DatabaseLock;
|
||||
static DWORD ResumeCount = 1;
|
||||
|
||||
/* The critical section synchronizes service controls commands */
|
||||
static CRITICAL_SECTION ControlServiceCriticalSection;
|
||||
static DWORD PipeTimeout = 30000; /* 30 Seconds */
|
||||
|
||||
@@ -359,7 +360,7 @@ ScmGetServiceEntryByResumeCount(DWORD dwResumeCount)
|
||||
|
||||
DWORD
|
||||
ScmCreateNewServiceRecord(LPCWSTR lpServiceName,
|
||||
PSERVICE *lpServiceRecord)
|
||||
PSERVICE* lpServiceRecord)
|
||||
{
|
||||
PSERVICE lpService = NULL;
|
||||
|
||||
@@ -772,13 +773,11 @@ ScmCheckDriver(PSERVICE Service)
|
||||
|
||||
if (Service->Status.dwServiceType == SERVICE_KERNEL_DRIVER)
|
||||
{
|
||||
RtlInitUnicodeString(&DirName,
|
||||
L"\\Driver");
|
||||
RtlInitUnicodeString(&DirName, L"\\Driver");
|
||||
}
|
||||
else
|
||||
else // if (Service->Status.dwServiceType == SERVICE_FILE_SYSTEM_DRIVER)
|
||||
{
|
||||
RtlInitUnicodeString(&DirName,
|
||||
L"\\FileSystem");
|
||||
RtlInitUnicodeString(&DirName, L"\\FileSystem");
|
||||
}
|
||||
|
||||
InitializeObjectAttributes(&ObjectAttributes,
|
||||
@@ -796,7 +795,7 @@ ScmCheckDriver(PSERVICE Service)
|
||||
}
|
||||
|
||||
BufferLength = sizeof(OBJECT_DIRECTORY_INFORMATION) +
|
||||
2 * MAX_PATH * sizeof(WCHAR);
|
||||
2 * MAX_PATH * sizeof(WCHAR);
|
||||
DirInfo = HeapAlloc(GetProcessHeap(),
|
||||
HEAP_ZERO_MEMORY,
|
||||
BufferLength);
|
||||
@@ -1096,7 +1095,7 @@ Done:
|
||||
static DWORD
|
||||
ScmSendStartCommand(PSERVICE Service,
|
||||
DWORD argc,
|
||||
LPWSTR *argv)
|
||||
LPWSTR* argv)
|
||||
{
|
||||
PSCM_CONTROL_PACKET ControlPacket;
|
||||
SCM_REPLY_PACKET ReplyPacket;
|
||||
@@ -1496,7 +1495,7 @@ ScmWaitForServiceConnect(PSERVICE Service)
|
||||
static DWORD
|
||||
ScmStartUserModeService(PSERVICE Service,
|
||||
DWORD argc,
|
||||
LPWSTR *argv)
|
||||
LPWSTR* argv)
|
||||
{
|
||||
PROCESS_INFORMATION ProcessInformation;
|
||||
STARTUPINFOW StartupInfo;
|
||||
@@ -1512,6 +1511,7 @@ ScmStartUserModeService(PSERVICE Service,
|
||||
return ScmSendStartCommand(Service, argc, argv);
|
||||
}
|
||||
|
||||
/* Otherwise start its process */
|
||||
ZeroMemory(&StartupInfo, sizeof(StartupInfo));
|
||||
StartupInfo.cb = sizeof(StartupInfo);
|
||||
ZeroMemory(&ProcessInformation, sizeof(ProcessInformation));
|
||||
@@ -1551,9 +1551,7 @@ ScmStartUserModeService(PSERVICE Service,
|
||||
if (dwError == ERROR_SUCCESS)
|
||||
{
|
||||
/* Send start command */
|
||||
dwError = ScmSendStartCommand(Service,
|
||||
argc,
|
||||
argv);
|
||||
dwError = ScmSendStartCommand(Service, argc, argv);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1569,24 +1567,22 @@ ScmStartUserModeService(PSERVICE Service,
|
||||
}
|
||||
|
||||
|
||||
DWORD
|
||||
ScmStartService(PSERVICE Service, DWORD argc, LPWSTR *argv)
|
||||
static DWORD
|
||||
ScmLoadService(PSERVICE Service,
|
||||
DWORD argc,
|
||||
LPWSTR* argv)
|
||||
{
|
||||
PSERVICE_GROUP Group = Service->lpGroup;
|
||||
DWORD dwError = ERROR_SUCCESS;
|
||||
LPCWSTR ErrorLogStrings[2];
|
||||
WCHAR szErrorBuffer[32];
|
||||
|
||||
DPRINT("ScmStartService() called\n");
|
||||
|
||||
DPRINT("ScmLoadService() called\n");
|
||||
DPRINT("Start Service %p (%S)\n", Service, Service->lpServiceName);
|
||||
|
||||
EnterCriticalSection(&ControlServiceCriticalSection);
|
||||
|
||||
if (Service->Status.dwCurrentState != SERVICE_STOPPED)
|
||||
{
|
||||
DPRINT("Service %S is already running!\n", Service->lpServiceName);
|
||||
LeaveCriticalSection(&ControlServiceCriticalSection);
|
||||
return ERROR_SERVICE_ALREADY_RUNNING;
|
||||
}
|
||||
|
||||
@@ -1602,7 +1598,7 @@ ScmStartService(PSERVICE Service, DWORD argc, LPWSTR *argv)
|
||||
Service->Status.dwCurrentState = SERVICE_RUNNING;
|
||||
}
|
||||
}
|
||||
else
|
||||
else // if (Service->Status.dwServiceType & (SERVICE_WIN32 | SERVICE_INTERACTIVE_PROCESS))
|
||||
{
|
||||
/* Start user-mode service */
|
||||
dwError = ScmCreateOrReferenceServiceImage(Service);
|
||||
@@ -1625,9 +1621,7 @@ ScmStartService(PSERVICE Service, DWORD argc, LPWSTR *argv)
|
||||
}
|
||||
}
|
||||
|
||||
LeaveCriticalSection(&ControlServiceCriticalSection);
|
||||
|
||||
DPRINT("ScmStartService() done (Error %lu)\n", dwError);
|
||||
DPRINT("ScmLoadService() done (Error %lu)\n", dwError);
|
||||
|
||||
if (dwError == ERROR_SUCCESS)
|
||||
{
|
||||
@@ -1677,18 +1671,81 @@ ScmStartService(PSERVICE Service, DWORD argc, LPWSTR *argv)
|
||||
}
|
||||
|
||||
|
||||
DWORD
|
||||
ScmStartService(PSERVICE Service,
|
||||
DWORD argc,
|
||||
LPWSTR* argv)
|
||||
{
|
||||
DWORD dwError = ERROR_SUCCESS;
|
||||
SC_RPC_LOCK Lock = NULL;
|
||||
|
||||
DPRINT("ScmStartService() called\n");
|
||||
DPRINT("Start Service %p (%S)\n", Service, Service->lpServiceName);
|
||||
|
||||
/* Acquire the service control critical section, to synchronize starts */
|
||||
EnterCriticalSection(&ControlServiceCriticalSection);
|
||||
|
||||
/*
|
||||
* Acquire the user service start lock while the service is starting, if
|
||||
* needed (i.e. if we are not starting it during the initialization phase).
|
||||
* If we don't success, bail out.
|
||||
*/
|
||||
if (!ScmInitialize)
|
||||
{
|
||||
dwError = ScmAcquireServiceStartLock(TRUE, &Lock);
|
||||
if (dwError != ERROR_SUCCESS) goto done;
|
||||
}
|
||||
|
||||
/* Really start the service */
|
||||
dwError = ScmLoadService(Service, argc, argv);
|
||||
|
||||
/* Release the service start lock, if needed, and the critical section */
|
||||
if (Lock) ScmReleaseServiceStartLock(&Lock);
|
||||
|
||||
done:
|
||||
LeaveCriticalSection(&ControlServiceCriticalSection);
|
||||
|
||||
DPRINT("ScmStartService() done (Error %lu)\n", dwError);
|
||||
|
||||
return dwError;
|
||||
}
|
||||
|
||||
|
||||
VOID
|
||||
ScmAutoStartServices(VOID)
|
||||
{
|
||||
DWORD dwError = ERROR_SUCCESS;
|
||||
SC_RPC_LOCK Lock = NULL;
|
||||
|
||||
PLIST_ENTRY GroupEntry;
|
||||
PLIST_ENTRY ServiceEntry;
|
||||
PSERVICE_GROUP CurrentGroup;
|
||||
PSERVICE CurrentService;
|
||||
WCHAR szSafeBootServicePath[MAX_PATH];
|
||||
DWORD dwError;
|
||||
HKEY hKey;
|
||||
ULONG i;
|
||||
|
||||
/* Acquire the service control critical section, to synchronize starts */
|
||||
EnterCriticalSection(&ControlServiceCriticalSection);
|
||||
|
||||
/*
|
||||
* Acquire the user service start lock while the service is starting, if
|
||||
* needed (i.e. if we are not starting it during the initialization phase).
|
||||
* If we don't success, bail out.
|
||||
*/
|
||||
if (!ScmInitialize)
|
||||
{
|
||||
/*
|
||||
* Actually this code is never executed since we are called
|
||||
* at initialization time, so that ScmInitialize == TRUE.
|
||||
* But keep the code here if someday we are called later on
|
||||
* for whatever reason...
|
||||
*/
|
||||
dwError = ScmAcquireServiceStartLock(TRUE, &Lock);
|
||||
if (dwError != ERROR_SUCCESS) goto done;
|
||||
}
|
||||
|
||||
|
||||
/* Clear 'ServiceVisited' flag (or set if not to start in Safe Mode) */
|
||||
ServiceEntry = ServiceListHead.Flink;
|
||||
while (ServiceEntry != &ServiceListHead)
|
||||
@@ -1779,7 +1836,7 @@ ScmAutoStartServices(VOID)
|
||||
(CurrentService->dwTag == CurrentGroup->TagArray[i]))
|
||||
{
|
||||
CurrentService->ServiceVisited = TRUE;
|
||||
ScmStartService(CurrentService, 0, NULL);
|
||||
ScmLoadService(CurrentService, 0, NULL);
|
||||
}
|
||||
|
||||
ServiceEntry = ServiceEntry->Flink;
|
||||
@@ -1797,7 +1854,7 @@ ScmAutoStartServices(VOID)
|
||||
(CurrentService->ServiceVisited == FALSE))
|
||||
{
|
||||
CurrentService->ServiceVisited = TRUE;
|
||||
ScmStartService(CurrentService, 0, NULL);
|
||||
ScmLoadService(CurrentService, 0, NULL);
|
||||
}
|
||||
|
||||
ServiceEntry = ServiceEntry->Flink;
|
||||
@@ -1817,7 +1874,7 @@ ScmAutoStartServices(VOID)
|
||||
(CurrentService->ServiceVisited == FALSE))
|
||||
{
|
||||
CurrentService->ServiceVisited = TRUE;
|
||||
ScmStartService(CurrentService, 0, NULL);
|
||||
ScmLoadService(CurrentService, 0, NULL);
|
||||
}
|
||||
|
||||
ServiceEntry = ServiceEntry->Flink;
|
||||
@@ -1834,7 +1891,7 @@ ScmAutoStartServices(VOID)
|
||||
(CurrentService->ServiceVisited == FALSE))
|
||||
{
|
||||
CurrentService->ServiceVisited = TRUE;
|
||||
ScmStartService(CurrentService, 0, NULL);
|
||||
ScmLoadService(CurrentService, 0, NULL);
|
||||
}
|
||||
|
||||
ServiceEntry = ServiceEntry->Flink;
|
||||
@@ -1848,6 +1905,13 @@ ScmAutoStartServices(VOID)
|
||||
CurrentService->ServiceVisited = FALSE;
|
||||
ServiceEntry = ServiceEntry->Flink;
|
||||
}
|
||||
|
||||
|
||||
/* Release the service start lock, if needed, and the critical section */
|
||||
if (Lock) ScmReleaseServiceStartLock(&Lock);
|
||||
|
||||
done:
|
||||
LeaveCriticalSection(&ControlServiceCriticalSection);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -2895,7 +2895,6 @@ DWORD RStartServiceW(
|
||||
DWORD dwError = ERROR_SUCCESS;
|
||||
PSERVICE_HANDLE hSvc;
|
||||
PSERVICE lpService = NULL;
|
||||
SC_RPC_LOCK Lock = NULL;
|
||||
|
||||
#ifndef NDEBUG
|
||||
DWORD i;
|
||||
@@ -2941,17 +2940,9 @@ DWORD RStartServiceW(
|
||||
if (lpService->bDeleted)
|
||||
return ERROR_SERVICE_MARKED_FOR_DELETE;
|
||||
|
||||
/* Acquire the service start lock until the service has been started */
|
||||
dwError = ScmAcquireServiceStartLock(TRUE, &Lock);
|
||||
if (dwError != ERROR_SUCCESS)
|
||||
return dwError;
|
||||
|
||||
/* Start the service */
|
||||
dwError = ScmStartService(lpService, argc, (LPWSTR*)argv);
|
||||
|
||||
/* Release the service start lock */
|
||||
ScmReleaseServiceStartLock(&Lock);
|
||||
|
||||
return dwError;
|
||||
}
|
||||
|
||||
@@ -4171,7 +4162,6 @@ DWORD RStartServiceA(
|
||||
DWORD dwError = ERROR_SUCCESS;
|
||||
PSERVICE_HANDLE hSvc;
|
||||
PSERVICE lpService = NULL;
|
||||
SC_RPC_LOCK Lock = NULL;
|
||||
LPWSTR *lpVector = NULL;
|
||||
DWORD i;
|
||||
DWORD dwLength;
|
||||
@@ -4244,17 +4234,9 @@ DWORD RStartServiceA(
|
||||
}
|
||||
}
|
||||
|
||||
/* Acquire the service start lock until the service has been started */
|
||||
dwError = ScmAcquireServiceStartLock(TRUE, &Lock);
|
||||
if (dwError != ERROR_SUCCESS)
|
||||
goto done;
|
||||
|
||||
/* Start the service */
|
||||
dwError = ScmStartService(lpService, argc, lpVector);
|
||||
|
||||
/* Release the service start lock */
|
||||
ScmReleaseServiceStartLock(&Lock);
|
||||
|
||||
done:
|
||||
/* Free the Unicode argument vector */
|
||||
if (lpVector != NULL)
|
||||
|
||||
@@ -22,6 +22,12 @@ int WINAPI RegisterServicesProcess(DWORD ServicesProcessId);
|
||||
#define PIPE_BUFSIZE 1024
|
||||
#define PIPE_TIMEOUT 1000
|
||||
|
||||
/* Defined in include/reactos/services/services.h */
|
||||
// #define SCM_START_EVENT L"SvcctrlStartEvent_A3752DX"
|
||||
#define SCM_AUTOSTARTCOMPLETE_EVENT L"SC_AutoStartComplete"
|
||||
#define LSA_RPC_SERVER_ACTIVE L"LSA_RPC_SERVER_ACTIVE"
|
||||
|
||||
BOOL ScmInitialize = FALSE;
|
||||
BOOL ScmShutdown = FALSE;
|
||||
static HANDLE hScmShutdownEvent = NULL;
|
||||
|
||||
@@ -77,35 +83,38 @@ ScmLogError(DWORD dwEventId,
|
||||
|
||||
|
||||
BOOL
|
||||
ScmCreateStartEvent(PHANDLE StartEvent)
|
||||
ScmCreateControlEvent(PHANDLE Event,
|
||||
LPCWSTR Name,
|
||||
DWORD dwDesiredAccess)
|
||||
{
|
||||
/*
|
||||
* This function creates a generic non-inheritable event
|
||||
* and return a handle to the caller. The caller must
|
||||
* close this handle afterwards.
|
||||
*/
|
||||
|
||||
HANDLE hEvent;
|
||||
|
||||
hEvent = CreateEventW(NULL,
|
||||
TRUE,
|
||||
FALSE,
|
||||
L"SvcctrlStartEvent_A3752DX");
|
||||
hEvent = CreateEventW(NULL, TRUE, FALSE, Name);
|
||||
if (hEvent == NULL)
|
||||
{
|
||||
if (GetLastError() == ERROR_ALREADY_EXISTS)
|
||||
{
|
||||
hEvent = OpenEventW(EVENT_ALL_ACCESS,
|
||||
FALSE,
|
||||
L"SvcctrlStartEvent_A3752DX");
|
||||
if (hEvent == NULL)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return FALSE;
|
||||
hEvent = OpenEventW(dwDesiredAccess, FALSE, Name);
|
||||
}
|
||||
}
|
||||
|
||||
*StartEvent = hEvent;
|
||||
|
||||
return TRUE;
|
||||
if (hEvent)
|
||||
{
|
||||
DPRINT("SERVICES: Created event %S with handle %x\n", Name, hEvent);
|
||||
*Event = hEvent;
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
DPRINT1("SERVICES: Failed to create event %S (Error %lu)\n", Name, GetLastError());
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -113,35 +122,21 @@ VOID
|
||||
ScmWaitForLsa(VOID)
|
||||
{
|
||||
HANDLE hEvent;
|
||||
DWORD dwError;
|
||||
|
||||
hEvent = CreateEventW(NULL,
|
||||
TRUE,
|
||||
FALSE,
|
||||
L"LSA_RPC_SERVER_ACTIVE");
|
||||
if (hEvent == NULL)
|
||||
if (!ScmCreateControlEvent(&hEvent,
|
||||
LSA_RPC_SERVER_ACTIVE,
|
||||
SYNCHRONIZE))
|
||||
{
|
||||
dwError = GetLastError();
|
||||
DPRINT1("Failed to create the notication event (Error %lu)\n", dwError);
|
||||
|
||||
if (dwError == ERROR_ALREADY_EXISTS)
|
||||
{
|
||||
hEvent = OpenEventW(SYNCHRONIZE,
|
||||
FALSE,
|
||||
L"LSA_RPC_SERVER_ACTIVE");
|
||||
if (hEvent == NULL)
|
||||
{
|
||||
DPRINT1("Could not open the notification event (Error %lu)\n", GetLastError());
|
||||
return;
|
||||
}
|
||||
}
|
||||
DPRINT1("Failed to create the notification event (Error %lu)\n", GetLastError());
|
||||
}
|
||||
else
|
||||
{
|
||||
DPRINT("Wait for the LSA server!\n");
|
||||
WaitForSingleObject(hEvent, INFINITE);
|
||||
DPRINT("LSA server running!\n");
|
||||
|
||||
DPRINT("Wait for the LSA server!\n");
|
||||
WaitForSingleObject(hEvent, INFINITE);
|
||||
DPRINT("LSA server running!\n");
|
||||
|
||||
CloseHandle(hEvent);
|
||||
CloseHandle(hEvent);
|
||||
}
|
||||
|
||||
DPRINT("ScmWaitForLsa() done\n");
|
||||
}
|
||||
@@ -351,23 +346,38 @@ wWinMain(HINSTANCE hInstance,
|
||||
int nShowCmd)
|
||||
{
|
||||
HANDLE hScmStartEvent = NULL;
|
||||
HANDLE hScmAutoStartCompleteEvent = NULL;
|
||||
SC_RPC_LOCK Lock = NULL;
|
||||
BOOL bCanDeleteNamedPipeCriticalSection = FALSE;
|
||||
DWORD dwError;
|
||||
|
||||
DPRINT("SERVICES: Service Control Manager\n");
|
||||
|
||||
/* Create start event */
|
||||
if (!ScmCreateStartEvent(&hScmStartEvent))
|
||||
/* We are initializing ourselves */
|
||||
ScmInitialize = TRUE;
|
||||
|
||||
/* Create the start event */
|
||||
if (!ScmCreateControlEvent(&hScmStartEvent,
|
||||
SCM_START_EVENT,
|
||||
EVENT_ALL_ACCESS))
|
||||
{
|
||||
DPRINT1("SERVICES: Failed to create start event\n");
|
||||
DPRINT1("SERVICES: Failed to create the start event\n");
|
||||
goto done;
|
||||
}
|
||||
DPRINT("SERVICES: Created start event with handle %p.\n", hScmStartEvent);
|
||||
|
||||
DPRINT("SERVICES: created start event with handle %p.\n", hScmStartEvent);
|
||||
/* Create the auto-start complete event */
|
||||
if (!ScmCreateControlEvent(&hScmAutoStartCompleteEvent,
|
||||
SCM_AUTOSTARTCOMPLETE_EVENT,
|
||||
EVENT_ALL_ACCESS))
|
||||
{
|
||||
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 = CreateEvent(NULL, TRUE, FALSE, NULL);
|
||||
hScmShutdownEvent = CreateEventW(NULL, TRUE, FALSE, NULL);
|
||||
if (hScmShutdownEvent == NULL)
|
||||
{
|
||||
DPRINT1("SERVICES: Failed to create shutdown event\n");
|
||||
@@ -385,7 +395,7 @@ wWinMain(HINSTANCE hInstance,
|
||||
/* Read the control set values */
|
||||
if (!ScmGetControlSetValues())
|
||||
{
|
||||
DPRINT1("SERVICES: failed to read the control set values\n");
|
||||
DPRINT1("SERVICES: Failed to read the control set values\n");
|
||||
goto done;
|
||||
}
|
||||
|
||||
@@ -393,50 +403,59 @@ wWinMain(HINSTANCE hInstance,
|
||||
dwError = ScmCreateServiceDatabase();
|
||||
if (dwError != ERROR_SUCCESS)
|
||||
{
|
||||
DPRINT1("SERVICES: failed to create SCM database (Error %lu)\n", dwError);
|
||||
DPRINT1("SERVICES: Failed to create SCM database (Error %lu)\n", dwError);
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* Wait for the LSA server */
|
||||
ScmWaitForLsa();
|
||||
|
||||
/* Update the services database */
|
||||
ScmGetBootAndSystemDriverState();
|
||||
|
||||
/* Register the Service Control Manager process with CSRSS */
|
||||
/* 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 service start lock until autostart services have been started */
|
||||
/*
|
||||
* 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 the service start lock (Error %lu)\n", dwError);
|
||||
DPRINT1("SERVICES: Failed to acquire the service start lock (Error %lu)\n", dwError);
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* Start the RPC server */
|
||||
ScmStartRpcServer();
|
||||
|
||||
DPRINT("SERVICES: Initialized.\n");
|
||||
|
||||
/* Signal start event */
|
||||
SetEvent(hScmStartEvent);
|
||||
|
||||
DPRINT("SERVICES: Initialized.\n");
|
||||
|
||||
/* Register event handler (used for system shutdown) */
|
||||
SetConsoleCtrlHandler(ShutdownHandlerRoutine, TRUE);
|
||||
|
||||
/* Wait for the LSA server */
|
||||
ScmWaitForLsa();
|
||||
|
||||
/* 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 */
|
||||
@@ -451,6 +470,10 @@ done:
|
||||
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);
|
||||
@@ -458,7 +481,6 @@ done:
|
||||
DPRINT("SERVICES: Finished.\n");
|
||||
|
||||
ExitThread(0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -86,6 +86,7 @@ typedef struct _START_LOCK
|
||||
extern LIST_ENTRY ServiceListHead;
|
||||
extern LIST_ENTRY GroupListHead;
|
||||
extern LIST_ENTRY ImageListHead;
|
||||
extern BOOL ScmInitialize;
|
||||
extern BOOL ScmShutdown;
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user