ReactOS  0.4.14-dev-49-gfb4591c
capture.c
Go to the documentation of this file.
1 /*
2  * COPYRIGHT: See COPYING in the top level directory
3  * PROJECT: ReactOS kernel
4  * FILE: dll/ntdll/csr/capture.c
5  * PURPOSE: Routines for probing and capturing CSR API Messages
6  * PROGRAMMERS: Alex Ionescu (alex@relsoft.net)
7  * Hermes Belusca-Maito (hermes.belusca@sfr.fr)
8  */
9 
10 /* INCLUDES *******************************************************************/
11 
12 #include <ntdll.h>
13 
14 #define NDEBUG
15 #include <debug.h>
16 
17 /* GLOBALS ********************************************************************/
18 
19 extern HANDLE CsrPortHeap;
20 
21 /* FUNCTIONS ******************************************************************/
22 
23 /*
24  * @implemented
25  */
26 VOID
27 NTAPI
29  IN ULONG Length,
31 {
32  volatile UCHAR *Pointer;
33  UCHAR Data;
34 
35  /* Validate length */
36  if (Length == 0) return;
37 
38  /* Validate alignment */
39  if ((ULONG_PTR)Address & (Alignment - 1))
40  {
41  /* Raise exception if it doesn't match */
43  }
44 
45  /* Probe first byte */
46  Pointer = Address;
47  Data = *Pointer;
48 
49  /* Probe last byte */
50  Pointer = (PUCHAR)Address + Length - 1;
51  Data = *Pointer;
52  (void)Data;
53 }
54 
55 /*
56  * @implemented
57  */
58 VOID
59 NTAPI
61  IN ULONG Length,
63 {
64  volatile UCHAR *Pointer;
65 
66  /* Validate length */
67  if (Length == 0) return;
68 
69  /* Validate alignment */
70  if ((ULONG_PTR)Address & (Alignment - 1))
71  {
72  /* Raise exception if it doesn't match */
74  }
75 
76  /* Probe first byte */
77  Pointer = Address;
78  *Pointer = *Pointer;
79 
80  /* Probe last byte */
81  Pointer = (PUCHAR)Address + Length - 1;
82  *Pointer = *Pointer;
83 }
84 
85 /*
86  * @implemented
87  */
89 NTAPI
92 {
93  PCSR_CAPTURE_BUFFER CaptureBuffer;
94 
95  /* Validate size */
96  if (BufferSize >= MAXLONG) return NULL;
97 
98  /* Add the size of the header and for each offset to the pointers */
99  BufferSize += FIELD_OFFSET(CSR_CAPTURE_BUFFER, PointerOffsetsArray) +
100  (ArgumentCount * sizeof(ULONG_PTR));
101 
102  /* Align it to a 4-byte boundary */
103  BufferSize = (BufferSize + 3) & ~3;
104 
105  /* Add the size of the alignment padding for each argument */
106  BufferSize += ArgumentCount * 3;
107 
108  /* Allocate memory from the port heap */
110  if (CaptureBuffer == NULL) return NULL;
111 
112  /* Initialize the header */
113  CaptureBuffer->Size = BufferSize;
114  CaptureBuffer->PointerCount = 0;
115 
116  /* Initialize all the offsets */
117  RtlZeroMemory(CaptureBuffer->PointerOffsetsArray,
118  ArgumentCount * sizeof(ULONG_PTR));
119 
120  /* Point to the start of the free buffer */
121  CaptureBuffer->BufferEnd = (PVOID)((ULONG_PTR)CaptureBuffer->PointerOffsetsArray +
122  ArgumentCount * sizeof(ULONG_PTR));
123 
124  /* Return the address of the buffer */
125  return CaptureBuffer;
126 }
127 
128 /*
129  * @implemented
130  */
131 ULONG
132 NTAPI
134  IN ULONG MessageLength,
135  OUT PVOID* CapturedData)
136 {
137  if (MessageLength == 0)
138  {
139  *CapturedData = NULL;
140  CapturedData = NULL;
141  }
142  else
143  {
144  /* Set the capture data at our current available buffer */
145  *CapturedData = CaptureBuffer->BufferEnd;
146 
147  /* Validate the size */
148  if (MessageLength >= MAXLONG) return 0;
149 
150  /* Align it to a 4-byte boundary */
151  MessageLength = (MessageLength + 3) & ~3;
152 
153  /* Move our available buffer beyond this space */
154  CaptureBuffer->BufferEnd = (PVOID)((ULONG_PTR)CaptureBuffer->BufferEnd + MessageLength);
155  }
156 
157  /* Write down this pointer in the array and increase the count */
158  CaptureBuffer->PointerOffsetsArray[CaptureBuffer->PointerCount++] = (ULONG_PTR)CapturedData;
159 
160  /* Return the aligned length */
161  return MessageLength;
162 }
163 
164 /*
165  * @implemented
166  */
167 VOID
168 NTAPI
170  IN PVOID MessageBuffer OPTIONAL,
171  IN ULONG MessageLength,
172  OUT PVOID* CapturedData)
173 {
174  /* Simply allocate a message pointer in the buffer */
175  CsrAllocateMessagePointer(CaptureBuffer, MessageLength, CapturedData);
176 
177  /* Check if there was any data */
178  if (!MessageBuffer || !MessageLength) return;
179 
180  /* Copy the data into the buffer */
181  RtlMoveMemory(*CapturedData, MessageBuffer, MessageLength);
182 }
183 
184 /*
185  * @implemented
186  */
187 VOID
188 NTAPI
190 {
191  /* Free it from the heap */
192  RtlFreeHeap(CsrPortHeap, 0, CaptureBuffer);
193 }
194 
195 /*
196  * @implemented
197  */
198 VOID
199 NTAPI
202  IN ULONG StringLength,
204  OUT PSTRING CapturedString)
205 {
206  ASSERT(CapturedString != NULL);
207 
208  /*
209  * If we don't have a string, initialize an empty one,
210  * otherwise capture the given string.
211  */
212  if (!String)
213  {
214  CapturedString->Length = 0;
215  CapturedString->MaximumLength = (USHORT)MaximumLength;
216 
217  /* Allocate a pointer for it */
218  CsrAllocateMessagePointer(CaptureBuffer,
220  (PVOID*)&CapturedString->Buffer);
221  }
222  else
223  {
224  /* Cut-off the string length if needed */
225  if (StringLength > MaximumLength)
226  StringLength = MaximumLength;
227 
228  CapturedString->Length = (USHORT)StringLength;
229 
230  /* Allocate a buffer and get its size */
231  CapturedString->MaximumLength =
232  (USHORT)CsrAllocateMessagePointer(CaptureBuffer,
234  (PVOID*)&CapturedString->Buffer);
235 
236  /* If the string has data, copy it into the buffer */
237  if (StringLength)
238  RtlMoveMemory(CapturedString->Buffer, String, StringLength);
239  }
240 
241  /* Null-terminate the string if we don't take up the whole space */
242  if (CapturedString->Length < CapturedString->MaximumLength)
243  CapturedString->Buffer[CapturedString->Length] = '\0';
244 }
245 
246 static VOID
249 {
250  ASSERT(String != NULL);
251 
252  /* This is a way to capture the UNICODE string, since (Maximum)Length are also in bytes */
253  CsrCaptureMessageString(CaptureBuffer,
254  (PCSTR)String->Buffer,
255  String->Length,
256  String->MaximumLength,
257  (PSTRING)String);
258 
259  /* Null-terminate the string */
260  if (String->MaximumLength >= String->Length + sizeof(WCHAR))
261  {
262  String->Buffer[String->Length / sizeof(WCHAR)] = L'\0';
263  }
264 }
265 
266 /*
267  * @implemented
268  */
269 NTSTATUS
270 NTAPI
272  IN ULONG StringsCount,
273  IN PUNICODE_STRING* MessageStrings)
274 {
275  ULONG Count;
276 
277  if (!CaptureBuffer) return STATUS_INVALID_PARAMETER;
278 
279  /* Allocate a new capture buffer if we don't have one already */
280  if (!*CaptureBuffer)
281  {
282  /* Compute the required size for the capture buffer */
283  ULONG Size = 0;
284 
285  Count = 0;
286  while (Count < StringsCount)
287  {
288  if (MessageStrings[Count])
289  Size += MessageStrings[Count]->MaximumLength;
290 
291  ++Count;
292  }
293 
294  /* Allocate the capture buffer */
295  *CaptureBuffer = CsrAllocateCaptureBuffer(StringsCount, Size);
296  if (!*CaptureBuffer) return STATUS_NO_MEMORY;
297  }
298 
299  /* Now capture each UNICODE string */
300  Count = 0;
301  while (Count < StringsCount)
302  {
303  if (MessageStrings[Count])
304  CsrCaptureMessageUnicodeStringInPlace(*CaptureBuffer, MessageStrings[Count]);
305 
306  ++Count;
307  }
308 
309  return STATUS_SUCCESS;
310 }
311 
312 /*
313  * @implemented
314  */
316 NTAPI
319 {
320  /* Validate the time */
321  if (Milliseconds == -1) return NULL;
322 
323  /* Convert to relative ticks */
324  Timeout->QuadPart = Milliseconds * -10000LL;
325  return Timeout;
326 }
327 
328 /* EOF */
VOID NTAPI CsrFreeCaptureBuffer(IN PCSR_CAPTURE_BUFFER CaptureBuffer)
Definition: capture.c:189
#define IN
Definition: typedefs.h:38
DECLSPEC_NORETURN NTSYSAPI VOID NTAPI RtlRaiseStatus(_In_ NTSTATUS Status)
#define LL
Definition: tui.h:85
struct png_info_def **typedef void(__cdecl typeof(png_destroy_read_struct))(struct png_struct_def **
Definition: typeof.h:49
#define MAXLONG
Definition: umtypes.h:116
ULONG NTAPI CsrAllocateMessagePointer(IN OUT PCSR_CAPTURE_BUFFER CaptureBuffer, IN ULONG MessageLength, OUT PVOID *CapturedData)
Definition: capture.c:133
PCSR_CAPTURE_BUFFER NTAPI CsrAllocateCaptureBuffer(IN ULONG ArgumentCount, IN ULONG BufferSize)
Definition: capture.c:90
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
unsigned char * PUCHAR
Definition: retypes.h:3
LONG NTSTATUS
Definition: precomp.h:26
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:606
HANDLE CsrPortHeap
Definition: connect.c:23
_Inout_ __drv_aliasesMem PSLIST_ENTRY _Inout_ PSLIST_ENTRY _In_ ULONG Count
Definition: exfuncs.h:1015
PLARGE_INTEGER NTAPI CsrCaptureTimeout(IN ULONG Milliseconds, OUT PLARGE_INTEGER Timeout)
Definition: capture.c:317
static WCHAR String[]
Definition: stringtable.c:55
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:263
uint32_t ULONG_PTR
Definition: typedefs.h:63
VOID NTAPI CsrCaptureMessageBuffer(IN OUT PCSR_CAPTURE_BUFFER CaptureBuffer, IN PVOID MessageBuffer OPTIONAL, IN ULONG MessageLength, OUT PVOID *CapturedData)
Definition: capture.c:169
VOID NTAPI CsrProbeForWrite(IN PVOID Address, IN ULONG Length, IN ULONG Alignment)
Definition: capture.c:60
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
smooth NULL
Definition: ftsmooth.c:416
static WCHAR Address[46]
Definition: ping.c:68
_In_ LPGUID _In_ PVOID Data
Definition: classpnp.h:778
void * PVOID
Definition: retypes.h:9
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:588
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define BufferSize
Definition: classpnp.h:419
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
VOID NTAPI CsrCaptureMessageString(IN OUT PCSR_CAPTURE_BUFFER CaptureBuffer, IN PCSTR String OPTIONAL, IN ULONG StringLength, IN ULONG MaximumLength, OUT PSTRING CapturedString)
Definition: capture.c:200
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
unsigned char UCHAR
Definition: xmlstorage.h:181
static const WCHAR L[]
Definition: oid.c:1250
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:359
UnicodeString MaximumLength
Definition: rtlfuncs.h:2982
ULONG PointerCount
Definition: csrmsg.h:96
static ULONG Timeout
Definition: ping.c:61
unsigned short USHORT
Definition: pedump.c:61
#define STATUS_NO_MEMORY
Definition: ntstatus.h:246
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:254
static VOID CsrCaptureMessageUnicodeStringInPlace(IN OUT PCSR_CAPTURE_BUFFER CaptureBuffer, IN PUNICODE_STRING String)
Definition: capture.c:247
#define HEAP_ZERO_MEMORY
Definition: compat.h:123
#define OUT
Definition: typedefs.h:39
#define STATUS_DATATYPE_MISALIGNMENT
Definition: ntstatus.h:171
NTSTATUS NTAPI CsrCaptureMessageMultiUnicodeStringsInPlace(OUT PCSR_CAPTURE_BUFFER *CaptureBuffer, IN ULONG StringsCount, IN PUNICODE_STRING *MessageStrings)
Definition: capture.c:271
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
#define ULONG_PTR
Definition: config.h:101
VOID NTAPI CsrProbeForRead(IN PVOID Address, IN ULONG Length, IN ULONG Alignment)
Definition: capture.c:28
const char * PCSTR
Definition: typedefs.h:51
return STATUS_SUCCESS
Definition: btrfs.c:2966
ULONG_PTR PointerOffsetsArray[ANYSIZE_ARRAY]
Definition: csrmsg.h:98
PULONG MinorVersion OPTIONAL
Definition: CrossNt.h:68