[SERVICES]
[reactos.git] / reactos / base / system / services / database.c
index c0b5f7a..476c627 100644 (file)
 
 #include "services.h"
 
+#include <winuser.h>
+
 #define NDEBUG
 #include <debug.h>
 
 /*
  * 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
  * on the service control pipes.
  */
-// #define USE_ASYNCHRONOUS_IO
+#define USE_ASYNCHRONOUS_IO
 
 
 /* GLOBALS *******************************************************************/
@@ -36,10 +38,11 @@ LIST_ENTRY ImageListHead;
 LIST_ENTRY ServiceListHead;
 
 static RTL_RESOURCE DatabaseLock;
-static DWORD dwResumeCount = 1;
+static DWORD ResumeCount = 1;
 
+/* The critical section synchronizes service control requests */
 static CRITICAL_SECTION ControlServiceCriticalSection;
-static DWORD dwPipeTimeout = 30000; /* 30 Seconds */
+static DWORD PipeTimeout = 30000; /* 30 Seconds */
 
 
 /* FUNCTIONS *****************************************************************/
@@ -96,7 +99,7 @@ ScmCreateNewControlPipe(PSERVICE_IMAGE pServiceImage)
     }
 
     /* Create '\\.\pipe\net\NtControlPipeXXX' instance */
-    swprintf(szControlPipeName, L"\\\\.\\pipe\\net\\NtControlPipe%u", ServiceCurrent);
+    swprintf(szControlPipeName, L"\\\\.\\pipe\\net\\NtControlPipe%lu", ServiceCurrent);
 
     DPRINT("PipeName: %S\n", szControlPipeName);
 
@@ -110,7 +113,7 @@ ScmCreateNewControlPipe(PSERVICE_IMAGE pServiceImage)
                                                    100,
                                                    8000,
                                                    4,
-                                                   dwPipeTimeout,
+                                                   PipeTimeout,
                                                    NULL);
     DPRINT("CreateNamedPipeW(%S) done\n", szControlPipeName);
     if (pServiceImage->hControlPipe == INVALID_HANDLE_VALUE)
