Open named pipe to SCM
authorCasper Hornstrup <chorns@users.sourceforge.net>
Sun, 21 Oct 2001 19:06:42 +0000 (19:06 +0000)
committerCasper Hornstrup <chorns@users.sourceforge.net>
Sun, 21 Oct 2001 19:06:42 +0000 (19:06 +0000)
svn path=/trunk/; revision=2310

reactos/lib/advapi32/makefile
reactos/lib/advapi32/service/scm.c
reactos/lib/advapi32/service/sctrl.c
reactos/lib/kernel32/file/npipe.c

index 65fd558..726079c 100644 (file)
@@ -1,4 +1,4 @@
-# $Id: makefile,v 1.19 2001/08/21 20:13:05 chorns Exp $
+# $Id: makefile,v 1.20 2001/10/21 19:06:42 chorns Exp $
 
 PATH_TO_TOP = ../..
 
@@ -8,6 +8,8 @@ TARGET_NAME = advapi32
 
 TARGET_SDKLIBS = ntdll.a kernel32.a
 
+# TARGET_CFLAGS = -DUNICODE
+
 TARGET_BASE = 0x77dc0000
 
 MISC_OBJECTS=\
index b4f9653..01d17c1 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: scm.c,v 1.7 2001/06/25 14:19:56 ekohl Exp $
+/* $Id: scm.c,v 1.8 2001/10/21 19:06:42 chorns Exp $
  * 
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS system libraries
@@ -100,18 +100,18 @@ SC_HANDLE
 STDCALL
 CreateServiceA(
        SC_HANDLE       hSCManager,
-       LPCTSTR         lpServiceName,
-       LPCTSTR         lpDisplayName,
+       LPCSTR          lpServiceName,
+       LPCSTR          lpDisplayName,
        DWORD           dwDesiredAccess,
        DWORD           dwServiceType,
        DWORD           dwStartType,
        DWORD           dwErrorControl,
-       LPCTSTR         lpBinaryPathName,
-       LPCTSTR         lpLoadOrderGroup,
+       LPCSTR          lpBinaryPathName,
+       LPCSTR          lpLoadOrderGroup,
        LPDWORD         lpdwTagId,
-       LPCTSTR         lpDependencies,
-       LPCTSTR         lpServiceStartName,
-       LPCTSTR         lpPassword
+       LPCSTR          lpDependencies,
+       LPCSTR          lpServiceStartName,
+       LPCSTR          lpPassword
        )
 {
        SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
@@ -410,35 +410,112 @@ SC_HANDLE STDCALL OpenSCManagerW(LPCWSTR lpMachineName,
                                 LPCWSTR        lpDatabaseName,                 
                                 DWORD  dwDesiredAccess)
 {
-   HANDLE h;
-   
-   if (lpMachineName == NULL ||
-       wcslen(lpMachineName) == 0)
-     {
-       if (lpDatabaseName != NULL &&
-           wcscmp(lpDatabaseName, SERVICES_ACTIVE_DATABASEW) != 0)
-         {
-            return(NULL);
-         }
-       
-       h = CreateFileW(L"\\\\.\\pipe\\ntsrvctrl",
-                      dwDesiredAccess,
-                      0,
-                      NULL,
-                      OPEN_EXISTING,
-                      0,
-                      NULL);
-       if (h == INVALID_HANDLE_VALUE)
-         {
-            return(NULL);
-         }
+  HANDLE hPipe;
+  DWORD dwMode;
+  BOOL fSuccess;
+  LPWSTR lpszPipeName = L"\\\\.\\pipe\\Ntsvcs";
+
+  if (lpMachineName == NULL || wcslen(lpMachineName) == 0)
+  {
+         if (lpDatabaseName != NULL && wcscmp(lpDatabaseName, SERVICES_ACTIVE_DATABASEW) != 0)
+    {
+           return(NULL);
+    }
        
-       return(h);
-     }
-   else
-     {
-       return(NULL);
-     }
+    // Try to open a named pipe; wait for it, if necessary
+    while (1)
+    {
+      hPipe = CreateFileW(
+        lpszPipeName,     // pipe name
+        dwDesiredAccess,
+        0,                // no sharing
+        NULL,             // no security attributes
+        OPEN_EXISTING,    // opens existing pipe
+        0,                // default attributes
+        NULL);            // no template file
+
+      // Break if the pipe handle is valid
+
+      if (hPipe != INVALID_HANDLE_VALUE)
+         break;
+
+      // Exit if an error other than ERROR_PIPE_BUSY occurs
+
+      if (GetLastError() != ERROR_PIPE_BUSY)
+      {
+         return(NULL);
+      }
+
+      // All pipe instances are busy, so wait for 20 seconds
+
+      if (!WaitNamedPipeW(lpszPipeName, 20000))
+      {
+         return(NULL);
+      }
+    }
+
+    // The pipe connected; change to message-read mode
+
+    dwMode = PIPE_READMODE_MESSAGE;
+    fSuccess = SetNamedPipeHandleState(
+      hPipe,    // pipe handle
+      &dwMode,  // new pipe mode
+      NULL,     // don't set maximum bytes
+      NULL);    // don't set maximum time
+    if (!fSuccess)
+    {
+      CloseHandle(hPipe);
+      return(NULL);
+    }
+#if 0
+    // Send a message to the pipe server
+
+    lpvMessage = (argc > 1) ? argv[1] : "default message";
+
+    fSuccess = WriteFile(
+      hPipe,                  // pipe handle
+      lpvMessage,             // message
+      strlen(lpvMessage) + 1, // message length
+      &cbWritten,             // bytes written
+      NULL);                  // not overlapped
+    if (!fSuccess)
+    {
+      CloseHandle(hPipe);
+      return(NULL);
+    }
+
+    do
+    {
+      // Read from the pipe
+
+      fSuccess = ReadFile(
+        hPipe,    // pipe handle
+        chBuf,    // buffer to receive reply
+        512,      // size of buffer
+        &cbRead,  // number of bytes read
+        NULL);    // not overlapped
+
+      if (! fSuccess && GetLastError() != ERROR_MORE_DATA)
+        break;
+
+      // Reply from the pipe is written to STDOUT.
+
+      if (!WriteFile(GetStdHandle(STD_OUTPUT_HANDLE),
+         chBuf, cbRead, &cbWritten, NULL))
+      {
+        break;
+      }
+
+    } while (!fSuccess);  // repeat loop if ERROR_MORE_DATA
+    //CloseHandle(hPipe);
+#endif
+    return(hPipe);
+  }
+  else
+  {
+    /* FIXME: Connect to remote SCM */
+         return(NULL);
+  }
 }
 
 
