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 *******************************************************************/
16 /* GLOBALS ********************************************************************/
18 extern HANDLE CsrPortHeap
;
20 /* FUNCTIONS ******************************************************************/
27 CsrProbeForRead(IN PVOID Address
,
31 volatile UCHAR
*Pointer
;
35 if (Length
== 0) return;
37 /* Validate alignment */
38 if ((ULONG_PTR
)Address
& (Alignment
- 1))
40 /* Raise exception if it doesn't match */
41 RtlRaiseStatus(STATUS_DATATYPE_MISALIGNMENT
);
44 /* Probe first byte */
49 Pointer
= (PUCHAR
)Address
+ Length
- 1;
59 CsrProbeForWrite(IN PVOID Address
,
63 volatile UCHAR
*Pointer
;
66 if (Length
== 0) return;
68 /* Validate alignment */
69 if ((ULONG_PTR
)Address
& (Alignment
- 1))
71 /* Raise exception if it doesn't match */
72 RtlRaiseStatus(STATUS_DATATYPE_MISALIGNMENT
);
75 /* Probe first byte */
80 Pointer
= (PUCHAR
)Address
+ Length
- 1;
89 CsrAllocateCaptureBuffer(IN ULONG ArgumentCount
,
92 PCSR_CAPTURE_BUFFER CaptureBuffer
;
95 if (BufferSize
>= MAXLONG
) return NULL
;
97 /* Add the size of the header and for each offset to the pointers */
98 BufferSize
+= FIELD_OFFSET(CSR_CAPTURE_BUFFER
, PointerOffsetsArray
) +
99 (ArgumentCount
* sizeof(ULONG_PTR
));
101 /* Align it to a 4-byte boundary */
102 BufferSize
= (BufferSize
+ 3) & ~3;
104 /* Add the size of the alignment padding for each argument */
105 BufferSize
+= ArgumentCount
* 3;
107 /* Allocate memory from the port heap */
108 CaptureBuffer
= RtlAllocateHeap(CsrPortHeap
, HEAP_ZERO_MEMORY
, BufferSize
);
109 if (CaptureBuffer
== NULL
) return NULL
;
111 /* Initialize the header */
112 CaptureBuffer
->Size
= BufferSize
;
113 CaptureBuffer
->PointerCount
= 0;
115 /* Initialize all the offsets */
116 RtlZeroMemory(CaptureBuffer
->PointerOffsetsArray
,
117 ArgumentCount
* sizeof(ULONG_PTR
));
119 /* Point to the start of the free buffer */
120 CaptureBuffer
->BufferEnd
= (PVOID
)((ULONG_PTR
)CaptureBuffer
->PointerOffsetsArray
+
121 ArgumentCount
* sizeof(ULONG_PTR
));
123 /* Return the address of the buffer */
124 return CaptureBuffer
;
132 CsrAllocateMessagePointer(IN OUT PCSR_CAPTURE_BUFFER CaptureBuffer
,
133 IN ULONG MessageLength
,
134 OUT PVOID
*CapturedData
)
136 if (MessageLength
== 0)
138 *CapturedData
= NULL
;
143 /* Set the capture data at our current available buffer */
144 *CapturedData
= CaptureBuffer
->BufferEnd
;
146 /* Validate the size */
147 if (MessageLength
>= MAXLONG
) return 0;
149 /* Align it to a 4-byte boundary */
150 MessageLength
= (MessageLength
+ 3) & ~3;
152 /* Move our available buffer beyond this space */
153 CaptureBuffer
->BufferEnd
= (PVOID
)((ULONG_PTR
)CaptureBuffer
->BufferEnd
+ MessageLength
);
156 /* Write down this pointer in the array and increase the count */
157 CaptureBuffer
->PointerOffsetsArray
[CaptureBuffer
->PointerCount
++] = (ULONG_PTR
)CapturedData
;
159 /* Return the aligned length */
160 return MessageLength
;
168 CsrCaptureMessageBuffer(IN OUT PCSR_CAPTURE_BUFFER CaptureBuffer
,
169 IN PVOID MessageBuffer OPTIONAL
,
170 IN ULONG MessageLength
,
171 OUT PVOID
*CapturedData
)
173 /* Simply allocate a message pointer in the buffer */
174 CsrAllocateMessagePointer(CaptureBuffer
, MessageLength
, CapturedData
);
176 /* Check if there was any data */
177 if (!MessageBuffer
|| !MessageLength
) return;
179 /* Copy the data into the buffer */
180 RtlMoveMemory(*CapturedData
, MessageBuffer
, MessageLength
);
188 CsrFreeCaptureBuffer(IN PCSR_CAPTURE_BUFFER CaptureBuffer
)
190 /* Free it from the heap */
191 RtlFreeHeap(CsrPortHeap
, 0, CaptureBuffer
);
199 CsrCaptureMessageMultiUnicodeStringsInPlace(IN PCSR_CAPTURE_BUFFER
*CaptureBuffer
,
200 IN ULONG MessageCount
,
201 IN PVOID MessageStrings
)
203 /* FIXME: allocate a buffer if we don't have one, and return it */
204 /* FIXME: call CsrCaptureMessageUnicodeStringInPlace for each string */
206 return STATUS_NOT_IMPLEMENTED
;
214 CsrCaptureMessageString(IN OUT PCSR_CAPTURE_BUFFER CaptureBuffer
,
215 IN LPSTR String OPTIONAL
,
216 IN ULONG StringLength
,
217 IN ULONG MaximumLength
,
218 OUT PANSI_STRING CapturedString
)
220 ULONG ReturnedLength
;
222 /* If we don't have a string, initialize an empty one */
225 CapturedString
->Length
= 0;
226 CapturedString
->MaximumLength
= (USHORT
)MaximumLength
;
228 /* Allocate a pointer for it */
229 CsrAllocateMessagePointer(CaptureBuffer
,
231 (PVOID
*)&CapturedString
->Buffer
);
235 /* Initialize this string */
236 CapturedString
->Length
= (USHORT
)StringLength
;
238 /* Allocate a buffer and get its size */
239 ReturnedLength
= CsrAllocateMessagePointer(CaptureBuffer
,
241 (PVOID
*)&CapturedString
->Buffer
);
242 CapturedString
->MaximumLength
= (USHORT
)ReturnedLength
;
244 /* If the string had data */
247 /* Copy it into the capture buffer */
248 RtlMoveMemory(CapturedString
->Buffer
, String
, MaximumLength
);
250 /* If we don't take up the whole space */
251 if (CapturedString
->Length
< CapturedString
->MaximumLength
)
253 /* Null-terminate it */
254 CapturedString
->Buffer
[CapturedString
->Length
] = '\0';
264 CsrCaptureTimeout(IN ULONG Milliseconds
,
265 OUT PLARGE_INTEGER Timeout
)
267 /* Validate the time */
268 if (Milliseconds
== -1) return NULL
;
270 /* Convert to relative ticks */
271 Timeout
->QuadPart
= Int32x32To64(Milliseconds
, -10000);