Sync with trunk r63502.
[reactos.git] / dll / ntdll / csr / capture.c
1 /*
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)
7 */
8
9 /* INCLUDES *******************************************************************/
10
11 #include <ntdll.h>
12
13 #define NDEBUG
14 #include <debug.h>
15
16 /* GLOBALS ********************************************************************/
17
18 extern HANDLE CsrPortHeap;
19
20 /* FUNCTIONS ******************************************************************/
21
22 /*
23 * @implemented
24 */
25 VOID
26 NTAPI
27 CsrProbeForRead(IN PVOID Address,
28 IN ULONG Length,
29 IN ULONG Alignment)
30 {
31 volatile UCHAR *Pointer;
32 UCHAR Data;
33
34 /* Validate length */
35 if (Length == 0) return;
36
37 /* Validate alignment */
38 if ((ULONG_PTR)Address & (Alignment - 1))
39 {
40 /* Raise exception if it doesn't match */
41 RtlRaiseStatus(STATUS_DATATYPE_MISALIGNMENT);
42 }
43
44 /* Probe first byte */
45 Pointer = Address;
46 Data = *Pointer;
47
48 /* Probe last byte */
49 Pointer = (PUCHAR)Address + Length - 1;
50 Data = *Pointer;
51 (void)Data;
52 }
53
54 /*
55 * @implemented
56 */
57 VOID
58 NTAPI
59 CsrProbeForWrite(IN PVOID Address,
60 IN ULONG Length,
61 IN ULONG Alignment)
62 {
63 volatile UCHAR *Pointer;
64
65 /* Validate length */
66 if (Length == 0) return;
67
68 /* Validate alignment */
69 if ((ULONG_PTR)Address & (Alignment - 1))
70 {
71 /* Raise exception if it doesn't match */
72 RtlRaiseStatus(STATUS_DATATYPE_MISALIGNMENT);
73 }
74
75 /* Probe first byte */
76 Pointer = Address;
77 *Pointer = *Pointer;
78
79 /* Probe last byte */
80 Pointer = (PUCHAR)Address + Length - 1;
81 *Pointer = *Pointer;
82 }
83
84 /*
85 * @implemented
86 */
87 PCSR_CAPTURE_BUFFER
88 NTAPI
89 CsrAllocateCaptureBuffer(IN ULONG ArgumentCount,
90 IN ULONG BufferSize)
91 {
92 PCSR_CAPTURE_BUFFER CaptureBuffer;
93
94 /* Validate size */
95 if (BufferSize >= MAXLONG) return NULL;
96
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));
100
101 /* Align it to a 4-byte boundary */
102 BufferSize = (BufferSize + 3) & ~3;
103
104 /* Add the size of the alignment padding for each argument */
105 BufferSize += ArgumentCount * 3;
106
107 /* Allocate memory from the port heap */
108 CaptureBuffer = RtlAllocateHeap(CsrPortHeap, HEAP_ZERO_MEMORY, BufferSize);
109 if (CaptureBuffer == NULL) return NULL;
110
111 /* Initialize the header */
112 CaptureBuffer->Size = BufferSize;
113 CaptureBuffer->PointerCount = 0;
114
115 /* Initialize all the offsets */
116 RtlZeroMemory(CaptureBuffer->PointerOffsetsArray,
117 ArgumentCount * sizeof(ULONG_PTR));
118
119 /* Point to the start of the free buffer */
120 CaptureBuffer->BufferEnd = (PVOID)((ULONG_PTR)CaptureBuffer->PointerOffsetsArray +
121 ArgumentCount * sizeof(ULONG_PTR));
122
123 /* Return the address of the buffer */
124 return CaptureBuffer;
125 }
126
127 /*
128 * @implemented
129 */
130 ULONG
131 NTAPI
132 CsrAllocateMessagePointer(IN OUT PCSR_CAPTURE_BUFFER CaptureBuffer,
133 IN ULONG MessageLength,
134 OUT PVOID *CapturedData)
135 {
136 if (MessageLength == 0)
137 {
138 *CapturedData = NULL;
139 CapturedData = NULL;
140 }
141 else
142 {
143 /* Set the capture data at our current available buffer */
144 *CapturedData = CaptureBuffer->BufferEnd;
145
146 /* Validate the size */
147 if (MessageLength >= MAXLONG) return 0;
148
149 /* Align it to a 4-byte boundary */
150 MessageLength = (MessageLength + 3) & ~3;
151
152 /* Move our available buffer beyond this space */
153 CaptureBuffer->BufferEnd = (PVOID)((ULONG_PTR)CaptureBuffer->BufferEnd + MessageLength);
154 }
155
156 /* Write down this pointer in the array and increase the count */
157 CaptureBuffer->PointerOffsetsArray[CaptureBuffer->PointerCount++] = (ULONG_PTR)CapturedData;
158
159 /* Return the aligned length */
160 return MessageLength;
161 }
162
163 /*
164 * @implemented
165 */
166 VOID
167 NTAPI
168 CsrCaptureMessageBuffer(IN OUT PCSR_CAPTURE_BUFFER CaptureBuffer,
169 IN PVOID MessageBuffer OPTIONAL,
170 IN ULONG MessageLength,
171 OUT PVOID *CapturedData)
172 {
173 /* Simply allocate a message pointer in the buffer */
174 CsrAllocateMessagePointer(CaptureBuffer, MessageLength, CapturedData);
175
176 /* Check if there was any data */
177 if (!MessageBuffer || !MessageLength) return;
178
179 /* Copy the data into the buffer */
180 RtlMoveMemory(*CapturedData, MessageBuffer, MessageLength);
181 }
182
183 /*
184 * @implemented
185 */
186 VOID
187 NTAPI
188 CsrFreeCaptureBuffer(IN PCSR_CAPTURE_BUFFER CaptureBuffer)
189 {
190 /* Free it from the heap */
191 RtlFreeHeap(CsrPortHeap, 0, CaptureBuffer);
192 }
193
194 /*
195 * @unimplemented
196 */
197 NTSTATUS
198 NTAPI
199 CsrCaptureMessageMultiUnicodeStringsInPlace(IN PCSR_CAPTURE_BUFFER *CaptureBuffer,
200 IN ULONG MessageCount,
201 IN PVOID MessageStrings)
202 {
203 /* FIXME: allocate a buffer if we don't have one, and return it */
204 /* FIXME: call CsrCaptureMessageUnicodeStringInPlace for each string */
205 UNIMPLEMENTED;
206 return STATUS_NOT_IMPLEMENTED;
207 }
208
209 /*
210 * @implemented
211 */
212 VOID
213 NTAPI
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)
219 {
220 ULONG ReturnedLength;
221
222 /* If we don't have a string, initialize an empty one */
223 if (!String)
224 {
225 CapturedString->Length = 0;
226 CapturedString->MaximumLength = (USHORT)MaximumLength;
227
228 /* Allocate a pointer for it */
229 CsrAllocateMessagePointer(CaptureBuffer,
230 MaximumLength,
231 (PVOID*)&CapturedString->Buffer);
232 return;
233 }
234
235 /* Initialize this string */
236 CapturedString->Length = (USHORT)StringLength;
237
238 /* Allocate a buffer and get its size */
239 ReturnedLength = CsrAllocateMessagePointer(CaptureBuffer,
240 MaximumLength,
241 (PVOID*)&CapturedString->Buffer);
242 CapturedString->MaximumLength = (USHORT)ReturnedLength;
243
244 /* If the string had data */
245 if (StringLength)
246 {
247 /* Copy it into the capture buffer */
248 RtlMoveMemory(CapturedString->Buffer, String, MaximumLength);
249
250 /* If we don't take up the whole space */
251 if (CapturedString->Length < CapturedString->MaximumLength)
252 {
253 /* Null-terminate it */
254 CapturedString->Buffer[CapturedString->Length] = '\0';
255 }
256 }
257 }
258
259 /*
260 * @implemented
261 */
262 PLARGE_INTEGER
263 NTAPI
264 CsrCaptureTimeout(IN ULONG Milliseconds,
265 OUT PLARGE_INTEGER Timeout)
266 {
267 /* Validate the time */
268 if (Milliseconds == -1) return NULL;
269
270 /* Convert to relative ticks */
271 Timeout->QuadPart = Int32x32To64(Milliseconds, -10000);
272 return Timeout;
273 }
274
275 /* EOF */