[NTDLL]
authorHermès Bélusca-Maïto <hermes.belusca-maito@reactos.org>
Mon, 5 Nov 2012 00:23:58 +0000 (00:23 +0000)
committerHermès Bélusca-Maïto <hermes.belusca-maito@reactos.org>
Mon, 5 Nov 2012 00:23:58 +0000 (00:23 +0000)
- Add parameter annotations.
- Improve CSR buffer allocation with 4-byte align.
- Simplify the capture-buffer pointers settings.

[CSRSRV]
- Remove last console structure from csrsrv.h (in next commits it will be placed in a proper header).
- Enable global CSR debugging (for debugging purposes... ;-) ).
- api.c: Enable debugging.
- api.c/.h: Remove old code and deprecated unused definitions.
- Use the Win2k3-compliant version of CsrCreateThread (code from subsystems/csr/csrsrv) (TODO: correct its usage in basesrv:BaseSrvCreateThread).
- init.c: Implement a helper routine, CsrInitCsrRootProcess, in order to initialize the per-process server data (see CSR_PROCESS structure) in the Root CSR process. New process inherit it from this Root process.
- server.c - Add a DPRINT. Remove a hack. Correct a parameter passing.
- session.c - Remove a hack (it will go to the new process initialization in consrv)
- Disable the code of CsrConnectToUser while user32:ClientThreadSetup doesn't work.
- Correct the implementation of CsrValidateMessageBuffer.
- Basic implementation of CsrValidateMessageString using CsrValidateMessageBuffer.

TODO:
- Compare CsrpHandleConnectionRequest with the other one function in api.c.
- Compare CsrValidateMessageBuffer with Win32CsrValidateBuffer ?

svn path=/branches/ros-csrss/; revision=57673

14 files changed:
dll/ntdll/csr/api.c
dll/ntdll/csr/capture.c
dll/ntdll/csr/connect.c
include/reactos/subsys/csr/csr.h
include/reactos/subsys/csr/csrmsg.h
include/reactos/subsys/csr/csrsrv.h
subsystems/win32/csrsrv/api.c
subsystems/win32/csrsrv/csrsrv.spec
subsystems/win32/csrsrv/include/api.h
subsystems/win32/csrsrv/init.c
subsystems/win32/csrsrv/procsup.c
subsystems/win32/csrsrv/server.c
subsystems/win32/csrsrv/session.c
subsystems/win32/csrsrv/thredsup.c

index 26fec9c..76de9c7 100644 (file)
@@ -50,7 +50,7 @@ CsrSetPriorityClass(HANDLE hProcess,
                                  NULL,
                                  CSR_CREATE_API_NUMBER(CSRSRV_SERVERDLL_INDEX, CsrpSetPriorityClass),
                                  sizeof(CSR_SET_PRIORITY_CLASS));
-    
+
     /* Return what we got, if requested */
     if (*PriorityClass) *PriorityClass = SetPriorityClass->PriorityClass;
 
@@ -68,7 +68,7 @@ CsrIdentifyAlertableThread(VOID)
     NTSTATUS Status;
     CSR_API_MESSAGE ApiMessage;
     PCSR_IDENTIFY_ALTERTABLE_THREAD IdentifyAlertableThread;
-    
+
     /* Set up the data for CSR */
     DbgBreakPoint();
     IdentifyAlertableThread = &ApiMessage.Data.IdentifyAlertableThread;