index ddf2dae..e5abf82 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: sctrl.c,v 1.2 2001/06/25 14:19:56 ekohl Exp $
+/* $Id: sctrl.c,v 1.3 2001/10/21 19:06:42 chorns Exp $
  * 
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS system libraries
 
 typedef struct
 {
-   DWORD ThreadId;
+  DWORD ThreadId;
+  UNICODE_STRING ServiceName;
+  SERVICE_STATUS ServiceStatus;
+  LPHANDLER_FUNCTION   Handler;
 } ACTIVE_SERVICE, *PACTIVE_SERVICE;
 
 /* GLOBALS *******************************************************************/
@@ -30,6 +33,39 @@ static PHANDLE ActiveServicesThreadHandles;
 
 /* FUNCTIONS *****************************************************************/
 
+PACTIVE_SERVICE
+ScLookupServiceByThreadId(
+  DWORD ThreadId)
+{
+  DWORD i;
+
+  for (i = 0; i < ActiveServiceCount; i++)
+  {
+    if (ActiveServices[i].ThreadId == ThreadId)
+    {
+      return &ActiveServices[i];
+    }
+  }
+
+  return NULL;
+}
+
+
+DWORD
+WINAPI
+ScServiceMainStub(
+  LPVOID Context)
+{
+  LPSERVICE_MAIN_FUNCTION lpServiceProc = (LPSERVICE_MAIN_FUNCTION)Context;
+
+  /* FIXME: Send argc and argv (from command line) as arguments */
+
+  (lpServiceProc)(0, NULL);
+
+  return ERROR_SUCCESS;
+}
+
+
 /**********************************************************************
  *     RegisterServiceCtrlHandlerA
  */
@@ -43,12 +79,16 @@ SERVICE_STATUS_HANDLE STDCALL RegisterServiceCtrlHandlerA(
    SERVICE_STATUS_HANDLE SHandle;
    
    RtlInitAnsiString(&ServiceNameA, (LPSTR)lpServiceName);
-   RtlAnsiStringToUnicodeString(&ServiceNameU, &ServiceNameA, TRUE);
-   
+   if (!NT_SUCCESS(RtlAnsiStringToUnicodeString(&ServiceNameU, &ServiceNameA, TRUE)))
+   {
+         SetLastError(ERROR_OUTOFMEMORY);
+       return (SERVICE_STATUS_HANDLE)0;
+   }
+
    SHandle = RegisterServiceCtrlHandlerW(ServiceNameU.Buffer,
                                         lpHandlerProc);
-   
-   RtlFreeHeap(RtlGetProcessHeap(), 0, ServiceNameU.Buffer);
+
+   RtlFreeUnicodeString(&ServiceNameU);
    
    return(SHandle);
 }
