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
,
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
);
43 Pointer
= (PUCHAR
)Address
;
45 Pointer
= (PUCHAR
)((ULONG
)Address
+ Length
-1);
54 CsrProbeForWrite(IN PVOID Address
,
62 if (Length
== 0) return;
64 /* Validate alignment */
65 if ((ULONG_PTR
)Address
& (Alignment
- 1))
67 /* Raise exception if it doesn't match */
68 RtlRaiseStatus(STATUS_DATATYPE_MISALIGNMENT
);
72 Pointer
= (PUCHAR
)Address
;
75 Pointer
= (PUCHAR
)((ULONG
)Address
+ Length
-1);
85 CsrAllocateCaptureBuffer(ULONG ArgumentCount
,
88 PCSR_CAPTURE_BUFFER CaptureBuffer
;
91 if (BufferSize
>= MAXLONG
) return NULL
;
93 /* Add the size of the header and for each pointer to the pointers */
94 BufferSize
+= sizeof(CSR_CAPTURE_BUFFER
) + (ArgumentCount
* sizeof(PVOID
));
96 /* Allocate memory from the port heap */
97 CaptureBuffer
= RtlAllocateHeap(CsrPortHeap
, 0, BufferSize
);
99 /* Initialize the header */
100 CaptureBuffer
->Size
= BufferSize
;
101 CaptureBuffer
->PointerCount
= 0;
103 /* Initialize all the pointers */
104 RtlZeroMemory(CaptureBuffer
->PointerArray
,
105 ArgumentCount
* sizeof(ULONG_PTR
));
107 /* Point the start of the free buffer */
108 CaptureBuffer
->BufferEnd
= (ULONG_PTR
)CaptureBuffer
->PointerArray
+
109 ArgumentCount
* sizeof(ULONG_PTR
);
111 /* Return the address of the buffer */
112 return CaptureBuffer
;
120 CsrAllocateMessagePointer(PCSR_CAPTURE_BUFFER CaptureBuffer
,
124 /* If there's no data, our job is easy. */
125 if (MessageLength
== 0)
132 /* Set the capture data at our current available buffer */
133 *CaptureData
= (PVOID
)CaptureBuffer
->BufferEnd
;
135 /* Validate the size */
136 if (MessageLength
>= MAXLONG
) return 0;
138 /* Align it to a 4-byte boundary */
139 MessageLength
= (MessageLength
+ 3) & ~3;
141 /* Move our available buffer beyond this space */
142 CaptureBuffer
->BufferEnd
+= MessageLength
;
145 /* Increase the pointer count */
146 CaptureBuffer
->PointerCount
++;
148 /* Write down this pointer in the array */
149 CaptureBuffer
->PointerArray
[CaptureBuffer
->PointerCount
] = (ULONG_PTR
)CaptureData
;
151 /* Return the aligned length */
152 return MessageLength
;
160 CsrCaptureMessageBuffer(PCSR_CAPTURE_BUFFER CaptureBuffer
,
165 /* Simply allocate a message pointer in the buffer */
166 CsrAllocateMessagePointer(CaptureBuffer
, StringLength
, CapturedData
);
168 /* Check if there was any data */
169 if (!MessageString
|| !StringLength
) return;
171 /* Copy the data into the buffer */
172 RtlMoveMemory(*CapturedData
, MessageString
, StringLength
);
180 CsrFreeCaptureBuffer(PCSR_CAPTURE_BUFFER CaptureBuffer
)
182 /* Free it from the heap */
183 RtlFreeHeap(CsrPortHeap
, 0, CaptureBuffer
);
191 CsrCaptureMessageMultiUnicodeStringsInPlace(IN PCSR_CAPTURE_BUFFER
*CaptureBuffer
,
192 IN ULONG MessageCount
,
193 IN PVOID MessageStrings
)
195 /* FIXME: allocate a buffer if we don't have one, and return it */
196 /* FIXME: call CsrCaptureMessageUnicodeStringInPlace for each string */
198 return STATUS_NOT_IMPLEMENTED
;
206 CsrCaptureMessageString(PCSR_CAPTURE_BUFFER CaptureBuffer
,
208 IN ULONG StringLength
,
209 IN ULONG MaximumLength
,
210 OUT PANSI_STRING CapturedString
)
212 ULONG ReturnedLength
;
214 /* If we don't have a string, initialize an empty one */
217 CapturedString
->Length
= 0;
218 CapturedString
->MaximumLength
= MaximumLength
;
220 /* Allocate a pointer for it */
221 CsrAllocateMessagePointer(CaptureBuffer
,
223 (PVOID
*)&CapturedString
->Buffer
);
227 /* Initialize this string */
228 CapturedString
->Length
= StringLength
;
230 /* Allocate a buffer and get its size */
231 ReturnedLength
= CsrAllocateMessagePointer(CaptureBuffer
,
233 (PVOID
*)&CapturedString
->Buffer
);
234 CapturedString
->MaximumLength
= ReturnedLength
;
236 /* If the string had data */
239 /* Copy it into the capture buffer */
240 RtlMoveMemory(CapturedString
->Buffer
, String
, MaximumLength
);
242 /* If we don't take up the whole space */
243 if (CapturedString
->Length
< CapturedString
->MaximumLength
)
245 /* Null-terminate it */
246 CapturedString
->Buffer
[CapturedString
->Length
] = '\0';
256 CsrCaptureTimeout(LONG Milliseconds
,
257 PLARGE_INTEGER Timeout
)
259 /* Validate the time */
260 if (Milliseconds
== -1) return NULL
;
262 /* Convert to relative ticks */
263 Timeout
->QuadPart
= Milliseconds
* -100000;