reactos/dll/ntdll/csr/capture.c
Hermès Bélusca-Maïto d7bac86452 [NTDLL]
When calling CsrClientConnectToServer with a valid connection info user buffer, after capturing the buffer and calling CsrClientCallServer, do not forget to copy back to the user buffer the updated connection info and to free the capture buffer !

svn path=/branches/ros-csrss/; revision=57743
2012-11-20 22:48:11 +00:00

271 lines
7 KiB
C

/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: lib/ntdll/csr/capture.c
* PURPOSE: Routines for probing and capturing CSR API Messages
* PROGRAMMER: Alex Ionescu (alex@relsoft.net)
*/
/* 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 pointer 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;
/* 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 pointers */
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);
}
/*
* @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 ULONG StringLength,
IN ULONG MaximumLength,
OUT PANSI_STRING CapturedString)
{
ULONG ReturnedLength;
/* If we don't have a string, initialize an empty one */
if (!String)
{
CapturedString->Length = 0;
CapturedString->MaximumLength = (USHORT)MaximumLength;
/* Allocate a pointer for it */
CsrAllocateMessagePointer(CaptureBuffer,
MaximumLength,
(PVOID*)&CapturedString->Buffer);
return;
}
/* Initialize this string */
CapturedString->Length = (USHORT)StringLength;
/* Allocate a buffer and get its size */
ReturnedLength = CsrAllocateMessagePointer(CaptureBuffer,
MaximumLength,
(PVOID*)&CapturedString->Buffer);
CapturedString->MaximumLength = (USHORT)ReturnedLength;
/* If the string had data */
if (StringLength)
{
/* Copy it into the capture buffer */
RtlMoveMemory(CapturedString->Buffer, String, MaximumLength);
/* If we don't take up the whole space */
if (CapturedString->Length < CapturedString->MaximumLength)
{
/* Null-terminate it */
CapturedString->Buffer[CapturedString->Length] = '\0';
}
}
}
/*
* @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 = Int32x32To64(Milliseconds, -100000);
return Timeout;
}
/* EOF */