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