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