ReactOS 0.4.16-dev-1078-g21d3e29
NtCreateProfile.c File Reference
#include "precomp.h"
Include dependency graph for NtCreateProfile.c:

Go to the source code of this file.

Macros

#define SIZEOF_MDL   (5 * sizeof(PVOID) + 2 * sizeof(ULONG))
 
#define MAX_MDL_BUFFER_SIZE   ((MAXUSHORT - SIZEOF_MDL) / sizeof(PFN_NUMBER) * PAGE_SIZE + PAGE_SIZE - 1)
 
#define broken(cond)   (strcmp(winetest_platform, "windows") ? 0 : cond)
 

Typedefs

typedef ULONG_PTR PFN_NUMBER
 

Functions

static void TestParameterValidation (void)
 
static void TestBufferSizeValidation (void)
 
 START_TEST (NtCreateProfile)
 

Variables

static BOOL IsWow64
 

Macro Definition Documentation

◆ broken

#define broken (   cond)    (strcmp(winetest_platform, "windows") ? 0 : cond)

Definition at line 15 of file NtCreateProfile.c.

◆ MAX_MDL_BUFFER_SIZE

#define MAX_MDL_BUFFER_SIZE   ((MAXUSHORT - SIZEOF_MDL) / sizeof(PFN_NUMBER) * PAGE_SIZE + PAGE_SIZE - 1)

Definition at line 13 of file NtCreateProfile.c.

◆ SIZEOF_MDL

#define SIZEOF_MDL   (5 * sizeof(PVOID) + 2 * sizeof(ULONG))

Definition at line 10 of file NtCreateProfile.c.

Typedef Documentation

◆ PFN_NUMBER

Definition at line 11 of file NtCreateProfile.c.

Function Documentation

◆ START_TEST()

START_TEST ( NtCreateProfile  )

Definition at line 351 of file NtCreateProfile.c.

352{
356}
static void TestParameterValidation(void)
static BOOL IsWow64
static void TestBufferSizeValidation(void)
#define GetCurrentProcess()
Definition: compat.h:759
#define IsWow64Process
Definition: compat.h:760

◆ TestBufferSizeValidation()

static void TestBufferSizeValidation ( void  )
static

Definition at line 253 of file NtCreateProfile.c.

