2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS kernel
4 * FILE: lib/ntdll/csr/capture.c
5 * PURPOSE: Routines for probing and capturing CSR API Messages
6 * PROGRAMMER: Alex Ionescu (alex@relsoft.net)
9 /* INCLUDES *****************************************************************/
15 /* GLOBALS *******************************************************************/
16 extern HANDLE CsrPortHeap
;
18 /* FUNCTIONS *****************************************************************/
25 CsrProbeForRead(IN PVOID Address
,
29 volatile UCHAR
*Pointer
;
33 if (Length
== 0) return;
35 /* Validate alignment */
36 if ((ULONG_PTR
)Address
& (Alignment
- 1))
38 /* Raise exception if it doesn't match */
39 RtlRaiseStatus(STATUS_DATATYPE_MISALIGNMENT
);
42 /* Probe first byte */
47 Pointer
= (PUCHAR
)Address
+ Length
- 1;
57 CsrProbeForWrite(IN PVOID Address
,
61 volatile UCHAR
*Pointer
;
64 if (Length
== 0) return;
66 /* Validate alignment */
67 if ((ULONG_PTR
)Address
& (Alignment
- 1))
69 /* Raise exception if it doesn't match */
70 RtlRaiseStatus(STATUS_DATATYPE_MISALIGNMENT
);
73 /* Probe first byte */
78 Pointer
= (PUCHAR
)Address
+ Length
- 1;
87 CsrAllocateCaptureBuffer(ULONG ArgumentCount
,
90 PCSR_CAPTURE_BUFFER CaptureBuffer
;
93 if (BufferSize
>= MAXLONG
) return NULL
;
95 /* Add the size of the header and for each pointer to the pointers */
96 BufferSize
+= sizeof(CSR_CAPTURE_BUFFER
) + (ArgumentCount
* sizeof(PVOID
));
98 /* Allocate memory from the port heap */
99 CaptureBuffer
= RtlAllocateHeap(CsrPortHeap
, 0, BufferSize
);
100 if (CaptureBuffer
== NULL
) return NULL
;
102 /* Initialize the header */
103 CaptureBuffer
->Size
= BufferSize
;
104 CaptureBuffer
->PointerCount
= 0;
106 /* Initialize all the pointers */
107 RtlZeroMemory(CaptureBuffer
->PointerArray
,
108 ArgumentCount
* sizeof(ULONG_PTR
));
110 /* Point the start of the free buffer */
111 CaptureBuffer
->BufferEnd
= (ULONG_PTR
)CaptureBuffer
->PointerArray
+
112 ArgumentCount
* sizeof(ULONG_PTR
);
114 /* Return the address of the buffer */
115 return CaptureBuffer
;
123 CsrAllocateMessagePointer(PCSR_CAPTURE_BUFFER CaptureBuffer
,
127 /* If there's no data, our job is easy. */
128 if (MessageLength
== 0)
135 /* Set the capture data at our current available buffer */
136 *CaptureData
= (PVOID
)CaptureBuffer
->BufferEnd
;
138 /* Validate the size */
139 if (MessageLength
>= MAXLONG
) return 0;
141 /* Align it to a 4-byte boundary */
142 MessageLength
= (MessageLength
+ 3) & ~3;
144 /* Move our available buffer beyond this space */
145 CaptureBuffer
->BufferEnd
+= MessageLength
;
148 /* Write down this pointer in the array */
149 CaptureBuffer
->PointerArray
[CaptureBuffer
->PointerCount
] = (ULONG_PTR
)CaptureData
;
151 /* Increase the pointer count */
152 CaptureBuffer
->PointerCount
++;
154 /* Return the aligned length */
155 return MessageLength
;
163 CsrCaptureMessageBuffer(PCSR_CAPTURE_BUFFER CaptureBuffer
,
168 /* Simply allocate a message pointer in the buffer */
169 CsrAllocateMessagePointer(CaptureBuffer
, StringLength
, CapturedData
);
171 /* Check if there was any data */
172 if (!MessageString
|| !StringLength
) return;
174 /* Copy the data into the buffer */
175 RtlMoveMemory(*CapturedData
, MessageString
, StringLength
);
183 CsrFreeCaptureBuffer(PCSR_CAPTURE_BUFFER CaptureBuffer
)
185 /* Free it from the heap */
186 RtlFreeHeap(CsrPortHeap
, 0, CaptureBuffer
);
194 CsrCaptureMessageMultiUnicodeStringsInPlace(IN PCSR_CAPTURE_BUFFER
*CaptureBuffer
,
195 IN ULONG MessageCount
,
196 IN PVOID MessageStrings
)
198 /* FIXME: allocate a buffer if we don't have one, and return it */
199 /* FIXME: call CsrCaptureMessageUnicodeStringInPlace for each string */
201 return STATUS_NOT_IMPLEMENTED
;
209 CsrCaptureMessageString(PCSR_CAPTURE_BUFFER CaptureBuffer
,
211 IN ULONG StringLength
,
212 IN ULONG MaximumLength
,
213 OUT PANSI_STRING CapturedString
)
215 ULONG ReturnedLength
;
217 /* If we don't have a string, initialize an empty one */
220 CapturedString
->Length
= 0;
221 CapturedString
->MaximumLength
= (USHORT
)MaximumLength
;
223 /* Allocate a pointer for it */
224 CsrAllocateMessagePointer(CaptureBuffer
,
226 (PVOID
*)&CapturedString
->Buffer
);
230 /* Initialize this string */
231 CapturedString
->Length
= (USHORT
)StringLength
;
233 /* Allocate a buffer and get its size */
234 ReturnedLength
= CsrAllocateMessagePointer(CaptureBuffer
,
236 (PVOID
*)&CapturedString
->Buffer
);
237 CapturedString
->MaximumLength
= (USHORT
)ReturnedLength
;
239 /* If the string had data */
242 /* Copy it into the capture buffer */
243 RtlMoveMemory(CapturedString
->Buffer
, String
, MaximumLength
);
245 /* If we don't take up the whole space */
246 if (CapturedString
->Length
< CapturedString
->MaximumLength
)
248 /* Null-terminate it */
249 CapturedString
->Buffer
[CapturedString
->Length
] = '\0';
259 CsrCaptureTimeout(LONG Milliseconds
,
260 PLARGE_INTEGER Timeout
)
262 /* Validate the time */
263 if (Milliseconds
== -1) return NULL
;
265 /* Convert to relative ticks */
266 Timeout
->QuadPart
= Milliseconds
* -100000;