ReactOS 0.4.15-dev-8131-g4988de4
NtQueryInformationProcess.c
Go to the documentation of this file.
1/*
2 * PROJECT: ReactOS API tests
3 * LICENSE: LGPLv2.1+ - See COPYING.LIB in the top level directory
4 * PURPOSE: Tests for the NtQueryInformationProcess API
5 * PROGRAMMER: Thomas Faber <thomas.faber@reactos.org>
6 * George Bișoc <george.bisoc@reactos.org>
7 */
8
9#include "precomp.h"
10#include <internal/ps_i.h>
11
13
14static
15void
17{
18#define SPIN_TIME 1000000
20 KERNEL_USER_TIMES Times1;
21 KERNEL_USER_TIMES Times2;
23 LARGE_INTEGER Time1, Time2;
24
25 /* Everything is NULL */
28 NULL,
29 0,
30 NULL);
32
33 /* Right size, invalid process */
36 NULL,
37 sizeof(KERNEL_USER_TIMES),
38 NULL);
40
41 /* Valid process, no buffer */
44 NULL,
45 0,
46 NULL);
48
49 /* Unaligned buffer, wrong size */
52 (PVOID)2,
53 0,
54 NULL);
56
57 /* Unaligned buffer, correct size */
60 (PVOID)2,
61 sizeof(KERNEL_USER_TIMES),
62 NULL);
64
65 /* Buffer too small */
68 NULL,
69 sizeof(KERNEL_USER_TIMES) - 1,
70 NULL);
72
73 /* Right buffer size but NULL pointer */
76 NULL,
77 sizeof(KERNEL_USER_TIMES),
78 NULL);
80
81 /* Buffer too large */
84 NULL,
85 sizeof(KERNEL_USER_TIMES) + 1,
86 NULL);
88
89 /* Buffer too small, ask for length */
90 Length = 0x55555555;
93 NULL,
94 sizeof(KERNEL_USER_TIMES) - 1,
95 &Length);
97 ok_dec(Length, 0x55555555);
98
99 Status = NtQuerySystemTime(&Time1);
101
102 /* Do some busy waiting to increase UserTime */
103 do
104 {
105 Status = NtQuerySystemTime(&Time2);
106 if (!NT_SUCCESS(Status))
107 {
108 ok(0, "NtQuerySystemTime failed with %lx\n", Status);
109 break;
110 }
111 } while (Time2.QuadPart - Time1.QuadPart < SPIN_TIME);
112
113 /* Valid parameters, no return length */
114 Status = NtQuerySystemTime(&Time1);
116
117 RtlFillMemory(&Times1, sizeof(Times1), 0x55);
120 &Times1,
121 sizeof(KERNEL_USER_TIMES),
122 NULL);
125 "CreateTime is %I64u, expected < %I64u\n", Times1.CreateTime.QuadPart, TestStartTime.QuadPart);
126 ok(Times1.CreateTime.QuadPart > TestStartTime.QuadPart - 100000000LL,
127 "CreateTime is %I64u, expected > %I64u\n", Times1.CreateTime.QuadPart, TestStartTime.QuadPart - 100000000LL);
128 ok(Times1.ExitTime.QuadPart == 0,
129 "ExitTime is %I64u, expected 0\n", Times1.ExitTime.QuadPart);
130 ok(Times1.KernelTime.QuadPart != 0, "KernelTime is 0\n");
132 ok(Times1.UserTime.QuadPart != 0, "UserTime is 0\n");
133
134 /* Do some busy waiting to increase UserTime */
135 do
136 {
137 Status = NtQuerySystemTime(&Time2);
138 if (!NT_SUCCESS(Status))
139 {
140 ok(0, "NtQuerySystemTime failed with %lx\n", Status);
141 break;
142 }
143 } while (Time2.QuadPart - Time1.QuadPart < SPIN_TIME);
144
145 /* Again, this time with a return length */
146 Length = 0x55555555;
147 RtlFillMemory(&Times2, sizeof(Times2), 0x55);
150 &Times2,
151 sizeof(KERNEL_USER_TIMES),
152 &Length);
155 ok(Times1.CreateTime.QuadPart == Times2.CreateTime.QuadPart,
156 "CreateTimes not equal: %I64u != %I64u\n", Times1.CreateTime.QuadPart, Times2.CreateTime.QuadPart);
157 ok(Times2.ExitTime.QuadPart == 0,
158 "ExitTime is %I64u, expected 0\n", Times2.ExitTime.QuadPart);
159 ok(Times2.KernelTime.QuadPart != 0, "KernelTime is 0\n");
160 ok(Times2.UserTime.QuadPart != 0, "UserTime is 0\n");
161
162 /* Compare the two sets of KernelTime/UserTime values */
163 Status = NtQuerySystemTime(&Time2);
165 /* Time values must have increased */
166 ok(Times2.KernelTime.QuadPart > Times1.KernelTime.QuadPart,
167 "KernelTime values inconsistent. Expected %I64u > %I64u\n", Times2.KernelTime.QuadPart, Times1.KernelTime.QuadPart);
169 ok(Times2.UserTime.QuadPart > Times1.UserTime.QuadPart,
170 "UserTime values inconsistent. Expected %I64u > %I64u\n", Times2.UserTime.QuadPart, Times1.UserTime.QuadPart);
171 /* They can't have increased by more than wall clock time difference (we only have one thread) */
173 ok(Times2.KernelTime.QuadPart - Times1.KernelTime.QuadPart < Time2.QuadPart - Time1.QuadPart,
174 "KernelTime values inconsistent. Expected %I64u - %I64u < %I64u\n",
175 Times2.KernelTime.QuadPart, Times1.KernelTime.QuadPart, Time2.QuadPart - Time1.QuadPart);
176 ok(Times2.UserTime.QuadPart - Times1.UserTime.QuadPart < Time2.QuadPart - Time1.QuadPart,
177 "UserTime values inconsistent. Expected %I64u - %I64u < %I64u\n",
178 Times2.UserTime.QuadPart, Times1.UserTime.QuadPart, Time2.QuadPart - Time1.QuadPart);
179
180 trace("KernelTime1 = %I64u\n", Times1.KernelTime.QuadPart);
181 trace("KernelTime2 = %I64u\n", Times2.KernelTime.QuadPart);
182 trace("UserTime1 = %I64u\n", Times1.UserTime.QuadPart);
183 trace("UserTime2 = %I64u\n", Times2.UserTime.QuadPart);
184
185 /* TODO: Test ExitTime on a terminated process */
186#undef SPIN_TIME
187}
188
189static
190void
192{
194 PPROCESS_PRIORITY_CLASS ProcPriority;
195
196 /* Allocate some memory for the priority class structure */
197 ProcPriority = malloc(sizeof(PROCESS_PRIORITY_CLASS));
198 if (ProcPriority == NULL)
199 {
200 skip("Failed to allocate memory for PROCESS_PRIORITY_CLASS!\n");
201 return;
202 }
203
204 /*
205 * Initialize the PriorityClass member to ensure the test won't randomly succeed (if such data is uninitialized).
206 * Filling 85 to the data member makes sure that if the test fails continously then NtQueryInformationProcess()
207 * didn't initialize the structure with data.
208 */
209 RtlFillMemory(&ProcPriority->PriorityClass, sizeof(ProcPriority->PriorityClass), 0x55);
210
211 /* Unaligned buffer -- wrong size */
214 (PVOID)1,
215 0,
216 NULL);
218
219 /* Unaligned buffer -- correct size */
222 (PVOID)1,
224 NULL);
226
227 /* Unaligned buffer -- wrong size (but this time do with an alignment of 2) */
230 (PVOID)2,
231 0,
232 NULL);
234
235 /* Unaligned buffer -- correct size (but this time do with an alignment of 2) */
238 (PVOID)2,
240 NULL);
242
243 /* Do not care for the length but expect to return the priority class */
246 ProcPriority,
248 NULL);
250
251 /* Make sure the returned priority class is a valid number (non negative) but also it should be within the PROCESS_PRIORITY_CLASS range */
253 "Expected a valid number from priority class range but got %d\n", ProcPriority->PriorityClass);
254 free(ProcPriority);
255}
256
257static
258void
260{
262 ULONG VdmPower = 1, ReturnLength;
263
264 /* Everything is NULL */
267 NULL,
268 0,
269 NULL);
271
272 /* Given an invalid process handle */
275 &VdmPower,
276 sizeof(VdmPower),
277 NULL);
279
280 /* Don't query anything */
283 NULL,
284 sizeof(VdmPower),
285 NULL);
287
288 /* The buffer is misaligned and information length is wrong */
291 (PVOID)1,
292 0,
293 NULL);
295
296 /* The buffer is misaligned */
299 (PVOID)1,
300 sizeof(VdmPower),
301 NULL);
303
304 /* The buffer is misaligned -- try with an alignment size of 2 */
307 (PVOID)2,
308 sizeof(VdmPower),
309 NULL);
311
312 /* Query the VDM power */
315 &VdmPower,
316 sizeof(VdmPower),
317 NULL);
319 ok(VdmPower == 0 || VdmPower == 1, "The VDM power value must be within the boundary between 0 and 1, not anything else! Got %lu\n", VdmPower);
320
321 /* Same but with ReturnLength */
324 &VdmPower,
325 sizeof(VdmPower),
326 &ReturnLength);
328 ok(ReturnLength != 0, "ReturnLength shouldn't be 0!\n");
329 ok(VdmPower == 0 || VdmPower == 1, "The VDM power value must be within the boundary between 0 and 1, not anything else! Got %lu\n", VdmPower);
330
331 /* Trace the VDM power value and returned length */
332 trace("ReturnLength = %lu\n", ReturnLength);
333 trace("VdmPower = %lu\n", VdmPower);
334}
335
336static
337void
339{
340 ULONG InfoClass;
341
342 /* Iterate over the process info classes and begin the tests */
343 for (InfoClass = 0; InfoClass < _countof(PsProcessInfoClass); InfoClass++)
344 {
345 /* The buffer is misaligned */
347 InfoClass,
348 (PVOID)(ULONG_PTR)1,
349 PsProcessInfoClass[InfoClass].RequiredSizeQUERY,
351
352 /* We query an invalid buffer address */
354 InfoClass,
355 (PVOID)(ULONG_PTR)PsProcessInfoClass[InfoClass].AlignmentQUERY,
356 PsProcessInfoClass[InfoClass].RequiredSizeQUERY,
358
359 /* The information length is wrong */
361 InfoClass,
362 (PVOID)(ULONG_PTR)PsProcessInfoClass[InfoClass].AlignmentQUERY,
363 PsProcessInfoClass[InfoClass].RequiredSizeQUERY - 1,
365 }
366}
367
369{
371
372 /* Make sure that some time has passed since process creation, even if the resolution of our NtQuerySystemTime is low. */
373 Sleep(1);
374
377
382}
static void Test_ProcessWx86Information(void)
static void Test_ProcQueryAlignmentProbe(void)
#define SPIN_TIME
static LARGE_INTEGER TestStartTime
static void Test_ProcessTimes(void)
static void Test_ProcessPriorityClassAlignment(void)
#define ok_hex(expression, result)
Definition: atltest.h:94
#define trace
Definition: atltest.h:70
#define ok(value,...)
Definition: atltest.h:57
#define skip(...)
Definition: atltest.h:64
#define ok_dec(expression, result)
Definition: atltest.h:101
#define START_TEST(x)
Definition: atltest.h:75
LONG NTSTATUS
Definition: precomp.h:26
#define free
Definition: debug_ros.c:5
#define malloc
Definition: debug_ros.c:4
#define NULL
Definition: types.h:112
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
IN CINT OUT PVOID IN ULONG OUT PULONG ReturnLength
Definition: dumpinfo.c:43
Status
Definition: gdiplustypes.h:25
#define PROCESS_PRIORITY_CLASS_INVALID
Definition: pstypes.h:106
#define PROCESS_PRIORITY_CLASS_ABOVE_NORMAL
Definition: pstypes.h:112
#define RtlFillMemory(Dest, Length, Fill)
Definition: winternl.h:599
@ ProcessWx86Information
Definition: winternl.h:875
@ ProcessPriorityClass
Definition: winternl.h:874
@ ProcessTimes
Definition: winternl.h:860
@ QUERY
Definition: precomp.h:18
VOID QuerySetProcessValidator(_In_ ALIGNMENT_PROBE_MODE ValidationMode, _In_ ULONG InfoClassIndex, _In_ PVOID InfoPointer, _In_ ULONG InfoLength, _In_ NTSTATUS ExpectedStatus)
Definition: probelib.c:12
#define NtCurrentProcess()
Definition: nt_native.h:1657
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
NTSTATUS NTAPI NtQuerySystemTime(OUT PLARGE_INTEGER SystemTime)
Definition: time.c:569
NTSTATUS NTAPI NtQueryInformationProcess(_In_ HANDLE ProcessHandle, _In_ PROCESSINFOCLASS ProcessInformationClass, _Out_ PVOID ProcessInformation, _In_ ULONG ProcessInformationLength, _Out_opt_ PULONG ReturnLength)
Definition: query.c:59
#define STATUS_INVALID_HANDLE
Definition: ntstatus.h:245
#define STATUS_ACCESS_VIOLATION
Definition: ntstatus.h:242
#define STATUS_DATATYPE_MISALIGNMENT
Definition: ntstatus.h:183
static const INFORMATION_CLASS_INFO PsProcessInfoClass[]
Definition: ps_i.h:15
#define ros_skip_flaky
Definition: test.h:180
#define STATUS_SUCCESS
Definition: shellext.h:65
#define _countof(array)
Definition: sndvol32.h:70
LARGE_INTEGER UserTime
Definition: winternl.h:1063
LARGE_INTEGER CreateTime
Definition: winternl.h:1060
LARGE_INTEGER KernelTime
Definition: winternl.h:1062
LARGE_INTEGER ExitTime
Definition: winternl.h:1061
VOID WINAPI DECLSPEC_HOTPATCH Sleep(IN DWORD dwMilliseconds)
Definition: synch.c:790
uint32_t ULONG_PTR
Definition: typedefs.h:65
uint32_t ULONG
Definition: typedefs.h:59
#define STATUS_INFO_LENGTH_MISMATCH
Definition: udferr_usr.h:133
LONGLONG QuadPart
Definition: typedefs.h:114