/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
- * FILE: lib/ntdll/csr/capture.c
+ * 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 *******************************************************************/
#include <ntdll.h>
+
#define NDEBUG
#include <debug.h>
/* GLOBALS ********************************************************************/
+
extern HANDLE CsrPortHeap;
/* FUNCTIONS ******************************************************************/
/*
* @implemented
*/
-PVOID
+PCSR_CAPTURE_BUFFER
NTAPI
-CsrAllocateCaptureBuffer(ULONG ArgumentCount,
- ULONG BufferSize)
+CsrAllocateCaptureBuffer(IN ULONG ArgumentCount,
+ IN ULONG BufferSize)
{
PCSR_CAPTURE_BUFFER CaptureBuffer;
/* Validate size */
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));
+ /* Add the size of the header and for each offset to the pointers */
+ BufferSize += FIELD_OFFSET(CSR_CAPTURE_BUFFER, PointerOffsetsArray) +
+ (ArgumentCount * sizeof(ULONG_PTR));
+
+ /* 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, 0, BufferSize);
+ CaptureBuffer = RtlAllocateHeap(CsrPortHeap, HEAP_ZERO_MEMORY, BufferSize);
if (CaptureBuffer == NULL) return NULL;
/* Initialize the header */
CaptureBuffer->Size = BufferSize;
CaptureBuffer->PointerCount = 0;
- /* Initialize all the pointers */
- RtlZeroMemory(CaptureBuffer->PointerArray,
+ /* Initialize all the offsets */
+ 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;
*/
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;
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;
*/
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);
}
/*
*/
VOID
NTAPI
-CsrFreeCaptureBuffer(PCSR_CAPTURE_BUFFER CaptureBuffer)
+CsrFreeCaptureBuffer(IN PCSR_CAPTURE_BUFFER CaptureBuffer)
{
/* Free it from the heap */
RtlFreeHeap(CsrPortHeap, 0, CaptureBuffer);
}
-/*
- * @implemented
- */
-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(PCSR_CAPTURE_BUFFER CaptureBuffer,
- LPSTR String,
+CsrCaptureMessageString(IN OUT PCSR_CAPTURE_BUFFER CaptureBuffer,
+ 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;
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);
- /* If the string had data */
- if (StringLength)
+ /* 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';
+ }
+}
+
+/*
+ * @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)
{
- /* 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;
}
/*
*/
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 = Milliseconds * -10000LL;
return Timeout;
}