index 97215d7..71fa441 100644 (file)
@@ -82,10 +82,10 @@ CsrProbeForWrite(IN PVOID Address,
 /*
  * @implemented
  */
-PVOID
+PCSR_CAPTURE_BUFFER
 NTAPI
-CsrAllocateCaptureBuffer(ULONG ArgumentCount,
-                         ULONG BufferSize)
+CsrAllocateCaptureBuffer(IN ULONG ArgumentCount,
+                         IN ULONG BufferSize)
 {
     PCSR_CAPTURE_BUFFER CaptureBuffer;
 
@@ -93,10 +93,13 @@ CsrAllocateCaptureBuffer(ULONG ArgumentCount,
     if (BufferSize >= MAXLONG) return NULL;
 
     /* Add the size of the header and for each pointer to the pointers */
-    BufferSize += sizeof(CSR_CAPTURE_BUFFER) + (ArgumentCount * sizeof(PVOID));
+    BufferSize += FIELD_OFFSET(CSR_CAPTURE_BUFFER, PointerOffsetsArray) + (ArgumentCount * sizeof(ULONG_PTR));
+
+    /* Align it to a 4-byte boundary */
+    BufferSize = (BufferSize + 3) & ~3;
 
     /* Allocate memory from the port heap */
-    CaptureBuffer = RtlAllocateHeap(CsrPortHeap, 0, BufferSize);
+    CaptureBuffer = RtlAllocateHeap(CsrPortHeap, HEAP_ZERO_MEMORY, BufferSize);
     if (CaptureBuffer == NULL) return NULL;
 
     /* Initialize the header */
@@ -104,12 +107,12 @@ CsrAllocateCaptureBuffer(ULONG ArgumentCount,
     CaptureBuffer->PointerCount = 0;
 
     /* Initialize all the pointers */
-    RtlZeroMemory(CaptureBuffer->PointerArray,
+    RtlZeroMemory(CaptureBuffer->PointerOffsetsArray,
                   ArgumentCount * sizeof(ULONG_PTR));
 
-    /* Point the start of the free buffer */
-    CaptureBuffer->BufferEnd = (ULONG_PTR)CaptureBuffer->PointerArray +
-                               ArgumentCount * sizeof(ULONG_PTR);
+    /* Point to the start of the free buffer */
+    CaptureBuffer->BufferEnd = (PVOID)((ULONG_PTR)CaptureBuffer->PointerOffsetsArray +
+                                       ArgumentCount * sizeof(ULONG_PTR));
 
     /* Return the address of the buffer */
     return CaptureBuffer;
@@ -120,20 +123,19 @@ CsrAllocateCaptureBuffer(ULONG ArgumentCount,
  */
 ULONG
 NTAPI
-CsrAllocateMessagePointer(PCSR_CAPTURE_BUFFER CaptureBuffer,
-                          ULONG MessageLength,
-                          PVOID *CaptureData)
+CsrAllocateMessagePointer(IN OUT PCSR_CAPTURE_BUFFER CaptureBuffer,
+                          IN ULONG MessageLength,
+                          OUT PVOID *CapturedData)
 {
-    /* If there's no data, our job is easy. */
     if (MessageLength == 0)
     {
-        *CaptureData = NULL;
-        CaptureData = NULL;
+        *CapturedData = NULL;
+        CapturedData = NULL;
     }
     else
     {
         /* Set the capture data at our current available buffer */
-        *CaptureData = (PVOID)CaptureBuffer->BufferEnd;
+        *CapturedData = CaptureBuffer->BufferEnd;
 
         /* Validate the size */
         if (MessageLength >= MAXLONG) return 0;
@@ -142,14 +144,11 @@ CsrAllocateMessagePointer(PCSR_CAPTURE_BUFFER CaptureBuffer,
         MessageLength = (MessageLength + 3) & ~3;
 
         /* Move our available buffer beyond this space */
-        CaptureBuffer->BufferEnd += MessageLength;
+        CaptureBuffer->BufferEnd = (PVOID)((ULONG_PTR)CaptureBuffer->BufferEnd + MessageLength);
     }
 
-    /* Write down this pointer in the array */
-    CaptureBuffer->PointerArray[CaptureBuffer->PointerCount] = (ULONG_PTR)CaptureData;
-
-    /* Increase the pointer count */
-    CaptureBuffer->PointerCount++;
+    /* Write down this pointer in the array and increase the count */
+    CaptureBuffer->PointerOffsetsArray[CaptureBuffer->PointerCount++] = (ULONG_PTR)CapturedData;
 
     /* Return the aligned length */
     return MessageLength;
@@ -160,19 +159,19 @@ CsrAllocateMessagePointer(PCSR_CAPTURE_BUFFER CaptureBuffer,
  */
 VOID
 NTAPI
-CsrCaptureMessageBuffer(PCSR_CAPTURE_BUFFER CaptureBuffer,
-                        PVOID MessageString,
-                        ULONG StringLength,
-                        PVOID *CapturedData)
+CsrCaptureMessageBuffer(IN OUT PCSR_CAPTURE_BUFFER CaptureBuffer,
+                        IN PVOID MessageBuffer OPTIONAL,
+                        IN ULONG MessageLength,
+                        OUT PVOID *CapturedData)
 {
     /* Simply allocate a message pointer in the buffer */
-    CsrAllocateMessagePointer(CaptureBuffer, StringLength, CapturedData);
+    CsrAllocateMessagePointer(CaptureBuffer, MessageLength, CapturedData);
 
     /* Check if there was any data */
-    if (!MessageString || !StringLength) return;
+    if (!MessageBuffer || !MessageLength) return;
 
     /* Copy the data into the buffer */
-    RtlMoveMemory(*CapturedData, MessageString, StringLength);
+    RtlMoveMemory(*CapturedData, MessageBuffer, MessageLength);
 }
 
 /*
@@ -180,14 +179,14 @@ CsrCaptureMessageBuffer(PCSR_CAPTURE_BUFFER CaptureBuffer,
  */
 VOID
 NTAPI
-CsrFreeCaptureBuffer(PCSR_CAPTURE_BUFFER CaptureBuffer)
+CsrFreeCaptureBuffer(IN PCSR_CAPTURE_BUFFER CaptureBuffer)
 {
     /* Free it from the heap */
     RtlFreeHeap(CsrPortHeap, 0, CaptureBuffer);
 }
 
 /*
- * @implemented
+ * @unimplemented
  */
 NTSTATUS
 NTAPI
@@ -206,8 +205,8 @@ CsrCaptureMessageMultiUnicodeStringsInPlace(IN PCSR_CAPTURE_BUFFER *CaptureBuffe
  */
 VOID
 NTAPI
-CsrCaptureMessageString(PCSR_CAPTURE_BUFFER CaptureBuffer,
-                        LPSTR String,
+CsrCaptureMessageString(IN OUT PCSR_CAPTURE_BUFFER CaptureBuffer,
+                        IN LPSTR String OPTIONAL,
                         IN ULONG StringLength,
                         IN ULONG MaximumLength,
                         OUT PANSI_STRING CapturedString)
@@ -256,14 +255,14 @@ CsrCaptureMessageString(PCSR_CAPTURE_BUFFER CaptureBuffer,
  */
 PLARGE_INTEGER
 NTAPI
-CsrCaptureTimeout(LONG Milliseconds,
-                  PLARGE_INTEGER Timeout)
+CsrCaptureTimeout(IN ULONG Milliseconds,
+                  OUT PLARGE_INTEGER Timeout)
 {
     /* Validate the time */
     if (Milliseconds == -1) return NULL;
 
     /* Convert to relative ticks */
-    Timeout->QuadPart = Milliseconds * -100000;
+    Timeout->QuadPart = Int32x32To64(Milliseconds, -100000);
     return Timeout;
 }
 
index 27fbb74..b142e16 100644 (file)
@@ -51,120 +51,113 @@ CsrClientCallServer(IN OUT PCSR_API_MESSAGE ApiMessage,
                     IN ULONG DataLength)
 {
     NTSTATUS Status;
-    ULONG PointerCount;
-    PULONG_PTR Pointers;
-    ULONG_PTR CurrentPointer;
-    DPRINT("CsrClientCallServer\n");
+    ULONG i;
 
-    /* Fill out the Port Message Header */
+    /* Fill out the Port Message Header. */
     ApiMessage->Header.u2.ZeroInit = 0;
     ApiMessage->Header.u1.s1.TotalLength =
         FIELD_OFFSET(CSR_API_MESSAGE, Data) + DataLength;
-        /* FIELD_OFFSET(CSR_API_MESSAGE, Data) <= sizeof(CSR_API_MESSAGE) - sizeof(ApiMessage->Data) */
     ApiMessage->Header.u1.s1.DataLength =
         ApiMessage->Header.u1.s1.TotalLength - sizeof(PORT_MESSAGE);
 
-    /* Fill out the CSR Header */
+    /* Fill out the CSR Header. */
     ApiMessage->ApiNumber = ApiNumber;
     ApiMessage->CsrCaptureData = NULL;
 
-    DPRINT("API: %lx, u1.s1.DataLength: %x, u1.s1.TotalLength: %x\n", 
+    DPRINT("API: %lx, u1.s1.DataLength: %x, u1.s1.TotalLength: %x\n",
            ApiNumber,
            ApiMessage->Header.u1.s1.DataLength,
            ApiMessage->Header.u1.s1.TotalLength);
                 
-    /* Check if we are already inside a CSR Server */
+    /* Check if we are already inside a CSR Server. */
     if (!InsideCsrProcess)
     {
-        /* Check if we got a a Capture Buffer */
+        /* Check if we got a Capture Buffer. */
         if (CaptureBuffer)
         {
-            /* We have to convert from our local view to the remote view */
-            ApiMessage->CsrCaptureData = (PVOID)((ULONG_PTR)CaptureBuffer +
-                                                 CsrPortMemoryDelta);
-
-            /* Lock the buffer */
-            CaptureBuffer->BufferEnd = 0;
-
-            /* Get the pointer information */
-            PointerCount = CaptureBuffer->PointerCount;
-            Pointers = CaptureBuffer->PointerArray;
-
-            /* Loop through every pointer and convert it */
-            DPRINT("PointerCount: %lx\n", PointerCount);
-            while (PointerCount--)
+            /*
+             * We have to convert from our local (client) view
+             * to the remote (server) view.
+             */
+            ApiMessage->CsrCaptureData = (PCSR_CAPTURE_BUFFER)
+                ((ULONG_PTR)CaptureBuffer + CsrPortMemoryDelta);
+
+            /* Lock the buffer. */
+            CaptureBuffer->BufferEnd = NULL;
+
+            /*
+             * Each client pointer inside the CSR message is converted into
+             * a server pointer, and each pointer to these message pointers
+             * is converted into an offset.
+             */
+            for (i = 0 ; i < CaptureBuffer->PointerCount ; ++i)
             {
-                /* Get this pointer and check if it's valid */
-                DPRINT("Array Address: %p. This pointer: %p. Data: %lx\n",
-                        &Pointers, Pointers, *Pointers);
-                if ((CurrentPointer = *Pointers++))
+                if (CaptureBuffer->PointerOffsetsArray[i] != 0)
                 {
-                    /* Update it */
-                    DPRINT("CurrentPointer: %lx.\n", *(PULONG_PTR)CurrentPointer);
-                    *(PULONG_PTR)CurrentPointer += CsrPortMemoryDelta;
-                    Pointers[-1] = CurrentPointer - (ULONG_PTR)ApiMessage;
-                    DPRINT("CurrentPointer: %lx.\n", *(PULONG_PTR)CurrentPointer);
+                    *(PULONG_PTR)CaptureBuffer->PointerOffsetsArray[i] += CsrPortMemoryDelta;
+                    CaptureBuffer->PointerOffsetsArray[i] -= (ULONG_PTR)ApiMessage;
                 }
             }
         }
 
-        /* Send the LPC Message */
+        /* Send the LPC Message. */
         Status = NtRequestWaitReplyPort(CsrApiPort,
                                         &ApiMessage->Header,
                                         &ApiMessage->Header);
 
-        /* Check if we got a a Capture Buffer */
+        /* Check if we got a Capture Buffer. */
         if (CaptureBuffer)
         {
-            /* We have to convert back from the remote view to our local view */
-            DPRINT("Reconverting CaptureBuffer\n");
-            ApiMessage->CsrCaptureData = (PVOID)((ULONG_PTR)
-                                                 ApiMessage->CsrCaptureData -
-                                                 CsrPortMemoryDelta);
-
-            /* Get the pointer information */
-            PointerCount = CaptureBuffer->PointerCount;
-            Pointers = CaptureBuffer->PointerArray;
-
-            /* Loop through every pointer and convert it */
-            while (PointerCount--)
+            /*
+             * We have to convert back from the remote (server) view
+             * to our local (client) view.
+             */
+            ApiMessage->CsrCaptureData = (PCSR_CAPTURE_BUFFER)
+                ((ULONG_PTR)ApiMessage->CsrCaptureData - CsrPortMemoryDelta);
+
+            /*
+             * Convert back the offsets into pointers to CSR message
+             * pointers, and convert back these message server pointers
+             * into client pointers.
+             */
+            for (i = 0 ; i < CaptureBuffer->PointerCount ; ++i)
             {
-                /* Get this pointer and check if it's valid */
-                if ((CurrentPointer = *Pointers++))
+                if (CaptureBuffer->PointerOffsetsArray[i] != 0)
                 {
-                    /* Update it */
-                    CurrentPointer += (ULONG_PTR)ApiMessage;
-                    Pointers[-1] = CurrentPointer;
-                    *(PULONG_PTR)CurrentPointer -= CsrPortMemoryDelta;
+                    CaptureBuffer->PointerOffsetsArray[i] += (ULONG_PTR)ApiMessage;
+                    *(PULONG_PTR)CaptureBuffer->PointerOffsetsArray[i] -= CsrPortMemoryDelta;
                 }
             }
         }
 
-        /* Check for success */
+        /* Check for success. */
         if (!NT_SUCCESS(Status))
         {
-            /* We failed. Overwrite the return value with the failure */
+            /* We failed. Overwrite the return value with the failure. */
             DPRINT1("LPC Failed: %lx\n", Status);
             ApiMessage->Status = Status;
         }
     }
     else
     {
-        /* This is a server-to-server call. Save our CID and do a direct call */
+        /* This is a server-to-server call. Save our CID and do a direct call. */
         DPRINT1("Next gen server-to-server call\n");
+
+        /* We check this equality inside CsrValidateMessageBuffer. */
         ApiMessage->Header.ClientId = NtCurrentTeb()->ClientId;
+
         Status = CsrServerApiRoutine(&ApiMessage->Header,
                                      &ApiMessage->Header);
-       
-        /* Check for success */
+
+        /* Check for success. */
         if (!NT_SUCCESS(Status))
         {
-            /* We failed. Overwrite the return value with the failure */
+            /* We failed. Overwrite the return value with the failure. */
             ApiMessage->Status = Status;
         }
     }
 
-    /* Return the CSR Result */
+    /* Return the CSR Result. */
     DPRINT("Got back: 0x%lx\n", ApiMessage->Status);
     return ApiMessage->Status;
 }
@@ -203,7 +196,7 @@ CsrpConnectToServer(IN PWSTR ObjectDirectory)
     PortName.MaximumLength = PortNameLength;
 
     /* Allocate a buffer for it */
-    PortName.Buffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, PortNameLength);
+    PortName.Buffer = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, PortNameLength);
     if (PortName.Buffer == NULL)
     {
         return STATUS_INSUFFICIENT_RESOURCES;
@@ -307,6 +300,8 @@ CsrpConnectToServer(IN PWSTR ObjectDirectory)
                                 0);
     if (CsrPortHeap == NULL)
     {
+        /* Failure */
+        DPRINT1("Couldn't create heap for CSR port\n");
         NtClose(CsrApiPort);
         CsrApiPort = NULL;
         return STATUS_INSUFFICIENT_RESOURCES;
@@ -332,9 +327,9 @@ CsrClientConnectToServer(IN PWSTR ObjectDirectory,
     UNICODE_STRING CsrSrvName;
     HANDLE hCsrSrv;
     ANSI_STRING CsrServerRoutineName;
-    PCSR_CAPTURE_BUFFER CaptureBuffer;
     CSR_API_MESSAGE ApiMessage;
     PCSR_CLIENT_CONNECT ClientConnect = &ApiMessage.Data.CsrClientConnect;
+    PCSR_CAPTURE_BUFFER CaptureBuffer;
 
     /* Validate the Connection Info */
     DPRINT("CsrClientConnectToServer: %lx %p\n", ServerId, ConnectionInfo);
@@ -419,15 +414,11 @@ CsrClientConnectToServer(IN PWSTR ObjectDirectory,
             return STATUS_INSUFFICIENT_RESOURCES;
         }
 
-        /* Allocate a pointer for the connection info*/
-        CsrAllocateMessagePointer(CaptureBuffer,
-                                  ClientConnect->ConnectionInfoSize,
-                                  &ClientConnect->ConnectionInfo);
-
-        /* Copy the data into the buffer */
-        RtlMoveMemory(ClientConnect->ConnectionInfo,
-                      ConnectionInfo,
-                      ClientConnect->ConnectionInfoSize);
+        /* Capture the connection info data */
+        CsrCaptureMessageBuffer(CaptureBuffer,
+                                ConnectionInfo,
+                                ClientConnect->ConnectionInfoSize,
+                                &ClientConnect->ConnectionInfo);
 
         /* Return the allocated length */
         *ConnectionInfoSize = ClientConnect->ConnectionInfoSize;
index 7586c39..1516860 100644 (file)
@@ -38,27 +38,40 @@ CsrClientCallServer(IN OUT PCSR_API_MESSAGE ApiMessage,
                     IN CSR_API_NUMBER ApiNumber,
                     IN ULONG DataLength);
 
-PVOID
+PCSR_CAPTURE_BUFFER
 NTAPI
 CsrAllocateCaptureBuffer(IN ULONG ArgumentCount,
                          IN ULONG BufferSize);
 
-VOID
-NTAPI
-CsrFreeCaptureBuffer(IN PCSR_CAPTURE_BUFFER CaptureBuffer);
-
 ULONG
 NTAPI
 CsrAllocateMessagePointer(IN OUT PCSR_CAPTURE_BUFFER CaptureBuffer,
                           IN ULONG MessageLength,
-                          OUT PVOID* CaptureData);
+                          OUT PVOID *CapturedData);
 
 VOID
 NTAPI
 CsrCaptureMessageBuffer(IN OUT PCSR_CAPTURE_BUFFER CaptureBuffer,
-                        IN PVOID MessageString,
+                        IN PVOID MessageBuffer OPTIONAL,
+                        IN ULONG MessageLength,
+                        OUT PVOID *CapturedData);
+
+VOID
+NTAPI
+CsrCaptureMessageString(IN OUT PCSR_CAPTURE_BUFFER CaptureBuffer,
+                        IN LPSTR String OPTIONAL,
                         IN ULONG StringLength,
-                        OUT PVOID* CapturedData);
+                        IN ULONG MaximumLength,
+                        OUT PANSI_STRING CapturedString);
+
+VOID
+NTAPI
+CsrFreeCaptureBuffer(IN PCSR_CAPTURE_BUFFER CaptureBuffer);
+
+PLARGE_INTEGER
+NTAPI
+CsrCaptureTimeout(IN ULONG Milliseconds,
+                  OUT PLARGE_INTEGER Timeout);
 
 VOID
 NTAPI
index c6d129b..a64bfff 100644 (file)
@@ -93,8 +93,8 @@ typedef struct _CSR_CAPTURE_BUFFER
     ULONG Size;
     struct _CSR_CAPTURE_BUFFER *PreviousCaptureBuffer;
     ULONG PointerCount;
-    ULONG_PTR BufferEnd;
-    ULONG_PTR PointerArray[1];
+    PVOID BufferEnd;
+    ULONG_PTR PointerOffsetsArray[ANYSIZE_ARRAY];
 } CSR_CAPTURE_BUFFER, *PCSR_CAPTURE_BUFFER;
 
 /* Keep in sync with definition below. */
index 22c1941..ae0db7d 100644 (file)
@@ -24,7 +24,7 @@
 /* TYPES **********************************************************************/
 
 // Used in ntdll/csr/connect.c
-#define CSR_CSRSS_SECTION_SIZE    (65536)
+#define CSR_CSRSS_SECTION_SIZE  65536
 
 typedef struct _CSR_NT_SESSION
 {
@@ -33,21 +33,6 @@ typedef struct _CSR_NT_SESSION
     ULONG SessionId;
 } CSR_NT_SESSION, *PCSR_NT_SESSION;
 
-/*** old thingie, remove it later... (put it in winsrv -- console) ***/
-#include <win/conmsg.h>
-typedef struct _CSRSS_CON_PROCESS_DATA
-{
-    HANDLE ConsoleEvent;
-    struct tagCSRSS_CONSOLE *Console;
-    struct tagCSRSS_CONSOLE *ParentConsole;
-    BOOL bInheritHandles;
-    RTL_CRITICAL_SECTION HandleTableLock;
-    ULONG HandleTableSize;
-    struct _CSRSS_HANDLE *HandleTable;
-    PCONTROLDISPATCHER CtrlDispatcher;
-    LIST_ENTRY ConsoleLink;
-} CSRSS_CON_PROCESS_DATA, *PCSRSS_CON_PROCESS_DATA;
-/*********************************************************************/
 typedef struct _CSR_PROCESS
 {
     CLIENT_ID ClientId;
@@ -73,8 +58,7 @@ typedef struct _CSR_PROCESS
     ULONG Reserved;
     ULONG ShutdownLevel;
     ULONG ShutdownFlags;
-    PVOID ServerData[ANYSIZE_ARRAY]; // ServerDllPerProcessData // One structure per CSR server.
-    CSRSS_CON_PROCESS_DATA; //// FIXME: Remove it after we activate the previous member.
+    PVOID ServerData[ANYSIZE_ARRAY];    // One structure per CSR server.
 } CSR_PROCESS, *PCSR_PROCESS;
 
 typedef struct _CSR_THREAD
@@ -181,10 +165,10 @@ NTSTATUS
     OUT PULONG Reply
 );
 
-#define CSR_API(n) NTSTATUS NTAPI n(    \
-    IN OUT PCSR_API_MESSAGE ApiMessage, \
-    OUT PULONG Reply)
-    // IN OUT PCSR_REPLY_STATUS ReplyStatus)
+#define CSR_API(n)                                          \
+    NTSTATUS NTAPI n(IN OUT PCSR_API_MESSAGE ApiMessage,    \
+                     OUT PULONG Reply)
+                     // IN OUT PCSR_REPLY_STATUS ReplyStatus)
 
 typedef
 NTSTATUS
@@ -250,7 +234,8 @@ typedef
 NTSTATUS
 (NTAPI *PCSR_SERVER_DLL_INIT_CALLBACK)(IN PCSR_SERVER_DLL LoadedServerDll);
 
-#define CSR_SERVER_DLL_INIT(n) NTSTATUS NTAPI n(IN PCSR_SERVER_DLL LoadedServerDll)
+#define CSR_SERVER_DLL_INIT(n)  \
+    NTSTATUS NTAPI n(IN PCSR_SERVER_DLL LoadedServerDll)
 
 
 /* PROTOTYPES ****************************************************************/
@@ -306,7 +291,8 @@ NTSTATUS
 NTAPI
 CsrCreateThread(IN PCSR_PROCESS CsrProcess,
                 IN HANDLE hThread,
-                IN PCLIENT_ID ClientId);
+                IN PCLIENT_ID ClientId,
+                IN BOOLEAN HaveClient);
 
 BOOLEAN
 NTAPI
@@ -431,8 +417,8 @@ BOOLEAN
 NTAPI
 CsrValidateMessageBuffer(IN PCSR_API_MESSAGE ApiMessage,
                          IN PVOID *Buffer,
-                         IN ULONG ArgumentSize,
-                         IN ULONG ArgumentCount);
+                         IN ULONG ElementCount,
+                         IN ULONG ElementSize);
 
 BOOLEAN
 NTAPI
index 111cf89..854a26e 100644 (file)
 
 #include "srv.h"
 
-#define NDEBUG
+//#define NDEBUG
 #include <debug.h>
 
 /* GLOBALS ********************************************************************/
 
-static unsigned ApiDefinitionsCount = 0;
-static PCSRSS_API_DEFINITION ApiDefinitions = NULL;
-
 BOOLEAN (*CsrClientThreadSetup)(VOID) = NULL;
 UNICODE_STRING CsrApiPortName;
 volatile LONG CsrpStaticThreadCount;
@@ -27,88 +24,6 @@ extern ULONG CsrMaxApiRequestThreads;
 
 /* FUNCTIONS ******************************************************************/
 
-#if 0
-NTSTATUS FASTCALL
-CsrApiRegisterDefinitions(PCSRSS_API_DEFINITION NewDefinitions)
-{
-  unsigned NewCount;
-  PCSRSS_API_DEFINITION Scan;
-  PCSRSS_API_DEFINITION New;
-
-  DPRINT("CSR: %s called\n", __FUNCTION__);
-
-  NewCount = 0;
-  for (Scan = NewDefinitions; 0 != Scan->Handler; Scan++)
-    {
-      NewCount++;
-    }
-
-  New = RtlAllocateHeap(CsrHeap, 0,
-                        (ApiDefinitionsCount + NewCount)
-                        * sizeof(CSRSS_API_DEFINITION));
-  if (NULL == New)
-    {
-      DPRINT1("Unable to allocate memory\n");
-      return STATUS_NO_MEMORY;
-    }
-  if (0 != ApiDefinitionsCount)
-    {
-      RtlCopyMemory(New, ApiDefinitions,
-                    ApiDefinitionsCount * sizeof(CSRSS_API_DEFINITION));
-      RtlFreeHeap(CsrHeap, 0, ApiDefinitions);
-    }
-  RtlCopyMemory(New + ApiDefinitionsCount, NewDefinitions,
-                NewCount * sizeof(CSRSS_API_DEFINITION));
-  ApiDefinitions = New;
-  ApiDefinitionsCount += NewCount;
-
-  return STATUS_SUCCESS;
-}
-#endif
-
-/*
-VOID
-FASTCALL
-CsrApiCallHandler(PCSR_PROCESS ProcessData,
-                  PCSR_API_MESSAGE Request)
-*/
-VOID
-FASTCALL
-CsrApiCallHandler(
-    IN OUT PCSR_API_MESSAGE ApiMessage,
-    OUT PULONG Reply
-)
-{
-  unsigned DefIndex;
-  ULONG ApiId;
-
-  DPRINT("CSR: Calling handler for ApiNumber: %x.\n", ApiMessage->ApiNumber);
-  ApiId = CSR_API_NUMBER_TO_API_ID(ApiMessage->ApiNumber);
-  DPRINT("CSR: ApiID: %x ServerID: %x\n", ApiId, CSR_API_NUMBER_TO_SERVER_ID(ApiMessage->ApiNumber));
-
-  /* FIXME: Extract DefIndex instead of looping */
-  for (DefIndex = 0; DefIndex < ApiDefinitionsCount; DefIndex++)
-    {
-      if (ApiDefinitions[DefIndex].ApiID == ApiId)
-        {
-          if (ApiMessage->Header.u1.s1.DataLength < ApiDefinitions[DefIndex].MinRequestSize)
-            {
-              DPRINT1("Request ApiID %d min request size %d actual %d\n",
-                      ApiId, ApiDefinitions[DefIndex].MinRequestSize,
-                      ApiMessage->Header.u1.s1.DataLength);
-              ApiMessage->Status = STATUS_INVALID_PARAMETER;
-            }
-          else
-            {
-              ApiMessage->Status = (ApiDefinitions[DefIndex].Handler)(ApiMessage, Reply);
-            }
-          return;
-        }
-    }
-  DPRINT1("CSR: Unknown request ApiNumber 0x%x\n", ApiMessage->ApiNumber);
-  ApiMessage->Status = STATUS_INVALID_SYSTEM_SERVICE;
-}
-
 VOID
 CallHardError(IN PCSR_THREAD ThreadData,
               IN PHARDERROR_MSG HardErrorMessage);
@@ -152,7 +67,6 @@ NTAPI
 CsrCallServerFromServer(IN PCSR_API_MESSAGE ReceiveMsg,
                         IN OUT PCSR_API_MESSAGE ReplyMsg)
 {
-#if 1 // Real code
     ULONG ServerId;
     PCSR_SERVER_DLL ServerDll;
     ULONG ApiId;
@@ -173,11 +87,8 @@ CsrCallServerFromServer(IN PCSR_API_MESSAGE ReceiveMsg,
     }
     else
     {
-        /* Get the API ID */
-        ApiId = CSR_API_NUMBER_TO_API_ID(ReceiveMsg->ApiNumber);
-
-        /* Normalize it with our Base ID */
-        ApiId -= ServerDll->ApiBase;
+        /* Get the API ID, normalized with our Base ID */
+        ApiId = CSR_API_NUMBER_TO_API_ID(ReceiveMsg->ApiNumber) - ServerDll->ApiBase;
 
         /* Make sure that the ID is within limits, and the entry exists */
         if ((ApiId >= ServerDll->HighestApiSupported) ||
@@ -220,40 +131,6 @@ CsrCallServerFromServer(IN PCSR_API_MESSAGE ReceiveMsg,
 
     /* Return success */
     return STATUS_SUCCESS;
-
-#else // Hacky reactos code
-
-    PCSR_PROCESS ProcessData;
-    ULONG ReplyCode;
-
-    /* Get the Process Data */
-    CsrLockProcessByClientId(&ReceiveMsg->Header.ClientId.UniqueProcess, &ProcessData);
-    if (!ProcessData)
-    {
-        DPRINT1("Message: Unable to find data for process 0x%x\n",
-                ReceiveMsg->Header.ClientId.UniqueProcess);
-        return STATUS_NOT_SUPPORTED;
-    }
-
-    /* Validation complete, start SEH */
-    _SEH2_TRY
-    {
-        /* Call the API and get the result */
-        CsrApiCallHandler(ReplyMsg, /*ProcessData*/ &ReplyCode);
-    }
-    _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
-    {
-        /* If we got an exception, return access violation */
-        ReplyMsg->Status = STATUS_ACCESS_VIOLATION;
-    }
-    _SEH2_END;
-
-    /* Release the process reference */
-    CsrUnlockProcess(ProcessData);
-
-    /* Return success */
-    return STATUS_SUCCESS;
-#endif
 }
 
 /*++
@@ -391,6 +268,107 @@ CsrApiHandleConnectionRequest(IN PCSR_API_MESSAGE ApiMessage)
     return Status;
 }
 
+// TODO: See CsrApiHandleConnectionRequest
+NTSTATUS WINAPI
+CsrpHandleConnectionRequest(PPORT_MESSAGE Request)
+{
+    NTSTATUS Status;
+    HANDLE ServerPort = NULL;//, ServerThread = NULL;
+    PCSR_PROCESS ProcessData = NULL;
+    REMOTE_PORT_VIEW RemotePortView;
+//    CLIENT_ID ClientId;
+    BOOLEAN AllowConnection = FALSE;
+    PCSR_CONNECTION_INFO ConnectInfo;
+    ServerPort = NULL;
+
+    DPRINT1("CSR: %s: Handling: %p\n", __FUNCTION__, Request);
+
+    ConnectInfo = (PCSR_CONNECTION_INFO)(Request + 1);
+
+    /* Save the process ID */
+    RtlZeroMemory(ConnectInfo, sizeof(CSR_CONNECTION_INFO));
+
+    CsrLockProcessByClientId(Request->ClientId.UniqueProcess, &ProcessData);
+    if (!ProcessData)
+    {
+        DPRINT1("CSRSRV: Unknown process: %lx. Will be rejecting connection\n",
+                Request->ClientId.UniqueProcess);
+    }
+
+    if ((ProcessData) && (ProcessData != CsrRootProcess))
+    {
+        /* Attach the Shared Section */
+        Status = CsrSrvAttachSharedSection(ProcessData, ConnectInfo);
+        if (NT_SUCCESS(Status))
+        {
+            DPRINT1("Connection ok\n");
+            AllowConnection = TRUE;
+        }
+        else
+        {
+            DPRINT1("Shared section map failed: %lx\n", Status);
+        }
+    }
+    else if (ProcessData == CsrRootProcess)
+    {
+        AllowConnection = TRUE;
+    }
+
+    /* Release the process */
+    if (ProcessData) CsrUnlockProcess(ProcessData);
+
+    /* Setup the Port View Structure */
+    RemotePortView.Length = sizeof(REMOTE_PORT_VIEW);
+    RemotePortView.ViewSize = 0;
+    RemotePortView.ViewBase = NULL;
+
+    /* Save the Process ID */
+    ConnectInfo->ProcessId = NtCurrentTeb()->ClientId.UniqueProcess;
+
+    Status = NtAcceptConnectPort(&ServerPort,
+                                 AllowConnection ? UlongToPtr(ProcessData->SequenceNumber) : 0,
+                                 Request,
+                                 AllowConnection,
+                                 NULL,
+                                 &RemotePortView);
+    if (!NT_SUCCESS(Status))
+    {
+         DPRINT1("CSRSS: NtAcceptConnectPort - failed.  Status == %X\n", Status);
+    }
+    else if (AllowConnection)
+    {
+        if (CsrDebug & 2)
+        {
+            DPRINT1("CSRSS: ClientId: %lx.%lx has ClientView: Base=%p, Size=%lx\n",
+                    Request->ClientId.UniqueProcess,
+                    Request->ClientId.UniqueThread,
+                    RemotePortView.ViewBase,
+                    RemotePortView.ViewSize);
+        }
+
+        /* Set some Port Data in the Process */
+        ProcessData->ClientPort = ServerPort;
+        ProcessData->ClientViewBase = (ULONG_PTR)RemotePortView.ViewBase;
+        ProcessData->ClientViewBounds = (ULONG_PTR)((ULONG_PTR)RemotePortView.ViewBase +
+                                                    (ULONG_PTR)RemotePortView.ViewSize);
+
+        /* Complete the connection */
+        Status = NtCompleteConnectPort(ServerPort);
+        if (!NT_SUCCESS(Status))
+        {
+            DPRINT1("CSRSS: NtCompleteConnectPort - failed.  Status == %X\n", Status);
+        }
+    }
+    else
+    {
+        DPRINT1("CSRSS: Rejecting Connection Request from ClientId: %lx.%lx\n",
+                Request->ClientId.UniqueProcess,
+                Request->ClientId.UniqueThread);
+    }
+
+    return Status;
+}
+
 /*++
  * @name CsrpCheckRequestThreads
  *
@@ -486,7 +464,6 @@ CsrpCheckRequestThreads(VOID)
 NTSTATUS
 NTAPI
 CsrApiRequestThread(IN PVOID Parameter)
-#if 1
 {
     PTEB Teb = NtCurrentTeb();
     LARGE_INTEGER TimeOut;
@@ -649,7 +626,7 @@ CsrApiRequestThread(IN PVOID Parameter)
                         if ((ServerDll) && (ServerDll->HardErrorCallback))
                         {
                             /* Call it */
-                            ServerDll->HardErrorCallback(NULL, HardErrorMsg);
+                            ServerDll->HardErrorCallback(NULL /* CsrThread */, HardErrorMsg);
 
                             /* If it's handled, get out of here */
                             if (HardErrorMsg->Response != ResponseNotHandled) break;
@@ -697,11 +674,8 @@ CsrApiRequestThread(IN PVOID Parameter)
                     continue;
                 }
 
-                   /* Get the API ID */
-                ApiId = CSR_API_NUMBER_TO_API_ID(ReceiveMsg.ApiNumber);
-
-                /* Normalize it with our Base ID */
-                ApiId -= ServerDll->ApiBase;
+                /* Get the API ID, normalized with our Base ID */
+                ApiId = CSR_API_NUMBER_TO_API_ID(ReceiveMsg.ApiNumber) - ServerDll->ApiBase;
 
                 /* Make sure that the ID is within limits, and the entry exists */
                 if (ApiId >= ServerDll->HighestApiSupported)
@@ -897,11 +871,8 @@ CsrApiRequestThread(IN PVOID Parameter)
             continue;
         }
 
-        /* Get the API ID */
-        ApiId = CSR_API_NUMBER_TO_API_ID(ReceiveMsg.ApiNumber);
-
-        /* Normalize it with our Base ID */
-        ApiId -= ServerDll->ApiBase;
+        /* Get the API ID, normalized with our Base ID */
+        ApiId = CSR_API_NUMBER_TO_API_ID(ReceiveMsg.ApiNumber) - ServerDll->ApiBase;
 
         /* Make sure that the ID is within limits, and the entry exists */
         if (ApiId >= ServerDll->HighestApiSupported)
@@ -1007,429 +978,78 @@ CsrApiRequestThread(IN PVOID Parameter)
     NtTerminateThread(NtCurrentThread(), Status);
     return Status;
 }
-#else
+
+/*++
+ * @name CsrApiPortInitialize
+ *
+ * The CsrApiPortInitialize routine initializes the LPC Port used for
+ * communications with the Client/Server Runtime (CSR) and initializes the
+ * static thread that will handle connection requests and APIs.
+ *
+ * @param None
+ *
+ * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL
+ *         otherwise.
+ *
+ * @remarks None.
+ *
+ *--*/
+NTSTATUS
+NTAPI
+CsrApiPortInitialize(VOID)
 {
-    PTEB Teb = NtCurrentTeb();
-    LARGE_INTEGER TimeOut;
+    ULONG Size;
+    OBJECT_ATTRIBUTES ObjectAttributes;
     NTSTATUS Status;
-    BYTE RawRequest[LPC_MAX_DATA_LENGTH];
-    PCSR_API_MESSAGE Request = (PCSR_API_MESSAGE)RawRequest;
-    PCSR_API_MESSAGE Reply;
-    PCSR_PROCESS CsrProcess;
-    PCSR_THREAD ServerThread, CsrThread;
-    ULONG MessageType;
-    HANDLE ReplyPort;
-    PDBGKM_MSG DebugMessage;
-    PHARDERROR_MSG HardErrorMsg;
-    PCLIENT_DIED_MSG ClientDiedMsg;
-    DPRINT("CSR: %s called\n", __FUNCTION__);
+    HANDLE hRequestEvent, hThread;
+    CLIENT_ID ClientId;
+    PLIST_ENTRY ListHead, NextEntry;
+    PCSR_THREAD ServerThread;
 
-    /* Setup LPC loop port and message */
-    Reply = NULL;
-    ReplyPort = CsrApiPort;
+    /* Calculate how much space we'll need for the Port Name */
+    Size = CsrDirectoryName.Length + sizeof(CSR_PORT_NAME) + sizeof(WCHAR);
 
-    /* Connect to user32 */
-    while (!CsrConnectToUser())
-    {
-        /* Set up the timeout for the connect (30 seconds) */
-        TimeOut.QuadPart = -30 * 1000 * 1000 * 10;
+    /* Create the buffer for it */
+    CsrApiPortName.Buffer = RtlAllocateHeap(CsrHeap, 0, Size);
+    if (!CsrApiPortName.Buffer) return STATUS_NO_MEMORY;
 
-        /* Keep trying until we get a response */
-        Teb->Win32ClientInfo[0] = 0;
-        NtDelayExecution(FALSE, &TimeOut);
+    /* Setup the rest of the empty string */
+    CsrApiPortName.Length = 0;
+    CsrApiPortName.MaximumLength = (USHORT)Size;
+    RtlAppendUnicodeStringToString(&CsrApiPortName, &CsrDirectoryName);
+    RtlAppendUnicodeToString(&CsrApiPortName, UNICODE_PATH_SEP);
+    RtlAppendUnicodeToString(&CsrApiPortName, CSR_PORT_NAME);
+    if (CsrDebug & 1)
+    {
+        DPRINT1("CSRSS: Creating %wZ port and associated threads\n", &CsrApiPortName);
+        DPRINT1("CSRSS: sizeof( CONNECTINFO ) == %ld  sizeof( API_MSG ) == %ld\n",
+                sizeof(CSR_CONNECTION_INFO), sizeof(CSR_API_MESSAGE));
     }
 
-    /* Get our thread */
-    ServerThread = Teb->CsrClientThread;
-
-    /* If we got an event... */
-    if (Parameter)
-    {
-        /* Set it, to let stuff waiting on us load */
-        Status = NtSetEvent((HANDLE)Parameter, NULL);
-        ASSERT(NT_SUCCESS(Status));
+    /* FIXME: Create a Security Descriptor */
 
-        /* Increase the Thread Counts */
-        _InterlockedIncrement(&CsrpStaticThreadCount);
-        _InterlockedIncrement(&CsrpDynamicThreadTotal);
-    }
+    /* Initialize the Attributes */
+    InitializeObjectAttributes(&ObjectAttributes,
+                               &CsrApiPortName,
+                               0,
+                               NULL,
+                               NULL /* FIXME*/);
 
-    /* Now start the loop */
-    while (TRUE)
+    /* Create the Port Object */
+    Status = NtCreatePort(&CsrApiPort,
+                          &ObjectAttributes,
+                          LPC_MAX_DATA_LENGTH, // HACK: the real value is: sizeof(CSR_CONNECTION_INFO),
+                          LPC_MAX_MESSAGE_LENGTH, // HACK: the real value is: sizeof(CSR_API_MESSAGE),
+                          16 * PAGE_SIZE);
+    if (NT_SUCCESS(Status))
     {
-        /* Make sure the real CID is set */
-        Teb->RealClientId = Teb->ClientId;
-
-        /* Debug check */
-        if (Teb->CountOfOwnedCriticalSections)
-        {
-            DPRINT1("CSRSRV: FATAL ERROR. CsrThread is Idle while holding %lu critical sections\n",
-                    Teb->CountOfOwnedCriticalSections);
-            DPRINT1("CSRSRV: Last Receive Message %lx ReplyMessage %lx\n",
-                    Request, Reply);
-            DbgBreakPoint();
-        }
-
-        /* Send the reply and wait for a new request */
-        DPRINT("Replying to: %lx (%lx)\n", ReplyPort, CsrApiPort);
-        Status = NtReplyWaitReceivePort(ReplyPort,
-                                        0,
-                                        &Reply->Header,
-                                        &Request->Header);
-        /* Check if we didn't get success */
-        if (Status != STATUS_SUCCESS)
-        {
-            /* Was it a failure or another success code? */
-            if (!NT_SUCCESS(Status))
-            {
-                /* Check for specific status cases */
-                if ((Status != STATUS_INVALID_CID) &&
-                    (Status != STATUS_UNSUCCESSFUL) &&
-                    ((Status == STATUS_INVALID_HANDLE) || (ReplyPort == CsrApiPort)))
-                {
-                    /* Notify the debugger */
-                    DPRINT1("CSRSS: ReceivePort failed - Status == %X\n", Status);
-                    DPRINT1("CSRSS: ReplyPortHandle %lx CsrApiPort %lx\n", ReplyPort, CsrApiPort);
-                }
-
-                /* We failed big time, so start out fresh */
-                Reply = NULL;
-                ReplyPort = CsrApiPort;
-                DPRINT1("failed: %lx\n", Status);
-                continue;
-            }
-            else
-            {
-                /* A bizare "success" code, just try again */
-                DPRINT1("NtReplyWaitReceivePort returned \"success\" status 0x%x\n", Status);
-                continue;
-            }
-        }
-
-        /* Use whatever Client ID we got */
-        Teb->RealClientId = Request->Header.ClientId;
-
-        /* Get the Message Type */
-        MessageType = Request->Header.u2.s2.Type;
-
-        /* Handle connection requests */
-        if (MessageType == LPC_CONNECTION_REQUEST)
-        {
-            /* Handle the Connection Request */
-            DPRINT("Accepting new connection\n");
-            CsrpHandleConnectionRequest((PPORT_MESSAGE)Request);
-            Reply = NULL;
-            ReplyPort = CsrApiPort;
-            continue;
-        }
-
-        /* It's some other kind of request. Get the lock for the lookup */
-        CsrAcquireProcessLock();
-
-        /* Now do the lookup to get the CSR_THREAD */
-        CsrThread = CsrLocateThreadByClientId(&CsrProcess,
-                                              &Request->Header.ClientId);
-
-        /* Did we find a thread? */
-        if (!CsrThread)
-        {
-            /* This wasn't a CSR Thread, release lock */
-            CsrReleaseProcessLock();
-
-            /* If this was an exception, handle it */
-            if (MessageType == LPC_EXCEPTION)
-            {
-                DPRINT1("Exception from unknown thread, just continue\n");
-                Reply = Request;
-                ReplyPort = CsrApiPort;
-                Reply->Status = DBG_CONTINUE;
-            }
-            else if (MessageType == LPC_PORT_CLOSED ||
-                     MessageType == LPC_CLIENT_DIED)
-            {
-                /* The Client or Port are gone, loop again */
-                DPRINT("Death from unknown thread, just continue\n");
-                Reply = NULL;
-                ReplyPort = CsrApiPort;
-            }
-            else if (MessageType == LPC_ERROR_EVENT)
-            {
-                /* If it's a hard error, handle this too */
-                DPRINT1("Hard error from unknown thread, call handlers\n");
-HandleHardError:
-                HardErrorMsg = (PHARDERROR_MSG)Request;
-
-                /* Default it to unhandled */
-                HardErrorMsg->Response = ResponseNotHandled;
-
-                /* Check if there are free api threads */
-                CsrpCheckRequestThreads();
-                if (CsrpStaticThreadCount)
-                {
-                    CsrHandleHardError(CsrThread, (PHARDERROR_MSG)Request);
-                }
-
-                /* If the response was 0xFFFFFFFF, we'll ignore it */
-                if (HardErrorMsg->Response == 0xFFFFFFFF)
-                {
-                    Reply = NULL;
-                    ReplyPort = CsrApiPort;
-                }
-                else
-                {
-                    if (CsrThread) CsrDereferenceThread(CsrThread);
-                    Reply = Request;
-                    ReplyPort = CsrApiPort;
-                }
-            }
-            else if (MessageType == LPC_REQUEST)
-            {
-                /* This is an API Message coming from a non-CSR Thread */
-                DPRINT1("No thread found for request %lx and clientID %lx.%lx\n",
-                        Request->ApiNumber & 0xFFFF,
-                        Request->Header.ClientId.UniqueProcess,
-                        Request->Header.ClientId.UniqueThread);
-                Reply = Request;
-                ReplyPort = CsrApiPort;
-                Reply->Status = STATUS_ILLEGAL_FUNCTION;
-            }
-            else if (MessageType == LPC_DATAGRAM)
-            {
-                DPRINT1("Kernel datagram: not yet supported\n");
-                Reply = NULL;
-                ReplyPort = CsrApiPort;
-            }
-            else
-            {
-                /* Some other ignored message type */
-                Reply = NULL;
-                ReplyPort = CsrApiPort;
-            }
-
-            /* Keep going */
-            continue;
-        }
-
-        /* We have a valid thread, was this an LPC Request? */
-        if (MessageType != LPC_REQUEST)
-        {
-            /* It's not an API, check if the client died */
-            if (MessageType == LPC_CLIENT_DIED)
-            {
-                /* Get the information and check if it matches our thread */
-                ClientDiedMsg = (PCLIENT_DIED_MSG)Request;
-                if (ClientDiedMsg->CreateTime.QuadPart == CsrThread->CreateTime.QuadPart)
-                {
-                    /* Reference the thread */
-                    CsrLockedReferenceThread(CsrThread);
-
-                    /* Destroy the thread in the API Message */
-                    CsrDestroyThread(&Request->Header.ClientId);
-
-                    /* Check if the thread was actually ourselves */
-                    if (CsrProcess->ThreadCount == 1)
-                    {
-                        /* Kill the process manually here */
-                        DPRINT1("Last thread\n");
-                        CsrDestroyProcess(&CsrThread->ClientId, 0);
-                    }
-
-                    /* Remove our extra reference */
-                    CsrLockedDereferenceThread(CsrThread);
-                }
-
-                /* Release the lock and keep looping */
-                CsrReleaseProcessLock();
-                Reply = NULL;
-                ReplyPort = CsrApiPort;
-                continue;
-            }
-
-            /* Reference the thread and release the lock */
-            CsrLockedReferenceThread(CsrThread);
-            CsrReleaseProcessLock();
-
-            /* If this was an exception, handle it */
-            if (MessageType == LPC_EXCEPTION)
-            {
-                /* Kill the process */
-                DPRINT1("Exception in %lx.%lx. Killing...\n",
-                        Request->Header.ClientId.UniqueProcess,
-                        Request->Header.ClientId.UniqueThread);
-                NtTerminateProcess(CsrProcess->ProcessHandle, STATUS_ABANDONED);
-
-                /* Destroy it from CSR */
-                CsrDestroyProcess(&Request->Header.ClientId, STATUS_ABANDONED);
-
-                /* Return a Debug Message */
-                DebugMessage = (PDBGKM_MSG)Request;
-                DebugMessage->ReturnedStatus = DBG_CONTINUE;
-                Reply = Request;
-                ReplyPort = CsrApiPort;
-
-                /* Remove our extra reference */
-                CsrDereferenceThread(CsrThread);
-            }
-            else if (MessageType == LPC_ERROR_EVENT)
-            {
-                DPRINT1("Hard error from known CSR thread... handling\n");
-                goto HandleHardError;
-            }
-            else
-            {
-                /* Something else */
-                DPRINT1("Unhandled message type: %lx\n", MessageType);
-                CsrDereferenceThread(CsrThread);
-                Reply = NULL;
-            }
-
-            /* Keep looping */
-            continue;
-        }
-
-        /* We got an API Request */
-        CsrLockedReferenceThread(CsrThread);
-        CsrReleaseProcessLock();
-
-        /* Assume success */
-        Reply = Request;
-        Request->Status = STATUS_SUCCESS;
-
-        /* Now we reply to a particular client */
-        ReplyPort = CsrThread->Process->ClientPort;
-
-        DPRINT("CSR: Got CSR API: %x [Message Origin: %x]\n",
-                Request->ApiNumber,
-                Request->Header.ClientId.UniqueThread);
-
-        /* Validation complete, start SEH */
-        _SEH2_TRY
-        {
-            ULONG ReplyCode;
-
-            /* Make sure we have enough threads */
-            CsrpCheckRequestThreads();
-
-            /* Set the client thread pointer */
-            NtCurrentTeb()->CsrClientThread = CsrThread;
-
-            /* Call the Handler */
-            CsrApiCallHandler(Request, &ReplyCode);
-
-            /* Increase the static thread count */
-            _InterlockedIncrement(&CsrpStaticThreadCount);
-
-            /* Restore the server thread */
-            NtCurrentTeb()->CsrClientThread = ServerThread;
-
-            /* Check if this is a dead client now */
-            if (Request->ApiNumber == 0xBABE)
-            {
-                /* Reply to the death message */
-                NtReplyPort(ReplyPort, &Reply->Header);
-
-                /* Reply back to the API port now */
-                ReplyPort = CsrApiPort;
-                Reply = NULL;
-
-                /* Drop the reference */
-                CsrDereferenceThread(CsrThread);
-            }
-            else
-            {
-                /* Drop the reference */
-                CsrDereferenceThread(CsrThread);
-            }
-        }
-        _SEH2_EXCEPT(CsrUnhandledExceptionFilter(_SEH2_GetExceptionInformation()))
-        {
-            Reply = NULL;
-            ReplyPort = CsrApiPort;
-        }
-        _SEH2_END;
-    }
-
-    /* Close the port and exit the thread */
-    // NtClose(ServerPort);
-
-    DPRINT1("CSR: %s done\n", __FUNCTION__);
-    /* We're out of the loop for some reason, terminate! */
-    NtTerminateThread(NtCurrentThread(), Status);
-    //return Status;
-}
-#endif
-
-/*++
- * @name CsrApiPortInitialize
- *
- * The CsrApiPortInitialize routine initializes the LPC Port used for
- * communications with the Client/Server Runtime (CSR) and initializes the
- * static thread that will handle connection requests and APIs.
- *
- * @param None
- *
- * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL
- *         otherwise.
- *
- * @remarks None.
- *
- *--*/
-NTSTATUS
-NTAPI
-CsrApiPortInitialize(VOID)
-{
-    ULONG Size;
-    OBJECT_ATTRIBUTES ObjectAttributes;
-    NTSTATUS Status;
-    HANDLE hRequestEvent, hThread;
-    CLIENT_ID ClientId;
-    PLIST_ENTRY ListHead, NextEntry;
-    PCSR_THREAD ServerThread;
-
-    /* Calculate how much space we'll need for the Port Name */
-    Size = CsrDirectoryName.Length + sizeof(CSR_PORT_NAME) + sizeof(WCHAR);
-
-    /* Create the buffer for it */
-    CsrApiPortName.Buffer = RtlAllocateHeap(CsrHeap, 0, Size);
-    if (!CsrApiPortName.Buffer) return STATUS_NO_MEMORY;
-
-    /* Setup the rest of the empty string */
-    CsrApiPortName.Length = 0;
-    CsrApiPortName.MaximumLength = (USHORT)Size;
-    RtlAppendUnicodeStringToString(&CsrApiPortName, &CsrDirectoryName);
-    RtlAppendUnicodeToString(&CsrApiPortName, UNICODE_PATH_SEP);
-    RtlAppendUnicodeToString(&CsrApiPortName, CSR_PORT_NAME);
-    if (CsrDebug & 1)
-    {
-        DPRINT1("CSRSS: Creating %wZ port and associated threads\n", &CsrApiPortName);
-        DPRINT1("CSRSS: sizeof( CONNECTINFO ) == %ld  sizeof( API_MSG ) == %ld\n",
-                sizeof(CSR_CONNECTION_INFO), sizeof(CSR_API_MESSAGE));
-    }
-
-    /* FIXME: Create a Security Descriptor */
-
-    /* Initialize the Attributes */
-    InitializeObjectAttributes(&ObjectAttributes,
-                               &CsrApiPortName,
-                               0,
-                               NULL,
-                               NULL /* FIXME*/);
-
-    /* Create the Port Object */
-    Status = NtCreatePort(&CsrApiPort,
-                          &ObjectAttributes,
-                          LPC_MAX_DATA_LENGTH, // hack ; sizeof(CSR_CONNECTION_INFO),
-                          LPC_MAX_MESSAGE_LENGTH, // hack ; sizeof(CSR_API_MESSAGE),
-                          16 * PAGE_SIZE);
-    if (NT_SUCCESS(Status))
-    {
-        /* Create the event the Port Thread will use */
-        Status = NtCreateEvent(&hRequestEvent,
-                               EVENT_ALL_ACCESS,
-                               NULL,
-                               SynchronizationEvent,
-                               FALSE);
-        if (NT_SUCCESS(Status))
+        /* Create the event the Port Thread will use */
+        Status = NtCreateEvent(&hRequestEvent,
+                               EVENT_ALL_ACCESS,
+                               NULL,
+                               SynchronizationEvent,
+                               FALSE);
+        if (NT_SUCCESS(Status))
         {
             /* Create the Request Thread */
             Status = RtlCreateUserThread(NtCurrentProcess(),
@@ -1482,106 +1102,6 @@ CsrApiPortInitialize(VOID)
     return Status;
 }
 
-NTSTATUS WINAPI
-CsrpHandleConnectionRequest(PPORT_MESSAGE Request)
-{
-    NTSTATUS Status;
-    HANDLE ServerPort = NULL;//, ServerThread = NULL;
-    PCSR_PROCESS ProcessData = NULL;
-    REMOTE_PORT_VIEW RemotePortView;
-//    CLIENT_ID ClientId;
-    BOOLEAN AllowConnection = FALSE;
-    PCSR_CONNECTION_INFO ConnectInfo;
-    ServerPort = NULL;
-
-    DPRINT("CSR: %s: Handling: %p\n", __FUNCTION__, Request);
-
-    ConnectInfo = (PCSR_CONNECTION_INFO)(Request + 1);
-
-    /* Save the process ID */
-    RtlZeroMemory(ConnectInfo, sizeof(CSR_CONNECTION_INFO));
-
-    CsrLockProcessByClientId(Request->ClientId.UniqueProcess, &ProcessData);
-    if (!ProcessData)
-    {
-        DPRINT1("CSRSRV: Unknown process: %lx. Will be rejecting connection\n",
-                Request->ClientId.UniqueProcess);
-    }
-
-    if ((ProcessData) && (ProcessData != CsrRootProcess))
-    {
-        /* Attach the Shared Section */
-        Status = CsrSrvAttachSharedSection(ProcessData, ConnectInfo);
-        if (NT_SUCCESS(Status))
-        {
-            DPRINT("Connection ok\n");
-            AllowConnection = TRUE;
-        }
-        else
-        {
-            DPRINT1("Shared section map failed: %lx\n", Status);
-        }
-    }
-    else if (ProcessData == CsrRootProcess)
-    {
-        AllowConnection = TRUE;
-    }
-
-    /* Release the process */
-    if (ProcessData) CsrUnlockProcess(ProcessData);
-
-    /* Setup the Port View Structure */
-    RemotePortView.Length = sizeof(REMOTE_PORT_VIEW);
-    RemotePortView.ViewSize = 0;
-    RemotePortView.ViewBase = NULL;
-
-    /* Save the Process ID */
-    ConnectInfo->ProcessId = NtCurrentTeb()->ClientId.UniqueProcess;
-
-    Status = NtAcceptConnectPort(&ServerPort,
-                                 AllowConnection ? UlongToPtr(ProcessData->SequenceNumber) : 0,
-                                 Request,
-                                 AllowConnection,
-                                 NULL,
-                                 &RemotePortView);
-    if (!NT_SUCCESS(Status))
-    {
-         DPRINT1("CSRSS: NtAcceptConnectPort - failed.  Status == %X\n", Status);
-    }
-    else if (AllowConnection)
-    {
-        if (CsrDebug & 2)
-        {
-            DPRINT1("CSRSS: ClientId: %lx.%lx has ClientView: Base=%p, Size=%lx\n",
-                    Request->ClientId.UniqueProcess,
-                    Request->ClientId.UniqueThread,
-                    RemotePortView.ViewBase,
-                    RemotePortView.ViewSize);
-        }
-
-        /* Set some Port Data in the Process */
-        ProcessData->ClientPort = ServerPort;
-        ProcessData->ClientViewBase = (ULONG_PTR)RemotePortView.ViewBase;
-        ProcessData->ClientViewBounds = (ULONG_PTR)((ULONG_PTR)RemotePortView.ViewBase +
-                                                    (ULONG_PTR)RemotePortView.ViewSize);
-
-        /* Complete the connection */
-        Status = NtCompleteConnectPort(ServerPort);
-        if (!NT_SUCCESS(Status))
-        {
-            DPRINT1("CSRSS: NtCompleteConnectPort - failed.  Status == %X\n", Status);
-        }
-    }
-    else
-    {
-        DPRINT1("CSRSS: Rejecting Connection Request from ClientId: %lx.%lx\n",
-                Request->ClientId.UniqueProcess,
-                Request->ClientId.UniqueThread);
-    }
-
-    return Status;
-}
-
 /*++
  * @name CsrConnectToUser
  * @implemented NT4
@@ -1599,6 +1119,7 @@ PCSR_THREAD
 NTAPI
 CsrConnectToUser(VOID)
 {
+#if 0 // This code is OK, however it is ClientThreadSetup which sucks.
     NTSTATUS Status;
     ANSI_STRING DllName;
     UNICODE_STRING TempName;
@@ -1655,6 +1176,19 @@ CsrConnectToUser(VOID)
 
     /* Return it */
     return CsrThread;
+
+#else
+
+    PTEB Teb = NtCurrentTeb();
+    PCSR_THREAD CsrThread;
+
+    /* Save pointer to this thread in TEB */
+    CsrThread = CsrLocateThreadInProcess(NULL, &Teb->ClientId);
+    if (CsrThread) Teb->CsrClientThread = CsrThread;
+
+    /* Return it */
+    return CsrThread;
+#endif
 }
 
 /*++
@@ -1703,20 +1237,20 @@ CsrCaptureArguments(IN PCSR_THREAD CsrThread,
                     IN PCSR_API_MESSAGE ApiMessage)
 {
     PCSR_CAPTURE_BUFFER LocalCaptureBuffer = NULL, RemoteCaptureBuffer = NULL;
-    ULONG LocalLength = 0, PointerCount = 0;
-    SIZE_T BufferDistance = 0;
-    ULONG_PTR **PointerOffsets = NULL, *CurrentPointer = NULL;
+    SIZE_T BufferDistance;
+    ULONG Length = 0;
+    ULONG i;
 
     /* Use SEH to make sure this is valid */
     _SEH2_TRY
     {
         /* Get the buffer we got from whoever called NTDLL */
         LocalCaptureBuffer = ApiMessage->CsrCaptureData;
-        LocalLength = LocalCaptureBuffer->Size;
+        Length = LocalCaptureBuffer->Size;
 
         /* Now check if the buffer is inside our mapped section */
         if (((ULONG_PTR)LocalCaptureBuffer < CsrThread->Process->ClientViewBase) ||
-            (((ULONG_PTR)LocalCaptureBuffer + LocalLength) >= CsrThread->Process->ClientViewBounds))
+            (((ULONG_PTR)LocalCaptureBuffer + Length) >= CsrThread->Process->ClientViewBounds))
         {
             /* Return failure */
             DPRINT1("*** CSRSS: CaptureBuffer outside of ClientView\n");
@@ -1725,8 +1259,9 @@ CsrCaptureArguments(IN PCSR_THREAD CsrThread,
         }
 
         /* Check if the Length is valid */
-        if (((LocalCaptureBuffer->PointerCount * 4 + sizeof(CSR_CAPTURE_BUFFER)) >
-            LocalLength) ||(LocalLength > MAXWORD))
+        if ((FIELD_OFFSET(CSR_CAPTURE_BUFFER, PointerOffsetsArray) +
+                (LocalCaptureBuffer->PointerCount * sizeof(PVOID)) > Length) ||
+            (Length > MAXWORD))
         {
             /* Return failure */
             DPRINT1("*** CSRSS: CaptureBuffer %p has bad length\n", LocalCaptureBuffer);
@@ -1743,7 +1278,7 @@ CsrCaptureArguments(IN PCSR_THREAD CsrThread,
     } _SEH2_END;
 
     /* We validated the incoming buffer, now allocate the remote one */
-    RemoteCaptureBuffer = RtlAllocateHeap(CsrHeap, 0, LocalLength);
+    RemoteCaptureBuffer = RtlAllocateHeap(CsrHeap, 0, Length);
     if (!RemoteCaptureBuffer)
     {
         /* We're out of memory */
@@ -1752,33 +1287,27 @@ CsrCaptureArguments(IN PCSR_THREAD CsrThread,
     }
 
     /* Copy the client's buffer */
-    RtlMoveMemory(RemoteCaptureBuffer, LocalCaptureBuffer, LocalLength);
-
-    /* Copy the length */
-    RemoteCaptureBuffer->Size = LocalLength;
+    RtlMoveMemory(RemoteCaptureBuffer, LocalCaptureBuffer, Length);
 
     /* Calculate the difference between our buffer and the client's */
     BufferDistance = (ULONG_PTR)RemoteCaptureBuffer - (ULONG_PTR)LocalCaptureBuffer;
 
-    /* Save the pointer count and offset pointer */
-    PointerCount = RemoteCaptureBuffer->PointerCount;
-    PointerOffsets = (ULONG_PTR**)(RemoteCaptureBuffer + 1);
-
-    /* Start the loop */
-    while (PointerCount)
+    /*
+     * Convert all the pointer offsets into real pointers, and make
+     * them point to the remote data buffer instead of the local one.
+     */
+    for (i = 0 ; i < RemoteCaptureBuffer->PointerCount ; ++i)
     {
-        /* Get the current pointer */
-        if ((CurrentPointer = *PointerOffsets++))
+        if (RemoteCaptureBuffer->PointerOffsetsArray[i] != 0)
         {
-            /* Add it to the CSR Message structure */
-            CurrentPointer += (ULONG_PTR)ApiMessage;
+            RemoteCaptureBuffer->PointerOffsetsArray[i] += (ULONG_PTR)ApiMessage;
 
             /* Validate the bounds of the current pointer */
-            if ((*CurrentPointer >= CsrThread->Process->ClientViewBase) &&
-                (*CurrentPointer < CsrThread->Process->ClientViewBounds))
+            if ((*(PULONG_PTR)RemoteCaptureBuffer->PointerOffsetsArray[i] >= CsrThread->Process->ClientViewBase) &&
+                (*(PULONG_PTR)RemoteCaptureBuffer->PointerOffsetsArray[i] < CsrThread->Process->ClientViewBounds))
             {
                 /* Modify the pointer to take into account its new position */
-                *CurrentPointer += BufferDistance;
+                *(PULONG_PTR)RemoteCaptureBuffer->PointerOffsetsArray[i] += BufferDistance;
             }
             else
             {
@@ -1788,9 +1317,6 @@ CsrCaptureArguments(IN PCSR_THREAD CsrThread,
                 ApiMessage->Status = STATUS_INVALID_PARAMETER;
             }
         }
-
-        /* Move to the next Pointer */
-        PointerCount--;
     }
 
     /* Check if we got success */
@@ -1833,39 +1359,33 @@ CsrReleaseCapturedArguments(IN PCSR_API_MESSAGE ApiMessage)
 {
     PCSR_CAPTURE_BUFFER RemoteCaptureBuffer, LocalCaptureBuffer;
     SIZE_T BufferDistance;
-    ULONG PointerCount;
-    ULONG_PTR **PointerOffsets, *CurrentPointer;
+    ULONG i;
 
     /* Get the capture buffers */
     RemoteCaptureBuffer = ApiMessage->CsrCaptureData;
     LocalCaptureBuffer = RemoteCaptureBuffer->PreviousCaptureBuffer;
 
+    /* Do not continue if there is no captured buffer */
+    if (!RemoteCaptureBuffer) return;
+
     /* Free the previous one */
     RemoteCaptureBuffer->PreviousCaptureBuffer = NULL;
 
-    /* Find out the difference between the two buffers */
-    BufferDistance = (ULONG_PTR)LocalCaptureBuffer - (ULONG_PTR)RemoteCaptureBuffer;
-
-    /* Save the pointer count and offset pointer */
-    PointerCount = RemoteCaptureBuffer->PointerCount;
-    PointerOffsets = (ULONG_PTR**)(RemoteCaptureBuffer + 1);
+    /* Calculate the difference between our buffer and the client's */
+    BufferDistance = (ULONG_PTR)RemoteCaptureBuffer - (ULONG_PTR)LocalCaptureBuffer;
 
-    /* Start the loop */
-    while (PointerCount)
+    /*
+     * Convert back all the pointers into pointer offsets, and make them
+     * point to the local data buffer instead of the remote one (revert
+     * the logic of CsrCaptureArguments).
+     */
+    for (i = 0 ; i < RemoteCaptureBuffer->PointerCount ; ++i)
     {
-        /* Get the current pointer */
-        CurrentPointer = *PointerOffsets++;
-        if (CurrentPointer)
+        if (RemoteCaptureBuffer->PointerOffsetsArray[i] != 0)
         {
-            /* Add it to the CSR Message structure */
-            CurrentPointer += (ULONG_PTR)ApiMessage;
-
-            /* Modify the pointer to take into account its new position */
-            *CurrentPointer += BufferDistance;
+            *(PULONG_PTR)RemoteCaptureBuffer->PointerOffsetsArray[i] -= BufferDistance;
+            RemoteCaptureBuffer->PointerOffsetsArray[i] -= (ULONG_PTR)ApiMessage;
         }
-
-        /* Move to the next Pointer */
-        PointerCount--;
     }
 
     /* Copy the data back */
@@ -1889,11 +1409,11 @@ CsrReleaseCapturedArguments(IN PCSR_API_MESSAGE ApiMessage)
  * @param Buffer
  *        Pointer to the message buffer to validate.
  *
- * @param ArgumentSize
- *        Size of the message to check.
+ * @param ElementCount
+ *        Number of elements contained in the message buffer.
  *
- * @param ArgumentCount
- *        Number of messages to check.
+ * @param ElementSize
+ *        Size of each element.
  *
  * @return TRUE if validation suceeded, FALSE otherwise.
  *
@@ -1904,62 +1424,97 @@ BOOLEAN
 NTAPI
 CsrValidateMessageBuffer(IN PCSR_API_MESSAGE ApiMessage,
                          IN PVOID *Buffer,
-                         IN ULONG ArgumentSize,
-                         IN ULONG ArgumentCount)
+                         IN ULONG ElementCount,
+                         IN ULONG ElementSize)
 {
     PCSR_CAPTURE_BUFFER CaptureBuffer = ApiMessage->CsrCaptureData;
-    SIZE_T BufferDistance;
-    ULONG PointerCount, i;
-    ULONG_PTR **PointerOffsets, *CurrentPointer;
-
-    /* Make sure there are some arguments */
-    if (!ArgumentCount) return FALSE;
+    // SIZE_T BufferDistance = (ULONG_PTR)Buffer - (ULONG_PTR)ApiMessage;
+    ULONG i;
+
+    /*
+     * Check whether we have a valid buffer pointer, elements
+     * of non-trivial size and that we don't overflow.
+     */
+    if (!Buffer || ElementSize == 0 ||
+        (ULONGLONG)ElementCount * ElementSize > (ULONGLONG)0xFFFFFFFF)
+    {
+        return FALSE;
+    }
 
     /* Check if didn't get a buffer and there aren't any arguments to check */
-    if (!(*Buffer) && (!(ArgumentCount * ArgumentSize))) return TRUE;
+    // if (!*Buffer && (ElementCount * ElementSize == 0))
+    if (!*Buffer && ElementCount == 0) // Here ElementSize != 0 therefore only ElementCount can be == 0
+        return TRUE;
 
     /* Check if we have no capture buffer */
     if (!CaptureBuffer)
     {
-        /* In this case, check only the Process ID */
+        /*
+         * In this case, check only the Process ID
+         * and if there is a match, we succeed.
+         */
         if (NtCurrentTeb()->ClientId.UniqueProcess ==
             ApiMessage->Header.ClientId.UniqueProcess)
         {
-            /* There is a match, validation succeeded */
             return TRUE;
         }
     }
     else
     {
         /* Make sure that there is still space left in the buffer */
-        if ((CaptureBuffer->Size - (ULONG_PTR)*Buffer + (ULONG_PTR)CaptureBuffer) <
-            (ArgumentCount * ArgumentSize))
+        if ((CaptureBuffer->Size - (ULONG_PTR)*Buffer + (ULONG_PTR)CaptureBuffer) >=
+            (ElementCount * ElementSize))
         {
-            /* Find out the difference between the two buffers */
-            BufferDistance = (ULONG_PTR)Buffer - (ULONG_PTR)ApiMessage;
-
-             /* Save the pointer count */
-            PointerCount = CaptureBuffer->PointerCount;
-            PointerOffsets = (ULONG_PTR**)(CaptureBuffer + 1);
-
-            /* Start the loop */
-            for (i = 0; i < PointerCount; i++)
+            for (i = 0 ; i < CaptureBuffer->PointerCount ; ++i)
             {
-                /* Get the current pointer */
-                CurrentPointer = *PointerOffsets++;
-
-                /* Check if its' equal to the difference */
-                if (*CurrentPointer == BufferDistance) return TRUE;
+                /*
+                 * If the pointer offset is in fact equal to the
+                 * real address of the buffer then it's OK.
+                 */
+                if (CaptureBuffer->PointerOffsetsArray[i] == (ULONG_PTR)Buffer /* BufferDistance + (ULONG_PTR)ApiMessage */)
+                {
+                    return TRUE;
+                }
             }
         }
     }
 
     /* Failure */
-    DbgPrint("CSRSRV: Bad message buffer %p\n", ApiMessage);
+    DPRINT1("CSRSRV: Bad message buffer %p\n", ApiMessage);
     DbgBreakPoint();
     return FALSE;
 }
 
+/*** This is what we have in consrv/server.c ***
+
+/\* Ensure that a captured buffer is safe to access *\/
+BOOL FASTCALL
+Win32CsrValidateBuffer(PCSR_PROCESS ProcessData, PVOID Buffer,
+                       SIZE_T NumElements, SIZE_T ElementSize)
+{
+    /\* Check that the following conditions are true:
+     * 1. The start of the buffer is somewhere within the process's
+     *    shared memory section view.
+     * 2. The remaining space in the view is at least as large as the buffer.
+     *    (NB: Please don't try to "optimize" this by using multiplication
+     *    instead of division; remember that 2147483648 * 2 = 0.)
+     * 3. The buffer is DWORD-aligned.
+     *\/
+    ULONG_PTR Offset = (BYTE *)Buffer - (BYTE *)ProcessData->ClientViewBase;
+    if (Offset >= ProcessData->ClientViewBounds
+            || NumElements > (ProcessData->ClientViewBounds - Offset) / ElementSize
+            || (Offset & (sizeof(DWORD) - 1)) != 0)
+    {
+        DPRINT1("Invalid buffer %p(%u*%u); section view is %p(%u)\n",
+                Buffer, NumElements, ElementSize,
+                ProcessData->ClientViewBase, ProcessData->ClientViewBounds);
+        return FALSE;
+    }
+    return TRUE;
+}
+
+***********************************************/
+
 /*++
  * @name CsrValidateMessageString
  * @implemented NT5.1
@@ -1983,8 +1538,17 @@ NTAPI
 CsrValidateMessageString(IN PCSR_API_MESSAGE ApiMessage,
                          IN LPWSTR *MessageString)
 {
-    DPRINT1("CSRSRV: %s called\n", __FUNCTION__);
-    return FALSE;
+    if (MessageString)
+    {
+        return CsrValidateMessageBuffer(ApiMessage,
+                                        (PVOID*)MessageString,
+                                        wcslen(*MessageString) + 1,
+                                        sizeof(WCHAR));
+    }
+    else
+    {
+        return FALSE;
+    }
 }
 
 /* EOF */
index b224449..b84f92e 100644 (file)
@@ -3,7 +3,7 @@
 @ stdcall CsrConnectToUser()
 @ stdcall CsrCreateProcess(ptr ptr ptr ptr long ptr)
 @ stdcall CsrCreateRemoteThread(ptr ptr)
-@ stdcall CsrCreateThread(ptr ptr ptr) ;;; @ stdcall CsrCreateThread(ptr ptr ptr long) ??
+@ stdcall CsrCreateThread(ptr ptr ptr long)
 @ stdcall CsrCreateWait(ptr ptr ptr ptr ptr ptr)
 @ stdcall CsrDebugProcess(ptr)
 @ stdcall CsrDebugProcessStop(ptr)
index f6ffb1a..7124dbc 100644 (file)
@@ -41,37 +41,6 @@ extern RTL_CRITICAL_SECTION CsrProcessLock, CsrWaitListsLock;
 #define CSR_SERVER_DLL_MAX  4
 
 
-/***
- *** Old structure. Deprecated.
- ***/
-typedef struct _CSRSS_API_DEFINITION
-{
-    ULONG ApiID;
-    ULONG MinRequestSize;
-    PCSR_API_ROUTINE Handler;
-} CSRSS_API_DEFINITION, *PCSRSS_API_DEFINITION;
-
-#define CSRSS_DEFINE_API(Func, Handler) \
-    { Func, sizeof(CSRSS_##Func), Handler }
-
-
-
-
-typedef struct _CSRSS_LISTEN_DATA
-{
-    HANDLE ApiPortHandle;
-    ULONG ApiDefinitionsCount;
-    PCSRSS_API_DEFINITION *ApiDefinitions;
-} CSRSS_LISTEN_DATA, *PCSRSS_LISTEN_DATA;
-
-
-
-
-/******************************************************************************
- ******************************************************************************
- ******************************************************************************/
-
-
 extern HANDLE hBootstrapOk;
 extern HANDLE CsrApiPort;
 extern HANDLE CsrSmApiPort;
@@ -154,13 +123,6 @@ CsrInsertProcess(IN PCSR_PROCESS Parent OPTIONAL,
                  IN PCSR_PROCESS CurrentProcess OPTIONAL,
                  IN PCSR_PROCESS CsrProcess);
 
-
-#if 0
-NTSTATUS FASTCALL CsrApiRegisterDefinitions(PCSRSS_API_DEFINITION NewDefinitions);
-#endif
-
-VOID FASTCALL CsrApiCallHandler(IN OUT PCSR_API_MESSAGE ApiMessage, OUT PULONG Reply);
-
 NTSTATUS
 NTAPI
 CsrApiRequestThread(IN PVOID Parameter); // HANDLE ServerPort ??
@@ -209,16 +171,6 @@ NTAPI
 CsrLocateThreadByClientId(OUT PCSR_PROCESS *Process OPTIONAL,
                           IN PCLIENT_ID ClientId);
 
-// HACK
-VOID
-NTAPI
-CsrProcessRefcountZero(IN PCSR_PROCESS CsrProcess);
-
-// HACK
-VOID
-NTAPI
-CsrThreadRefcountZero(IN PCSR_THREAD CsrThread);
-
 NTSTATUS
 NTAPI
 CsrInitializeNtSessionList(VOID);
index 7ab7765..2c123b6 100644 (file)
@@ -25,7 +25,7 @@ PCSR_THREAD CsrSbApiRequestThreadPtr;
 HANDLE CsrSmApiPort = NULL;
 HANDLE hSbApiPort = NULL;
 HANDLE CsrApiPort = NULL;
-ULONG CsrDebug = 0;//0xFFFFFFFF;
+ULONG CsrDebug = 0xFFFFFFFF; // 0;
 ULONG CsrMaxApiRequestThreads;
 ULONG CsrTotalPerProcessDataLength;
 ULONG SessionId;
@@ -564,7 +564,7 @@ CsrCreateSessionObjectDirectory(IN ULONG Session)
  *
  *--*/
 NTSTATUS
-FASTCALL
+NTAPI
 CsrParseServerCommandLine(IN ULONG ArgumentCount,
                           IN PCHAR Arguments[])
 {
@@ -668,7 +668,7 @@ CsrParseServerCommandLine(IN ULONG ArgumentCount,
             /* Load us */
             Status = CsrLoadServerDll("CSRSS" /* "CSRSRV" */, NULL, CSRSRV_SERVERDLL_INDEX);
         }
-        else if (_stricmp(ParameterName, "ServerDLL") == 0)
+        else if (_stricmp(ParameterName, "ServerDll") == 0)
         {
             /* Loop the command line */
             EntryPoint = NULL;
@@ -728,6 +728,84 @@ CsrParseServerCommandLine(IN ULONG ArgumentCount,
     return Status;
 }
 
+/*++
+ * @name CsrInitCsrRootProcess
+ *
+ * The CsrInitCsrRootProcess routine further initializes the CSR Root Process
+ * created by CsrInitializeProcessStructure, by allocating and initializing
+ * per-process data for each Server DLL.
+ *
+ * @param None.
+ *
+ * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL
+ *         otherwise.
+ *
+ * @remarks None.
+ *
+ *--*/
+NTSTATUS
+NTAPI
+CsrInitCsrRootProcess(VOID)
+{
+    PVOID ProcessData;
+    PCSR_SERVER_DLL ServerDll;
+    ULONG i = 0;
+
+    /* All Server DLLs are now loaded, allocate a heap for the Root Process */
+    ProcessData = RtlAllocateHeap(CsrHeap,
+                                  HEAP_ZERO_MEMORY,
+                                  CsrTotalPerProcessDataLength);
+    if (!ProcessData)
+    {
+        DPRINT1("CSRSRV:%s: RtlAllocateHeap failed (Status=%08lx)\n",
+                __FUNCTION__, STATUS_NO_MEMORY);
+        return STATUS_NO_MEMORY;
+    }
+
+    /*
+     * Our Root Process was never officially initalized, so write the data
+     * for each Server DLL manually.
+     */
+    for (i = 0; i < CSR_SERVER_DLL_MAX; i++)
+    {
+        /* Get the current Server */
+        ServerDll = CsrLoadedServerDll[i];
+
+        /* Is it loaded, and does it have per process data? */
+        if (ServerDll && ServerDll->SizeOfProcessData)
+        {
+            /* It does, give it part of our allocated heap */
+            CsrRootProcess->ServerData[i] = ProcessData;
+
+            /* Move to the next heap position */
+            ProcessData = (PVOID)((ULONG_PTR)ProcessData +
+                                  ServerDll->SizeOfProcessData);
+        }
+        else
+        {
+            /* Nothing for this Server DLL */
+            CsrRootProcess->ServerData[i] = NULL;
+        }
+    }
+
+    /* Now initialize the Root Process manually as well */
+    for (i = 0; i < CSR_SERVER_DLL_MAX; i++)
+    {
+        /* Get the current Server */
+        ServerDll = CsrLoadedServerDll[i];
+
+        /* Is it loaded, and does it a callback for new processes? */
+        if (ServerDll && ServerDll->NewProcessCallback)
+        {
+            /* Call the callback */
+            DPRINT1("Call NewProcessCallback(NULL, 0x%p) called\n", CsrRootProcess);
+            ServerDll->NewProcessCallback(NULL, CsrRootProcess);
+        }
+    }
+
+    return STATUS_SUCCESS;
+}
+
 /*++
  * @name CsrCreateLocalSystemSD
  *
@@ -971,7 +1049,7 @@ CsrServerInitialization(IN ULONG ArgumentCount,
         return Status;
     }
 
-    /* Set up Process Support */
+    /* Set up Process Support and allocate the CSR Root Process */
     Status = CsrInitializeProcessStructure();
     if (!NT_SUCCESS(Status))
     {
@@ -989,6 +1067,15 @@ CsrServerInitialization(IN ULONG ArgumentCount,
         return Status;
     }
 
+    /* Finish to initialize the CSR Root Process */
+    Status = CsrInitCsrRootProcess();
+    if (!NT_SUCCESS(Status))
+    {
+        DPRINT1("CSRSRV:%s: CsrInitCsrRootProcess failed (Status=%08lx)\n",
+                __FUNCTION__, Status);
+        return Status;
+    }
+
     /* Now initialize our API Port */
     Status = CsrApiPortInitialize();
     if (!NT_SUCCESS(Status))
@@ -1068,12 +1155,12 @@ CsrPopulateDosDevices(VOID)
 
 BOOL
 NTAPI
-DllMain(IN HANDLE hDll,
+DllMain(IN HINSTANCE hInstanceDll,
         IN DWORD dwReason,
         IN LPVOID lpReserved)
 {
     /* We don't do much */
-    UNREFERENCED_PARAMETER(hDll);
+    UNREFERENCED_PARAMETER(hInstanceDll);
     UNREFERENCED_PARAMETER(dwReason);
     UNREFERENCED_PARAMETER(lpReserved);
 
index 2976af0..25e37db 100644 (file)
@@ -341,7 +341,7 @@ CsrLockedReferenceProcess(IN PCSR_PROCESS CsrProcess)
  * @implemented NT4
  *
  * The CsrInitializeProcessStructure routine sets up support for CSR Processes
- * and CSR Threads.
+ * and CSR Threads by initializing our own CSR Root Process.
  *
  * @param None.
  *
@@ -467,9 +467,9 @@ CsrRemoveProcess(IN PCSR_PROCESS CsrProcess)
  *--*/
 VOID
 NTAPI
-CsrInsertProcess(IN PCSR_PROCESS Parent OPTIONAL,
-                 IN PCSR_PROCESS CurrentProcess OPTIONAL,
-                 IN PCSR_PROCESS CsrProcess)
+CsrInsertProcess(IN PCSR_PROCESS Parent OPTIONAL,   // ParentProcess
+                 IN PCSR_PROCESS CurrentProcess OPTIONAL,   // CallingProcess
+                 IN PCSR_PROCESS CsrProcess)    // Process
 {
     PCSR_SERVER_DLL ServerDll;
     ULONG i;
@@ -488,7 +488,7 @@ CsrInsertProcess(IN PCSR_PROCESS Parent OPTIONAL,
         ServerDll = CsrLoadedServerDll[i];
 
         /* Make sure it's valid and that it has callback */
-        if ((ServerDll) && (ServerDll->NewProcessCallback))
+        if (ServerDll && ServerDll->NewProcessCallback)
         {
             ServerDll->NewProcessCallback(CurrentProcess, CsrProcess);
         }
index 57592aa..91a2545 100644 (file)
@@ -119,6 +119,8 @@ CsrLoadServerDll(IN PCHAR DllString,
     PCSR_SERVER_DLL_INIT_CALLBACK ServerDllInitProcedure;
     ULONG Response;
 
+    DPRINT1("CsrLoadServerDll(%s, 0x%p, %lu)\n", DllString, EntryPoint, ServerId);
+
     /* Check if it's beyond the maximum we support */
     if (ServerId >= CSR_SERVER_DLL_MAX) return STATUS_TOO_MANY_NAMES;
 
@@ -222,14 +224,6 @@ CsrLoadServerDll(IN PCHAR DllString,
                 /* No, save the pointer to its shared section in our list */
                 CsrSrvSharedStaticServerData[ServerDll->ServerId] = ServerDll->SharedSection;
             }
-
-#if 0 /* HACK: ReactOS Specific hax. REMOVE IT. */
-            if (ServerDll->HighestApiSupported == 0xDEADBABE)
-            {
-                // CSRSS_API_DEFINITIONS == Old structure.
-                Status = CsrApiRegisterDefinitions((PVOID)ServerDll->DispatchTable);
-            }
-#endif
         }
         else
         {
@@ -274,12 +268,11 @@ CsrSrvClientConnect(IN OUT PCSR_API_MESSAGE ApiMessage,
                     IN OUT PULONG Reply OPTIONAL)
 {
     NTSTATUS Status;
-    PCSR_CLIENT_CONNECT ClientConnect;
+    PCSR_CLIENT_CONNECT ClientConnect = &ApiMessage->Data.CsrClientConnect;
     PCSR_SERVER_DLL ServerDll;
     PCSR_PROCESS CurrentProcess = CsrGetClientThread()->Process;
 
-    /* Load the Message, set default reply */
-    ClientConnect = &ApiMessage->Data.CsrClientConnect;
+    /* Set default reply */
     *Reply = 0;
 
     /* Validate the ServerID */
@@ -294,9 +287,9 @@ CsrSrvClientConnect(IN OUT PCSR_API_MESSAGE ApiMessage,
 
     /* Validate the Message Buffer */
     if (!(CsrValidateMessageBuffer(ApiMessage,
-                                   ClientConnect->ConnectionInfo,
+                                   &ClientConnect->ConnectionInfo,
                                    ClientConnect->ConnectionInfoSize,
-                                   1)))
+                                   sizeof(BYTE))))
     {
         /* Fail due to buffer overflow or other invalid buffer */
         return STATUS_INVALID_PARAMETER;
@@ -429,8 +422,7 @@ CsrSrvCreateSharedSection(IN PCHAR ParameterValue)
     /* Now allocate space from the heap for the Shared Data */
     CsrSrvSharedStaticServerData = RtlAllocateHeap(CsrSrvSharedSectionHeap,
                                                    0,
-                                                   CSR_SERVER_DLL_MAX *
-                                                   sizeof(PVOID));
+                                                   CSR_SERVER_DLL_MAX * sizeof(PVOID));
     if (!CsrSrvSharedStaticServerData) return STATUS_NO_MEMORY;
 
     /* Write the values to the PEB */
index ad53c79..7df3457 100644 (file)
@@ -326,9 +326,6 @@ CsrSbCreateSession(IN PSB_API_MSG ApiMessage)
         }
     }
 
-    /* HACK: FIXME: should go in BaseSrv part of CreateCallback done in Insert below */
-    // RtlInitializeCriticalSection(&CsrProcess->HandleTableLock);
-
     /* Insert the Process */
     CsrInsertProcess(NULL, NULL, CsrProcess);
 
index 91e1083..90b3bda 100644 (file)
@@ -659,7 +659,6 @@ CsrCreateRemoteThread(IN HANDLE hThread,
  *--*/
 NTSTATUS
 NTAPI
-#if 0
 CsrCreateThread(IN PCSR_PROCESS CsrProcess,
                 IN HANDLE hThread,
                 IN PCLIENT_ID ClientId,
@@ -670,12 +669,13 @@ CsrCreateThread(IN PCSR_PROCESS CsrProcess,
     PCSR_PROCESS CurrentProcess;
     CLIENT_ID CurrentCid;
     KERNEL_USER_TIMES KernelTimes;
+
     DPRINT("CSRSRV: %s called\n", __FUNCTION__);
 
     if (HaveClient)
     {
         /* Get the current thread and CID */
-        CurrentThread = NtCurrentTeb()->CsrClientThread;
+        CurrentThread = CsrGetClientThread();
         CurrentCid = CurrentThread->ClientId;
 
         /* Acquire the Process Lock */
@@ -683,6 +683,8 @@ CsrCreateThread(IN PCSR_PROCESS CsrProcess,
 
         /* Get the current Process and make sure the Thread is valid with this CID */
         CurrentThread = CsrLocateThreadByClientId(&CurrentProcess, &CurrentCid);
+
+        /* Something is wrong if we get an empty thread back */
         if (!CurrentThread)
         {
             DPRINT1("CSRSRV:%s: invalid thread!\n", __FUNCTION__);
@@ -729,66 +731,9 @@ CsrCreateThread(IN PCSR_PROCESS CsrProcess,
 
     /* Release the lock and return */
     CsrReleaseProcessLock();
-    return STATUS_SUCCESS;
-}
-#else
-CsrCreateThread(IN PCSR_PROCESS CsrProcess,
-                IN HANDLE hThread,
-                IN PCLIENT_ID ClientId)
-{
-    PCSR_THREAD CsrThread;
-    PCSR_PROCESS CurrentProcess;
-    PCSR_THREAD CurrentThread = CsrGetClientThread();
-    CLIENT_ID CurrentCid;
-    KERNEL_USER_TIMES KernelTimes;
-
-    /* Get the current thread and CID */
-    CurrentCid = CurrentThread->ClientId;
-
-    /* Acquire the Process Lock */
-    CsrAcquireProcessLock();
-
-    /* Get the current Process and make sure the Thread is valid with this CID */
-    CurrentThread = CsrLocateThreadByClientId(&CurrentProcess,
-                                              &CurrentCid);
-
-    /* Something is wrong if we get an empty thread back */
-    if (!CurrentThread)
-    {
-        DPRINT1("CSRSRV:%s: invalid thread!\n", __FUNCTION__);
-        CsrReleaseProcessLock();
-        return STATUS_THREAD_IS_TERMINATING;
-    }
 
-    /* Get the Thread Create Time */
-    NtQueryInformationThread(hThread,
-                             ThreadTimes,
-                             (PVOID)&KernelTimes,
-                             sizeof(KernelTimes),
-                             NULL);
-
-    /* Allocate a CSR Thread Structure */
-    if (!(CsrThread = CsrAllocateThread(CsrProcess)))
-    {
-        DPRINT1("CSRSRV:%s: out of memory!\n", __FUNCTION__);
-        CsrReleaseProcessLock();
-        return STATUS_NO_MEMORY;
-    }
-
-    /* Save the data we have */
-    CsrThread->CreateTime = KernelTimes.CreateTime;
-    CsrThread->ClientId = *ClientId;
-    CsrThread->ThreadHandle = hThread;
-    CsrThread->Flags = 0;
-
-    /* Insert the Thread into the Process */
-    CsrInsertThread(CsrProcess, CsrThread);
-
-    /* Release the lock and return */
-    CsrReleaseProcessLock();
     return STATUS_SUCCESS;
 }
-#endif
 
 /*++
  * @name CsrDereferenceThread