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 ********************************************************************/
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
) + (ArgumentCount
* sizeof(ULONG_PTR
));
99 /* Align it to a 4-byte boundary */
100 BufferSize
= (BufferSize
+ 3) & ~3;
102 /* Allocate memory from the port heap */
103 CaptureBuffer
= RtlAllocateHeap(CsrPortHeap
, HEAP_ZERO_MEMORY
, BufferSize
);
104 if (CaptureBuffer
== NULL
) return NULL
;
106 /* Initialize the header */
107 CaptureBuffer
->Size
= BufferSize
;
108 CaptureBuffer
->PointerCount
= 0;
110 /* Initialize all the offsets */
111 RtlZeroMemory(CaptureBuffer
->PointerOffsetsArray
,
112 ArgumentCount
* sizeof(ULONG_PTR
));
114 /* Point to the start of the free buffer */
115 CaptureBuffer
->BufferEnd
= (PVOID
)((ULONG_PTR
)CaptureBuffer
->PointerOffsetsArray
+
116 ArgumentCount
* sizeof(ULONG_PTR
));
118 /* Return the address of the buffer */
119 return CaptureBuffer
;
127 CsrAllocateMessagePointer(IN OUT PCSR_CAPTURE_BUFFER CaptureBuffer
,
128 IN ULONG MessageLength
,
129 OUT PVOID
*CapturedData
)
131 if (MessageLength
== 0)
133 *CapturedData
= NULL
;
138 /* Set the capture data at our current available buffer */
139 *CapturedData
= CaptureBuffer
->BufferEnd
;
141 /* Validate the size */
142 if (MessageLength
>= MAXLONG
) return 0;
144 /* Align it to a 4-byte boundary */
145 MessageLength
= (MessageLength
+ 3) & ~3;
147 /* Move our available buffer beyond this space */
148 CaptureBuffer
->BufferEnd
= (PVOID
)((ULONG_PTR
)CaptureBuffer
->BufferEnd
+ MessageLength
);
151 /* Write down this pointer in the array and increase the count */
152 CaptureBuffer
->PointerOffsetsArray
[CaptureBuffer
->PointerCount
++] = (ULONG_PTR
)CapturedData
;
154 /* Return the aligned length */
155 return MessageLength
;
163 CsrCaptureMessageBuffer(IN OUT PCSR_CAPTURE_BUFFER CaptureBuffer
,
164 IN PVOID MessageBuffer OPTIONAL
,
165 IN ULONG MessageLength
,
166 OUT PVOID
*CapturedData
)
168 /* Simply allocate a message pointer in the buffer */
169 CsrAllocateMessagePointer(CaptureBuffer
, MessageLength
, CapturedData
);
171 /* Check if there was any data */
172 if (!MessageBuffer
|| !MessageLength
) return;
174 /* Copy the data into the buffer */
175 RtlMoveMemory(*CapturedData
, MessageBuffer
, MessageLength
);
183 CsrFreeCaptureBuffer(IN 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(IN OUT PCSR_CAPTURE_BUFFER CaptureBuffer
,
210 IN LPSTR String OPTIONAL
,
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(IN ULONG Milliseconds
,
260 OUT PLARGE_INTEGER Timeout
)
262 /* Validate the time */
263 if (Milliseconds
== -1) return NULL
;
265 /* Convert to relative ticks */
266 Timeout
->QuadPart
= Int32x32To64(Milliseconds
, -10000);