[NTDLL]
authorHermès Bélusca-Maïto <hermes.belusca-maito@reactos.org>
Wed, 7 May 2014 23:00:03 +0000 (23:00 +0000)
committerHermès Bélusca-Maïto <hermes.belusca-maito@reactos.org>
Wed, 7 May 2014 23:00:03 +0000 (23:00 +0000)
- Fix potential bug in CsrCaptureMessageString, in case StringLength > MaximumLength, and also do not copy too much data into the captured buffer. Then always NULL-terminate the captured strings if possible.
- Implement CsrCaptureMessageMultiUnicodeStringsInPlace, used by Win2k3 kernel32.dll in CreateProcess and for SxS thingies.

svn path=/branches/condrv_restructure/; revision=63184

dll/ntdll/csr/capture.c
include/reactos/subsys/csr/csr.h

index d22644b..5c8d09e 100644 (file)
@@ -128,7 +128,7 @@ ULONG
 NTAPI
 CsrAllocateMessagePointer(IN OUT PCSR_CAPTURE_BUFFER CaptureBuffer,
                           IN ULONG MessageLength,
-                          OUT PVOID *CapturedData)
+                          OUT PVOIDCapturedData)
 {
     if (MessageLength == 0)
     {
@@ -165,7 +165,7 @@ NTAPI
 CsrCaptureMessageBuffer(IN OUT PCSR_CAPTURE_BUFFER CaptureBuffer,
                         IN PVOID MessageBuffer OPTIONAL,
                         IN ULONG MessageLength,
-                        OUT PVOID *CapturedData)
+                        OUT PVOIDCapturedData)
 {
     /* Simply allocate a message pointer in the buffer */
     CsrAllocateMessagePointer(CaptureBuffer, MessageLength, CapturedData);
@@ -188,35 +188,23 @@ CsrFreeCaptureBuffer(IN PCSR_CAPTURE_BUFFER CaptureBuffer)
     RtlFreeHeap(CsrPortHeap, 0, CaptureBuffer);
 }
 
-/*
- * @unimplemented
- */
-NTSTATUS
-NTAPI
-CsrCaptureMessageMultiUnicodeStringsInPlace(IN PCSR_CAPTURE_BUFFER *CaptureBuffer,
-                                            IN ULONG MessageCount,
-                                            IN PVOID MessageStrings)
-{
-    /* FIXME: allocate a buffer if we don't have one, and return it */
-    /* FIXME: call CsrCaptureMessageUnicodeStringInPlace for each string */
-    UNIMPLEMENTED;
-    return STATUS_NOT_IMPLEMENTED;
-}
-
 /*
  * @implemented
  */
 VOID
 NTAPI
 CsrCaptureMessageString(IN OUT PCSR_CAPTURE_BUFFER CaptureBuffer,
-                        IN LPSTR String OPTIONAL,
+                        IN PCSTR String OPTIONAL,
                         IN ULONG StringLength,
                         IN ULONG MaximumLength,
-                        OUT PANSI_STRING CapturedString)
+                        OUT PSTRING CapturedString)
 {
-    ULONG ReturnedLength;
+    ASSERT(CapturedString != NULL);
 
-    /* If we don't have a string, initialize an empty one */
+    /*
+     * If we don't have a string, initialize an empty one,
+     * otherwise capture the given string.
+     */
     if (!String)
     {
         CapturedString->Length = 0;
@@ -226,31 +214,95 @@ CsrCaptureMessageString(IN OUT PCSR_CAPTURE_BUFFER CaptureBuffer,
         CsrAllocateMessagePointer(CaptureBuffer,
                                   MaximumLength,
                                   (PVOID*)&CapturedString->Buffer);
-        return;
+    }
+    else
+    {
+        /* Cut-off the string length if needed */
+        if (StringLength > MaximumLength)
+            StringLength = MaximumLength;
+
+        CapturedString->Length = (USHORT)StringLength;
+
+        /* Allocate a buffer and get its size */
+        CapturedString->MaximumLength =
+            (USHORT)CsrAllocateMessagePointer(CaptureBuffer,
+                                              MaximumLength,
+                                              (PVOID*)&CapturedString->Buffer);
+
+        /* If the string has data, copy it into the buffer */
+        if (StringLength)
+            RtlMoveMemory(CapturedString->Buffer, String, StringLength);
     }
 
-    /* Initialize this string */
-    CapturedString->Length = (USHORT)StringLength;
+    /* Null-terminate the string if we don't take up the whole space */
+    if (CapturedString->Length < CapturedString->MaximumLength)
+        CapturedString->Buffer[CapturedString->Length] = '\0';
+}
 
-    /* Allocate a buffer and get its size */
-    ReturnedLength = CsrAllocateMessagePointer(CaptureBuffer,
-                                               MaximumLength,
-                                               (PVOID*)&CapturedString->Buffer);
-    CapturedString->MaximumLength = (USHORT)ReturnedLength;
+static VOID
+CsrCaptureMessageUnicodeStringInPlace(IN OUT PCSR_CAPTURE_BUFFER CaptureBuffer,
+                                      IN PUNICODE_STRING String)
+{
+    ASSERT(String != NULL);
+
+    /* This is a way to capture the UNICODE string, since (Maximum)Length are also in bytes */
+    CsrCaptureMessageString(CaptureBuffer,
+                            (PCSTR)String->Buffer,
+                            String->Length,
+                            String->MaximumLength,
+                            (PSTRING)String);
 
-    /* If the string had data */
-    if (StringLength)
+    /* Null-terminate the string */
+    if (String->MaximumLength >= String->Length + sizeof(WCHAR))
     {
-        /* Copy it into the capture buffer */
-        RtlMoveMemory(CapturedString->Buffer, String, MaximumLength);
+        String->Buffer[String->Length / sizeof(WCHAR)] = L'\0';
+    }
+}
 
-        /* If we don't take up the whole space */
-        if (CapturedString->Length < CapturedString->MaximumLength)
+/*
+ * @implemented
+ */
+NTSTATUS
+NTAPI
+CsrCaptureMessageMultiUnicodeStringsInPlace(OUT PCSR_CAPTURE_BUFFER* CaptureBuffer,
+                                            IN ULONG StringsCount,
+                                            IN PUNICODE_STRING* MessageStrings)
+{
+    ULONG Count;
+
+    if (!CaptureBuffer) return STATUS_INVALID_PARAMETER;
+
+    /* Allocate a new capture buffer if we don't have one already */
+    if (!*CaptureBuffer)
+    {
+        /* Compute the required size for the capture buffer */
+        ULONG Size = 0;
+
+        Count = 0;
+        while (Count < StringsCount)
         {
-            /* Null-terminate it */
-            CapturedString->Buffer[CapturedString->Length] = '\0';
+            if (MessageStrings[Count])
+                Size += MessageStrings[Count]->MaximumLength;
+
+            ++Count;
         }
+
+        /* Allocate the capture buffer */
+        *CaptureBuffer = CsrAllocateCaptureBuffer(StringsCount, Size);
+        if (!*CaptureBuffer) return STATUS_NO_MEMORY;
+    }
+
+    /* Now capture each UNICODE string */
+    Count = 0;
+    while (Count < StringsCount)
+    {
+        if (MessageStrings[Count])
+            CsrCaptureMessageUnicodeStringInPlace(*CaptureBuffer, MessageStrings[Count]);
+
+        ++Count;
     }
+
+    return STATUS_SUCCESS;
 }
 
 /*
index 00338d9..e778b11 100644 (file)
@@ -36,26 +36,32 @@ ULONG
 NTAPI
 CsrAllocateMessagePointer(IN OUT PCSR_CAPTURE_BUFFER CaptureBuffer,
                           IN ULONG MessageLength,
-                          OUT PVOID *CapturedData);
+                          OUT PVOIDCapturedData);
 
 VOID
 NTAPI
 CsrCaptureMessageBuffer(IN OUT PCSR_CAPTURE_BUFFER CaptureBuffer,
                         IN PVOID MessageBuffer OPTIONAL,
                         IN ULONG MessageLength,
-                        OUT PVOID *CapturedData);
+                        OUT PVOID* CapturedData);
+
+VOID
+NTAPI
+CsrFreeCaptureBuffer(IN PCSR_CAPTURE_BUFFER CaptureBuffer);
 
 VOID
 NTAPI
 CsrCaptureMessageString(IN OUT PCSR_CAPTURE_BUFFER CaptureBuffer,
-                        IN LPSTR String OPTIONAL,
+                        IN PCSTR String OPTIONAL,
                         IN ULONG StringLength,
                         IN ULONG MaximumLength,
-                        OUT PANSI_STRING CapturedString);
+                        OUT PSTRING CapturedString);
 
-VOID
+NTSTATUS
 NTAPI
-CsrFreeCaptureBuffer(IN PCSR_CAPTURE_BUFFER CaptureBuffer);
+CsrCaptureMessageMultiUnicodeStringsInPlace(OUT PCSR_CAPTURE_BUFFER* CaptureBuffer,
+                                            IN ULONG StringsCount,
+                                            IN PUNICODE_STRING* MessageStrings);
 
 PLARGE_INTEGER
 NTAPI