2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS kernel
4 * FILE: dll/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 ********************************************************************/
17 extern HANDLE CsrPortHeap
;
19 /* FUNCTIONS ******************************************************************/
26 CsrProbeForRead(IN PVOID Address
,
30 volatile UCHAR
*Pointer
;
34 if (Length
== 0) return;
36 /* Validate alignment */
37 if ((ULONG_PTR
)Address
& (Alignment
- 1))
39 /* Raise exception if it doesn't match */
40 RtlRaiseStatus(STATUS_DATATYPE_MISALIGNMENT
);
43 /* Probe first byte */
48 Pointer
= (PUCHAR
)Address
+ Length
- 1;
58 CsrProbeForWrite(IN PVOID Address
,
62 volatile UCHAR
*Pointer
;
65 if (Length
== 0) return;
67 /* Validate alignment */
68 if ((ULONG_PTR
)Address
& (Alignment
- 1))
70 /* Raise exception if it doesn't match */
71 RtlRaiseStatus(STATUS_DATATYPE_MISALIGNMENT
);
74 /* Probe first byte */
79 Pointer
= (PUCHAR
)Address
+ Length
- 1;
88 CsrAllocateCaptureBuffer(IN ULONG ArgumentCount
,
91 PCSR_CAPTURE_BUFFER CaptureBuffer
;
94 if (BufferSize
>= MAXLONG
) return NULL
;
96 /* Add the size of the header and for each offset to the pointers */
97 BufferSize
+= FIELD_OFFSET(CSR_CAPTURE_BUFFER
, PointerOffsetsArray
) +
98 (ArgumentCount
* sizeof(ULONG_PTR
));
100 /* Align it to a 4-byte boundary */
101 BufferSize
= (BufferSize
+ 3) & ~3;
103 /* Allocate memory from the port heap */
104 CaptureBuffer
= RtlAllocateHeap(CsrPortHeap
, HEAP_ZERO_MEMORY
, BufferSize
);
105 if (CaptureBuffer
== NULL
) return NULL
;
107 /* Initialize the header */
108 CaptureBuffer
->Size
= BufferSize
;
109 CaptureBuffer
->PointerCount
= 0;
111 /* Initialize all the offsets */
112 RtlZeroMemory(CaptureBuffer
->PointerOffsetsArray
,
113 ArgumentCount
* sizeof(ULONG_PTR
));
115 /* Point to the start of the free buffer */
116 CaptureBuffer
->BufferEnd
= (PVOID
)((ULONG_PTR
)CaptureBuffer
->PointerOffsetsArray
+
117 ArgumentCount
* sizeof(ULONG_PTR
));
119 /* Return the address of the buffer */
120 return CaptureBuffer
;
128 CsrAllocateMessagePointer(IN OUT PCSR_CAPTURE_BUFFER CaptureBuffer
,
129 IN ULONG MessageLength
,
130 OUT PVOID
*CapturedData
)
132 if (MessageLength
== 0)
134 *CapturedData
= NULL
;
139 /* Set the capture data at our current available buffer */
140 *CapturedData
= CaptureBuffer
->BufferEnd
;
142 /* Validate the size */
143 if (MessageLength
>= MAXLONG
) return 0;
145 /* Align it to a 4-byte boundary */
146 MessageLength
= (MessageLength
+ 3) & ~3;
148 /* Move our available buffer beyond this space */
149 CaptureBuffer
->BufferEnd
= (PVOID
)((ULONG_PTR
)CaptureBuffer
->BufferEnd
+ MessageLength
);
152 /* Write down this pointer in the array and increase the count */
153 CaptureBuffer
->PointerOffsetsArray
[CaptureBuffer
->PointerCount
++] = (ULONG_PTR
)CapturedData
;
155 /* Return the aligned length */
156 return MessageLength
;
164 CsrCaptureMessageBuffer(IN OUT PCSR_CAPTURE_BUFFER CaptureBuffer
,
165 IN PVOID MessageBuffer OPTIONAL
,
166 IN ULONG MessageLength
,
167 OUT PVOID
*CapturedData
)
169 /* Simply allocate a message pointer in the buffer */
170 CsrAllocateMessagePointer(CaptureBuffer
, MessageLength
, CapturedData
);
172 /* Check if there was any data */
173 if (!MessageBuffer
|| !MessageLength
) return;
175 /* Copy the data into the buffer */
176 RtlMoveMemory(*CapturedData
, MessageBuffer
, MessageLength
);
184 CsrFreeCaptureBuffer(IN PCSR_CAPTURE_BUFFER CaptureBuffer
)
186 /* Free it from the heap */
187 RtlFreeHeap(CsrPortHeap
, 0, CaptureBuffer
);
195 CsrCaptureMessageMultiUnicodeStringsInPlace(IN PCSR_CAPTURE_BUFFER
*CaptureBuffer
,
196 IN ULONG MessageCount
,
197 IN PVOID MessageStrings
)
199 /* FIXME: allocate a buffer if we don't have one, and return it */
200 /* FIXME: call CsrCaptureMessageUnicodeStringInPlace for each string */
202 return STATUS_NOT_IMPLEMENTED
;
210 CsrCaptureMessageString(IN OUT PCSR_CAPTURE_BUFFER CaptureBuffer
,
211 IN LPSTR String OPTIONAL
,
212 IN ULONG StringLength
,
213 IN ULONG MaximumLength
,
214 OUT PANSI_STRING CapturedString
)
216 ULONG ReturnedLength
;
218 /* If we don't have a string, initialize an empty one */
221 CapturedString
->Length
= 0;
222 CapturedString
->MaximumLength
= (USHORT
)MaximumLength
;
224 /* Allocate a pointer for it */
225 CsrAllocateMessagePointer(CaptureBuffer
,
227 (PVOID
*)&CapturedString
->Buffer
);
231 /* Initialize this string */
232 CapturedString
->Length
= (USHORT
)StringLength
;
234 /* Allocate a buffer and get its size */
235 ReturnedLength
= CsrAllocateMessagePointer(CaptureBuffer
,
237 (PVOID
*)&CapturedString
->Buffer
);
238 CapturedString
->MaximumLength
= (USHORT
)ReturnedLength
;
240 /* If the string had data */
243 /* Copy it into the capture buffer */
244 RtlMoveMemory(CapturedString
->Buffer
, String
, MaximumLength
);
246 /* If we don't take up the whole space */
247 if (CapturedString
->Length
< CapturedString
->MaximumLength
)
249 /* Null-terminate it */
250 CapturedString
->Buffer
[CapturedString
->Length
] = '\0';
260 CsrCaptureTimeout(IN ULONG Milliseconds
,
261 OUT PLARGE_INTEGER Timeout
)
263 /* Validate the time */
264 if (Milliseconds
== -1) return NULL
;
266 /* Convert to relative ticks */
267 Timeout
->QuadPart
= Int32x32To64(Milliseconds
, -10000);