254{
255 static const struct
256 {
257 INT Line;
258 SIZE_T RangeSize;
259 ULONG BucketSize;
261 NTSTATUS ExpectedStatus;
262 NTSTATUS BrokenStatus;
263 } Tests[] =
264 {
265 /* RangeSize=(1 << BucketSize) means we'll need exactly one ULONG */
266 { __LINE__, 0x4, 2, sizeof(ULONG) - 1, STATUS_BUFFER_TOO_SMALL },
267 { __LINE__, 0x4, 2, sizeof(ULONG), STATUS_ACCESS_VIOLATION },
268 { __LINE__, 0x8, 3, sizeof(ULONG) - 1, STATUS_BUFFER_TOO_SMALL },
269 { __LINE__, 0x8, 3, sizeof(ULONG), STATUS_ACCESS_VIOLATION },
270 { __LINE__, 0x400, 10, sizeof(ULONG) - 1, STATUS_BUFFER_TOO_SMALL },
271 { __LINE__, 0x400, 10, sizeof(ULONG), STATUS_ACCESS_VIOLATION },
272 { __LINE__, 0x40000000, 30, sizeof(ULONG) - 1, STATUS_BUFFER_TOO_SMALL },
273 { __LINE__, 0x40000000, 30, sizeof(ULONG), STATUS_ACCESS_VIOLATION },
274 { __LINE__, 0x80000000, 31, sizeof(ULONG) - 1, STATUS_BUFFER_TOO_SMALL },
275 { __LINE__, 0x80000000, 31, sizeof(ULONG), STATUS_ACCESS_VIOLATION },
276
277 /* RangeSize<(1 << BucketSize) also means we'll need one ULONG.
278 * However, old Windows versions get this wrong.
279 */
280 { __LINE__, 3, 2, sizeof(ULONG) - 1, STATUS_BUFFER_TOO_SMALL, STATUS_ACCESS_VIOLATION },
281 { __LINE__, 3, 2, sizeof(ULONG), STATUS_ACCESS_VIOLATION },
282 { __LINE__, 1, 2, sizeof(ULONG) - 1, STATUS_BUFFER_TOO_SMALL, STATUS_ACCESS_VIOLATION },
283
284 /* Various sizes to show that the bug allows buffers that are a quarter of a bucket too big. */
285 { __LINE__, 8, 3, sizeof(ULONG), STATUS_ACCESS_VIOLATION },
286 { __LINE__, 9, 3, sizeof(ULONG), STATUS_BUFFER_TOO_SMALL, STATUS_ACCESS_VIOLATION },
287 { __LINE__, 10, 3, sizeof(ULONG), STATUS_BUFFER_TOO_SMALL },
288
289 { __LINE__, 16, 4, sizeof(ULONG), STATUS_ACCESS_VIOLATION },
290 { __LINE__, 17, 4, sizeof(ULONG), STATUS_BUFFER_TOO_SMALL, STATUS_ACCESS_VIOLATION },
291 { __LINE__, 18, 4, sizeof(ULONG), STATUS_BUFFER_TOO_SMALL, STATUS_ACCESS_VIOLATION },
292 { __LINE__, 19, 4, sizeof(ULONG), STATUS_BUFFER_TOO_SMALL, STATUS_ACCESS_VIOLATION },
293 { __LINE__, 20, 4, sizeof(ULONG), STATUS_BUFFER_TOO_SMALL },
294
295 { __LINE__, 32, 5, sizeof(ULONG), STATUS_ACCESS_VIOLATION },
296 { __LINE__, 33, 5, sizeof(ULONG), STATUS_BUFFER_TOO_SMALL, STATUS_ACCESS_VIOLATION },
297 { __LINE__, 39, 5, sizeof(ULONG), STATUS_BUFFER_TOO_SMALL, STATUS_ACCESS_VIOLATION },
298 { __LINE__, 40, 5, sizeof(ULONG), STATUS_BUFFER_TOO_SMALL },
299
300 { __LINE__, 256, 8, sizeof(ULONG), STATUS_ACCESS_VIOLATION },
301 { __LINE__, 257, 8, sizeof(ULONG), STATUS_BUFFER_TOO_SMALL, STATUS_ACCESS_VIOLATION },
302 { __LINE__, 319, 8, sizeof(ULONG), STATUS_BUFFER_TOO_SMALL, STATUS_ACCESS_VIOLATION },
303 { __LINE__, 320, 8, sizeof(ULONG), STATUS_BUFFER_TOO_SMALL },
304
305 { __LINE__, 256, 8, sizeof(ULONG), STATUS_ACCESS_VIOLATION },
306 { __LINE__, 257, 8, sizeof(ULONG), STATUS_BUFFER_TOO_SMALL, STATUS_ACCESS_VIOLATION },
307 { __LINE__, 319, 8, sizeof(ULONG), STATUS_BUFFER_TOO_SMALL, STATUS_ACCESS_VIOLATION },
308 { __LINE__, 320, 8, sizeof(ULONG), STATUS_BUFFER_TOO_SMALL },
309
310 { __LINE__, 0x80000000, 31, sizeof(ULONG), STATUS_ACCESS_VIOLATION },
311 { __LINE__, 0x80000001, 31, sizeof(ULONG), STATUS_BUFFER_TOO_SMALL, STATUS_ACCESS_VIOLATION },
312 { __LINE__, 0xBFFFFFFF, 31, sizeof(ULONG), STATUS_BUFFER_TOO_SMALL, STATUS_ACCESS_VIOLATION },
313 { __LINE__, 0xA0000000, 31, sizeof(ULONG), STATUS_BUFFER_TOO_SMALL },
314
315 /* Nothing checks against the max MDL size */
316 { __LINE__, 3, 2, MAX_MDL_BUFFER_SIZE, STATUS_ACCESS_VIOLATION },
317 { __LINE__, 3, 2, MAX_MDL_BUFFER_SIZE + 1, STATUS_ACCESS_VIOLATION },
318 { __LINE__, 3, 2, (MAX_MDL_BUFFER_SIZE + 1) * 2, STATUS_ACCESS_VIOLATION },
319
320 };
322 ULONG i;
323
324 for (i = 0; i < RTL_NUMBER_OF(Tests); i++)
325 {
327 NULL,
328 (PVOID)(ULONG_PTR)0x10000,
329 Tests[i].RangeSize,
330 Tests[i].BucketSize,
331 NULL,
334 1);
335 if (Tests[i].BrokenStatus)
336 {
337 ok(Status == Tests[i].ExpectedStatus ||
338 broken(Status == Tests[i].BrokenStatus),
339 "[L%d] For RangeSize 0x%Ix, BucketSize %lu, BufferSize %lu, expected 0x%lx, got 0x%lx\n",
340 Tests[i].Line, Tests[i].RangeSize, Tests[i].BucketSize, Tests[i].BufferSize, Tests[i].ExpectedStatus, Status);
341 }
342 else
343 {
344 ok(Status == Tests[i].ExpectedStatus,
345 "[L%d] For RangeSize 0x%Ix, BucketSize %lu, BufferSize %lu, expected 0x%lx, got 0x%lx\n",
346 Tests[i].Line, Tests[i].RangeSize, Tests[i].BucketSize, Tests[i].BufferSize, Tests[i].ExpectedStatus, Status);
347 }
348 }
349}
#define MAX_MDL_BUFFER_SIZE
#define broken(cond)
struct test_data Tests[]
#define RTL_NUMBER_OF(x)
Definition: RtlRegistry.c:12
#define ok(value,...)
Definition: atltest.h:57
LONG NTSTATUS
Definition: precomp.h:26
#define BufferSize
Definition: mmc.h:75
#define NULL
Definition: types.h:112
Status
Definition: gdiplustypes.h:25
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
@ ProfileTime
Definition: winternl.h:2123
NTSTATUS NTAPI NtCreateProfile(OUT PHANDLE ProfileHandle, IN HANDLE Process OPTIONAL, IN PVOID RangeBase, IN SIZE_T RangeSize, IN ULONG BucketSize, IN PVOID Buffer, IN ULONG BufferSize, IN KPROFILE_SOURCE ProfileSource, IN KAFFINITY Affinity)
Definition: profile.c:89
#define STATUS_ACCESS_VIOLATION
Definition: ntstatus.h:242
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
Definition: ncftp.h:79
ULONG_PTR SIZE_T
Definition: typedefs.h:80
int32_t INT
Definition: typedefs.h:58
uint32_t ULONG_PTR
Definition: typedefs.h:65
uint32_t ULONG
Definition: typedefs.h:59
_In_ WDFMEMORY _Out_opt_ size_t * BufferSize
Definition: wdfmemory.h:254

