/* * 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 #define NDEBUG #include /* 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 */ PVOID NTAPI CsrAllocateCaptureBuffer(ULONG ArgumentCount, 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)); /* Allocate memory from the port heap */ CaptureBuffer = RtlAllocateHeap(CsrPortHeap, 0, BufferSize); if (CaptureBuffer == NULL) return NULL; /* Initialize the header */ CaptureBuffer->Size = BufferSize; CaptureBuffer->PointerCount = 0; /* Initialize all the pointers */ RtlZeroMemory(CaptureBuffer->PointerArray, ArgumentCount * sizeof(ULONG_PTR)); /* Point the start of the free buffer */ CaptureBuffer->BufferEnd = (ULONG_PTR)CaptureBuffer->PointerArray + ArgumentCount * sizeof(ULONG_PTR); /* Return the address of the buffer */ return CaptureBuffer; } /* * @implemented */ ULONG NTAPI CsrAllocateMessagePointer(PCSR_CAPTURE_BUFFER CaptureBuffer, ULONG MessageLength, PVOID *CaptureData) { /* If there's no data, our job is easy. */ if (MessageLength == 0) { *CaptureData = NULL; CaptureData = NULL; } else { /* Set the capture data at our current available buffer */ *CaptureData = (PVOID)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 += MessageLength; } /* Write down this pointer in the array */ CaptureBuffer->PointerArray[CaptureBuffer->PointerCount] = (ULONG_PTR)CaptureData; /* Increase the pointer count */ CaptureBuffer->PointerCount++; /* Return the aligned length */ return MessageLength; } /* * @implemented */ VOID NTAPI CsrCaptureMessageBuffer(PCSR_CAPTURE_BUFFER CaptureBuffer, PVOID MessageString, ULONG StringLength, PVOID *CapturedData) { /* Simply allocate a message pointer in the buffer */ CsrAllocateMessagePointer(CaptureBuffer, StringLength, CapturedData); /* Check if there was any data */ if (!MessageString || !StringLength) return; /* Copy the data into the buffer */ RtlMoveMemory(*CapturedData, MessageString, StringLength); } /* * @implemented */ VOID NTAPI CsrFreeCaptureBuffer(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, 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(LONG Milliseconds, PLARGE_INTEGER Timeout) { /* Validate the time */ if (Milliseconds == -1) return NULL; /* Convert to relative ticks */ Timeout->QuadPart = Milliseconds * -100000; return Timeout; } /* EOF */