ReactOS 0.4.16-dev-937-g7afcd2a
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 347 of file NtCreateProfile.c.

348{
352}
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 249 of file NtCreateProfile.c.

250{
251 static const struct
252 {
253 INT Line;
254 SIZE_T RangeSize;
255 ULONG BucketSize;
257 NTSTATUS ExpectedStatus;
258 NTSTATUS BrokenStatus;
259 } Tests[] =
260 {
261 /* RangeSize=(1 << BucketSize) means we'll need exactly one ULONG */
262 { __LINE__, 0x4, 2, sizeof(ULONG) - 1, STATUS_BUFFER_TOO_SMALL },
263 { __LINE__, 0x4, 2, sizeof(ULONG), STATUS_ACCESS_VIOLATION },
264 { __LINE__, 0x8, 3, sizeof(ULONG) - 1, STATUS_BUFFER_TOO_SMALL },
265 { __LINE__, 0x8, 3, sizeof(ULONG), STATUS_ACCESS_VIOLATION },
266 { __LINE__, 0x400, 10, sizeof(ULONG) - 1, STATUS_BUFFER_TOO_SMALL },
267 { __LINE__, 0x400, 10, sizeof(ULONG), STATUS_ACCESS_VIOLATION },
268 { __LINE__, 0x40000000, 30, sizeof(ULONG) - 1, STATUS_BUFFER_TOO_SMALL },
269 { __LINE__, 0x40000000, 30, sizeof(ULONG), STATUS_ACCESS_VIOLATION },
270 { __LINE__, 0x80000000, 31, sizeof(ULONG) - 1, STATUS_BUFFER_TOO_SMALL },
271 { __LINE__, 0x80000000, 31, sizeof(ULONG), STATUS_ACCESS_VIOLATION },
272
273 /* RangeSize<(1 << BucketSize) also means we'll need one ULONG.
274 * However, old Windows versions get this wrong.
275 */
276 { __LINE__, 3, 2, sizeof(ULONG) - 1, STATUS_BUFFER_TOO_SMALL, STATUS_ACCESS_VIOLATION },
277 { __LINE__, 3, 2, sizeof(ULONG), STATUS_ACCESS_VIOLATION },
278 { __LINE__, 1, 2, sizeof(ULONG) - 1, STATUS_BUFFER_TOO_SMALL, STATUS_ACCESS_VIOLATION },
279
280 /* Various sizes to show that the bug allows buffers that are a quarter of a bucket too big. */
281 { __LINE__, 8, 3, sizeof(ULONG), STATUS_ACCESS_VIOLATION },
282 { __LINE__, 9, 3, sizeof(ULONG), STATUS_BUFFER_TOO_SMALL, STATUS_ACCESS_VIOLATION },
283 { __LINE__, 10, 3, sizeof(ULONG), STATUS_BUFFER_TOO_SMALL },
284
285 { __LINE__, 16, 4, sizeof(ULONG), STATUS_ACCESS_VIOLATION },
286 { __LINE__, 17, 4, sizeof(ULONG), STATUS_BUFFER_TOO_SMALL, STATUS_ACCESS_VIOLATION },
287 { __LINE__, 18, 4, sizeof(ULONG), STATUS_BUFFER_TOO_SMALL, STATUS_ACCESS_VIOLATION },
288 { __LINE__, 19, 4, sizeof(ULONG), STATUS_BUFFER_TOO_SMALL, STATUS_ACCESS_VIOLATION },
289 { __LINE__, 20, 4, sizeof(ULONG), STATUS_BUFFER_TOO_SMALL },
290
291 { __LINE__, 32, 5, sizeof(ULONG), STATUS_ACCESS_VIOLATION },
292 { __LINE__, 33, 5, sizeof(ULONG), STATUS_BUFFER_TOO_SMALL, STATUS_ACCESS_VIOLATION },
293 { __LINE__, 39, 5, sizeof(ULONG), STATUS_BUFFER_TOO_SMALL, STATUS_ACCESS_VIOLATION },
294 { __LINE__, 40, 5, sizeof(ULONG), STATUS_BUFFER_TOO_SMALL },
295
296 { __LINE__, 256, 8, sizeof(ULONG), STATUS_ACCESS_VIOLATION },
297 { __LINE__, 257, 8, sizeof(ULONG), STATUS_BUFFER_TOO_SMALL, STATUS_ACCESS_VIOLATION },
298 { __LINE__, 319, 8, sizeof(ULONG), STATUS_BUFFER_TOO_SMALL, STATUS_ACCESS_VIOLATION },
299 { __LINE__, 320, 8, sizeof(ULONG), STATUS_BUFFER_TOO_SMALL },
300
301 { __LINE__, 256, 8, sizeof(ULONG), STATUS_ACCESS_VIOLATION },
302 { __LINE__, 257, 8, sizeof(ULONG), STATUS_BUFFER_TOO_SMALL, STATUS_ACCESS_VIOLATION },
303 { __LINE__, 319, 8, sizeof(ULONG), STATUS_BUFFER_TOO_SMALL, STATUS_ACCESS_VIOLATION },
304 { __LINE__, 320, 8, sizeof(ULONG), STATUS_BUFFER_TOO_SMALL },
305
306 { __LINE__, 0x80000000, 31, sizeof(ULONG), STATUS_ACCESS_VIOLATION },
307 { __LINE__, 0x80000001, 31, sizeof(ULONG), STATUS_BUFFER_TOO_SMALL, STATUS_ACCESS_VIOLATION },
308 { __LINE__, 0xBFFFFFFF, 31, sizeof(ULONG), STATUS_BUFFER_TOO_SMALL, STATUS_ACCESS_VIOLATION },
309 { __LINE__, 0xA0000000, 31, sizeof(ULONG), STATUS_BUFFER_TOO_SMALL },
310
311 /* Nothing checks against the max MDL size */
312 { __LINE__, 3, 2, MAX_MDL_BUFFER_SIZE, STATUS_ACCESS_VIOLATION },
313 { __LINE__, 3, 2, MAX_MDL_BUFFER_SIZE + 1, STATUS_ACCESS_VIOLATION },
314 { __LINE__, 3, 2, (MAX_MDL_BUFFER_SIZE + 1) * 2, STATUS_ACCESS_VIOLATION },
315
316 };
318 ULONG i;
319
320 for (i = 0; i < RTL_NUMBER_OF(Tests); i++)
321 {
323 NULL,
324 (PVOID)(ULONG_PTR)0x10000,
325 Tests[i].RangeSize,
326 Tests[i].BucketSize,
327 NULL,
330 1);
331 if (Tests[i].BrokenStatus)
332 {
333 ok(Status == Tests[i].ExpectedStatus ||
334 broken(Status == Tests[i].BrokenStatus),
335 "[L%d] For RangeSize 0x%Ix, BucketSize %lu, BufferSize %lu, expected 0x%lx, got 0x%lx\n",
336 Tests[i].Line, Tests[i].RangeSize, Tests[i].BucketSize, Tests[i].BufferSize, Tests[i].ExpectedStatus, Status);
337 }
338 else
339 {
340 ok(Status == Tests[i].ExpectedStatus,
341 "[L%d] For RangeSize 0x%Ix, BucketSize %lu, BufferSize %lu, expected 0x%lx, got 0x%lx\n",
342 Tests[i].Line, Tests[i].RangeSize, Tests[i].BucketSize, Tests[i].BufferSize, Tests[i].ExpectedStatus, Status);
343 }
344 }
345}
#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);
180
182 NULL,
183 (PVOID)(ULONG_PTR)0x10000,
184 SIZE_MAX,
185 31,
186 NULL,
187 0x80000000,
189 1);
191 }
192
193 /* Handle is probed first and requires no alignment, buffer requires ULONG alignment */
194 {
195 ULONG Buffer[1];
196
198 (HANDLE)(ULONG_PTR)1,
199 (PVOID)(ULONG_PTR)0x10002,
200 0x1000,
201 31,
202 (PVOID)(ULONG_PTR)2,
203 sizeof(ULONG),
205 1);
207
208 Status = NtCreateProfile(&ProfileHandle,
209 (HANDLE)(ULONG_PTR)1,
210 (PVOID)(ULONG_PTR)0x10000,
211 0x1000,
212 31,
213 (PVOID)(ULONG_PTR)2,
214 sizeof(ULONG),
216 1);
218
219 Status = NtCreateProfile(&ProfileHandle,
220 (HANDLE)(ULONG_PTR)1,
221 (PVOID)(ULONG_PTR)0x10000,
222 0x1000,
223 31,
224 (PVOID)(ULONG_PTR)4,
225 sizeof(ULONG),
227 1);
229
230 Status = NtCreateProfile(&ProfileHandle,
231 (HANDLE)(ULONG_PTR)1,
232 (PVOID)(ULONG_PTR)0x10000,
233 0x1000,
234 31,
235 Buffer,
236 sizeof(ULONG),
238 1);
240 }
241}
#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