[SERVICES][ADVAPI32] Support the security process aka lsass.exe
[reactos.git] / dll / win32 / advapi32 / service / sctrl.c
index f0de114..c0cf0f4 100644 (file)
@@ -12,7 +12,7 @@
 /* INCLUDES ******************************************************************/
 
 #include <advapi32.h>
-WINE_DEFAULT_DEBUG_CHANNEL(advapi_service);
+WINE_DEFAULT_DEBUG_CHANNEL(advapi);
 
 
 /* TYPES *********************************************************************/
@@ -22,6 +22,7 @@ typedef struct _SERVICE_THREAD_PARAMSA
     LPSERVICE_MAIN_FUNCTIONA lpServiceMain;
     DWORD dwArgCount;
     LPSTR *lpArgVector;
+    DWORD dwServiceTag;
 } SERVICE_THREAD_PARAMSA, *PSERVICE_THREAD_PARAMSA;
 
 
@@ -30,6 +31,7 @@ typedef struct _SERVICE_THREAD_PARAMSW
     LPSERVICE_MAIN_FUNCTIONW lpServiceMain;
     DWORD dwArgCount;
     LPWSTR *lpArgVector;
+    DWORD dwServiceTag;
 } SERVICE_THREAD_PARAMSW, *PSERVICE_THREAD_PARAMSW;
 
 
@@ -47,6 +49,7 @@ typedef struct _ACTIVE_SERVICE
     LPVOID HandlerContext;
     BOOL bUnicode;
     BOOL bOwnProcess;
+    DWORD dwServiceTag;
 } ACTIVE_SERVICE, *PACTIVE_SERVICE;
 
 
@@ -55,6 +58,7 @@ typedef struct _ACTIVE_SERVICE
 static DWORD dwActiveServiceCount = 0;
 static PACTIVE_SERVICE lpActiveServices = NULL;
 static handle_t hStatusBinding = NULL;
+static BOOL bSecurityServiceProcess = FALSE;
 
 
 /* FUNCTIONS *****************************************************************/
@@ -79,7 +83,7 @@ ScCreateStatusBinding(VOID)
     LPWSTR pszStringBinding;
     RPC_STATUS status;
 
