[SERVICES]
[reactos.git] / reactos / base / system / services / database.c
index 95bc302..9a332a0 100644 (file)
@@ -30,6 +30,8 @@ LIST_ENTRY ServiceListHead;
 static RTL_RESOURCE DatabaseLock;
 static DWORD dwResumeCount = 1;
 
+static CRITICAL_SECTION NamedPipeCriticalSection;
+static CRITICAL_SECTION StartServiceCriticalSection;
 
 /* FUNCTIONS *****************************************************************/
 
@@ -679,12 +681,15 @@ ScmGetBootAndSystemDriverState(VOID)
 
 DWORD
 ScmControlService(PSERVICE Service,
-                  DWORD dwControl,
-                  LPSERVICE_STATUS lpServiceStatus)
+                  DWORD dwControl)
 {
     PSCM_CONTROL_PACKET ControlPacket;
-    DWORD Count;
+    SCM_REPLY_PACKET ReplyPacket;
+
+    DWORD dwWriteCount = 0;
+    DWORD dwReadCount = 0;
     DWORD TotalLength;
+    DWORD dwError = ERROR_SUCCESS;
 
     DPRINT("ScmControlService() called\n");
 
@@ -701,27 +706,37 @@ ScmControlService(PSERVICE Service,
     ControlPacket->hServiceStatus = (SERVICE_STATUS_HANDLE)Service;
     wcscpy(&ControlPacket->szArguments[0], Service->lpServiceName);
 
+    EnterCriticalSection(&NamedPipeCriticalSection);
+
     /* Send the control packet */
     WriteFile(Service->ControlPipeHandle,
               ControlPacket,
               sizeof(SCM_CONTROL_PACKET) + (TotalLength * sizeof(WCHAR)),
-              &Count,
+              &dwWriteCount,
               NULL);
 
-    /* FIXME: Read the reply */
+    /* Read the reply */
+    ReadFile(Service->ControlPipeHandle,
+             &ReplyPacket,
+             sizeof(SCM_REPLY_PACKET),
+             &dwReadCount,
+             NULL);
+
+    LeaveCriticalSection(&NamedPipeCriticalSection);
 
     /* Release the contol packet */
     HeapFree(GetProcessHeap(),
              0,
              ControlPacket);
 
-    RtlCopyMemory(lpServiceStatus,
-                  &Service->Status,
-                  sizeof(SERVICE_STATUS));
+    if (dwReadCount == sizeof(SCM_REPLY_PACKET))
+    {
+        dwError = ReplyPacket.dwError;
+    }
 
-    DPRINT("ScmControlService) done\n");
+    DPRINT("ScmControlService() done\n");
 
-    return ERROR_SUCCESS;
+    return dwError;
 }
 
 
@@ -731,11 +746,15 @@ ScmSendStartCommand(PSERVICE Service,
                     LPWSTR *argv)
 {
     PSCM_CONTROL_PACKET ControlPacket;
+    SCM_REPLY_PACKET ReplyPacket;
     DWORD TotalLength;
     DWORD ArgsLength = 0;
     DWORD Length;
     PWSTR Ptr;
-    DWORD Count;
+    DWORD dwWriteCount = 0;
+    DWORD dwReadCount = 0;
+    DWORD dwError = ERROR_SUCCESS;
+    DWORD i;
 
     DPRINT("ScmSendStartCommand() called\n");
 
@@ -743,10 +762,10 @@ ScmSendStartCommand(PSERVICE Service,
     TotalLength = wcslen(Service->lpServiceName) + 1;
     if (argc > 0)
     {
-        for (Count = 0; Count < argc; Count++)
+        for (i = 0; i < argc; i++)
         {
-            DPRINT("Arg: %S\n", argv[Count]);
-            Length = wcslen(argv[Count]) + 1;
+            DPRINT("Arg: %S\n", argv[i]);
+            Length = wcslen(argv[i]) + 1;
             TotalLength += Length;
             ArgsLength += Length;
         }
@@ -782,23 +801,37 @@ ScmSendStartCommand(PSERVICE Service,
     /* Terminate the argument list */
     *Ptr = 0;
 
+    EnterCriticalSection(&NamedPipeCriticalSection);
+
     /* Send the start command */
     WriteFile(Service->ControlPipeHandle,
               ControlPacket,
               sizeof(SCM_CONTROL_PACKET) + (TotalLength - 1) * sizeof(WCHAR),
-              &Count,
+              &dwWriteCount,
               NULL);
 
-    /* FIXME: Read the reply */
+    /* Read the reply */
+    ReadFile(Service->ControlPipeHandle,
+             &ReplyPacket,
+             sizeof(SCM_REPLY_PACKET),
+             &dwReadCount,
+             NULL);
+
+    LeaveCriticalSection(&NamedPipeCriticalSection);
 
     /* Release the contol packet */
     HeapFree(GetProcessHeap(),
              0,
              ControlPacket);
 
+    if (dwReadCount == sizeof(SCM_REPLY_PACKET))
+    {
+        dwError = ReplyPacket.dwError;
+    }
+
     DPRINT("ScmSendStartCommand() done\n");
 
-    return ERROR_SUCCESS;
+    return dwError;
 }
 
 
@@ -1003,6 +1036,8 @@ ScmStartService(PSERVICE Service, DWORD argc, LPWSTR *argv)
     PSERVICE_GROUP Group = Service->lpGroup;
     DWORD dwError = ERROR_SUCCESS;
 
+    EnterCriticalSection(&StartServiceCriticalSection);
+
     DPRINT("ScmStartService() called\n");
 
     Service->ControlPipeHandle = INVALID_HANDLE_VALUE;
@@ -1033,6 +1068,7 @@ ScmStartService(PSERVICE Service, DWORD argc, LPWSTR *argv)
     }
 
     DPRINT("ScmStartService() done (Error %lu)\n", dwError);
+    LeaveCriticalSection(&StartServiceCriticalSection);
 
     if (dwError == ERROR_SUCCESS)
     {
@@ -1192,7 +1228,6 @@ ScmAutoShutdownServices(VOID)
 {
     PLIST_ENTRY ServiceEntry;
     PSERVICE CurrentService;
-    SERVICE_STATUS ServiceStatus;
 
     DPRINT("ScmAutoShutdownServices() called\n");
 
@@ -1205,7 +1240,7 @@ ScmAutoShutdownServices(VOID)
             CurrentService->Status.dwCurrentState == SERVICE_START_PENDING)
         {
             /* shutdown service */
-            ScmControlService(CurrentService, SERVICE_CONTROL_STOP, &ServiceStatus);
+            ScmControlService(CurrentService, SERVICE_CONTROL_STOP);
         }
 
         ServiceEntry = ServiceEntry->Flink;
@@ -1235,4 +1270,20 @@ ScmUnlockDatabase(VOID)
     RtlReleaseResource(&DatabaseLock);
 }
 
+
+VOID
+ScmInitNamedPipeCriticalSection(VOID)
+{
+    InitializeCriticalSection(&NamedPipeCriticalSection);
+    InitializeCriticalSection(&StartServiceCriticalSection);
+}
+
+
+VOID
+ScmDeleteNamedPipeCriticalSection(VOID)
+{
+    DeleteCriticalSection(&StartServiceCriticalSection);
+    DeleteCriticalSection(&NamedPipeCriticalSection);
+}
+
 /* EOF */