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