ReactOS  0.4.15-dev-2320-gf3e1697
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  */
7 
8 #include "precomp.h"
9 
11 
12 static
13 void
15 {
16 #define SPIN_TIME 1000000
18  KERNEL_USER_TIMES Times1;
19  KERNEL_USER_TIMES Times2;
20  ULONG Length;
21  LARGE_INTEGER Time1, Time2;
22 
23  /* Everything is NULL */
26  NULL,
27  0,
28  NULL);
30 
31  /* Right size, invalid process */
34  NULL,
35  sizeof(KERNEL_USER_TIMES),
36  NULL);
38 
39  /* Valid process, no buffer */
42  NULL,
43  0,
44  NULL);
46 
47  /* Unaligned buffer, wrong size */
50  (PVOID)2,
51  0,
52  NULL);
54 
55  /* Unaligned buffer, correct size */
58  (PVOID)2,
59  sizeof(KERNEL_USER_TIMES),
60  NULL);
62 
63  /* Buffer too small */
66  NULL,
67  sizeof(KERNEL_USER_TIMES) - 1,
68  NULL);
70 
71  /* Right buffer size but NULL pointer */
74  NULL,
75  sizeof(KERNEL_USER_TIMES),
76  NULL);
78 
79  /* Buffer too large */
82  NULL,
83  sizeof(KERNEL_USER_TIMES) + 1,
84  NULL);
86 
87  /* Buffer too small, ask for length */
88  Length = 0x55555555;
91  NULL,
92  sizeof(KERNEL_USER_TIMES) - 1,
93  &Length);
95  ok_dec(Length, 0x55555555);
96 
97  Status = NtQuerySystemTime(&Time1);
99 
100  /* Do some busy waiting to increase UserTime */
101  do
102  {
103  Status = NtQuerySystemTime(&Time2);
104  if (!NT_SUCCESS(Status))
105  {
106  ok(0, "NtQuerySystemTime failed with %lx\n", Status);
107  break;
108  }
109  } while (Time2.QuadPart - Time1.QuadPart < SPIN_TIME);
110 
111  /* Valid parameters, no return length */
112  Status = NtQuerySystemTime(&Time1);
114 
115  RtlFillMemory(&Times1, sizeof(Times1), 0x55);
117  ProcessTimes,
118  &Times1,
119  sizeof(KERNEL_USER_TIMES),
120  NULL);
123  "CreateTime is %I64u, expected < %I64u\n", Times1.CreateTime.QuadPart, TestStartTime.QuadPart);
124  ok(Times1.CreateTime.QuadPart > TestStartTime.QuadPart - 100000000LL,
125  "CreateTime is %I64u, expected > %I64u\n", Times1.CreateTime.QuadPart, TestStartTime.QuadPart - 100000000LL);
126  ok(Times1.ExitTime.QuadPart == 0,
127  "ExitTime is %I64u, expected 0\n", Times1.ExitTime.QuadPart);
128  ok(Times1.KernelTime.QuadPart != 0, "KernelTime is 0\n");
130  ok(Times1.UserTime.QuadPart != 0, "UserTime is 0\n");
131 
132  /* Do some busy waiting to increase UserTime */
133  do
134  {
135  Status = NtQuerySystemTime(&Time2);
136  if (!NT_SUCCESS(Status))
137  {
138  ok(0, "NtQuerySystemTime failed with %lx\n", Status);
139  break;
140  }
141  } while (Time2.QuadPart - Time1.QuadPart < SPIN_TIME);
142 
143  /* Again, this time with a return length */
144  Length = 0x55555555;
145  RtlFillMemory(&Times2, sizeof(Times2), 0x55);
147  ProcessTimes,
148  &Times2,
149  sizeof(KERNEL_USER_TIMES),
150  &Length);
152  ok_dec(Length, sizeof(KERNEL_USER_TIMES));
153  ok(Times1.CreateTime.QuadPart == Times2.CreateTime.QuadPart,
154  "CreateTimes not equal: %I64u != %I64u\n", Times1.CreateTime.QuadPart, Times2.CreateTime.QuadPart);
155  ok(Times2.ExitTime.QuadPart == 0,
156  "ExitTime is %I64u, expected 0\n", Times2.ExitTime.QuadPart);
157  ok(Times2.KernelTime.QuadPart != 0, "KernelTime is 0\n");
158  ok(Times2.UserTime.QuadPart != 0, "UserTime is 0\n");
159 
160  /* Compare the two sets of KernelTime/UserTime values */
161  Status = NtQuerySystemTime(&Time2);
163  /* Time values must have increased */
164  ok(Times2.KernelTime.QuadPart > Times1.KernelTime.QuadPart,
165  "KernelTime values inconsistent. Expected %I64u > %I64u\n", Times2.KernelTime.QuadPart, Times1.KernelTime.QuadPart);
167  ok(Times2.UserTime.QuadPart > Times1.UserTime.QuadPart,
168  "UserTime values inconsistent. Expected %I64u > %I64u\n", Times2.UserTime.QuadPart, Times1.UserTime.QuadPart);
169  /* They can't have increased by more than wall clock time difference (we only have one thread) */
171  ok(Times2.KernelTime.QuadPart - Times1.KernelTime.QuadPart < Time2.QuadPart - Time1.QuadPart,
172  "KernelTime values inconsistent. Expected %I64u - %I64u < %I64u\n",
173  Times2.KernelTime.QuadPart, Times1.KernelTime.QuadPart, Time2.QuadPart - Time1.QuadPart);
174  ok(Times2.UserTime.QuadPart - Times1.UserTime.QuadPart < Time2.QuadPart - Time1.QuadPart,
175  "UserTime values inconsistent. Expected %I64u - %I64u < %I64u\n",
176  Times2.UserTime.QuadPart, Times1.UserTime.QuadPart, Time2.QuadPart - Time1.QuadPart);
177 
178  trace("KernelTime1 = %I64u\n", Times1.KernelTime.QuadPart);
179  trace("KernelTime2 = %I64u\n", Times2.KernelTime.QuadPart);
180  trace("UserTime1 = %I64u\n", Times1.UserTime.QuadPart);
181  trace("UserTime2 = %I64u\n", Times2.UserTime.QuadPart);
182 
183  /* TODO: Test ExitTime on a terminated process */
184 #undef SPIN_TIME
185 }
186 
187 static
188 void
190 {
192  PPROCESS_PRIORITY_CLASS ProcPriority;
193 
194  /* Allocate some memory for the priority class structure */
195  ProcPriority = malloc(sizeof(PROCESS_PRIORITY_CLASS));
196  if (ProcPriority == NULL)
197  {
198  skip("Failed to allocate memory for PROCESS_PRIORITY_CLASS!\n");
199  return;
200  }
201 
202  /*
203  * Initialize the PriorityClass member to ensure the test won't randomly succeed (if such data is uninitialized).
204  * Filling 85 to the data member makes sure that if the test fails continously then NtQueryInformationProcess()
205  * didn't initialize the structure with data.
206  */
207  RtlFillMemory(&ProcPriority->PriorityClass, sizeof(ProcPriority->PriorityClass), 0x55);
208 
209  /* Unaligned buffer -- wrong size */
212  (PVOID)1,
213  0,
214  NULL);
216 
217  /* Unaligned buffer -- correct size */
220  (PVOID)1,
221  sizeof(PROCESS_PRIORITY_CLASS),
222  NULL);
224 
225  /* Unaligned buffer -- wrong size (but this time do with an alignment of 2) */
228  (PVOID)2,
229  0,
230  NULL);
232 
233  /* Unaligned buffer -- correct size (but this time do with an alignment of 2) */
236  (PVOID)2,
237  sizeof(PROCESS_PRIORITY_CLASS),
238  NULL);
240 
241  /* Do not care for the length but expect to return the priority class */
244  ProcPriority,
245  sizeof(PROCESS_PRIORITY_CLASS),
246  NULL);
248 
249  /* Make sure the returned priority class is a valid number (non negative) but also it should be within the PROCESS_PRIORITY_CLASS range */
251  "Expected a valid number from priority class range but got %d\n", ProcPriority->PriorityClass);
252  free(ProcPriority);
253 }
254 
255 static
256 void
258 {
260  ULONG VdmPower = 1, ReturnLength;
261 
262  /* Everything is NULL */
265  NULL,
266  0,
267  NULL);
269 
270  /* Given an invalid process handle */
273  &VdmPower,
274  sizeof(VdmPower),
275  NULL);
277 
278  /* Don't query anything */
281  NULL,
282  sizeof(VdmPower),
283  NULL);
285 
286  /* The buffer is misaligned and information length is wrong */
289  (PVOID)1,
290  0,
291  NULL);
293 
294  /* The buffer is misaligned */
297  (PVOID)1,
298  sizeof(VdmPower),
299  NULL);
301 
302  /* The buffer is misaligned -- try with an alignment size of 2 */
305  (PVOID)2,
306  sizeof(VdmPower),
307  NULL);
309 
310  /* Query the VDM power */
313  &VdmPower,
314  sizeof(VdmPower),
315  &ReturnLength);
317  ok(ReturnLength != 0, "ReturnLength shouldn't be 0!\n");
318  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);
319 
320  /* Trace the VDM power value and returned length */
321  trace("ReturnLength = %lu\n", ReturnLength);
322  trace("VdmPower = %lu\n", VdmPower);
323 }
324 
326 {
328 
329  /* Make sure that some time has passed since process creation, even if the resolution of our NtQuerySystemTime is low. */
330  Sleep(1);
331 
334 
338 }
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
NTSTATUS NTAPI NtQueryInformationProcess(IN HANDLE ProcessHandle, IN PROCESSINFOCLASS ProcessInformationClass, OUT PVOID ProcessInformation, IN ULONG ProcessInformationLength, OUT PULONG ReturnLength OPTIONAL)
Definition: query.c:59
#define ok_hex(expression, result)
Definition: atltest.h:94
#define STATUS_INVALID_HANDLE
Definition: ntstatus.h:245
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
#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 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
#define SPIN_TIME
LONGLONG QuadPart
Definition: typedefs.h:114
static void Test_ProcessPriorityClassAlignment(void)