ReactOS 0.4.15-dev-5672-gf73ac17
capture.c
Go to the documentation of this file.
1/*
2 * PROJECT: ReactOS Client/Server Runtime SubSystem
3 * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
4 * PURPOSE: CSR Client Library - CSR API Messages probing and capturing
5 * COPYRIGHT: Copyright 2005 Alex Ionescu <alex@relsoft.net>
6 * Copyright 2012-2022 Hermès Bélusca-Maïto <hermes.belusca-maito@reactos.org>
7 */
8
9/* INCLUDES *******************************************************************/
10
11#include "csrlib.h"
12
13#define NDEBUG
14#include <debug.h>
15
16/* FUNCTIONS ******************************************************************/
17
18/*
19 * @implemented
20 */
21VOID
27{
28 volatile UCHAR *Pointer;
29 UCHAR Data;
30
31 /* Validate length */
32 if (Length == 0) return;
33
34 /* Validate alignment */
35 if ((ULONG_PTR)Address & (Alignment - 1))
36 {
37 /* Raise exception if it doesn't match */
39 }
40
41 /* Probe first byte */
42 Pointer = Address;
43 Data = *Pointer;
44
45 /* Probe last byte */
46 Pointer = (PUCHAR)Address + Length - 1;
47 Data = *Pointer;
48 (void)Data;
49}
50
51/*
52 * @implemented
53 */
54VOID
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 */
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 */
88 _In_ ULONG ArgumentCount,
90{
91 PCSR_CAPTURE_BUFFER CaptureBuffer;
92 ULONG OffsetsArraySize;
94
95 /* Validate the argument count. Note that on server side, CSRSRV
96 * limits the count to MAXUSHORT; here we are a bit more lenient. */
97 if (ArgumentCount > (MAXLONG / sizeof(ULONG_PTR)))
98 return NULL;
99
100 OffsetsArraySize = ArgumentCount * sizeof(ULONG_PTR);
101
102 /*
103 * Validate the total buffer size.
104 * The total size of the header plus the pointer-offset array and the
105 * provided buffer, together with the alignment padding for each argument,
106 * must be less than MAXLONG aligned to 4-byte boundary.
107 */
108 MaximumSize = (MAXLONG & ~3) - FIELD_OFFSET(CSR_CAPTURE_BUFFER, PointerOffsetsArray);
109 if (OffsetsArraySize >= MaximumSize)
110 return NULL;
111 MaximumSize -= OffsetsArraySize;
112 if (BufferSize >= MaximumSize)
113 return NULL;
115 if ((ArgumentCount * 3) + 3 >= MaximumSize)
116 return NULL;
117
118 /* Add the size of the header and of the pointer-offset array */
119 BufferSize += FIELD_OFFSET(CSR_CAPTURE_BUFFER, PointerOffsetsArray) +
120 OffsetsArraySize;
121
122 /* Add the size of the alignment padding for each argument */
123 BufferSize += ArgumentCount * 3;
124
125 /* Align it to a 4-byte boundary */
126 BufferSize = (BufferSize + 3) & ~3;
127
128 /* Allocate memory from the port heap */
130 if (CaptureBuffer == NULL) return NULL;
131
132 /* Initialize the header */
133 CaptureBuffer->Size = BufferSize;
134 CaptureBuffer->PointerCount = 0;
135
136 /* Initialize the pointer-offset array */
137 RtlZeroMemory(CaptureBuffer->PointerOffsetsArray, OffsetsArraySize);
138
139 /* Point to the start of the free buffer */
140 CaptureBuffer->BufferEnd = (PVOID)((ULONG_PTR)CaptureBuffer->PointerOffsetsArray +
141 OffsetsArraySize);
142
143 /* Return the address of the buffer */
144 return CaptureBuffer;
145}
146
147/*
148 * @implemented
149 */
150ULONG
151NTAPI
153 _Inout_ PCSR_CAPTURE_BUFFER CaptureBuffer,
154 _In_ ULONG MessageLength,
155 _Out_ PVOID* CapturedData)
156{
157 if (MessageLength == 0)
158 {
159 *CapturedData = NULL;
160 CapturedData = NULL;
161 }
162 else
163 {
164 /* Set the capture data at our current available buffer */
165 *CapturedData = CaptureBuffer->BufferEnd;
166
167 /* Validate the size */
168 if (MessageLength >= MAXLONG) return 0;
169
170 /* Align it to a 4-byte boundary */
171 MessageLength = (MessageLength + 3) & ~3;
172
173 /* Move our available buffer beyond this space */
174 CaptureBuffer->BufferEnd = (PVOID)((ULONG_PTR)CaptureBuffer->BufferEnd + MessageLength);
175 }
176
177 /* Write down this pointer in the array and increase the count */
178 CaptureBuffer->PointerOffsetsArray[CaptureBuffer->PointerCount++] = (ULONG_PTR)CapturedData;
179
180 /* Return the aligned length */
181 return MessageLength;
182}
183
184/*
185 * @implemented
186 */
187VOID
188NTAPI
190 _Inout_ PCSR_CAPTURE_BUFFER CaptureBuffer,
191 _In_opt_ PVOID MessageBuffer,
192 _In_ ULONG MessageLength,
193 _Out_ PVOID* CapturedData)
194{
195 /* Simply allocate a message pointer in the buffer */
196 CsrAllocateMessagePointer(CaptureBuffer, MessageLength, CapturedData);
197
198 /* Check if there was any data */
199 if (!MessageBuffer || !MessageLength) return;
200
201 /* Copy the data into the buffer */
202 RtlMoveMemory(*CapturedData, MessageBuffer, MessageLength);
203}
204
205/*
206 * @implemented
207 */
208VOID
209NTAPI
212{
213 /* Free it from the heap */
214 RtlFreeHeap(CsrPortHeap, 0, CaptureBuffer);
215}
216
217/*
218 * @implemented
219 */
220VOID
221NTAPI
223 _Inout_ PCSR_CAPTURE_BUFFER CaptureBuffer,
225 _In_ ULONG StringLength,
227 _Out_ PSTRING CapturedString)
228{
229 ASSERT(CapturedString != NULL);
230
231 /*
232 * If we don't have a string, initialize an empty one,
233 * otherwise capture the given string.
234 */
235 if (!String)
236 {
237 CapturedString->Length = 0;
238 CapturedString->MaximumLength = (USHORT)MaximumLength;
239
240 /* Allocate a pointer for it */
241 CsrAllocateMessagePointer(CaptureBuffer,
243 (PVOID*)&CapturedString->Buffer);
244 }
245 else
246 {
247 /* Cut-off the string length if needed */
248 if (StringLength > MaximumLength)
249 StringLength = MaximumLength;
250
251 CapturedString->Length = (USHORT)StringLength;
252
253 /* Allocate a buffer and get its size */
254 CapturedString->MaximumLength =
255 (USHORT)CsrAllocateMessagePointer(CaptureBuffer,
257 (PVOID*)&CapturedString->Buffer);
258
259 /* If the string has data, copy it into the buffer */
260 if (StringLength)
261 RtlMoveMemory(CapturedString->Buffer, String, StringLength);
262 }
263
264 /* Null-terminate the string if we don't take up the whole space */
265 if (CapturedString->Length < CapturedString->MaximumLength)
266 CapturedString->Buffer[CapturedString->Length] = ANSI_NULL;
267}
268
269VOID
270NTAPI
272 _Inout_ PCSR_CAPTURE_BUFFER CaptureBuffer,
274{
275 ASSERT(String != NULL);
276
277 /* This is a way to capture the UNICODE string, since (Maximum)Length are also in bytes */
278 CsrCaptureMessageString(CaptureBuffer,
279 (PCSTR)String->Buffer,
280 String->Length,
281 String->MaximumLength,
282 (PSTRING)String);
283
284 /* Null-terminate the string if we don't take up the whole space */
285 if (String->Length + sizeof(WCHAR) <= String->MaximumLength)
286 String->Buffer[String->Length / sizeof(WCHAR)] = UNICODE_NULL;
287}
288
289/*
290 * @implemented
291 */
293NTAPI
295 _Inout_ PCSR_CAPTURE_BUFFER* CaptureBuffer,
296 _In_ ULONG StringsCount,
297 _In_ PUNICODE_STRING* MessageStrings)
298{
299 ULONG Count;
300
301 if (!CaptureBuffer) return STATUS_INVALID_PARAMETER;
302
303 /* Allocate a new capture buffer if we don't have one already */
304 if (!*CaptureBuffer)
305 {
306 /* Compute the required size for the capture buffer */
307 ULONG Size = 0;
308
309 Count = 0;
310 while (Count < StringsCount)
311 {
312 if (MessageStrings[Count])
313 Size += MessageStrings[Count]->MaximumLength;
314
315 ++Count;
316 }
317
318 /* Allocate the capture buffer */
319 *CaptureBuffer = CsrAllocateCaptureBuffer(StringsCount, Size);
320 if (!*CaptureBuffer) return STATUS_NO_MEMORY;
321 }
322
323 /* Now capture each UNICODE string */
324 Count = 0;
325 while (Count < StringsCount)
326 {
327 if (MessageStrings[Count])
328 CsrCaptureMessageUnicodeStringInPlace(*CaptureBuffer, MessageStrings[Count]);
329
330 ++Count;
331 }
332
333 return STATUS_SUCCESS;
334}
335
336/*
337 * @implemented
338 */
340NTAPI
342 _In_ ULONG Milliseconds,
344{
345 /* Validate the time */
346 if (Milliseconds == -1) return NULL;
347
348 /* Convert to relative ticks */
349 Timeout->QuadPart = Milliseconds * -10000LL;
350 return Timeout;
351}
352
353/* EOF */
LONG NTSTATUS
Definition: precomp.h:26
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:588
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:606
#define BufferSize
Definition: mmc.h:75
#define NULL
Definition: types.h:112
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
#define ULONG_PTR
Definition: config.h:101
#define ASSERT(a)
Definition: mode.c:44
#define _Inout_
Definition: ms_sal.h:378
#define _Out_
Definition: ms_sal.h:345
#define _In_
Definition: ms_sal.h:308
#define _In_opt_
Definition: ms_sal.h:309
_In_ ACCESS_MASK _In_opt_ POBJECT_ATTRIBUTES _In_opt_ PLARGE_INTEGER MaximumSize
Definition: mmfuncs.h:362
DECLSPEC_NORETURN NTSYSAPI VOID NTAPI RtlRaiseStatus(_In_ NTSTATUS Status)
int Count
Definition: noreturn.cpp:7
#define UNICODE_NULL
#define ANSI_NULL
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
#define STATUS_NO_MEMORY
Definition: ntstatus.h:260
#define STATUS_DATATYPE_MISALIGNMENT
Definition: ntstatus.h:183
unsigned short USHORT
Definition: pedump.c:61
static WCHAR Address[46]
Definition: ping.c:68
static ULONG Timeout
Definition: ping.c:61
#define STATUS_SUCCESS
Definition: shellext.h:65
#define _Frees_ptr_
Definition: specstrings.h:402
ULONG PointerCount
Definition: csrmsg.h:94
ULONG_PTR PointerOffsetsArray[ANYSIZE_ARRAY]
Definition: csrmsg.h:96
PCSR_CAPTURE_BUFFER NTAPI CsrAllocateCaptureBuffer(_In_ ULONG ArgumentCount, _In_ ULONG BufferSize)
Definition: capture.c:87
NTSTATUS NTAPI CsrCaptureMessageMultiUnicodeStringsInPlace(_Inout_ PCSR_CAPTURE_BUFFER *CaptureBuffer, _In_ ULONG StringsCount, _In_ PUNICODE_STRING *MessageStrings)
Definition: capture.c:294
VOID NTAPI CsrProbeForWrite(_In_ PVOID Address, _In_ ULONG Length, _In_ ULONG Alignment)
Definition: capture.c:56
ULONG NTAPI CsrAllocateMessagePointer(_Inout_ PCSR_CAPTURE_BUFFER CaptureBuffer, _In_ ULONG MessageLength, _Out_ PVOID *CapturedData)
Definition: capture.c:152
VOID NTAPI CsrCaptureMessageString(_Inout_ PCSR_CAPTURE_BUFFER CaptureBuffer, _In_opt_ PCSTR String, _In_ ULONG StringLength, _In_ ULONG MaximumLength, _Out_ PSTRING CapturedString)
Definition: capture.c:222
VOID NTAPI CsrFreeCaptureBuffer(_In_ _Frees_ptr_ PCSR_CAPTURE_BUFFER CaptureBuffer)
Definition: capture.c:210
VOID NTAPI CsrProbeForRead(_In_ PVOID Address, _In_ ULONG Length, _In_ ULONG Alignment)
Definition: capture.c:23
VOID NTAPI CsrCaptureMessageUnicodeStringInPlace(_Inout_ PCSR_CAPTURE_BUFFER CaptureBuffer, _Inout_ PUNICODE_STRING String)
Definition: capture.c:271
PLARGE_INTEGER NTAPI CsrCaptureTimeout(_In_ ULONG Milliseconds, _Out_ PLARGE_INTEGER Timeout)
Definition: capture.c:341
VOID NTAPI CsrCaptureMessageBuffer(_Inout_ PCSR_CAPTURE_BUFFER CaptureBuffer, _In_opt_ PVOID MessageBuffer, _In_ ULONG MessageLength, _Out_ PVOID *CapturedData)
Definition: capture.c:189
HANDLE CsrPortHeap
Definition: connect.c:29
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
#define NTAPI
Definition: typedefs.h:36
void * PVOID
Definition: typedefs.h:50
const char * PCSTR
Definition: typedefs.h:52
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:264
unsigned char * PUCHAR
Definition: typedefs.h:53
uint32_t ULONG
Definition: typedefs.h:59
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define MAXLONG
Definition: umtypes.h:116
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
Definition: wdfdevice.h:4533
_Must_inspect_result_ _In_ WDFDEVICE _In_ WDFSTRING String
Definition: wdfdevice.h:2433
_In_ WDFDMATRANSACTION _In_ size_t MaximumLength
_In_ WDFMEMORY _Out_opt_ size_t * BufferSize
Definition: wdfmemory.h:254
unsigned char UCHAR
Definition: xmlstorage.h:181
__wchar_t WCHAR
Definition: xmlstorage.h:180