ReactOS  0.4.15-dev-3203-gacde1e0
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 
14 static
15 void
17 {
18 #define SPIN_TIME 1000000
20  KERNEL_USER_TIMES Times1;
21  KERNEL_USER_TIMES Times2;
22  ULONG Length;
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);
119  ProcessTimes,
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);
149  ProcessTimes,
150  &Times2,
151  sizeof(KERNEL_USER_TIMES),
152  &Length);
154  ok_dec(Length, sizeof(KERNEL_USER_TIMES));
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 
189 static
190 void
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,
223  sizeof(PROCESS_PRIORITY_CLASS),
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,
239  sizeof(PROCESS_PRIORITY_CLASS),
240  NULL);
242 
243  /* Do not care for the length but expect to return the priority class */
246  ProcPriority,
247  sizeof(PROCESS_PRIORITY_CLASS),
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 
257 static
258 void
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  &ReturnLength);
319  ok(ReturnLength != 0, "ReturnLength shouldn't be 0!\n");
320  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);
321 
322  /* Trace the VDM power value and returned length */
323  trace("ReturnLength = %lu\n", ReturnLength);
324  trace("VdmPower = %lu\n", VdmPower);
325 }
326 
327 static
328 void
330 {
331  ULONG InfoClass;
332 
333  /* Iterate over the process info classes and begin the tests */
334  for (InfoClass = 0; InfoClass < _countof(PsProcessInfoClass); InfoClass++)
335  {
336  /* The buffer is misaligned */
338  InfoClass,
339  (PVOID)(ULONG_PTR)1,
340  PsProcessInfoClass[InfoClass].RequiredSizeQUERY,
342 
343  /* We query an invalid buffer address */
345  InfoClass,
346  (PVOID)(ULONG_PTR)PsProcessInfoClass[InfoClass].AlignmentQUERY,
347  PsProcessInfoClass[InfoClass].RequiredSizeQUERY,
349 
350  /* The information length is wrong */
352  InfoClass,
353  (PVOID)(ULONG_PTR)PsProcessInfoClass[InfoClass].AlignmentQUERY,
354  PsProcessInfoClass[InfoClass].RequiredSizeQUERY - 1,
356  }
357 }
358 
360 {
362 
363  /* Make sure that some time has passed since process creation, even if the resolution of our NtQuerySystemTime is low. */
364  Sleep(1);
365 
368 
373 }
IN CINT OUT PVOID IN ULONG OUT PULONG ReturnLength
Definition: dumpinfo.c:39
VOID WINAPI DECLSPEC_HOTPATCH Sleep(IN DWORD dwMilliseconds)
Definition: synch.c:790
#define LL
Definition: tui.h:84
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
#define STATUS_INFO_LENGTH_MISMATCH
Definition: udferr_usr.h:133
#define PROCESS_PRIORITY_CLASS_INVALID
Definition: pstypes.h:106
START_TEST(NtQueryInformationProcess)
#define free
Definition: debug_ros.c:5
LONG NTSTATUS
Definition: precomp.h:26
LARGE_INTEGER UserTime
Definition: winternl.h:1063
#define ok_hex(expression, result)
Definition: atltest.h:94
#define STATUS_INVALID_HANDLE
Definition: ntstatus.h:245
uint32_t ULONG_PTR
Definition: typedefs.h:65
LARGE_INTEGER ExitTime
Definition: winternl.h:1061
static void Test_ProcessWx86Information(void)
#define NtCurrentProcess()
Definition: nt_native.h:1657
static void Test_ProcessTimes(void)
#define PROCESS_PRIORITY_CLASS_ABOVE_NORMAL
Definition: pstypes.h:112
Status
Definition: gdiplustypes.h:24
VOID QuerySetProcessValidator(_In_ ALIGNMENT_PROBE_MODE ValidationMode, _In_ ULONG InfoClassIndex, _In_ PVOID InfoPointer, _In_ ULONG InfoLength, _In_ NTSTATUS ExpectedStatus)
Definition: probelib.c:12
#define trace
Definition: atltest.h:70
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define RtlFillMemory(Dest, Length, Fill)
Definition: winternl.h:593
LARGE_INTEGER CreateTime
Definition: winternl.h:1060
#define _countof(array)
Definition: sndvol32.h:68
#define STATUS_ACCESS_VIOLATION
Definition: ntstatus.h:242
#define ros_skip_flaky
Definition: test.h:168
#define ok(value,...)
Definition: atltest.h:57
#define NULL
Definition: types.h:112
#define skip(...)
Definition: atltest.h:64
static LARGE_INTEGER TestStartTime
#define STATUS_DATATYPE_MISALIGNMENT
Definition: ntstatus.h:183
unsigned int ULONG
Definition: retypes.h:1
NTSTATUS NTAPI NtQuerySystemTime(OUT PLARGE_INTEGER SystemTime)
Definition: time.c:472
#define malloc
Definition: debug_ros.c:4
#define STATUS_SUCCESS
Definition: shellext.h:65
#define ok_dec(expression, result)
Definition: atltest.h:101
LARGE_INTEGER KernelTime
Definition: winternl.h:1062
Definition: precomp.h:18
static void Test_ProcQueryAlignmentProbe(void)
NTSTATUS NTAPI NtQueryInformationProcess(_In_ HANDLE ProcessHandle, _In_ PROCESSINFOCLASS ProcessInformationClass, _Out_ PVOID ProcessInformation, _In_ ULONG ProcessInformationLength, _Out_opt_ PULONG ReturnLength)
Definition: query.c:59
static const INFORMATION_CLASS_INFO PsProcessInfoClass[]
Definition: ps_i.h:15
#define SPIN_TIME
LONGLONG QuadPart
Definition: typedefs.h:114
static void Test_ProcessPriorityClassAlignment(void)