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 /* Allocate memory from the port heap */
105 CaptureBuffer
= RtlAllocateHeap(CsrPortHeap
, HEAP_ZERO_MEMORY
, BufferSize
);
106 if (CaptureBuffer
== NULL
) return NULL
;
108 /* Initialize the header */
109 CaptureBuffer
->Size
= BufferSize
;
110 CaptureBuffer
->PointerCount
= 0;
112 /* Initialize all the offsets */
113 RtlZeroMemory(CaptureBuffer
->PointerOffsetsArray
,
114 ArgumentCount
* sizeof(ULONG_PTR
));
116 /* Point to the start of the free buffer */
117 CaptureBuffer
->BufferEnd
= (PVOID
)((ULONG_PTR
)CaptureBuffer
->PointerOffsetsArray
+
118 ArgumentCount
* sizeof(ULONG_PTR
));
120 /* Return the address of the buffer */
121 return CaptureBuffer
;
129 CsrAllocateMessagePointer(IN OUT PCSR_CAPTURE_BUFFER CaptureBuffer
,
130 IN ULONG MessageLength
,
131 OUT PVOID
*CapturedData
)
133 if (MessageLength
== 0)
135 *CapturedData
= NULL
;
140 /* Set the capture data at our current available buffer */
141 *CapturedData
= CaptureBuffer
->BufferEnd
;
143 /* Validate the size */
144 if (MessageLength
>= MAXLONG
) return 0;
146 /* Align it to a 4-byte boundary */
147 MessageLength
= (MessageLength
+ 3) & ~3;
149 /* Move our available buffer beyond this space */
150 CaptureBuffer
->BufferEnd
= (PVOID
)((ULONG_PTR
)CaptureBuffer
->BufferEnd
+ MessageLength
);
153 /* Write down this pointer in the array and increase the count */
154 CaptureBuffer
->PointerOffsetsArray
[CaptureBuffer
->PointerCount
++] = (ULONG_PTR
)CapturedData
;
156 /* Return the aligned length */
157 return MessageLength
;
165 CsrCaptureMessageBuffer(IN OUT PCSR_CAPTURE_BUFFER CaptureBuffer
,
166 IN PVOID MessageBuffer OPTIONAL
,
167 IN ULONG MessageLength
,
168 OUT PVOID
*CapturedData
)
170 /* Simply allocate a message pointer in the buffer */
171 CsrAllocateMessagePointer(CaptureBuffer
, MessageLength
, CapturedData
);
173 /* Check if there was any data */
174 if (!MessageBuffer
|| !MessageLength
) return;
176 /* Copy the data into the buffer */
177 RtlMoveMemory(*CapturedData
, MessageBuffer
, MessageLength
);
185 CsrFreeCaptureBuffer(IN PCSR_CAPTURE_BUFFER CaptureBuffer
)
187 /* Free it from the heap */
188 RtlFreeHeap(CsrPortHeap
, 0, CaptureBuffer
);
196 CsrCaptureMessageMultiUnicodeStringsInPlace(IN PCSR_CAPTURE_BUFFER
*CaptureBuffer
,
197 IN ULONG MessageCount
,
198 IN PVOID MessageStrings
)
200 /* FIXME: allocate a buffer if we don't have one, and return it */
201 /* FIXME: call CsrCaptureMessageUnicodeStringInPlace for each string */
203 return STATUS_NOT_IMPLEMENTED
;
211 CsrCaptureMessageString(IN OUT PCSR_CAPTURE_BUFFER CaptureBuffer
,
212 IN LPSTR String OPTIONAL
,
213 IN ULONG StringLength
,
214 IN ULONG MaximumLength
,
215 OUT PANSI_STRING CapturedString
)
217 ULONG ReturnedLength
;
219 /* If we don't have a string, initialize an empty one */
222 CapturedString
->Length
= 0;
223 CapturedString
->MaximumLength
= (USHORT
)MaximumLength
;
225 /* Allocate a pointer for it */
226 CsrAllocateMessagePointer(CaptureBuffer
,
228 (PVOID
*)&CapturedString
->Buffer
);
232 /* Initialize this string */
233 CapturedString
->Length
= (USHORT
)StringLength
;
235 /* Allocate a buffer and get its size */
236 ReturnedLength
= CsrAllocateMessagePointer(CaptureBuffer
,
238 (PVOID
*)&CapturedString
->Buffer
);
239 CapturedString
->MaximumLength
= (USHORT
)ReturnedLength
;
241 /* If the string had data */
244 /* Copy it into the capture buffer */
245 RtlMoveMemory(CapturedString
->Buffer
, String
, MaximumLength
);
247 /* If we don't take up the whole space */
248 if (CapturedString
->Length
< CapturedString
->MaximumLength
)
250 /* Null-terminate it */
251 CapturedString
->Buffer
[CapturedString
->Length
] = '\0';
261 CsrCaptureTimeout(IN ULONG Milliseconds
,
262 OUT PLARGE_INTEGER Timeout
)
264 /* Validate the time */
265 if (Milliseconds
== -1) return NULL
;
267 /* Convert to relative ticks */
268 Timeout
->QuadPart
= Int32x32To64(Milliseconds
, -10000);