[SERVICES]
[reactos.git] / reactos / base / system / services / services.c
index 0c213d3..1245fd3 100644 (file)
@@ -8,10 +8,6 @@
  *
  */
 
-/* NOTE:
- * - Services.exe is NOT a native application, it is a GUI app.
- */
-
 /* INCLUDES *****************************************************************/
 
 #include "services.h"
@@ -27,6 +23,7 @@ int WINAPI RegisterServicesProcess(DWORD ServicesProcessId);
 #define PIPE_TIMEOUT 1000
 
 BOOL ScmShutdown = FALSE;
+static HANDLE hScmShutdownEvent = NULL;
 
 
 /* FUNCTIONS *****************************************************************/
@@ -84,17 +81,17 @@ ScmCreateStartEvent(PHANDLE StartEvent)
 {
     HANDLE hEvent;
 
-    hEvent = CreateEvent(NULL,
-                         TRUE,
-                         FALSE,
-                         TEXT("SvcctrlStartEvent_A3752DX"));
+    hEvent = CreateEventW(NULL,
+                          TRUE,
+                          FALSE,
+                          L"SvcctrlStartEvent_A3752DX");
     if (hEvent == NULL)
     {
         if (GetLastError() == ERROR_ALREADY_EXISTS)
         {
-            hEvent = OpenEvent(EVENT_ALL_ACCESS,
-                               FALSE,
-                               TEXT("SvcctrlStartEvent_A3752DX"));
+            hEvent = OpenEventW(EVENT_ALL_ACCESS,
+                                FALSE,
+                                L"SvcctrlStartEvent_A3752DX");
             if (hEvent == NULL)
             {
                 return FALSE;
@@ -112,8 +109,8 @@ ScmCreateStartEvent(PHANDLE StartEvent)
 }
 
 
-static VOID
-ScmWaitForLsass(VOID)
+VOID
+ScmWaitForLsa(VOID)
 {
     HANDLE hEvent;
     DWORD dwError;
@@ -125,7 +122,7 @@ ScmWaitForLsass(VOID)
     if (hEvent == NULL)
     {
         dwError = GetLastError();
-        DPRINT("Failed to create the notication event (Error %lu)\n", dwError);
+        DPRINT1("Failed to create the notication event (Error %lu)\n", dwError);
 
         if (dwError == ERROR_ALREADY_EXISTS)
         {
@@ -145,6 +142,8 @@ ScmWaitForLsass(VOID)
     DPRINT("LSA server running!\n");
 
     CloseHandle(hEvent);
+
+    DPRINT("ScmWaitForLsa() done\n");
 }
 
 
@@ -224,7 +223,7 @@ ScmCreateNamedPipe(VOID)
 
     DPRINT("ScmCreateNamedPipe() - CreateNamedPipe(\"\\\\.\\pipe\\Ntsvcs\")\n");
 
-    hPipe = CreateNamedPipe(TEXT("\\\\.\\pipe\\Ntsvcs"),
+    hPipe = CreateNamedPipeW(L"\\\\.\\pipe\\Ntsvcs",
               PIPE_ACCESS_DUPLEX,
               PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT,
               PIPE_UNLIMITED_INSTANCES,
@@ -260,6 +259,8 @@ ScmCreateNamedPipe(VOID)
             DPRINT("CreateNamedPipe() - returning FALSE\n");
             return FALSE;
         }
+
+        CloseHandle(hThread);
     }
     else
     {
@@ -316,29 +317,9 @@ StartScmNamedPipeThreadListener(VOID)
         return FALSE;
     }
 
-    return TRUE;
-}
-
-
-VOID FASTCALL
-AcquireLoadDriverPrivilege(VOID)
-{
-    HANDLE hToken;
-    TOKEN_PRIVILEGES tkp;
-
-    /* Get a token for this process */
-    if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))
-    {
-        /* Get the LUID for the debug privilege */
-        LookupPrivilegeValue(NULL, SE_LOAD_DRIVER_NAME, &tkp.Privileges[0].Luid);
-
-        /* One privilege to set */
-        tkp.PrivilegeCount = 1;
-        tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
+    CloseHandle(hThread);
 
-        /* Get the debug privilege for this process */
-        AdjustTokenPrivileges(hToken, FALSE, &tkp, 0, (PTOKEN_PRIVILEGES)NULL, 0);
-    }
+    return TRUE;
 }
 
 
@@ -354,6 +335,9 @@ ShutdownHandlerRoutine(DWORD dwCtrlType)
 
         ScmAutoShutdownServices();
         ScmShutdownServiceDatabase();
+
+        /* Set the shutdwon event */
+        SetEvent(hScmShutdownEvent);
     }
 
     return TRUE;
@@ -366,8 +350,9 @@ wWinMain(HINSTANCE hInstance,
          LPWSTR lpCmdLine,
          int nShowCmd)
 {
-    HANDLE hScmStartEvent;
-    HANDLE hEvent;
+    HANDLE hScmStartEvent = NULL;
+    SC_RPC_LOCK Lock = NULL;
+    BOOL bCanDeleteNamedPipeCriticalSection = FALSE;
     DWORD dwError;
 
     DPRINT("SERVICES: Service Control Manager\n");
@@ -376,33 +361,63 @@ wWinMain(HINSTANCE hInstance,
     if (!ScmCreateStartEvent(&hScmStartEvent))
     {
         DPRINT1("SERVICES: Failed to create start event\n");
-        ExitThread(0);
+        goto done;
+    }
+
+    DPRINT("SERVICES: created start event with handle %p.\n", hScmStartEvent);
+
+    /* Create the shutdown event */
+    hScmShutdownEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
+    if (hScmShutdownEvent == NULL)
+    {
+        DPRINT1("SERVICES: Failed to create shutdown event\n");
+        goto done;
     }
 
-    DPRINT("SERVICES: created start event with handle %x.\n", hScmStartEvent);
+    /* Initialize our communication named pipe's critical section */
+    ScmInitNamedPipeCriticalSection();
+    bCanDeleteNamedPipeCriticalSection = TRUE;
 
 //    ScmInitThreadManager();
 
     /* FIXME: more initialization */
 
+    /* Read the control set values */
+    if (!ScmGetControlSetValues())
+    {
+        DPRINT1("SERVICES: failed to read the control set values\n");
+        goto done;
+    }
 
-    /* Create the service database */
+    /* Create the services database */
     dwError = ScmCreateServiceDatabase();
     if (dwError != ERROR_SUCCESS)
     {
         DPRINT1("SERVICES: failed to create SCM database (Error %lu)\n", dwError);
-        ExitThread(0);
+        goto done;
     }
 
-    /* Update service database */
+    /* Update the services database */
     ScmGetBootAndSystemDriverState();
 
+    /* Register the Service Control Manager process with CSRSS */
+    if (!RegisterServicesProcess(GetCurrentProcessId()))
+    {
+        DPRINT1("SERVICES: Could not register SCM process\n");
+        goto done;
+    }
+
+    /* Acquire the service start lock until autostart 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);
+        goto done;
+    }
+
     /* Start the RPC server */
     ScmStartRpcServer();
 
-    /* Register service process with CSRSS */
-    RegisterServicesProcess(GetCurrentProcessId());
-
     DPRINT("SERVICES: Initialized.\n");
 
     /* Signal start event */
@@ -412,35 +427,33 @@ wWinMain(HINSTANCE hInstance,
     SetConsoleCtrlHandler(ShutdownHandlerRoutine, TRUE);
 
     /* Wait for the LSA server */
-    ScmWaitForLsass();
-
-    /* Acquire privileges to load drivers */
-    AcquireLoadDriverPrivilege();
-
-    ScmInitNamedPipeCriticalSection();
+    ScmWaitForLsa();
 
     /* Start auto-start services */
     ScmAutoStartServices();
 
     /* FIXME: more to do ? */
 
+    /* Release the service start lock */
+    ScmReleaseServiceStartLock(&Lock);
 
     DPRINT("SERVICES: Running.\n");
 
-#if 1
-    hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
-    if (hEvent)
-        WaitForSingleObject(hEvent, INFINITE);
-#else
-    for (;;)
-    {
-        NtYieldExecution();
-    }
-#endif
+    /* Wait until the shutdown event gets signaled */
+    WaitForSingleObject(hScmShutdownEvent, INFINITE);
+
+done:
+    /* Delete our communication named pipe's critical section */
+    if (bCanDeleteNamedPipeCriticalSection == TRUE)
+        ScmDeleteNamedPipeCriticalSection();
 
-    ScmDeleteNamedPipeCriticalSection();
+    /* Close the shutdown event */
+    if (hScmShutdownEvent != NULL)
+        CloseHandle(hScmShutdownEvent);
 
-    CloseHandle(hScmStartEvent);
+    /* Close the start event */
+    if (hScmStartEvent != NULL)
+        CloseHandle(hScmStartEvent);
 
     DPRINT("SERVICES: Finished.\n");