[SDK][ACGENRAL] Add the shim IgnoreFreeLibrary
[reactos.git] / dll / ntdll / csr / capture.c
index d22644b..1f1e695 100644 (file)
@@ -3,7 +3,8 @@
  * PROJECT:         ReactOS kernel
  * FILE:            dll/ntdll/csr/capture.c
  * PURPOSE:         Routines for probing and capturing CSR API Messages
- * PROGRAMMER:      Alex Ionescu (alex@relsoft.net)
+ * PROGRAMMERS:     Alex Ionescu (alex@relsoft.net)
+ *                  Hermes Belusca-Maito (hermes.belusca@sfr.fr)
  */
 
 /* INCLUDES *******************************************************************/
@@ -101,6 +102,9 @@ CsrAllocateCaptureBuffer(IN ULONG ArgumentCount,
     /* Align it to a 4-byte boundary */
     BufferSize = (BufferSize + 3) & ~3;
 
+    /* Add the size of the alignment padding for each argument */
+    BufferSize += ArgumentCount * 3;
+
     /* Allocate memory from the port heap */
     CaptureBuffer = RtlAllocateHeap(CsrPortHeap, HEAP_ZERO_MEMORY, BufferSize);
     if (CaptureBuffer == NULL) return NULL;
@@ -128,7 +132,7 @@ ULONG
 NTAPI
 CsrAllocateMessagePointer(IN OUT PCSR_CAPTURE_BUFFER CaptureBuffer,
                           IN ULONG MessageLength,
-                          OUT PVOID *CapturedData)
+                          OUT PVOIDCapturedData)
 {
     if (MessageLength == 0)
     {
@@ -165,7 +169,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 +192,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 +218,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);
+    }
+
+    /* Null-terminate the string if we don't take up the whole space */
+    if (CapturedString->Length < CapturedString->MaximumLength)
+        CapturedString->Buffer[CapturedString->Length] = '\0';
+}
+
+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);
+
+    /* Null-terminate the string */
+    if (String->MaximumLength >= String->Length + sizeof(WCHAR))
+    {
+        String->Buffer[String->Length / sizeof(WCHAR)] = L'\0';
+    }
+}
 
-    /* Initialize this string */
-    CapturedString->Length = (USHORT)StringLength;
+/*
+ * @implemented
+ */
+NTSTATUS
+NTAPI
+CsrCaptureMessageMultiUnicodeStringsInPlace(OUT PCSR_CAPTURE_BUFFER* CaptureBuffer,
+                                            IN ULONG StringsCount,
+                                            IN PUNICODE_STRING* MessageStrings)
+{
+    ULONG Count;
 
-    /* Allocate a buffer and get its size */
-    ReturnedLength = CsrAllocateMessagePointer(CaptureBuffer,
-                                               MaximumLength,
-                                               (PVOID*)&CapturedString->Buffer);
-    CapturedString->MaximumLength = (USHORT)ReturnedLength;
+    if (!CaptureBuffer) return STATUS_INVALID_PARAMETER;
 
-    /* If the string had data */
-    if (StringLength)
+    /* Allocate a new capture buffer if we don't have one already */
+    if (!*CaptureBuffer)
     {
-        /* Copy it into the capture buffer */
-        RtlMoveMemory(CapturedString->Buffer, String, MaximumLength);
+        /* Compute the required size for the capture buffer */
+        ULONG Size = 0;
 
-        /* If we don't take up the whole space */
-        if (CapturedString->Length < CapturedString->MaximumLength)
+        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;
 }
 
 /*
@@ -265,7 +321,7 @@ CsrCaptureTimeout(IN ULONG Milliseconds,
     if (Milliseconds == -1) return NULL;
 
     /* Convert to relative ticks */
-    Timeout->QuadPart = Int32x32To64(Milliseconds, -10000);
+    Timeout->QuadPart = Milliseconds * -10000LL;
     return Timeout;
 }