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