@@ -61,8 +101,15 @@ SERVICE_STATUS_HANDLE STDCALL RegisterServiceCtrlHandlerW(
        LPCWSTR                 lpServiceName,
        LPHANDLER_FUNCTION      lpHandlerProc)
 {
-       SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-       return 0;
+  PACTIVE_SERVICE Service;
+
+  /* FIXME: Locate active service entry from name */
+
+  Service = &ActiveServices[0];
+
+  Service->Handler = lpHandlerProc;
+
+       return (SERVICE_STATUS_HANDLE)Service->ThreadId;
 }
 
 
@@ -102,61 +149,85 @@ BOOL
 STDCALL
 SetServiceStatus(
        SERVICE_STATUS_HANDLE   hServiceStatus,
-       LPSERVICE_STATUS        lpServiceStatus
-       )
+       LPSERVICE_STATUS        lpServiceStatus)
 {
-       SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-       return FALSE;
+  PACTIVE_SERVICE Service;
+
+  Service = ScLookupServiceByThreadId((DWORD)hServiceStatus);
+  if (!Service)
+  {
+    SetLastError(ERROR_INVALID_HANDLE);
+    return FALSE;
+  }
+
+  RtlCopyMemory(
+    &Service->ServiceStatus,
+    lpServiceStatus, 
+    sizeof(SERVICE_STATUS));
+
+       return TRUE;
 }
 
 /**********************************************************************
  *     StartServiceCtrlDispatcherA
  */
 BOOL STDCALL StartServiceCtrlDispatcherA(
-           LPSERVICE_TABLE_ENTRYA      lpServiceStartTable)
+  LPSERVICE_TABLE_ENTRYA       lpServiceStartTable)
 {
-   LPSERVICE_TABLE_ENTRYW ServiceStartTableW;
-   ANSI_STRING ServiceNameA;
-   UNICODE_STRING ServiceNameW;
-   ULONG i;
-   ULONG Count;
-   BOOL b;
-   
-   i = 0;
-   while (lpServiceStartTable[i].lpServiceProc != NULL)
-     {
-       i++;
-     }
-   Count = i;
-   
-   ServiceStartTableW = RtlAllocateHeap(RtlGetProcessHeap(),
-                                       HEAP_ZERO_MEMORY,
-                                       sizeof(SERVICE_TABLE_ENTRYW) * Count);
-   for (i = 0; i < Count; i++)
-     {
-       RtlInitAnsiString(&ServiceNameA,
-                         lpServiceStartTable[i].lpServiceName);
-       RtlAnsiStringToUnicodeString(&ServiceNameW,
-                                    &ServiceNameA,
-                                    TRUE);
-       ServiceStartTableW[i].lpServiceName = ServiceNameW.Buffer;
-       ServiceStartTableW[i].lpServiceProc = 
-         lpServiceStartTable[i].lpServiceProc;
-     }
-   
-   b = StartServiceCtrlDispatcherW(ServiceStartTableW);
-   
-   for (i = 0; i < Count; i++)
-     {
-       RtlFreeHeap(RtlGetProcessHeap(),
-                   0,
-                   ServiceStartTableW[i].lpServiceName);
-     }
-   RtlFreeHeap(RtlGetProcessHeap(),
-              0,
-              ServiceStartTableW);
-   
-   return(b);
+  LPSERVICE_TABLE_ENTRYW ServiceStartTableW;
+  ANSI_STRING ServiceNameA;
+  UNICODE_STRING ServiceNameW;
+  ULONG i, j;
+  ULONG Count;
+  BOOL b;
+
+  i = 0;
+  while (lpServiceStartTable[i].lpServiceProc != NULL)
+  {
+    i++;
+  }
+  Count = i;
+
+  ServiceStartTableW = RtlAllocateHeap(
+    RtlGetProcessHeap(),
+    HEAP_ZERO_MEMORY,
+    sizeof(SERVICE_TABLE_ENTRYW) * Count);
+  for (i = 0; i < Count; i++)
+  {
+    RtlInitAnsiString(
+      &ServiceNameA,
+         lpServiceStartTable[i].lpServiceName);
+    if (!NT_SUCCESS(RtlAnsiStringToUnicodeString(
+      &ServiceNameW,
+         &ServiceNameA,
+               TRUE)))
+    {
+      for (j = 0; j < i; j++)
+      {
+        RtlInitUnicodeString(
+          &ServiceNameW,
+           ServiceStartTableW[j].lpServiceName);
+        RtlFreeUnicodeString(&ServiceNameW);
+      }
+      RtlFreeHeap(RtlGetProcessHeap(), 0, ServiceStartTableW);
+      SetLastError(ERROR_OUTOFMEMORY);
+         return FALSE;
+    }
+    ServiceStartTableW[i].lpServiceName = ServiceNameW.Buffer;
+    ServiceStartTableW[i].lpServiceProc = 
+      lpServiceStartTable[i].lpServiceProc;
+  }
+
+  b = StartServiceCtrlDispatcherW(ServiceStartTableW);
+
+  for (i = 0; i < Count; i++)
+  {
+    RtlFreeHeap(RtlGetProcessHeap(), 0, ServiceStartTableW[i].lpServiceName);
+  }
+
+  RtlFreeHeap(RtlGetProcessHeap(), 0, ServiceStartTableW);
+
+  return b;
 }
 
 
