ReactOS 0.4.15-dev-7788-g1ad9096
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
11static const LARGE_INTEGER __emptyLargeInteger = {{0, 0}};
12static const ULARGE_INTEGER __emptyULargeInteger = {{0, 0}};
13static const IO_STATUS_BLOCK __emptyIoStatusBlock = {{0}, 0};
14
15#if defined(_WIN32K_) && !defined(__cplusplus)
16static 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_)
97static __inline
98VOID
99ProbeArrayForRead(IN const VOID *ArrayPtr,
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
118static __inline
119VOID
120ProbeArrayForWrite(IN OUT PVOID ArrayPtr,
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
140static __inline
143 IN KPROCESSOR_MODE CurrentMode,
144 IN const UNICODE_STRING *UnsafeSrc)
145{
148 ASSERT(Dest != NULL);
149
150 /* Probe the structure and buffer*/
151 if(CurrentMode != KernelMode)
152 {
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 {
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 if (Dest->Length % sizeof(WCHAR))
184 {
185 Dest->Length--;
186 }
187 if (Dest->Length >= UNICODE_STRING_MAX_BYTES)
188 {
189 Dest->MaximumLength = Dest->Length;
190 }
191 else
192 {
193 Dest->MaximumLength = Dest->Length + sizeof(WCHAR);
194 }
195 }
196 else
197 {
198 /* Sanitize structure */
199 Dest->MaximumLength = 0;
200 Dest->Buffer = NULL;
201 }
202 }
203 else
204 {
205 /* Sanitize structure */
206 Dest->Length = 0;
207 Dest->MaximumLength = 0;
208 }
209 }
211 {
212 /* Free allocated resources and zero the destination string */
213 if (Buffer != NULL)
214 {
215 ExFreePoolWithTag(Buffer, 'RTSU');
216 }
217 Dest->Length = 0;
218 Dest->MaximumLength = 0;
219 Dest->Buffer = NULL;
220
221 /* Return the error code */
223 }
224 _SEH2_END;
225 }
226 else
227 {
228 /* Just copy the UNICODE_STRING structure, don't allocate new memory!
229 We trust the caller to supply valid pointers and data. */
230 *Dest = *UnsafeSrc;
231 }
232
233 /* Return */
234 return Status;
235}
236
237static __inline
238VOID
240 IN KPROCESSOR_MODE CurrentMode)
241{
242 if(CurrentMode != KernelMode && CapturedString->Buffer != NULL)
243 {
244 ExFreePoolWithTag(CapturedString->Buffer, 'RTSU');
245 }
246
247 CapturedString->Length = 0;
248 CapturedString->MaximumLength = 0;
249 CapturedString->Buffer = NULL;
250}
251
252#endif /* INCLUDE_REACTOS_CAPTURE_H */
LONG NTSTATUS
Definition: precomp.h:26
Definition: bufpool.h:45
#define NULL
Definition: types.h:112
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define PagedPool
Definition: env_spec_w32.h:308
VOID NTAPI ProbeForRead(IN CONST VOID *Address, IN SIZE_T Length, IN ULONG Alignment)
Definition: exintrin.c:102
VOID NTAPI ProbeForWrite(IN PVOID Address, IN SIZE_T Length, IN ULONG Alignment)
Definition: exintrin.c:143
#define _SEH2_END
Definition: filesup.c:22
#define _SEH2_TRY
Definition: filesup.c:19
#define _SEH2_LEAVE
Definition: filesup.c:20
Status
Definition: gdiplustypes.h:25
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
#define ASSERT(a)
Definition: mode.c:44
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1109
#define KernelMode
Definition: asm.h:34
#define UNICODE_NULL
#define UNICODE_STRING_MAX_BYTES
#define ExRaiseStatus
Definition: ntoskrnl.h:114
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:159
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:34
static __inline NTSTATUS ProbeAndCaptureUnicodeString(OUT PUNICODE_STRING Dest, IN KPROCESSOR_MODE CurrentMode, IN const UNICODE_STRING *UnsafeSrc)
Definition: probe.h:142
static const ULARGE_INTEGER __emptyULargeInteger
Definition: probe.h:12
static __inline VOID ReleaseCapturedUnicodeString(IN PUNICODE_STRING CapturedString, IN KPROCESSOR_MODE CurrentMode)
Definition: probe.h:239
static const LARGE_INTEGER __emptyLargeInteger
Definition: probe.h:11
static const IO_STATUS_BLOCK __emptyIoStatusBlock
Definition: probe.h:13
#define ProbeForReadUnicodeString(Ptr)
Definition: probe.h:77
static const UNICODE_STRING __emptyUnicodeString
Definition: probe.h:10
static UCHAR ItemSize[4]
Definition: parser.c:16
#define STATUS_SUCCESS
Definition: shellext.h:65
#define _PRAGMA_WARNING_SUPPRESS(x)
Definition: suppress.h:28
#define __WARNING_PROBE_NO_TRY
Definition: suppress.h:538
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define IN
Definition: typedefs.h:39
uint16_t * PWCHAR
Definition: typedefs.h:56
uint32_t ULONG
Definition: typedefs.h:59
#define OUT
Definition: typedefs.h:40
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
CCHAR KPROCESSOR_MODE
Definition: ketypes.h:7
__wchar_t WCHAR
Definition: xmlstorage.h:180