@@ -359,7 +362,7 @@ ScmGetServiceEntryByResumeCount(DWORD dwResumeCount)
 
 DWORD
 ScmCreateNewServiceRecord(LPCWSTR lpServiceName,
-                          PSERVICE *lpServiceRecord)
+                          PSERVICElpServiceRecord)
 {
     PSERVICE lpService = NULL;
 
@@ -380,7 +383,7 @@ ScmCreateNewServiceRecord(LPCWSTR lpServiceName,
     lpService->lpDisplayName = lpService->lpServiceName;
 
     /* Set the resume count */
-    lpService->dwResumeCount = dwResumeCount++;
+    lpService->dwResumeCount = ResumeCount++;
 
     /* Append service record */
     InsertTailList(&ServiceListHead,
@@ -591,7 +594,7 @@ ScmDeleteRegKey(HKEY hKey, LPCWSTR lpszSubKey)
             if (dwMaxSubkeyLen > sizeof(szNameBuf) / sizeof(WCHAR))
             {
                 /* Name too big: alloc a buffer for it */
-                lpszName = HeapAlloc(GetProcessHeap(), 0, dwMaxSubkeyLen * sizeof(WCHAR));
+                lpszName = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwMaxSubkeyLen * sizeof(WCHAR));
             }
 
             if (!lpszName)
@@ -772,13 +775,12 @@ 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");
+        ASSERT(Service->Status.dwServiceType == SERVICE_FILE_SYSTEM_DRIVER);
+        RtlInitUnicodeString(&DirName, L"\\FileSystem");
     }
 
     InitializeObjectAttributes(&ObjectAttributes,
@@ -796,7 +798,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);
@@ -893,16 +895,17 @@ ScmControlService(PSERVICE Service,
     DWORD dwError = ERROR_SUCCESS;
     BOOL bResult;
 #ifdef USE_ASYNCHRONOUS_IO
-    OVERLAPPED Overlapped = {0, 0, 0, 0, 0};
+    OVERLAPPED Overlapped = {0};
 #endif
 
     DPRINT("ScmControlService() called\n");
 
+    /* Acquire the service control critical section, to synchronize requests */
     EnterCriticalSection(&ControlServiceCriticalSection);
 
     /* Calculate the total length of the start command line */
     PacketSize = sizeof(SCM_CONTROL_PACKET);
-    PacketSize += (wcslen(Service->lpServiceName) + 1) * sizeof(WCHAR);
+    PacketSize += (DWORD)((wcslen(Service->lpServiceName) + 1) * sizeof(WCHAR));
 
     ControlPacket = HeapAlloc(GetProcessHeap(),
                               HEAP_ZERO_MEMORY,
@@ -933,16 +936,16 @@ ScmControlService(PSERVICE Service,
                         &Overlapped);
     if (bResult == FALSE)
     {
-        DPRINT1("WriteFile() returned FALSE\n");
+        DPRINT("WriteFile() returned FALSE\n");
 
         dwError = GetLastError();
         if (dwError == ERROR_IO_PENDING)
         {
-            DPRINT1("dwError: ERROR_IO_PENDING\n");
+            DPRINT("dwError: ERROR_IO_PENDING\n");
 
             dwError = WaitForSingleObject(Service->lpImage->hControlPipe,
-                                          dwPipeTimeout);
-            DPRINT1("WaitForSingleObject() returned %lu\n", dwError);
+                                          PipeTimeout);
+            DPRINT("WaitForSingleObject() returned %lu\n", dwError);
 
             if (dwError == WAIT_TIMEOUT)
             {
@@ -955,7 +958,7 @@ ScmControlService(PSERVICE Service,
                 dwError = ERROR_SERVICE_REQUEST_TIMEOUT;
                 goto Done;
             }
-            else if (dwError == ERROR_SUCCESS)
+            else if (dwError == WAIT_OBJECT_0)
             {
                 bResult = GetOverlappedResult(Service->lpImage->hControlPipe,
                                               &Overlapped,
@@ -987,16 +990,16 @@ ScmControlService(PSERVICE Service,
                        &Overlapped);
     if (bResult == FALSE)
     {
-        DPRINT1("ReadFile() returned FALSE\n");
+        DPRINT("ReadFile() returned FALSE\n");
 
         dwError = GetLastError();
         if (dwError == ERROR_IO_PENDING)
         {
-            DPRINT1("dwError: ERROR_IO_PENDING\n");
+            DPRINT("dwError: ERROR_IO_PENDING\n");
 
             dwError = WaitForSingleObject(Service->lpImage->hControlPipe,
-                                          dwPipeTimeout);
-            DPRINT1("WaitForSingleObject() returned %lu\n", dwError);
+                                          PipeTimeout);
+            DPRINT("WaitForSingleObject() returned %lu\n", dwError);
 
             if (dwError == WAIT_TIMEOUT)
             {
@@ -1009,7 +1012,7 @@ ScmControlService(PSERVICE Service,
                 dwError = ERROR_SERVICE_REQUEST_TIMEOUT;
                 goto Done;
             }
-            else if (dwError == ERROR_SUCCESS)
+            else if (dwError == WAIT_OBJECT_0)
             {
                 bResult = GetOverlappedResult(Service->lpImage->hControlPipe,
                                               &Overlapped,
@@ -1096,7 +1099,7 @@ Done:
 static DWORD
 ScmSendStartCommand(PSERVICE Service,
                     DWORD argc,
-                    LPWSTR *argv)
+                    LPWSTRargv)
 {
     PSCM_CONTROL_PACKET ControlPacket;
     SCM_REPLY_PACKET ReplyPacket;
@@ -1110,14 +1113,14 @@ ScmSendStartCommand(PSERVICE Service,
     PWSTR pArgPtr;
     BOOL bResult;
 #ifdef USE_ASYNCHRONOUS_IO
-    OVERLAPPED Overlapped = {0, 0, 0, 0, 0};
+    OVERLAPPED Overlapped = {0};
 #endif
 
     DPRINT("ScmSendStartCommand() called\n");
 
     /* Calculate the total length of the start command line */
-    PacketSize = sizeof(SCM_CONTROL_PACKET);
-    PacketSize += (wcslen(Service->lpServiceName) + 1) * sizeof(WCHAR);
+    PacketSize = sizeof(SCM_CONTROL_PACKET) +
+                 (DWORD)((wcslen(Service->lpServiceName) + 1) * sizeof(WCHAR));
 
     /* Calculate the required packet size for the start arguments */
     if (argc > 0 && argv != NULL)
@@ -1128,7 +1131,7 @@ ScmSendStartCommand(PSERVICE Service,
         for (i = 0; i < argc; i++)
         {
             DPRINT("Argv[%lu]: %S\n", i, argv[i]);
-            PacketSize += (wcslen(argv[i]) + 1) * sizeof(WCHAR) + sizeof(PWSTR);
+            PacketSize += (DWORD)((wcslen(argv[i]) + 1) * sizeof(WCHAR) + sizeof(PWSTR));
         }
     }
 
@@ -1140,7 +1143,9 @@ ScmSendStartCommand(PSERVICE Service,
         return ERROR_NOT_ENOUGH_MEMORY;
 
     ControlPacket->dwSize = PacketSize;
-    ControlPacket->dwControl = SERVICE_CONTROL_START;
+    ControlPacket->dwControl = (Service->Status.dwServiceType & SERVICE_WIN32_OWN_PROCESS)
+                               ? SERVICE_CONTROL_START_OWN
+                               : SERVICE_CONTROL_START_SHARE;
     ControlPacket->hServiceStatus = (SERVICE_STATUS_HANDLE)Service;
     ControlPacket->dwServiceNameOffset = sizeof(SCM_CONTROL_PACKET);
 
@@ -1182,16 +1187,16 @@ ScmSendStartCommand(PSERVICE Service,
                         &Overlapped);
     if (bResult == FALSE)
     {
-        DPRINT1("WriteFile() returned FALSE\n");
+        DPRINT("WriteFile() returned FALSE\n");
 
         dwError = GetLastError();
         if (dwError == ERROR_IO_PENDING)
         {
-            DPRINT1("dwError: ERROR_IO_PENDING\n");
+            DPRINT("dwError: ERROR_IO_PENDING\n");
 
             dwError = WaitForSingleObject(Service->lpImage->hControlPipe,
-                                          dwPipeTimeout);
-            DPRINT1("WaitForSingleObject() returned %lu\n", dwError);
+                                          PipeTimeout);
+            DPRINT("WaitForSingleObject() returned %lu\n", dwError);
 
             if (dwError == WAIT_TIMEOUT)
             {
@@ -1204,7 +1209,7 @@ ScmSendStartCommand(PSERVICE Service,
                 dwError = ERROR_SERVICE_REQUEST_TIMEOUT;
                 goto Done;
             }
-            else if (dwError == ERROR_SUCCESS)
+            else if (dwError == WAIT_OBJECT_0)
             {
                 bResult = GetOverlappedResult(Service->lpImage->hControlPipe,
                                               &Overlapped,
@@ -1236,16 +1241,16 @@ ScmSendStartCommand(PSERVICE Service,
                        &Overlapped);
     if (bResult == FALSE)
     {
-        DPRINT1("ReadFile() returned FALSE\n");
+        DPRINT("ReadFile() returned FALSE\n");
 
         dwError = GetLastError();
         if (dwError == ERROR_IO_PENDING)
         {
-            DPRINT1("dwError: ERROR_IO_PENDING\n");
+            DPRINT("dwError: ERROR_IO_PENDING\n");
 
             dwError = WaitForSingleObject(Service->lpImage->hControlPipe,
-                                          dwPipeTimeout);
-            DPRINT1("WaitForSingleObject() returned %lu\n", dwError);
+                                          PipeTimeout);
+            DPRINT("WaitForSingleObject() returned %lu\n", dwError);
 
             if (dwError == WAIT_TIMEOUT)
             {
@@ -1258,7 +1263,7 @@ ScmSendStartCommand(PSERVICE Service,
                 dwError = ERROR_SERVICE_REQUEST_TIMEOUT;
                 goto Done;
             }
-            else if (dwError == ERROR_SUCCESS)
+            else if (dwError == WAIT_OBJECT_0)
             {
                 bResult = GetOverlappedResult(Service->lpImage->hControlPipe,
                                               &Overlapped,
@@ -1332,7 +1337,12 @@ ScmWaitForServiceConnect(PSERVICE Service)
     DWORD dwError = ERROR_SUCCESS;
     BOOL bResult;
 #ifdef USE_ASYNCHRONOUS_IO
-    OVERLAPPED Overlapped = {0, 0, 0, 0, 0};
+    OVERLAPPED Overlapped = {0};
+#endif
+#if 0
+    LPCWSTR lpErrorStrings[3];
+    WCHAR szBuffer1[20];
+    WCHAR szBuffer2[20];
 #endif
 
     DPRINT("ScmWaitForServiceConnect()\n");
@@ -1352,7 +1362,7 @@ ScmWaitForServiceConnect(PSERVICE Service)
             DPRINT("dwError: ERROR_IO_PENDING\n");
 
             dwError = WaitForSingleObject(Service->lpImage->hControlPipe,
-                                          dwPipeTimeout);
+                                          PipeTimeout);
             DPRINT("WaitForSingleObject() returned %lu\n", dwError);
 
             if (dwError == WAIT_TIMEOUT)
@@ -1365,6 +1375,18 @@ ScmWaitForServiceConnect(PSERVICE Service)
                     DPRINT1("CancelIo() failed (Error: %lu)\n", GetLastError());
                 }
 
+#if 0
+                _ultow(PipeTimeout, szBuffer1, 10);
+                lpErrorStrings[0] = Service->lpDisplayName;
+                lpErrorStrings[1] = szBuffer1;
+
+                ScmLogEvent(EVENT_CONNECTION_TIMEOUT,
+                            EVENTLOG_ERROR_TYPE,
+                            2,
+                            lpErrorStrings);
+#endif
+                DPRINT1("Log EVENT_CONNECTION_TIMEOUT by %S\n", Service->lpDisplayName);
+
                 return ERROR_SERVICE_REQUEST_TIMEOUT;
             }
             else if (dwError == WAIT_OBJECT_0)
@@ -1409,7 +1431,7 @@ ScmWaitForServiceConnect(PSERVICE Service)
             DPRINT("dwError: ERROR_IO_PENDING\n");
 
             dwError = WaitForSingleObject(Service->lpImage->hControlPipe,
-                                          dwPipeTimeout);
+                                          PipeTimeout);
             if (dwError == WAIT_TIMEOUT)
             {
                 DPRINT("WaitForSingleObject() returned WAIT_TIMEOUT\n");
@@ -1420,11 +1442,22 @@ ScmWaitForServiceConnect(PSERVICE Service)
                     DPRINT1("CancelIo() failed (Error: %lu)\n", GetLastError());
                 }
 
+#if 0
+                _ultow(PipeTimeout, szBuffer1, 10);
+                lpErrorStrings[0] = szBuffer1;
+
+                ScmLogEvent(EVENT_READFILE_TIMEOUT,
+                            EVENTLOG_ERROR_TYPE,
+                            1,
+                            lpErrorStrings);
+#endif
+                DPRINT1("Log EVENT_READFILE_TIMEOUT by %S\n", Service->lpDisplayName);
+
                 return ERROR_SERVICE_REQUEST_TIMEOUT;
             }
-            else if (dwError == ERROR_SUCCESS)
+            else if (dwError == WAIT_OBJECT_0)
             {
-                DPRINT("WaitForSingleObject() returned ERROR_SUCCESS\n");
+                DPRINT("WaitForSingleObject() returned WAIT_OBJECT_0\n");
 
                 DPRINT("Process Id: %lu\n", dwProcessId);
 
@@ -1452,7 +1485,26 @@ ScmWaitForServiceConnect(PSERVICE Service)
         }
     }
 
-    DPRINT1("ScmWaitForServiceConnect() done\n");
+    if (dwProcessId != Service->lpImage->dwProcessId)
+    {
+#if 0
+        _ultow(Service->lpImage->dwProcessId, szBuffer1, 10);
+        _ultow(dwProcessId, szBuffer2, 10);
+
+        lpErrorStrings[0] = Service->lpDisplayName;
+        lpErrorStrings[1] = szBuffer1;
+        lpErrorStrings[2] = szBuffer2;
+
+        ScmLogEvent(EVENT_SERVICE_DIFFERENT_PID_CONNECTED,
+                    EVENTLOG_WARNING_TYPE,
+                    3,
+                    lpErrorStrings);
+#endif
+
+        DPRINT1("Log EVENT_SERVICE_DIFFERENT_PID_CONNECTED by %S\n", Service->lpDisplayName);
+    }
+
+    DPRINT("ScmWaitForServiceConnect() done\n");
 
     return ERROR_SUCCESS;
 #else
@@ -1494,7 +1546,7 @@ ScmWaitForServiceConnect(PSERVICE Service)
 static DWORD
 ScmStartUserModeService(PSERVICE Service,
                         DWORD argc,
-                        LPWSTR *argv)
+                        LPWSTRargv)
 {
     PROCESS_INFORMATION ProcessInformation;
     STARTUPINFOW StartupInfo;
@@ -1510,13 +1562,10 @@ ScmStartUserModeService(PSERVICE Service,
         return ScmSendStartCommand(Service, argc, argv);
     }
 
+    /* Otherwise start its process */
+    ZeroMemory(&StartupInfo, sizeof(StartupInfo));
     StartupInfo.cb = sizeof(StartupInfo);
-    StartupInfo.lpReserved = NULL;
-    StartupInfo.lpDesktop = NULL;
-    StartupInfo.lpTitle = NULL;
-    StartupInfo.dwFlags = 0;
-    StartupInfo.cbReserved2 = 0;
-    StartupInfo.lpReserved2 = 0;
+    ZeroMemory(&ProcessInformation, sizeof(ProcessInformation));
 
     Result = CreateProcessW(NULL,
                             Service->lpImage->szImagePath,
@@ -1553,9 +1602,7 @@ ScmStartUserModeService(PSERVICE Service,
     if (dwError == ERROR_SUCCESS)
     {
         /* Send start command */
-        dwError = ScmSendStartCommand(Service,
-                                      argc,
-                                      argv);
+        dwError = ScmSendStartCommand(Service, argc, argv);
     }
     else
     {
@@ -1571,24 +1618,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];
+    LPCWSTR lpErrorStrings[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;
     }
 
@@ -1604,7 +1649,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);
@@ -1627,9 +1672,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)
     {
@@ -1637,6 +1680,14 @@ ScmStartService(PSERVICE Service, DWORD argc, LPWSTR *argv)
         {
             Group->ServicesRunning = TRUE;
         }
+
+        /* Log a successful service start */
+        lpErrorStrings[0] = Service->lpDisplayName;
+        lpErrorStrings[1] = L"start";
+        ScmLogEvent(EVENT_SERVICE_CONTROL_SUCCESS,
+                    EVENTLOG_INFORMATION_TYPE,
+                    2,
+                    lpErrorStrings);
     }
     else
     {
@@ -1644,11 +1695,12 @@ ScmStartService(PSERVICE Service, DWORD argc, LPWSTR *argv)
         {
             /* Log a failed service start */
             swprintf(szErrorBuffer, L"%lu", dwError);
-            ErrorLogStrings[0] = Service->lpServiceName;
-            ErrorLogStrings[1] = szErrorBuffer;
-            ScmLogError(EVENT_SERVICE_START_FAILED,
+            lpErrorStrings[0] = Service->lpServiceName;
+            lpErrorStrings[1] = szErrorBuffer;
+            ScmLogEvent(EVENT_SERVICE_START_FAILED,
+                        EVENTLOG_ERROR_TYPE,
                         2,
-                        ErrorLogStrings);
+                        lpErrorStrings);
         }
 
 #if 0
@@ -1679,18 +1731,67 @@ 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;
     PLIST_ENTRY GroupEntry;
     PLIST_ENTRY ServiceEntry;
     PSERVICE_GROUP CurrentGroup;
     PSERVICE CurrentService;
     WCHAR szSafeBootServicePath[MAX_PATH];
-    DWORD dwError;
     HKEY hKey;
     ULONG i;
 
+    /*
+     * This function MUST be called ONLY at initialization time.
+     * Therefore, no need to acquire the user service start lock.
+     */
+    ASSERT(ScmInitialize);
+
+    /* Acquire the service control critical section, to synchronize starts */
+    EnterCriticalSection(&ControlServiceCriticalSection);
+
     /* Clear 'ServiceVisited' flag (or set if not to start in Safe Mode) */
     ServiceEntry = ServiceListHead.Flink;
     while (ServiceEntry != &ServiceListHead)
@@ -1781,7 +1882,7 @@ ScmAutoStartServices(VOID)
                     (CurrentService->dwTag == CurrentGroup->TagArray[i]))
                 {
                     CurrentService->ServiceVisited = TRUE;
-                    ScmStartService(CurrentService, 0, NULL);
+                    ScmLoadService(CurrentService, 0, NULL);
                 }
 
                 ServiceEntry = ServiceEntry->Flink;
@@ -1799,7 +1900,7 @@ ScmAutoStartServices(VOID)
                 (CurrentService->ServiceVisited == FALSE))
             {
                 CurrentService->ServiceVisited = TRUE;
-                ScmStartService(CurrentService, 0, NULL);
+                ScmLoadService(CurrentService, 0, NULL);
             }
 
             ServiceEntry = ServiceEntry->Flink;
@@ -1819,7 +1920,7 @@ ScmAutoStartServices(VOID)
             (CurrentService->ServiceVisited == FALSE))
         {
             CurrentService->ServiceVisited = TRUE;
-            ScmStartService(CurrentService, 0, NULL);
+            ScmLoadService(CurrentService, 0, NULL);
         }
 
         ServiceEntry = ServiceEntry->Flink;
@@ -1836,7 +1937,7 @@ ScmAutoStartServices(VOID)
             (CurrentService->ServiceVisited == FALSE))
         {
             CurrentService->ServiceVisited = TRUE;
-            ScmStartService(CurrentService, 0, NULL);
+            ScmLoadService(CurrentService, 0, NULL);
         }
 
         ServiceEntry = ServiceEntry->Flink;
@@ -1850,6 +1951,9 @@ ScmAutoStartServices(VOID)
         CurrentService->ServiceVisited = FALSE;
         ServiceEntry = ServiceEntry->Flink;
     }
+
+    /* Release the critical section */
+    LeaveCriticalSection(&ControlServiceCriticalSection);
 }
 
 
@@ -1929,7 +2033,7 @@ ScmInitNamedPipeCriticalSection(VOID)
                          L"ServicesPipeTimeout",
                          0,
                          NULL,
-                         (LPBYTE)&dwPipeTimeout,
+                         (LPBYTE)&PipeTimeout,
                          &dwKeySize);
 
        RegCloseKey(hKey);