-    TRACE("ScCreateStatusBinding() called\n");
+    TRACE("ScCreateStatusBinding()\n");
 
     status = RpcStringBindingComposeW(NULL,
                                       L"ncacn_np",
@@ -116,7 +120,7 @@ ScDestroyStatusBinding(VOID)
 {
     RPC_STATUS status;
 
-    TRACE("ScDestroyStatusBinding() called\n");
+    TRACE("ScDestroyStatusBinding()\n");
 
     if (hStatusBinding == NULL)
         return RPC_S_OK;
@@ -135,19 +139,16 @@ ScDestroyStatusBinding(VOID)
 }
 
 
-static DWORD
-ScLookupServiceByServiceName(IN LPCWSTR lpServiceName,
-                             OUT PACTIVE_SERVICE* pService)
+static PACTIVE_SERVICE
+ScLookupServiceByServiceName(LPCWSTR lpServiceName)
 {
     DWORD i;
 
-    TRACE("ScLookupServiceByServiceName(%S) called\n", lpServiceName);
+    TRACE("ScLookupServiceByServiceName(%S)\n",
+          lpServiceName);
 
     if (lpActiveServices[0].bOwnProcess)
-    {
-        *pService = &lpActiveServices[0];
-        return ERROR_SUCCESS;
-    }
+        return &lpActiveServices[0];
 
     for (i = 0; i < dwActiveServiceCount; i++)
     {
@@ -155,28 +156,34 @@ ScLookupServiceByServiceName(IN LPCWSTR lpServiceName,
         if (_wcsicmp(lpActiveServices[i].ServiceName.Buffer, lpServiceName) == 0)
         {
             TRACE("Found!\n");
-            *pService = &lpActiveServices[i];
-            return ERROR_SUCCESS;
+            return &lpActiveServices[i];
         }
     }
 
     TRACE("No service found!\n");
-    *pService = NULL;
-    return ERROR_SERVICE_NOT_IN_EXE;
+    return NULL;
 }
 
 
 static DWORD WINAPI
 ScServiceMainStubA(LPVOID Context)
 {
+    PTEB Teb;
     PSERVICE_THREAD_PARAMSA ThreadParams = Context;
 
-    TRACE("ScServiceMainStubA() called\n");
+    TRACE("ScServiceMainStubA(%p)\n", Context);
+
+    /* Set service tag */
+    Teb = NtCurrentTeb();
+    Teb->SubProcessTag = UlongToPtr(ThreadParams->dwServiceTag);
 
     /* Call the main service routine and free the arguments vector */
     (ThreadParams->lpServiceMain)(ThreadParams->dwArgCount,
                                   ThreadParams->lpArgVector);
 
+    /* Reset service tag */
+    Teb->SubProcessTag = 0;
+
     if (ThreadParams->lpArgVector != NULL)
     {
         HeapFree(GetProcessHeap(), 0, ThreadParams->lpArgVector);
@@ -190,14 +197,22 @@ ScServiceMainStubA(LPVOID Context)
 static DWORD WINAPI
 ScServiceMainStubW(LPVOID Context)
 {
+    PTEB Teb;
     PSERVICE_THREAD_PARAMSW ThreadParams = Context;
 
-    TRACE("ScServiceMainStubW() called\n");
+    TRACE("ScServiceMainStubW(%p)\n", Context);
+
+    /* Set service tag */
+    Teb = NtCurrentTeb();
+    Teb->SubProcessTag = UlongToPtr(ThreadParams->dwServiceTag);
 
     /* Call the main service routine and free the arguments vector */
     (ThreadParams->lpServiceMain)(ThreadParams->dwArgCount,
                                   ThreadParams->lpArgVector);
 
+    /* Reset service tag */
+    Teb->SubProcessTag = 0;
+
     if (ThreadParams->lpArgVector != NULL)
     {
         HeapFree(GetProcessHeap(), 0, ThreadParams->lpArgVector);
@@ -213,32 +228,42 @@ ScConnectControlPipe(HANDLE *hPipe)
 {
     DWORD dwBytesWritten;
     DWORD dwState;
-    DWORD dwServiceCurrent = 0;
+    DWORD dwServiceCurrent = 1;
     NTSTATUS Status;
     WCHAR NtControlPipeName[MAX_PATH + 1];
     RTL_QUERY_REGISTRY_TABLE QueryTable[2];
     DWORD dwProcessId;
 
+    TRACE("ScConnectControlPipe(%p)\n",
+          hPipe);
+
     /* Get the service number and create the named pipe */
-    RtlZeroMemory(&QueryTable,
-                  sizeof(QueryTable));
-
-    QueryTable[0].Name = L"";
-    QueryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_REQUIRED;
-    QueryTable[0].EntryContext = &dwServiceCurrent;
-
-    Status = RtlQueryRegistryValues(RTL_REGISTRY_CONTROL,
-                                    L"ServiceCurrent",
-                                    QueryTable,
-                                    NULL,
-                                    NULL);
-    if (!NT_SUCCESS(Status))
+    if (bSecurityServiceProcess == FALSE)
+    {
+        RtlZeroMemory(&QueryTable, sizeof(QueryTable));
+
+        QueryTable[0].Name = L"";
+        QueryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_REQUIRED;
+        QueryTable[0].EntryContext = &dwServiceCurrent;
+
+        Status = RtlQueryRegistryValues(RTL_REGISTRY_CONTROL,
+                                        L"ServiceCurrent",
+                                        QueryTable,
+                                        NULL,
+                                        NULL);
+        if (!NT_SUCCESS(Status))
+        {
+            ERR("RtlQueryRegistryValues() failed (Status %lx)\n", Status);
+            return RtlNtStatusToDosError(Status);
+        }
+    }
+    else
     {
-        ERR("RtlQueryRegistryValues() failed (Status %lx)\n", Status);
-        return RtlNtStatusToDosError(Status);
+        dwServiceCurrent = 0;
     }
 
     swprintf(NtControlPipeName, L"\\\\.\\pipe\\net\\NtControlPipe%u", dwServiceCurrent);
+    TRACE("PipeName: %S\n", NtControlPipeName);
 
     if (!WaitNamedPipeW(NtControlPipeName, 30000))
     {
@@ -431,15 +456,19 @@ ScStartService(PACTIVE_SERVICE lpService,
     PSERVICE_THREAD_PARAMSA ThreadParamsA;
     PSERVICE_THREAD_PARAMSW ThreadParamsW;
 
+    TRACE("ScStartService(%p %p)\n",
+          lpService, ControlPacket);
+
     if (lpService == NULL || ControlPacket == NULL)
         return ERROR_INVALID_PARAMETER;
 
-    TRACE("ScStartService(Size: %lu, Service: '%S') called\n",
-          ControlPacket->dwSize,
-          (PWSTR)((ULONG_PTR)ControlPacket + ControlPacket->dwServiceNameOffset));
+    TRACE("Size: %lu\n", ControlPacket->dwSize);
+    TRACE("Service: %S\n", (PWSTR)((ULONG_PTR)ControlPacket + ControlPacket->dwServiceNameOffset));
 
     /* Set the service status handle */
     lpService->hServiceStatus = ControlPacket->hServiceStatus;
+    /* Set the service tag */
+    lpService->dwServiceTag = ControlPacket->dwServiceTag;
 
     /* Build the arguments vector */
     if (lpService->bUnicode != FALSE)
@@ -456,6 +485,7 @@ ScStartService(PACTIVE_SERVICE lpService,
             return dwError;
         }
         ThreadParamsW->lpServiceMain = lpService->ServiceMain.W;
+        ThreadParamsW->dwServiceTag = ControlPacket->dwServiceTag;
         ThreadHandle = CreateThread(NULL,
                                     0,
                                     ScServiceMainStubW,
@@ -489,6 +519,7 @@ ScStartService(PACTIVE_SERVICE lpService,
             return dwError;
         }
         ThreadParamsA->lpServiceMain = lpService->ServiceMain.A;
+        ThreadParamsA->dwServiceTag = ControlPacket->dwServiceTag;
         ThreadHandle = CreateThread(NULL,
                                     0,
                                     ScServiceMainStubA,
@@ -517,29 +548,56 @@ static DWORD
 ScControlService(PACTIVE_SERVICE lpService,
                  PSCM_CONTROL_PACKET ControlPacket)
 {
-    DWORD dwError;
+    DWORD dwError = ERROR_SUCCESS;
+
+    TRACE("ScControlService(%p %p)\n",
+          lpService, ControlPacket);
 
     if (lpService == NULL || ControlPacket == NULL)
         return ERROR_INVALID_PARAMETER;
 
-    TRACE("ScControlService(Size: %lu, Service: '%S') called\n",
-          ControlPacket->dwSize,
-          (PWSTR)((ULONG_PTR)ControlPacket + ControlPacket->dwServiceNameOffset));
+    TRACE("Size: %lu\n", ControlPacket->dwSize);
+    TRACE("Service: %S\n", (PWSTR)((ULONG_PTR)ControlPacket + ControlPacket->dwServiceNameOffset));
+
+    /* Set service tag */
+    NtCurrentTeb()->SubProcessTag = UlongToPtr(lpService->dwServiceTag);
 
     if (lpService->HandlerFunction)
     {
-        (lpService->HandlerFunction)(ControlPacket->dwControl);
-        dwError = ERROR_SUCCESS;
+        _SEH2_TRY
+        {
+            (lpService->HandlerFunction)(ControlPacket->dwControl);
+        }
+        _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+        {
+            dwError = ERROR_EXCEPTION_IN_SERVICE;
+        }
+        _SEH2_END;
     }
     else if (lpService->HandlerFunctionEx)
     {
-        /* FIXME: Send correct 2nd and 3rd parameters */
-        dwError = (lpService->HandlerFunctionEx)(ControlPacket->dwControl,
-                                                 0, NULL,
-                                                 lpService->HandlerContext);
+        _SEH2_TRY
+        {
+            /* FIXME: Send correct 2nd and 3rd parameters */
+            (lpService->HandlerFunctionEx)(ControlPacket->dwControl,
+                                           0, NULL,
+                                           lpService->HandlerContext);
+        }
+        _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+        {
+            dwError = ERROR_EXCEPTION_IN_SERVICE;
+        }
+        _SEH2_END;
+    }
+    else
+    {
+        dwError = ERROR_SERVICE_CANNOT_ACCEPT_CTRL;
     }
 
-    TRACE("ScControlService() done (error %lu)\n", dwError);
+    /* Reset service tag */
+    NtCurrentTeb()->SubProcessTag = 0;
+
+    TRACE("ScControlService() done (Error %lu)\n", dwError);
 
     return dwError;
 }
@@ -558,7 +616,8 @@ ScServiceDispatcher(HANDLE hPipe,
     SCM_REPLY_PACKET ReplyPacket;
     DWORD dwError;
 
-    TRACE("ScDispatcherLoop() called\n");
+    TRACE("ScServiceDispatcher(%p %p %lu)\n",
+          hPipe, ControlPacket, dwBufferSize);
 
     if (ControlPacket == NULL || dwBufferSize < sizeof(SCM_CONTROL_PACKET))
         return FALSE;
@@ -580,9 +639,10 @@ ScServiceDispatcher(HANDLE hPipe,
         lpServiceName = (LPWSTR)((PBYTE)ControlPacket + ControlPacket->dwServiceNameOffset);
         TRACE("Service: %S\n", lpServiceName);
 
-        if (lpServiceName[0] == UNICODE_NULL)
+        if ((ControlPacket->dwControl == SERVICE_CONTROL_STOP) &&
+            (lpServiceName[0] == UNICODE_NULL))
         {
-            ERR("Stop dispatcher thread\n");
+            TRACE("Stop dispatcher thread\n");
             bRunning = FALSE;
             dwError = ERROR_SUCCESS;
         }
@@ -591,8 +651,8 @@ ScServiceDispatcher(HANDLE hPipe,
             if (ControlPacket->dwControl == SERVICE_CONTROL_START_OWN)
                 lpActiveServices[0].bOwnProcess = TRUE;
 
-            dwError = ScLookupServiceByServiceName(lpServiceName, &lpService);
-            if ((dwError == ERROR_SUCCESS) && (lpService != NULL))
+            lpService = ScLookupServiceByServiceName(lpServiceName);
+            if (lpService != NULL)
             {
                 /* Execute command */
                 switch (ControlPacket->dwControl)
@@ -614,6 +674,10 @@ ScServiceDispatcher(HANDLE hPipe,
                         break;
                 }
             }
+            else
+            {
+                dwError = ERROR_SERVICE_NOT_IN_EXE;
+            }
         }
 
         ReplyPacket.dwError = dwError;
@@ -648,6 +712,9 @@ RegisterServiceCtrlHandlerA(LPCSTR lpServiceName,
     UNICODE_STRING ServiceNameU;
     SERVICE_STATUS_HANDLE hServiceStatus;
 
+    TRACE("RegisterServiceCtrlHandlerA(%s %p)\n",
+          debugstr_a(lpServiceName), lpHandlerProc);
+
     RtlInitAnsiString(&ServiceNameA, lpServiceName);
     if (!NT_SUCCESS(RtlAnsiStringToUnicodeString(&ServiceNameU, &ServiceNameA, TRUE)))
     {
@@ -673,13 +740,15 @@ SERVICE_STATUS_HANDLE WINAPI
 RegisterServiceCtrlHandlerW(LPCWSTR lpServiceName,
                             LPHANDLER_FUNCTION lpHandlerProc)
 {
-    DWORD dwError;
     PACTIVE_SERVICE Service;
 
-    dwError = ScLookupServiceByServiceName(lpServiceName, &Service);
-    if ((dwError != ERROR_SUCCESS) || (Service == NULL))
+    TRACE("RegisterServiceCtrlHandlerW(%s %p)\n",
+          debugstr_w(lpServiceName), lpHandlerProc);
+
+    Service = ScLookupServiceByServiceName(lpServiceName);
+    if (Service == NULL)
     {
-        SetLastError(dwError);
+        SetLastError(ERROR_SERVICE_NOT_IN_EXE);
         return NULL;
     }
 
@@ -689,10 +758,10 @@ RegisterServiceCtrlHandlerW(LPCWSTR lpServiceName,
         return NULL;
     }
 
-    Service->HandlerFunction   = lpHandlerProc;
+    Service->HandlerFunction = lpHandlerProc;
     Service->HandlerFunctionEx = NULL;
 
-    TRACE("RegisterServiceCtrlHandler returning 0x%p\n", Service->hServiceStatus);
+    TRACE("RegisterServiceCtrlHandler returning %p\n", Service->hServiceStatus);
 
     return Service->hServiceStatus;
 }
@@ -712,6 +781,9 @@ RegisterServiceCtrlHandlerExA(LPCSTR lpServiceName,
     UNICODE_STRING ServiceNameU;
     SERVICE_STATUS_HANDLE hServiceStatus;
 
+    TRACE("RegisterServiceCtrlHandlerExA(%s %p %p)\n",
+          debugstr_a(lpServiceName), lpHandlerProc, lpContext);
+
     RtlInitAnsiString(&ServiceNameA, lpServiceName);
     if (!NT_SUCCESS(RtlAnsiStringToUnicodeString(&ServiceNameU, &ServiceNameA, TRUE)))
     {
@@ -739,13 +811,15 @@ RegisterServiceCtrlHandlerExW(LPCWSTR lpServiceName,
                               LPHANDLER_FUNCTION_EX lpHandlerProc,
                               LPVOID lpContext)
 {
-    DWORD dwError;
     PACTIVE_SERVICE Service;
 
-    dwError = ScLookupServiceByServiceName(lpServiceName, &Service);
-    if ((dwError != ERROR_SUCCESS) || (Service == NULL))
+    TRACE("RegisterServiceCtrlHandlerExW(%s %p %p)\n",
+          debugstr_w(lpServiceName), lpHandlerProc, lpContext);
+
+    Service = ScLookupServiceByServiceName(lpServiceName);
+    if (Service == NULL)
     {
-        SetLastError(dwError);
+        SetLastError(ERROR_SERVICE_NOT_IN_EXE);
         return NULL;
     }
 
@@ -755,11 +829,11 @@ RegisterServiceCtrlHandlerExW(LPCWSTR lpServiceName,
         return NULL;
     }
 
-    Service->HandlerFunction   = NULL;
+    Service->HandlerFunction = NULL;
     Service->HandlerFunctionEx = lpHandlerProc;
-    Service->HandlerContext    = lpContext;
+    Service->HandlerContext = lpContext;
 
-    TRACE("RegisterServiceCtrlHandlerEx returning 0x%p\n", Service->hServiceStatus);
+    TRACE("RegisterServiceCtrlHandlerEx returning %p\n", Service->hServiceStatus);
 
     return Service->hServiceStatus;
 }
@@ -770,12 +844,14 @@ RegisterServiceCtrlHandlerExW(LPCWSTR lpServiceName,
  *
  * Undocumented
  *
- * @unimplemented
+ * @implemented
  */
 VOID
 WINAPI
 I_ScIsSecurityProcess(VOID)
 {
+    TRACE("I_ScIsSecurityProcess()\n");
+    bSecurityServiceProcess = TRUE;
 }
 
 
@@ -794,6 +870,9 @@ I_ScPnPGetServiceName(IN SERVICE_STATUS_HANDLE hServiceStatus,
 {
     DWORD i;
 
+    TRACE("I_ScPnPGetServiceName(%lu %p %lu)\n",
+          hServiceStatus, lpServiceName, cchServiceName);
+
     for (i = 0; i < dwActiveServiceCount; i++)
     {
         if (lpActiveServices[i].hServiceStatus == hServiceStatus)
@@ -823,6 +902,10 @@ I_ScSetServiceBitsA(SERVICE_STATUS_HANDLE hServiceStatus,
 {
     BOOL bResult;
 
+    TRACE("I_ScSetServiceBitsA(%lu %lx %u %u %s)\n",
+          hServiceStatus, dwServiceBits, bSetBitsOn, bUpdateImmediately,
+          debugstr_a(lpString));
+
     RpcTryExcept
     {
         bResult = RI_ScSetServiceBitsA((RPC_SERVICE_STATUS_HANDLE)hServiceStatus,
@@ -858,6 +941,10 @@ I_ScSetServiceBitsW(SERVICE_STATUS_HANDLE hServiceStatus,
 {
     BOOL bResult;
 
+    TRACE("I_ScSetServiceBitsW(%lu %lx %u %u %s)\n",
+          hServiceStatus, dwServiceBits, bSetBitsOn, bUpdateImmediately,
+          debugstr_w(lpString));
+
     RpcTryExcept
     {
         bResult = RI_ScSetServiceBitsW((RPC_SERVICE_STATUS_HANDLE)hServiceStatus,
@@ -888,6 +975,9 @@ SetServiceBits(SERVICE_STATUS_HANDLE hServiceStatus,
                BOOL bSetBitsOn,
                BOOL bUpdateImmediately)
 {
+    TRACE("SetServiceBits(%lu %lx %u %u)\n",
+          hServiceStatus, dwServiceBits, bSetBitsOn, bUpdateImmediately);
+
     return I_ScSetServiceBitsW(hServiceStatus,
                                dwServiceBits,
                                bSetBitsOn,
@@ -907,7 +997,8 @@ SetServiceStatus(SERVICE_STATUS_HANDLE hServiceStatus,
 {
     DWORD dwError;
 
-    TRACE("SetServiceStatus(hServiceStatus %lu) called\n", hServiceStatus);
+    TRACE("SetServiceStatus(%lu %p)\n",
+          hServiceStatus, lpServiceStatus);
 
     RpcTryExcept
     {
@@ -927,7 +1018,7 @@ SetServiceStatus(SERVICE_STATUS_HANDLE hServiceStatus,
         return FALSE;
     }
 
-    TRACE("SetServiceStatus() done (ret %lu)\n", dwError);
+    TRACE("SetServiceStatus() done\n");
 
     return TRUE;
 }
@@ -948,7 +1039,8 @@ StartServiceCtrlDispatcherA(const SERVICE_TABLE_ENTRYA *lpServiceStartTable)
     DWORD dwBufSize;
     BOOL bRet = TRUE;
 
-    TRACE("StartServiceCtrlDispatcherA() called\n");
+    TRACE("StartServiceCtrlDispatcherA(%p)\n",
+          lpServiceStartTable);
 
     i = 0;
     while (lpServiceStartTable[i].lpServiceProc != NULL)
@@ -958,7 +1050,7 @@ StartServiceCtrlDispatcherA(const SERVICE_TABLE_ENTRYA *lpServiceStartTable)
 
     dwActiveServiceCount = i;
 
-    /* Initialize the service table */
+    /* Allocate the service table */
     lpActiveServices = RtlAllocateHeap(RtlGetProcessHeap(),
                                        HEAP_ZERO_MEMORY,
                                        dwActiveServiceCount * sizeof(ACTIVE_SERVICE));
@@ -979,13 +1071,12 @@ StartServiceCtrlDispatcherA(const SERVICE_TABLE_ENTRYA *lpServiceStartTable)
         lpActiveServices[i].bOwnProcess = FALSE;
     }
 
-    /* Initialize the connection to the SCM */
-
+    /* Connect to the SCM */
     dwError = ScConnectControlPipe(&hPipe);
     if (dwError != ERROR_SUCCESS)
     {
         bRet = FALSE;
-        goto Done;
+        goto done;
     }
 
     dwBufSize = sizeof(SCM_CONTROL_PACKET) +
@@ -998,22 +1089,24 @@ StartServiceCtrlDispatcherA(const SERVICE_TABLE_ENTRYA *lpServiceStartTable)
     {
         dwError = ERROR_NOT_ENOUGH_MEMORY;
         bRet = FALSE;
-        goto Done;
+        goto done;
     }
 
     ScCreateStatusBinding();
 
-    /* Start the dispatcher loop */
+    /* Call the dispatcher loop */
     ScServiceDispatcher(hPipe, ControlPacket, dwBufSize);
 
-    /* Close the connection */
+
     ScDestroyStatusBinding();
+
+    /* Close the connection */
     CloseHandle(hPipe);
 
     /* Free the control packet */
     RtlFreeHeap(RtlGetProcessHeap(), 0, ControlPacket);
 
-Done:
+done:
     /* Free the service table */
     for (i = 0; i < dwActiveServiceCount; i++)
     {
@@ -1023,7 +1116,8 @@ Done:
     lpActiveServices = NULL;
     dwActiveServiceCount = 0;
 
-    if (!bRet) SetLastError(dwError);
+    if (!bRet)
+        SetLastError(dwError);
 
     return bRet;
 }
@@ -1044,7 +1138,8 @@ StartServiceCtrlDispatcherW(const SERVICE_TABLE_ENTRYW *lpServiceStartTable)
     DWORD dwBufSize;
     BOOL bRet = TRUE;
 
-    TRACE("StartServiceCtrlDispatcherW() called\n");
+    TRACE("StartServiceCtrlDispatcherW(%p)\n",
+          lpServiceStartTable);
 
     i = 0;
     while (lpServiceStartTable[i].lpServiceProc != NULL)
@@ -1054,7 +1149,7 @@ StartServiceCtrlDispatcherW(const SERVICE_TABLE_ENTRYW *lpServiceStartTable)
 
     dwActiveServiceCount = i;
 
-    /* Initialize the service table */
+    /* Allocate the service table */
     lpActiveServices = RtlAllocateHeap(RtlGetProcessHeap(),
                                        HEAP_ZERO_MEMORY,
                                        dwActiveServiceCount * sizeof(ACTIVE_SERVICE));
@@ -1075,13 +1170,12 @@ StartServiceCtrlDispatcherW(const SERVICE_TABLE_ENTRYW *lpServiceStartTable)
         lpActiveServices[i].bOwnProcess = FALSE;
     }
 
-    /* Initialize the connection to the SCM */
-
+    /* Connect to the SCM */
     dwError = ScConnectControlPipe(&hPipe);
     if (dwError != ERROR_SUCCESS)
     {
         bRet = FALSE;
-        goto Done;
+        goto done;
     }
 
     dwBufSize = sizeof(SCM_CONTROL_PACKET) +
@@ -1094,22 +1188,23 @@ StartServiceCtrlDispatcherW(const SERVICE_TABLE_ENTRYW *lpServiceStartTable)
     {
         dwError = ERROR_NOT_ENOUGH_MEMORY;
         bRet = FALSE;
-        goto Done;
+        goto done;
     }
 
     ScCreateStatusBinding();
 
-    /* Start the dispatcher loop */
+    /* Call the dispatcher loop */
     ScServiceDispatcher(hPipe, ControlPacket, dwBufSize);
 
-    /* Close the connection */
     ScDestroyStatusBinding();
+
+    /* Close the connection */
     CloseHandle(hPipe);
 
     /* Free the control packet */
     RtlFreeHeap(RtlGetProcessHeap(), 0, ControlPacket);
 
-Done:
+done:
     /* Free the service table */
     for (i = 0; i < dwActiveServiceCount; i++)
     {
@@ -1119,7 +1214,8 @@ Done:
     lpActiveServices = NULL;
     dwActiveServiceCount = 0;
 
-    if (!bRet) SetLastError(dwError);
+    if (!bRet)
+        SetLastError(dwError);
 
     return bRet;
 }