@@ -166,71 +237,90 @@ BOOL STDCALL StartServiceCtrlDispatcherA(
 BOOL STDCALL StartServiceCtrlDispatcherW(
        LPSERVICE_TABLE_ENTRYW  lpServiceStartTable)
 {
-   ULONG i;
-   HANDLE h;
-   DWORD Tid;
-   DWORD r;
-   
-   i = 0;
-   while (lpServiceStartTable[i].lpServiceProc != NULL)
-     {
-       i++;
-     }
-   
-   ActiveServiceCount = i;
-   ActiveServices = RtlAllocateHeap(GetProcessHeap(),
-                                   HEAP_ZERO_MEMORY,
-                                   ActiveServiceCount * 
-                                   sizeof(ACTIVE_SERVICE));
-   ActiveServicesThreadHandles = RtlAllocateHeap(GetProcessHeap(),
-                                                HEAP_ZERO_MEMORY,
-                                                (ActiveServiceCount + 1) *
-                                                sizeof(HANDLE));
-   
-   for (i = 0; i<ActiveServiceCount; i++)
-     {
-       h = CreateThread(NULL,
-                        0,
-                        (LPTHREAD_START_ROUTINE)lpServiceStartTable[i].lpServiceProc,
-                        NULL,
-                        0,
-                        &Tid);
-       if (h == INVALID_HANDLE_VALUE)
-         {
-            return(FALSE);
-         }
-       ActiveServicesThreadHandles[i + 1] = h;
-       ActiveServices[i].ThreadId = Tid;
-     }
-   
-   while (ActiveServiceCount > 0)
-     {
-       r = WaitForMultipleObjects(ActiveServiceCount + 1,
-                                  ActiveServicesThreadHandles,
-                                  FALSE,
-                                  INFINITE);
-       if (r == WAIT_OBJECT_0)
-         {
-            /* Received message from the scm */
-         }
-       else if (r > WAIT_OBJECT_0 &&
-                r < (WAIT_OBJECT_0 + ActiveServiceCount))
-         {
-            /* A service died */
-            
-            ActiveServiceCount--;
-            ActiveServicesThreadHandles[r - WAIT_OBJECT_0 - 1] =
-              ActiveServicesThreadHandles[ActiveServiceCount + 1];
-            memcpy(&ActiveServices[r - WAIT_OBJECT_0 - 2],
-                   &ActiveServices[ActiveServiceCount],
-                   sizeof(ACTIVE_SERVICE));
-         }
-       else
-         {
-            /* Bail */
-         }
-     }
-   return(TRUE);
+  ULONG i;
+  HANDLE h;
+  DWORD Tid;
+  DWORD r;
+
+  i = 0;
+  while (lpServiceStartTable[i].lpServiceProc != NULL)
+  {
+    i++;
+  }
+
+  ActiveServiceCount = i;
+  ActiveServices = RtlAllocateHeap(
+    RtlGetProcessHeap(),
+       HEAP_ZERO_MEMORY,
+       ActiveServiceCount * 
+       sizeof(ACTIVE_SERVICE));
+  if (!ActiveServices)
+  {
+    return FALSE;
+  }
+
+  ActiveServicesThreadHandles = RtlAllocateHeap(
+    RtlGetProcessHeap(),
+       HEAP_ZERO_MEMORY,
+       (ActiveServiceCount + 1) *
+       sizeof(HANDLE));
+  if (!ActiveServicesThreadHandles)
+  {
+    RtlFreeHeap(RtlGetProcessHeap(), 0, ActiveServices);
+    ActiveServices = NULL;
+    return FALSE;
+  }
+
+  for (i = 0; i<ActiveServiceCount; i++)
+  {
+    h = CreateThread(
+      NULL,
+         0,
+         ScServiceMainStub,
+         lpServiceStartTable[i].lpServiceProc,
+         0,
+         &Tid);
+    if (h == INVALID_HANDLE_VALUE)
+    {
+      RtlFreeHeap(RtlGetProcessHeap(), 0, ActiveServicesThreadHandles);
+      ActiveServicesThreadHandles = NULL;
+      RtlFreeHeap(RtlGetProcessHeap(), 0, ActiveServices);
+      ActiveServices = NULL;
+      return(FALSE);
+    }
+    ActiveServicesThreadHandles[i + 1] = h;
+    ActiveServices[i].ThreadId = Tid;
+  }
+
+  while (ActiveServiceCount > 0)
+  {
+    r = WaitForMultipleObjects(
+      ActiveServiceCount + 1,
+         ActiveServicesThreadHandles,
+               FALSE,
+               INFINITE);
+    if (r == WAIT_OBJECT_0)
+    {
+      /* Received message from the scm */
+    }
+    else if (r > WAIT_OBJECT_0 && r < (WAIT_OBJECT_0 + ActiveServiceCount))
+    {
+      /* A service died */
+        
+      ActiveServiceCount--;
+      ActiveServicesThreadHandles[r - WAIT_OBJECT_0 - 1] =
+        ActiveServicesThreadHandles[ActiveServiceCount + 1];
+      RtlCopyMemory(
+        &ActiveServices[r - WAIT_OBJECT_0 - 2],
+        &ActiveServices[ActiveServiceCount],
+        sizeof(ACTIVE_SERVICE));
+    }
+    else
+    {
+      /* Bail */
+    }
+  }
+  return TRUE;
 }
 
 
index 72a19dd..24249e5 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: npipe.c,v 1.7 2001/10/20 15:28:03 ekohl Exp $
+/* $Id: npipe.c,v 1.8 2001/10/21 19:06:42 chorns Exp $
  *
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS system libraries
@@ -345,25 +345,29 @@ SetNamedPipeHandleState(HANDLE hNamedPipe,
    NPFS_SET_STATE SetState;
    IO_STATUS_BLOCK Iosb;
    NTSTATUS Status;
-   
-#if 0
+
    Status = NtFsControlFile(hNamedPipe,
                            NULL,
                            NULL,
                            NULL,
                            &Iosb,
-                           FSCTL_GET_STATE,
+                           FSCTL_PIPE_GET_STATE,
                            NULL,
                            0,
                            &GetState,
-                           sizeof(GetState));
-   if (!NT_SUCCESS(Status))
+                           sizeof(NPFS_GET_STATE));
+   if (Status == STATUS_PENDING)
      {
-       SetLastErrorByStatus (Status);
-       return(FALSE);
+       Status = NtWaitForSingleObject(hNamedPipe,
+                                      FALSE,
+                                      NULL);
+       if (!NT_SUCCESS(Status))
+         {
+            SetLastErrorByStatus(Status);
+            return(FALSE);
+         }
      }
-#endif
-   
+
    if (lpMode != NULL)
      {
        if ((*lpMode) & PIPE_READMODE_MESSAGE)
@@ -410,25 +414,30 @@ SetNamedPipeHandleState(HANDLE hNamedPipe,
      {
        SetState.Timeout = GetState.Timeout;
      }
-   
-#if 0
+
    Status = NtFsControlFile(hNamedPipe,
                            NULL,
                            NULL,
                            NULL,
                            &Iosb,
-                           FSCTL_SET_STATE,
+                           FSCTL_PIPE_SET_STATE,
                            &SetState,
-                           sizeof(SetState),
+                           sizeof(NPFS_SET_STATE),
                            NULL,
                            0);
-   if (!NT_SUCCESS(Status))
+   if (Status == STATUS_PENDING)
      {
-       SetLastErrorByStatus (Status);
-       return(FALSE);
+       Status = NtWaitForSingleObject(hNamedPipe,
+                                      FALSE,
+                                      NULL);
+       if (!NT_SUCCESS(Status))
+         {
+            SetLastErrorByStatus(Status);
+            return(FALSE);
+         }
      }
-#endif
-   return(TRUE);
+
+  return(TRUE);
 }