Referenced by START_TEST().

◆ TestParameterValidation()

static void TestParameterValidation ( void  )
static

Definition at line 21 of file NtCreateProfile.c.

22{
24 HANDLE ProfileHandle;
25
27 NULL,
28 NULL,
29 0,
30 0,
31 NULL,
32 0,
34 1);
36
37 /* For addresses below 0x10000, there's a special check for BufferSize<4 -- on x86 only */
38 {
40 NULL,
41 (PVOID)(ULONG_PTR)0xFFFF,
42 0,
43 0,
44 NULL,
45 3,
47 1);
48 if (sizeof(PVOID) > sizeof(ULONG) || IsWow64)
49 {
51 }
52 else
53 {
55 }
56
57 /* Increasing the pointer gets us past this */
59 NULL,
60 (PVOID)(ULONG_PTR)0x10000,
61 0,
62 0,
63 NULL,
64 3,
66 1);
68
69 /* So does increasing the size */
71 NULL,
72 (PVOID)(ULONG_PTR)0xFFFF,
73 0,
74 0,
75 NULL,
76 4,
78 1);
80
81 /* ... or, specifying a bucket size */
83 NULL,
84 (PVOID)(ULONG_PTR)0xFFFF,
85 0,
86 1,
87 NULL,
88 4,
90 1);
92 }
93
94 /* Bucket sizes less than two or larger than 31 are invalid */
95 {
97 NULL,
98 (PVOID)(ULONG_PTR)0x10000,
99 0x80000000,
100 1,
101 NULL,
102 1,
104 1);
106
108 NULL,
109 (PVOID)(ULONG_PTR)0x10000,
110 0x80000000,
111 32,
112 NULL,
113 1,
115 1);
117
118 /* But 2 and 31 are valid */
120 NULL,
121 (PVOID)(ULONG_PTR)0x10000,
122 0x80000000,
123 2,
124 NULL,
125 1,
127 1);
129
131 NULL,
132 (PVOID)(ULONG_PTR)0x10000,
133 0x80000000,
134 31,
135 NULL,
136 1,
138 1);
140 }
141
142 /* RangeSize validation has its own function */
143
144 /* RangeBase+RangeSize can overflow into kernel space, but can't wrap around.
145 * Note that a Wow64 test will never achieve overflow.
146 */
147 {
149 NULL,
150 (PVOID)(ULONG_PTR)0x10000,
151 SIZE_MAX / 2,
152 31,
153 NULL,
154 0x80000000,
156 1);
158
160 NULL,
161 (PVOID)(ULONG_PTR)0x10000,
162 SIZE_MAX - 0x10000,
163 31,
164 NULL,
165 0x80000000,
167 1);
169
171 NULL,
172 (PVOID)(ULONG_PTR)0x10000,
173 SIZE_MAX - 0x10000 + 1,
174 31,
175 NULL,
176 0x80000000,
178 1);
179 ok_hex(Status, (sizeof(PVOID) == 8) ? STATUS_BUFFER_TOO_SMALL :
182
184 NULL,
185 (PVOID)(ULONG_PTR)0x10000,
186 SIZE_MAX,
187 31,
188 NULL,
189 0x80000000,
191 1);
192 ok_hex(Status, (sizeof(PVOID) == 8) ? STATUS_BUFFER_TOO_SMALL :
195 }
196
197 /* Handle is probed first and requires no alignment, buffer requires ULONG alignment */
198 {
199 ULONG Buffer[1];
200
202 (HANDLE)(ULONG_PTR)1,
203 (PVOID)(ULONG_PTR)0x10002,
204 0x1000,
205 31,
206 (PVOID)(ULONG_PTR)2,
207 sizeof(ULONG),
209 1);
211
212 Status = NtCreateProfile(&ProfileHandle,
213 (HANDLE)(ULONG_PTR)1,
214 (PVOID)(ULONG_PTR)0x10000,
215 0x1000,
216 31,
217 (PVOID)(ULONG_PTR)2,
218 sizeof(ULONG),
220 1);
222
223 Status = NtCreateProfile(&ProfileHandle,
224 (HANDLE)(ULONG_PTR)1,
225 (PVOID)(ULONG_PTR)0x10000,
226 0x1000,
227 31,
228 (PVOID)(ULONG_PTR)4,
229 sizeof(ULONG),
231 1);
233
234 Status = NtCreateProfile(&ProfileHandle,
235 (HANDLE)(ULONG_PTR)1,
236 (PVOID)(ULONG_PTR)0x10000,
237 0x1000,
238 31,
239 Buffer,
240 sizeof(ULONG),
242 1);
244 }
245}
#define ok_hex(expression, result)
Definition: atltest.h:94
Definition: bufpool.h:45
#define STATUS_INVALID_HANDLE
Definition: d3dkmdt.h:40
PVOID *typedef PHANDLE
Definition: ntsecpkg.h:455
#define STATUS_INVALID_PARAMETER_7
Definition: ntstatus.h:481
#define STATUS_DATATYPE_MISALIGNMENT
Definition: ntstatus.h:183
#define SIZE_MAX
Definition: compat.h:66
#define STATUS_BUFFER_OVERFLOW
Definition: shellext.h:66
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135

Referenced by START_TEST().

Variable Documentation

◆ IsWow64

BOOL IsWow64
static