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