Synchronize with trunk revision 59636 (just before Alex's CreateProcess revamp).
[reactos.git] / subsystems / win32 / csrsrv / api.c
index 9446400..d56b50d 100644 (file)
 
 #include "srv.h"
 
-//#define NDEBUG
+#define NDEBUG
 #include <debug.h>
 
 /* GLOBALS ********************************************************************/
 
 BOOLEAN (*CsrClientThreadSetup)(VOID) = NULL;
 UNICODE_STRING CsrApiPortName;
-volatile LONG CsrpStaticThreadCount;
-volatile LONG CsrpDynamicThreadTotal;
+volatile ULONG CsrpStaticThreadCount;
+volatile ULONG CsrpDynamicThreadTotal;
 extern ULONG CsrMaxApiRequestThreads;
 
 /* FUNCTIONS ******************************************************************/
@@ -52,8 +52,7 @@ CsrCallServerFromServer(IN PCSR_API_MESSAGE ReceiveMsg,
     ULONG ServerId;
     PCSR_SERVER_DLL ServerDll;
     ULONG ApiId;
-    ULONG Reply;
-    NTSTATUS Status;
+    CSR_REPLY_CODE ReplyCode = CsrReplyImmediately;
 
     /* Get the Server ID */
     ServerId = CSR_API_NUMBER_TO_SERVER_ID(ReceiveMsg->ApiNumber);
@@ -64,7 +63,7 @@ CsrCallServerFromServer(IN PCSR_API_MESSAGE ReceiveMsg,
     {
         /* We are beyond the Maximum Server ID */
         DPRINT1("CSRSS: %lx is invalid ServerDllIndex (%08x)\n", ServerId, ServerDll);
-        ReplyMsg->Status = (ULONG)STATUS_ILLEGAL_FUNCTION;
+        ReplyMsg->Status = STATUS_ILLEGAL_FUNCTION;
         return STATUS_ILLEGAL_FUNCTION;
     }
     else
@@ -82,8 +81,8 @@ CsrCallServerFromServer(IN PCSR_API_MESSAGE ReceiveMsg,
                     ServerDll->ValidTable[ApiId],
                     ((ServerDll->NameTable) && (ServerDll->NameTable[ApiId])) ?
                     ServerDll->NameTable[ApiId] : "*** UNKNOWN ***", &ServerDll->Name);
-            DbgBreakPoint();
-            ReplyMsg->Status = (ULONG)STATUS_ILLEGAL_FUNCTION;
+            // DbgBreakPoint();
+            ReplyMsg->Status = STATUS_ILLEGAL_FUNCTION;
             return STATUS_ILLEGAL_FUNCTION;
         }
     }
@@ -97,12 +96,8 @@ CsrCallServerFromServer(IN PCSR_API_MESSAGE ReceiveMsg,
     /* Validation complete, start SEH */
     _SEH2_TRY
     {
-        /* Call the API and get the result */
-        /// CsrApiCallHandler(ReplyMsg, /*ProcessData*/ &ReplyCode); ///
-        Status = (ServerDll->DispatchTable[ApiId])(ReceiveMsg, &Reply);
-
-        /* Return the result, no matter what it is */
-        ReplyMsg->Status = Status;
+        /* Call the API, get the reply code and return the result */
+        ReplyMsg->Status = ServerDll->DispatchTable[ApiId](ReceiveMsg, &ReplyCode);
     }
     _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
     {
@@ -160,7 +155,7 @@ CsrApiHandleConnectionRequest(IN PCSR_API_MESSAGE ApiMessage)
         if (CsrProcess)
         {
             /* Reference the Process */
-            CsrLockedReferenceProcess(CsrThread->Process);
+            CsrLockedReferenceProcess(CsrProcess);
 
             /* Release the lock */
             CsrReleaseProcessLock();
@@ -274,7 +269,7 @@ CsrpCheckRequestThreads(VOID)
     NTSTATUS Status;
 
     /* Decrease the count, and see if we're out */
-    if (!(_InterlockedDecrement(&CsrpStaticThreadCount)))
+    if (InterlockedDecrementUL(&CsrpStaticThreadCount) == 0)
     {
         /* Check if we've still got space for a Dynamic Thread */
         if (CsrpDynamicThreadTotal < CsrMaxApiRequestThreads)
@@ -294,8 +289,8 @@ CsrpCheckRequestThreads(VOID)
             if (NT_SUCCESS(Status))
             {
                 /* Increase the thread counts */
-                _InterlockedIncrement(&CsrpStaticThreadCount);
-                _InterlockedIncrement(&CsrpDynamicThreadTotal);
+                InterlockedIncrementUL(&CsrpStaticThreadCount);
+                InterlockedIncrementUL(&CsrpDynamicThreadTotal);
 
                 /* Add a new server thread */
                 if (CsrAddStaticServerThread(hThread,
@@ -308,8 +303,8 @@ CsrpCheckRequestThreads(VOID)
                 else
                 {
                     /* Failed to create a new static thread */
-                    _InterlockedDecrement(&CsrpStaticThreadCount);
-                    _InterlockedDecrement(&CsrpDynamicThreadTotal);
+                    InterlockedDecrementUL(&CsrpStaticThreadCount);
+                    InterlockedDecrementUL(&CsrpDynamicThreadTotal);
 
                     /* Terminate it */
                     DPRINT1("Failing\n");
@@ -350,6 +345,7 @@ CsrApiRequestThread(IN PVOID Parameter)
     LARGE_INTEGER TimeOut;
     PCSR_THREAD CurrentThread, CsrThread;
     NTSTATUS Status;
+    CSR_REPLY_CODE ReplyCode;
     PCSR_API_MESSAGE ReplyMsg;
     CSR_API_MESSAGE ReceiveMsg;
     PCSR_PROCESS CsrProcess;
@@ -358,7 +354,7 @@ CsrApiRequestThread(IN PVOID Parameter)
     PCSR_SERVER_DLL ServerDll;
     PCLIENT_DIED_MSG ClientDiedMsg;
     PDBGKM_MSG DebugMessage;
-    ULONG ServerId, ApiId, Reply, MessageType, i;
+    ULONG ServerId, ApiId, MessageType, i;
     HANDLE ReplyPort;
 
     /* Setup LPC loop port and message */
@@ -387,8 +383,8 @@ CsrApiRequestThread(IN PVOID Parameter)
         ASSERT(NT_SUCCESS(Status));
 
         /* Increase the Thread Counts */
-        _InterlockedIncrement(&CsrpStaticThreadCount);
-        _InterlockedIncrement(&CsrpDynamicThreadTotal);
+        InterlockedIncrementUL(&CsrpStaticThreadCount);
+        InterlockedIncrementUL(&CsrpDynamicThreadTotal);
     }
 
     /* Now start the loop */
@@ -436,7 +432,7 @@ CsrApiRequestThread(IN PVOID Parameter)
             }
             else
             {
-                /* A bizare "success" code, just try again */
+                /* A strange "success" code, just try again */
                 DPRINT1("NtReplyWaitReceivePort returned \"success\" status 0x%x\n", Status);
                 continue;
             }
@@ -453,8 +449,9 @@ CsrApiRequestThread(IN PVOID Parameter)
         {
             /* Handle the Connection Request */
             CsrApiHandleConnectionRequest(&ReceiveMsg);
-            ReplyPort = CsrApiPort;
+
             ReplyMsg = NULL;
+            ReplyPort = CsrApiPort;
             continue;
         }
 
@@ -507,7 +504,7 @@ CsrApiRequestThread(IN PVOID Parameter)
                         if ((ServerDll) && (ServerDll->HardErrorCallback))
                         {
                             /* Call it */
-                            ServerDll->HardErrorCallback(NULL /* CsrThread == NULL */, HardErrorMsg);
+                            ServerDll->HardErrorCallback(NULL /* == CsrThread */, HardErrorMsg);
 
                             /* If it's handled, get out of here */
                             if (HardErrorMsg->Response != ResponseNotHandled) break;
@@ -516,7 +513,7 @@ CsrApiRequestThread(IN PVOID Parameter)
                 }
 
                 /* Increase the thread count */
-                _InterlockedIncrement(&CsrpStaticThreadCount);
+                InterlockedIncrementUL(&CsrpStaticThreadCount);
 
                 /* If the response was 0xFFFFFFFF, we'll ignore it */
                 if (HardErrorMsg->Response == 0xFFFFFFFF)
@@ -527,6 +524,7 @@ CsrApiRequestThread(IN PVOID Parameter)
                 else
                 {
                     ReplyMsg = &ReceiveMsg;
+                    ReplyPort = CsrApiPort;
                 }
             }
             else if (MessageType == LPC_REQUEST)
@@ -549,9 +547,10 @@ CsrApiRequestThread(IN PVOID Parameter)
                     /* We are beyond the Maximum Server ID */
                     DPRINT1("CSRSS: %lx is invalid ServerDllIndex (%08x)\n",
                             ServerId, ServerDll);
-                    DbgBreakPoint();
-                    ReplyPort = CsrApiPort;
+                    // DbgBreakPoint();
+
                     ReplyMsg = NULL;
+                    ReplyPort = CsrApiPort;
                     continue;
                 }
 
@@ -565,6 +564,7 @@ CsrApiRequestThread(IN PVOID Parameter)
                     DPRINT1("CSRSS: %lx is invalid ApiTableIndex for %Z\n",
                             CSR_API_NUMBER_TO_API_ID(ReceiveMsg.ApiNumber),
                             &ServerDll->Name);
+
                     ReplyPort = CsrApiPort;
                     ReplyMsg = NULL;
                     continue;
@@ -589,13 +589,13 @@ CsrApiRequestThread(IN PVOID Parameter)
                     /* Make sure we have enough threads */
                     CsrpCheckRequestThreads();
 
-                    /* Call the API and get the result */
+                    /* Call the API and get the reply code */
                     ReplyMsg = NULL;
                     ReplyPort = CsrApiPort;
-                    ServerDll->DispatchTable[ApiId](&ReceiveMsg, &Reply);
+                    ServerDll->DispatchTable[ApiId](&ReceiveMsg, &ReplyCode);
 
                     /* Increase the static thread count */
-                    _InterlockedIncrement(&CsrpStaticThreadCount);
+                    InterlockedIncrementUL(&CsrpStaticThreadCount);
                 }
                 _SEH2_EXCEPT(CsrUnhandledExceptionFilter(_SEH2_GetExceptionInformation()))
                 {
@@ -625,6 +625,9 @@ CsrApiRequestThread(IN PVOID Parameter)
                 ClientDiedMsg = (PCLIENT_DIED_MSG)&ReceiveMsg;
                 if (ClientDiedMsg->CreateTime.QuadPart == CsrThread->CreateTime.QuadPart)
                 {
+                    /* Now we reply to the dying client */
+                    ReplyPort = CsrThread->Process->ClientPort;
+
                     /* Reference the thread */
                     CsrLockedReferenceThread(CsrThread);
 
@@ -644,6 +647,7 @@ CsrApiRequestThread(IN PVOID Parameter)
 
                 /* Release the lock and keep looping */
                 CsrReleaseProcessLock();
+
                 ReplyMsg = NULL;
                 ReplyPort = CsrApiPort;
                 continue;
@@ -702,7 +706,7 @@ CsrApiRequestThread(IN PVOID Parameter)
                 }
 
                 /* Increase the thread count */
-                _InterlockedIncrement(&CsrpStaticThreadCount);
+                InterlockedIncrementUL(&CsrpStaticThreadCount);
 
                 /* If the response was 0xFFFFFFFF, we'll ignore it */
                 if (HardErrorMsg->Response == 0xFFFFFFFF)
@@ -743,7 +747,7 @@ CsrApiRequestThread(IN PVOID Parameter)
             /* We are beyond the Maximum Server ID */
             DPRINT1("CSRSS: %lx is invalid ServerDllIndex (%08x)\n",
                     ServerId, ServerDll);
-            DbgBreakPoint();
+            // DbgBreakPoint();
 
             ReplyPort = CsrApiPort;
             ReplyMsg = &ReceiveMsg;
@@ -772,12 +776,14 @@ CsrApiRequestThread(IN PVOID Parameter)
 
         if (CsrDebug & 2)
         {
-            DPRINT1("[%02x] CSRSS: [%02x,%02x] - %s Api called from %08x\n",
+            DPRINT1("[%02x] CSRSS: [%02x,%02x] - %s Api called from %08x, Process %08x - %08x\n",
                     Teb->ClientId.UniqueThread,
                     ReceiveMsg.Header.ClientId.UniqueProcess,
                     ReceiveMsg.Header.ClientId.UniqueThread,
                     ServerDll->NameTable[ApiId],
-                    CsrThread);
+                    CsrThread,
+                    CsrThread->Process,
+                    CsrProcess);
         }
 
         /* Assume success */
@@ -807,36 +813,40 @@ CsrApiRequestThread(IN PVOID Parameter)
 
             Teb->CsrClientThread = CsrThread;
 
-            /* Call the API and get the result */
-            Reply = 0;
-            ServerDll->DispatchTable[ApiId](&ReceiveMsg, &Reply);
+            /* Call the API, get the reply code and return the result */
+            ReplyCode = CsrReplyImmediately;
+            ReplyMsg->Status = ServerDll->DispatchTable[ApiId](&ReceiveMsg, &ReplyCode);
 
             /* Increase the static thread count */
-            _InterlockedIncrement(&CsrpStaticThreadCount);
+            InterlockedIncrementUL(&CsrpStaticThreadCount);
 
             Teb->CsrClientThread = CurrentThread;
 
-            if (Reply == 3)
+            if (ReplyCode == CsrReplyAlreadySent)
             {
-                ReplyMsg = NULL;
                 if (ReceiveMsg.CsrCaptureData)
                 {
                     CsrReleaseCapturedArguments(&ReceiveMsg);
                 }
-                CsrDereferenceThread(CsrThread);
+                ReplyMsg = NULL;
                 ReplyPort = CsrApiPort;
+                CsrDereferenceThread(CsrThread);
             }
-            else if (Reply == 2)
+            else if (ReplyCode == CsrReplyDeadClient)
             {
+                /* Reply to the death message */
                 NtReplyPort(ReplyPort, &ReplyMsg->Header);
-                ReplyPort = CsrApiPort;
+
+                /* Reply back to the API port now */
                 ReplyMsg = NULL;
+                ReplyPort = CsrApiPort;
+
                 CsrDereferenceThread(CsrThread);
             }
-            else if (Reply == 1)
+            else if (ReplyCode == CsrReplyPending)
             {
-                ReplyPort = CsrApiPort;
                 ReplyMsg = NULL;
+                ReplyPort = CsrApiPort;
             }
             else
             {
@@ -869,8 +879,7 @@ CsrApiRequestThread(IN PVOID Parameter)
  *
  * @param None
  *
- * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL
- *         otherwise.
+ * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL otherwise.
  *
  * @remarks None.
  *
@@ -914,13 +923,13 @@ CsrApiPortInitialize(VOID)
                                &CsrApiPortName,
                                0,
                                NULL,
-                               NULL /* FIXME*/);
+                               NULL /* FIXME: Use the Security Descriptor */);
 
     /* 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),
+                          sizeof(CSR_CONNECTION_INFO),
+                          sizeof(CSR_API_MESSAGE),
                           16 * PAGE_SIZE);
     if (NT_SUCCESS(Status))
     {
@@ -1000,7 +1009,7 @@ PCSR_THREAD
 NTAPI
 CsrConnectToUser(VOID)
 {
-#if 0 // This code is OK, however it is ClientThreadSetup which sucks.
+#if 0 // FIXME: This code is OK, however it is ClientThreadSetup which sucks.
     NTSTATUS Status;
     ANSI_STRING DllName;
     UNICODE_STRING TempName;
@@ -1064,7 +1073,9 @@ CsrConnectToUser(VOID)
     PCSR_THREAD CsrThread;
 
     /* Save pointer to this thread in TEB */
+    CsrAcquireProcessLock();
     CsrThread = CsrLocateThreadInProcess(NULL, &Teb->ClientId);
+    CsrReleaseProcessLock();
     if (CsrThread) Teb->CsrClientThread = CsrThread;
 
     /* Return it */
@@ -1089,7 +1100,6 @@ HANDLE
 NTAPI
 CsrQueryApiPort(VOID)
 {
-    DPRINT("CSRSRV: %s called\n", __FUNCTION__);
     return CsrApiPort;
 }
 
@@ -1120,7 +1130,9 @@ CsrCaptureArguments(IN PCSR_THREAD CsrThread,
     PCSR_CAPTURE_BUFFER LocalCaptureBuffer = NULL, RemoteCaptureBuffer = NULL;
     SIZE_T BufferDistance;
     ULONG Length = 0;
-    ULONG i;
+    ULONG PointerCount;
+    PULONG_PTR OffsetPointer;
+    ULONG_PTR CurrentOffset;
 
     /* Use SEH to make sure this is valid */
     _SEH2_TRY
@@ -1159,7 +1171,7 @@ CsrCaptureArguments(IN PCSR_THREAD CsrThread,
     } _SEH2_END;
 
     /* We validated the incoming buffer, now allocate the remote one */
-    RemoteCaptureBuffer = RtlAllocateHeap(CsrHeap, 0, Length);
+    RemoteCaptureBuffer = RtlAllocateHeap(CsrHeap, HEAP_ZERO_MEMORY, Length);
     if (!RemoteCaptureBuffer)
     {
         /* We're out of memory */
@@ -1174,21 +1186,26 @@ CsrCaptureArguments(IN PCSR_THREAD CsrThread,
     BufferDistance = (ULONG_PTR)RemoteCaptureBuffer - (ULONG_PTR)LocalCaptureBuffer;
 
     /*
-     * Convert all the pointer offsets into real pointers, and make
-     * them point to the remote data buffer instead of the local one.
+     * All the pointer offsets correspond to pointers which point
+     * to the remote data buffer instead of the local one.
      */
-    for (i = 0 ; i < RemoteCaptureBuffer->PointerCount ; ++i)
+    PointerCount  = RemoteCaptureBuffer->PointerCount;
+    OffsetPointer = RemoteCaptureBuffer->PointerOffsetsArray;
+    while (PointerCount--)
     {
-        if (RemoteCaptureBuffer->PointerOffsetsArray[i] != 0)
+        CurrentOffset = *OffsetPointer;
+
+        if (CurrentOffset != 0)
         {
-            RemoteCaptureBuffer->PointerOffsetsArray[i] += (ULONG_PTR)ApiMessage;
+            /* Get the pointer corresponding to the offset */
+            CurrentOffset += (ULONG_PTR)ApiMessage;
 
-            /* Validate the bounds of the current pointer */
-            if ((*(PULONG_PTR)RemoteCaptureBuffer->PointerOffsetsArray[i] >= CsrThread->Process->ClientViewBase) &&
-                (*(PULONG_PTR)RemoteCaptureBuffer->PointerOffsetsArray[i] < CsrThread->Process->ClientViewBounds))
+            /* Validate the bounds of the current pointed pointer */
+            if ((*(PULONG_PTR)CurrentOffset >= CsrThread->Process->ClientViewBase) &&
+                (*(PULONG_PTR)CurrentOffset < CsrThread->Process->ClientViewBounds))
             {
-                /* Modify the pointer to take into account its new position */
-                *(PULONG_PTR)RemoteCaptureBuffer->PointerOffsetsArray[i] += BufferDistance;
+                /* Modify the pointed pointer to take into account its new position */
+                *(PULONG_PTR)CurrentOffset += BufferDistance;
             }
             else
             {
@@ -1198,18 +1215,20 @@ CsrCaptureArguments(IN PCSR_THREAD CsrThread,
                 ApiMessage->Status = STATUS_INVALID_PARAMETER;
             }
         }
+
+        ++OffsetPointer;
     }
 
     /* Check if we got success */
     if (ApiMessage->Status != STATUS_SUCCESS)
     {
-        /* Failure. Free the buffer and return*/
+        /* Failure. Free the buffer and return */
         RtlFreeHeap(CsrHeap, 0, RemoteCaptureBuffer);
         return FALSE;
     }
     else
     {
-        /* Success, save the previous buffer */
+        /* Success, save the previous buffer and use the remote capture buffer */
         RemoteCaptureBuffer->PreviousCaptureBuffer = LocalCaptureBuffer;
         ApiMessage->CsrCaptureData = RemoteCaptureBuffer;
     }
@@ -1240,33 +1259,47 @@ CsrReleaseCapturedArguments(IN PCSR_API_MESSAGE ApiMessage)
 {
     PCSR_CAPTURE_BUFFER RemoteCaptureBuffer, LocalCaptureBuffer;
     SIZE_T BufferDistance;
-    ULONG i;
+    ULONG PointerCount;
+    PULONG_PTR OffsetPointer;
+    ULONG_PTR CurrentOffset;
 
-    /* Get the capture buffers */
+    /* Get the remote capture buffer */
     RemoteCaptureBuffer = ApiMessage->CsrCaptureData;
-    LocalCaptureBuffer = RemoteCaptureBuffer->PreviousCaptureBuffer;
 
     /* Do not continue if there is no captured buffer */
     if (!RemoteCaptureBuffer) return;
 
-    /* Free the previous one */
+    /* If there is one, get the corresponding local capture buffer */
+    LocalCaptureBuffer = RemoteCaptureBuffer->PreviousCaptureBuffer;
+
+    /* Free the previous one and use again the local capture buffer */
     RemoteCaptureBuffer->PreviousCaptureBuffer = NULL;
+    ApiMessage->CsrCaptureData = LocalCaptureBuffer;
 
     /* Calculate the difference between our buffer and the client's */
     BufferDistance = (ULONG_PTR)RemoteCaptureBuffer - (ULONG_PTR)LocalCaptureBuffer;
 
     /*
-     * Convert back all the pointers into pointer offsets, and make them
-     * point to the local data buffer instead of the remote one (revert
+     * All the pointer offsets correspond to pointers which point
+     * to the local data buffer instead of the remote one (revert
      * the logic of CsrCaptureArguments).
      */
-    for (i = 0 ; i < RemoteCaptureBuffer->PointerCount ; ++i)
+    PointerCount  = RemoteCaptureBuffer->PointerCount;
+    OffsetPointer = RemoteCaptureBuffer->PointerOffsetsArray;
+    while (PointerCount--)
     {
-        if (RemoteCaptureBuffer->PointerOffsetsArray[i] != 0)
+        CurrentOffset = *OffsetPointer;
+
+        if (CurrentOffset != 0)
         {
-            *(PULONG_PTR)RemoteCaptureBuffer->PointerOffsetsArray[i] -= BufferDistance;
-            RemoteCaptureBuffer->PointerOffsetsArray[i] -= (ULONG_PTR)ApiMessage;
+            /* Get the pointer corresponding to the offset */
+            CurrentOffset += (ULONG_PTR)ApiMessage;
+
+            /* Modify the pointed pointer to take into account its new position */
+            *(PULONG_PTR)CurrentOffset -= BufferDistance;
         }
+
+        ++OffsetPointer;
     }
 
     /* Copy the data back */
@@ -1276,7 +1309,6 @@ CsrReleaseCapturedArguments(IN PCSR_API_MESSAGE ApiMessage)
     RtlFreeHeap(CsrHeap, 0, RemoteCaptureBuffer);
 }
 
-
 /*++
  * @name CsrValidateMessageBuffer
  * @implemented NT5.1
@@ -1296,7 +1328,7 @@ CsrReleaseCapturedArguments(IN PCSR_API_MESSAGE ApiMessage)
  * @param ElementSize
  *        Size of each element.
  *
- * @return TRUE if validation suceeded, FALSE otherwise.
+ * @return TRUE if validation succeeded, FALSE otherwise.
  *
  * @remarks None.
  *
@@ -1309,8 +1341,9 @@ CsrValidateMessageBuffer(IN PCSR_API_MESSAGE ApiMessage,
                          IN ULONG ElementSize)
 {
     PCSR_CAPTURE_BUFFER CaptureBuffer = ApiMessage->CsrCaptureData;
-    // SIZE_T BufferDistance = (ULONG_PTR)Buffer - (ULONG_PTR)ApiMessage;
-    ULONG i;
+    SIZE_T BufferDistance = (ULONG_PTR)Buffer - (ULONG_PTR)ApiMessage;
+    ULONG PointerCount;
+    PULONG_PTR OffsetPointer;
 
     /*
      * Check whether we have a valid buffer pointer, elements
@@ -1346,16 +1379,20 @@ CsrValidateMessageBuffer(IN PCSR_API_MESSAGE ApiMessage,
         if ((CaptureBuffer->Size - (ULONG_PTR)*Buffer + (ULONG_PTR)CaptureBuffer) >=
             (ElementCount * ElementSize))
         {
-            for (i = 0 ; i < CaptureBuffer->PointerCount ; ++i)
+            /* Perform the validation test */
+            PointerCount  = CaptureBuffer->PointerCount;
+            OffsetPointer = CaptureBuffer->PointerOffsetsArray;
+            while (PointerCount--)
             {
                 /*
-                 * If the pointer offset is in fact equal to the
-                 * real address of the buffer then it's OK.
+                 * The pointer offset must be equal to the delta between
+                 * the addresses of the buffer and of the API message.
                  */
-                if (CaptureBuffer->PointerOffsetsArray[i] == (ULONG_PTR)Buffer /* BufferDistance + (ULONG_PTR)ApiMessage */)
+                if (*OffsetPointer == BufferDistance)
                 {
                     return TRUE;
                 }
+                ++OffsetPointer;
             }
         }
     }
@@ -1366,36 +1403,6 @@ CsrValidateMessageBuffer(IN PCSR_API_MESSAGE ApiMessage,
     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
@@ -1409,7 +1416,7 @@ Win32CsrValidateBuffer(PCSR_PROCESS ProcessData, PVOID Buffer,
  * @param MessageString
  *        Pointer to the buffer containing the string to validate.
  *
- * @return TRUE if validation suceeded, FALSE otherwise.
+ * @return TRUE if validation succeeded, FALSE otherwise.
  *
  * @remarks None.
  *