ReactOS  0.4.14-dev-98-gb0d4763
probe.h
Go to the documentation of this file.
1 #ifndef INCLUDE_REACTOS_CAPTURE_H
2 #define INCLUDE_REACTOS_CAPTURE_H
3 
4 #include <suppress.h>
5 
6 #if ! defined(_NTOSKRNL_) && ! defined(_WIN32K_)
7 #error Header intended for use by NTOSKRNL/WIN32K only!
8 #endif
9 
10 static const UNICODE_STRING __emptyUnicodeString = {0, 0, NULL};
11 static const LARGE_INTEGER __emptyLargeInteger = {{0, 0}};
12 static const ULARGE_INTEGER __emptyULargeInteger = {{0, 0}};
13 static const IO_STATUS_BLOCK __emptyIoStatusBlock = {{0}, 0};
14 
15 #if defined(_WIN32K_) && !defined(__cplusplus)
16 static const LARGE_STRING __emptyLargeString = {0, 0, 0, NULL};
17 #endif
18 
19 /*
20  * NOTE: Alignment of the pointers is not verified!
21  */
22 #define ProbeForWriteGenericType(Ptr, Type) \
23  do { \
24  if ((ULONG_PTR)(Ptr) + sizeof(Type) - 1 < (ULONG_PTR)(Ptr) || \
25  (ULONG_PTR)(Ptr) + sizeof(Type) - 1 >= (ULONG_PTR)MmUserProbeAddress) { \
26  ExRaiseAccessViolation(); \
27  } \
28  *(volatile Type *)(Ptr) = *(volatile Type *)(Ptr); \
29  } while (0)
30 
31 #define ProbeForWriteBoolean(Ptr) ProbeForWriteGenericType(Ptr, BOOLEAN)
32 #define ProbeForWriteUchar(Ptr) ProbeForWriteGenericType(Ptr, UCHAR)
33 #define ProbeForWriteChar(Ptr) ProbeForWriteGenericType(Ptr, CHAR)
34 #define ProbeForWriteUshort(Ptr) ProbeForWriteGenericType(Ptr, USHORT)
35 #define ProbeForWriteShort(Ptr) ProbeForWriteGenericType(Ptr, SHORT)
36 #define ProbeForWriteUlong(Ptr) ProbeForWriteGenericType(Ptr, ULONG)
37 #define ProbeForWriteLong(Ptr) ProbeForWriteGenericType(Ptr, LONG)
38 #define ProbeForWriteUint(Ptr) ProbeForWriteGenericType(Ptr, UINT)
39 #define ProbeForWriteInt(Ptr) ProbeForWriteGenericType(Ptr, INT)
40 #define ProbeForWriteUlonglong(Ptr) ProbeForWriteGenericType(Ptr, ULONGLONG)
41 #define ProbeForWriteLonglong(Ptr) ProbeForWriteGenericType(Ptr, LONGLONG)
42 #define ProbeForWritePointer(Ptr) ProbeForWriteGenericType(Ptr, PVOID)
43 #define ProbeForWriteHandle(Ptr) ProbeForWriteGenericType(Ptr, HANDLE)
44 #define ProbeForWriteLangid(Ptr) ProbeForWriteGenericType(Ptr, LANGID)
45 #define ProbeForWriteSize_t(Ptr) ProbeForWriteGenericType(Ptr, SIZE_T)
46 #define ProbeForWriteLargeInteger(Ptr) ProbeForWriteGenericType(&((PLARGE_INTEGER)Ptr)->QuadPart, LONGLONG)
47 #define ProbeForWriteUlargeInteger(Ptr) ProbeForWriteGenericType(&((PULARGE_INTEGER)Ptr)->QuadPart, ULONGLONG)
48 #define ProbeForWriteUnicodeString(Ptr) ProbeForWriteGenericType((PUNICODE_STRING)Ptr, UNICODE_STRING)
49 #if defined(_WIN32K_)
50 #define ProbeForWriteLargeString(Ptr) ProbeForWriteGenericType((PLARGE_STRING)Ptr, LARGE_STRING)
51 #endif
52 #define ProbeForWriteIoStatusBlock(Ptr) ProbeForWriteGenericType((PIO_STATUS_BLOCK)Ptr, IO_STATUS_BLOCK)
53 
54 #define ProbeForReadGenericType(Ptr, Type, Default) \
55  (((ULONG_PTR)(Ptr) + sizeof(Type) - 1 < (ULONG_PTR)(Ptr) || \
56  (ULONG_PTR)(Ptr) + sizeof(Type) - 1 >= (ULONG_PTR)MmUserProbeAddress) ? \
57  ExRaiseAccessViolation(), Default : \
58  *(const volatile Type *)(Ptr))
59 
60 #define ProbeForReadBoolean(Ptr) ProbeForReadGenericType(Ptr, BOOLEAN, FALSE)
61 #define ProbeForReadUchar(Ptr) ProbeForReadGenericType(Ptr, UCHAR, 0)
62 #define ProbeForReadChar(Ptr) ProbeForReadGenericType(Ptr, CHAR, 0)
63 #define ProbeForReadUshort(Ptr) ProbeForReadGenericType(Ptr, USHORT, 0)
64 #define ProbeForReadShort(Ptr) ProbeForReadGenericType(Ptr, SHORT, 0)
65 #define ProbeForReadUlong(Ptr) ProbeForReadGenericType(Ptr, ULONG, 0)
66 #define ProbeForReadLong(Ptr) ProbeForReadGenericType(Ptr, LONG, 0)
67 #define ProbeForReadUint(Ptr) ProbeForReadGenericType(Ptr, UINT, 0)
68 #define ProbeForReadInt(Ptr) ProbeForReadGenericType(Ptr, INT, 0)
69 #define ProbeForReadUlonglong(Ptr) ProbeForReadGenericType(Ptr, ULONGLONG, 0)
70 #define ProbeForReadLonglong(Ptr) ProbeForReadGenericType(Ptr, LONGLONG, 0)
71 #define ProbeForReadPointer(Ptr) ProbeForReadGenericType(Ptr, PVOID, NULL)
72 #define ProbeForReadHandle(Ptr) ProbeForReadGenericType(Ptr, HANDLE, NULL)
73 #define ProbeForReadLangid(Ptr) ProbeForReadGenericType(Ptr, LANGID, 0)
74 #define ProbeForReadSize_t(Ptr) ProbeForReadGenericType(Ptr, SIZE_T, 0)
75 #define ProbeForReadLargeInteger(Ptr) ProbeForReadGenericType((const LARGE_INTEGER *)(Ptr), LARGE_INTEGER, __emptyLargeInteger)
76 #define ProbeForReadUlargeInteger(Ptr) ProbeForReadGenericType((const ULARGE_INTEGER *)(Ptr), ULARGE_INTEGER, __emptyULargeInteger)
77 #define ProbeForReadUnicodeString(Ptr) ProbeForReadGenericType((const UNICODE_STRING *)(Ptr), UNICODE_STRING, __emptyUnicodeString)
78 #if defined(_WIN32K_)
79 #define ProbeForReadLargeString(Ptr) ProbeForReadGenericType((const LARGE_STRING *)(Ptr), LARGE_STRING, __emptyLargeString)
80 #endif
81 #define ProbeForReadIoStatusBlock(Ptr) ProbeForReadGenericType((const IO_STATUS_BLOCK *)(Ptr), IO_STATUS_BLOCK, __emptyIoStatusBlock)
82 
83 #define ProbeAndZeroHandle(Ptr) \
84  do { \
85  if ((ULONG_PTR)(Ptr) + sizeof(HANDLE) - 1 < (ULONG_PTR)(Ptr) || \
86  (ULONG_PTR)(Ptr) + sizeof(HANDLE) - 1 >= (ULONG_PTR)MmUserProbeAddress) { \
87  ExRaiseAccessViolation(); \
88  } \
89  *(volatile HANDLE *)(Ptr) = NULL; \
90  } while (0)
91 
92 /*
93  * Inlined Probing Macros
94  */
95 
96 #if defined(_WIN32K_)
97 static __inline
98 VOID
99 ProbeArrayForRead(IN const VOID *ArrayPtr,
100  IN ULONG ItemSize,
101  IN ULONG ItemCount,
103 {
104  ULONG ArraySize;
105 
106  /* Check for integer overflow */
107  ArraySize = ItemSize * ItemCount;
108  if (ArraySize / ItemSize != ItemCount)
109  {
111  }
112 
113  /* Probe the array */
114  _PRAGMA_WARNING_SUPPRESS(__WARNING_PROBE_NO_TRY) /* Must be inside __try / __except block */
115  ProbeForRead(ArrayPtr, ArraySize, Alignment);
116 }
117 
118 static __inline
119 VOID
120 ProbeArrayForWrite(IN OUT PVOID ArrayPtr,
121  IN ULONG ItemSize,
122  IN ULONG ItemCount,
124 {
125  ULONG ArraySize;
126 
127  /* Check for integer overflow */
128  ArraySize = ItemSize * ItemCount;
129  if (ArraySize / ItemSize != ItemCount)
130  {
132  }
133 
134  /* Probe the array */
135  _PRAGMA_WARNING_SUPPRESS(__WARNING_PROBE_NO_TRY) /* Must be inside __try / __except block */
136  ProbeForWrite(ArrayPtr, ArraySize, Alignment);
137 }
138 #endif /* _WIN32K_ */
139 
140 static __inline
141 NTSTATUS
143  IN KPROCESSOR_MODE CurrentMode,
144  IN const UNICODE_STRING *UnsafeSrc)
145 {
147  PWCHAR Buffer = NULL;
148  ASSERT(Dest != NULL);
149 
150  /* Probe the structure and buffer*/
151  if(CurrentMode != KernelMode)
152  {
153  _SEH2_TRY
154  {
155 #ifdef __cplusplus
156  ProbeForRead(UnsafeSrc, sizeof(*UnsafeSrc), 1);
157  RtlCopyMemory(Dest, UnsafeSrc, sizeof(*UnsafeSrc));
158 #else
159  *Dest = ProbeForReadUnicodeString(UnsafeSrc);
160 #endif
161  if(Dest->Buffer != NULL)
162  {
163  if (Dest->Length != 0)
164  {
165  ProbeForRead(Dest->Buffer, Dest->Length, sizeof(WCHAR));
166 
167  /* Allocate space for the buffer */
169  Dest->Length + sizeof(WCHAR),
170  'RTSU');
171  if (Buffer == NULL)
172  {
174  _SEH2_LEAVE;
175  }
176 
177  /* Copy it */
178  RtlCopyMemory(Buffer, Dest->Buffer, Dest->Length);
179  Buffer[Dest->Length / sizeof(WCHAR)] = UNICODE_NULL;
180 
181  /* Set it as the buffer */
182  Dest->Buffer = Buffer;
183  Dest->MaximumLength = Dest->Length + sizeof(WCHAR);
184  }
185  else
186  {
187  /* Sanitize structure */
188  Dest->MaximumLength = 0;
189  Dest->Buffer = NULL;
190  }
191  }
192  else
193  {
194  /* Sanitize structure */
195  Dest->Length = 0;
196  Dest->MaximumLength = 0;
197  }
198  }
200  {
201  /* Free allocated resources and zero the destination string */
202  if (Buffer != NULL)
203  {
204  ExFreePoolWithTag(Buffer, 'RTSU');
205  }
206  Dest->Length = 0;
207  Dest->MaximumLength = 0;
208  Dest->Buffer = NULL;
209 
210  /* Return the error code */
212  }
213  _SEH2_END;
214  }
215  else
216  {
217  /* Just copy the UNICODE_STRING structure, don't allocate new memory!
218  We trust the caller to supply valid pointers and data. */
219  *Dest = *UnsafeSrc;
220  }
221 
222  /* Return */
223  return Status;
224 }
225 
226 static __inline
227 VOID
229  IN KPROCESSOR_MODE CurrentMode)
230 {
231  if(CurrentMode != KernelMode && CapturedString->Buffer != NULL)
232  {
233  ExFreePoolWithTag(CapturedString->Buffer, 'RTSU');
234  }
235 
236  CapturedString->Length = 0;
237  CapturedString->MaximumLength = 0;
238  CapturedString->Buffer = NULL;
239 }
240 
241 #endif /* INCLUDE_REACTOS_CAPTURE_H */
static __inline NTSTATUS ProbeAndCaptureUnicodeString(OUT PUNICODE_STRING Dest, IN KPROCESSOR_MODE CurrentMode, IN const UNICODE_STRING *UnsafeSrc)
Definition: probe.h:142
#define IN
Definition: typedefs.h:38
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
LONG NTSTATUS
Definition: precomp.h:26
static const IO_STATUS_BLOCK __emptyIoStatusBlock
Definition: probe.h:13
#define ExRaiseStatus
Definition: ntoskrnl.h:95
uint16_t * PWCHAR
Definition: typedefs.h:54
VOID NTAPI ProbeForWrite(IN PVOID Address, IN SIZE_T Length, IN ULONG Alignment)
Definition: exintrin.c:143
_SEH2_TRY
Definition: create.c:4250
#define UNICODE_NULL
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
smooth NULL
Definition: ftsmooth.c:416
static const UNICODE_STRING __emptyUnicodeString
Definition: probe.h:10
Definition: bufpool.h:45
static __inline VOID ReleaseCapturedUnicodeString(IN PUNICODE_STRING CapturedString, IN KPROCESSOR_MODE CurrentMode)
Definition: probe.h:228
__wchar_t WCHAR
Definition: xmlstorage.h:180
static const LARGE_INTEGER __emptyLargeInteger
Definition: probe.h:11
CCHAR KPROCESSOR_MODE
Definition: ketypes.h:7
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
VOID NTAPI ProbeForRead(IN CONST VOID *Address, IN SIZE_T Length, IN ULONG Alignment)
Definition: exintrin.c:102
static const ULARGE_INTEGER __emptyULargeInteger
Definition: probe.h:12
static UCHAR ItemSize[4]
Definition: parser.c:16
Status
Definition: gdiplustypes.h:24
_SEH2_END
Definition: create.c:4424
#define ProbeForReadUnicodeString(Ptr)
Definition: probe.h:77
#define __WARNING_PROBE_NO_TRY
Definition: suppress.h:538
#define OUT
Definition: typedefs.h:39
unsigned int ULONG
Definition: retypes.h:1
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:6
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:12
#define _SEH2_LEAVE
Definition: filesup.c:20
IN BOOLEAN OUT PSTR Buffer
Definition: progress.h:34
return STATUS_SUCCESS
Definition: btrfs.c:2966
#define _PRAGMA_WARNING_SUPPRESS(x)
Definition: suppress.h:28