+++ /dev/null
-/*
- * COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS kernel
- * FILE: dll/ntdll/csr/capture.c
- * PURPOSE: Routines for probing and capturing CSR API Messages
- * 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
- */
-VOID
-NTAPI
-CsrProbeForRead(IN PVOID Address,
- IN ULONG Length,
- IN ULONG Alignment)
-{
- volatile UCHAR *Pointer;
- UCHAR Data;
-
- /* Validate length */
- if (Length == 0) return;
-
- /* Validate alignment */
- if ((ULONG_PTR)Address & (Alignment - 1))
- {
- /* Raise exception if it doesn't match */
- RtlRaiseStatus(STATUS_DATATYPE_MISALIGNMENT);
- }
-
- /* Probe first byte */
- Pointer = Address;
- Data = *Pointer;
-
- /* Probe last byte */
- Pointer = (PUCHAR)Address + Length - 1;
- Data = *Pointer;
- (void)Data;
-}
-
-/*
- * @implemented
- */
-VOID
-NTAPI
-CsrProbeForWrite(IN PVOID Address,
- IN ULONG Length,
- IN ULONG Alignment)
-{
- volatile UCHAR *Pointer;
-
- /* Validate length */
- if (Length == 0) return;
-
- /* Validate alignment */
- if ((ULONG_PTR)Address & (Alignment - 1))
- {
- /* Raise exception if it doesn't match */
- RtlRaiseStatus(STATUS_DATATYPE_MISALIGNMENT);
- }
-
- /* Probe first byte */
- Pointer = Address;
- *Pointer = *Pointer;
-
- /* Probe last byte */
- Pointer = (PUCHAR)Address + Length - 1;
- *Pointer = *Pointer;
-}
-
-/*
- * @implemented
- */
-PCSR_CAPTURE_BUFFER
-NTAPI
-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 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, HEAP_ZERO_MEMORY, BufferSize);
- if (CaptureBuffer == NULL) return NULL;
-
- /* Initialize the header */
- CaptureBuffer->Size = BufferSize;
- CaptureBuffer->PointerCount = 0;
-
- /* Initialize all the offsets */
- RtlZeroMemory(CaptureBuffer->PointerOffsetsArray,
- 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;
-}
-
-/*
- * @implemented
- */
-ULONG
-NTAPI
-CsrAllocateMessagePointer(IN OUT PCSR_CAPTURE_BUFFER CaptureBuffer,
- IN ULONG MessageLength,
- OUT PVOID* CapturedData)
-{
- if (MessageLength == 0)
- {
- *CapturedData = NULL;
- CapturedData = NULL;
- }
- else
- {
- /* Set the capture data at our current available buffer */
- *CapturedData = CaptureBuffer->BufferEnd;
-
- /* Validate the size */
- if (MessageLength >= MAXLONG) return 0;
-
- /* Align it to a 4-byte boundary */
- MessageLength = (MessageLength + 3) & ~3;
-
- /* Move our available buffer beyond this space */
- CaptureBuffer->BufferEnd = (PVOID)((ULONG_PTR)CaptureBuffer->BufferEnd + MessageLength);
- }
-
- /* Write down this pointer in the array and increase the count */
- CaptureBuffer->PointerOffsetsArray[CaptureBuffer->PointerCount++] = (ULONG_PTR)CapturedData;
-
- /* Return the aligned length */
- return MessageLength;
-}
-
-/*
- * @implemented
- */
-VOID
-NTAPI
-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, MessageLength, CapturedData);
-
- /* Check if there was any data */
- if (!MessageBuffer || !MessageLength) return;
-
- /* Copy the data into the buffer */
- RtlMoveMemory(*CapturedData, MessageBuffer, MessageLength);
-}
-
-/*
- * @implemented
- */
-VOID
-NTAPI
-CsrFreeCaptureBuffer(IN PCSR_CAPTURE_BUFFER CaptureBuffer)
-{
- /* Free it from the heap */
- RtlFreeHeap(CsrPortHeap, 0, CaptureBuffer);
-}
-
-/*
- * @implemented
- */
-VOID
-NTAPI
-CsrCaptureMessageString(IN OUT PCSR_CAPTURE_BUFFER CaptureBuffer,
- IN PCSTR String OPTIONAL,
- IN ULONG StringLength,
- IN ULONG MaximumLength,
- OUT PSTRING CapturedString)
-{
- ASSERT(CapturedString != NULL);
-
- /*
- * If we don't have a string, initialize an empty one,
- * otherwise capture the given string.
- */
- if (!String)
- {
- CapturedString->Length = 0;
- CapturedString->MaximumLength = (USHORT)MaximumLength;
-
- /* Allocate a pointer for it */
- CsrAllocateMessagePointer(CaptureBuffer,
- MaximumLength,
- (PVOID*)&CapturedString->Buffer);
- }
- 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';
- }
-}
-
-/*
- * @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)
- {
- 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;
-}
-
-/*
- * @implemented
- */
-PLARGE_INTEGER
-NTAPI
-CsrCaptureTimeout(IN ULONG Milliseconds,
- OUT PLARGE_INTEGER Timeout)
-{
- /* Validate the time */
- if (Milliseconds == -1) return NULL;
-
- /* Convert to relative ticks */
- Timeout->QuadPart = Milliseconds * -10000LL;
- return Timeout;
-}
-
-/* EOF */