ReactOS  0.4.15-dev-1171-gab82533
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);
124  "CreateTime is %I64u, expected < %I64u\n", Times1.CreateTime.QuadPart, TestStartTime.QuadPart);
125  ok(Times1.CreateTime.QuadPart > TestStartTime.QuadPart - 100000000LL,
126  "CreateTime is %I64u, expected > %I64u\n", Times1.CreateTime.QuadPart, TestStartTime.QuadPart - 100000000LL);
127  ok(Times1.ExitTime.QuadPart == 0,
128  "ExitTime is %I64u, expected 0\n", Times1.ExitTime.QuadPart);
129  ok(Times1.KernelTime.QuadPart != 0, "KernelTime is 0\n");
131  ok(Times1.UserTime.QuadPart != 0, "UserTime is 0\n");
132 
133  /* Do some busy waiting to increase UserTime */
134  do
135  {
136  Status = NtQuerySystemTime(&Time2);
137  if (!NT_SUCCESS(Status))
138  {
139  ok(0, "NtQuerySystemTime failed with %lx\n", Status);
140  break;
141  }
142  } while (Time2.QuadPart - Time1.QuadPart < SPIN_TIME);
143 
144  /* Again, this time with a return length */
145  Length = 0x55555555;
146  RtlFillMemory(&Times2, sizeof(Times2), 0x55);
148  ProcessTimes,
149  &Times2,
150  sizeof(KERNEL_USER_TIMES),
151  &Length);
153  ok_dec(Length, sizeof(KERNEL_USER_TIMES));
154  ok(Times1.CreateTime.QuadPart == Times2.CreateTime.QuadPart,
155  "CreateTimes not equal: %I64u != %I64u\n", Times1.CreateTime.QuadPart, Times2.CreateTime.QuadPart);
156  ok(Times2.ExitTime.QuadPart == 0,
157  "ExitTime is %I64u, expected 0\n", Times2.ExitTime.QuadPart);
158  ok(Times2.KernelTime.QuadPart != 0, "KernelTime is 0\n");
159  ok(Times2.UserTime.QuadPart != 0, "UserTime is 0\n");
160 
161  /* Compare the two sets of KernelTime/UserTime values */
162  Status = NtQuerySystemTime(&Time2);
164  /* Time values must have increased */
165  ok(Times2.KernelTime.QuadPart > Times1.KernelTime.QuadPart,
166  "KernelTime values inconsistent. Expected %I64u > %I64u\n", Times2.KernelTime.QuadPart, Times1.KernelTime.QuadPart);
168  ok(Times2.UserTime.QuadPart > Times1.UserTime.QuadPart,
169  "UserTime values inconsistent. Expected %I64u > %I64u\n", Times2.UserTime.QuadPart, Times1.UserTime.QuadPart);
170  /* They can't have increased by more than wall clock time difference (we only have one thread) */
172  ok(Times2.KernelTime.QuadPart - Times1.KernelTime.QuadPart < Time2.QuadPart - Time1.QuadPart,
173  "KernelTime values inconsistent. Expected %I64u - %I64u < %I64u\n",
174  Times2.KernelTime.QuadPart, Times1.KernelTime.QuadPart, Time2.QuadPart - Time1.QuadPart);
175  ok(Times2.UserTime.QuadPart - Times1.UserTime.QuadPart < Time2.QuadPart - Time1.QuadPart,
176  "UserTime values inconsistent. Expected %I64u - %I64u < %I64u\n",
177  Times2.UserTime.QuadPart, Times1.UserTime.QuadPart, Time2.QuadPart - Time1.QuadPart);
178 
179  trace("KernelTime1 = %I64u\n", Times1.KernelTime.QuadPart);
180  trace("KernelTime2 = %I64u\n", Times2.KernelTime.QuadPart);
181  trace("UserTime1 = %I64u\n", Times1.UserTime.QuadPart);
182  trace("UserTime2 = %I64u\n", Times2.UserTime.QuadPart);
183 
184  /* TODO: Test ExitTime on a terminated process */
185 #undef SPIN_TIME
186 }
187 
188 static
189 void
191 {
193  PPROCESS_PRIORITY_CLASS ProcPriority;
194 
195  /* Allocate some memory for the priority class structure */
196  ProcPriority = malloc(sizeof(PROCESS_PRIORITY_CLASS));
197  if (ProcPriority == NULL)
198  {
199  skip("Failed to allocate memory for PROCESS_PRIORITY_CLASS!\n");
200  return;
201  }
202 
203  /*
204  * Initialize the PriorityClass member to ensure the test won't randomly succeed (if such data is uninitialized).
205  * Filling 85 to the data member makes sure that if the test fails continously then NtQueryInformationProcess()
206  * didn't initialize the structure with data.
207  */
208  RtlFillMemory(&ProcPriority->PriorityClass, sizeof(ProcPriority->PriorityClass), 0x55);
209 
210  /* Unaligned buffer -- wrong size */
213  (PVOID)1,
214  0,
215  NULL);
217 
218  /* Unaligned buffer -- correct size */
221  (PVOID)1,
222  sizeof(PROCESS_PRIORITY_CLASS),
223  NULL);
225 
226  /* Unaligned buffer -- wrong size (but this time do with an alignment of 2) */
229  (PVOID)2,
230  0,
231  NULL);
233 
234  /* Unaligned buffer -- correct size (but this time do with an alignment of 2) */
237  (PVOID)2,
238  sizeof(PROCESS_PRIORITY_CLASS),
239  NULL);
241 
242  /* Do not care for the length but expect to return the priority class */
245  ProcPriority,
246  sizeof(PROCESS_PRIORITY_CLASS),
247  NULL);
249 
250  /* Make sure the returned priority class is a valid number (non negative) but also it should be within the PROCESS_PRIORITY_CLASS range */
252  "Expected a valid number from priority class range but got %d\n", ProcPriority->PriorityClass);
253  free(ProcPriority);
254 }
255 
256 static
257 void
259 {
261  ULONG VdmPower = 1, ReturnLength;
262 
263  /* Everything is NULL */
266  NULL,
267  0,
268  NULL);
270 
271  /* Given an invalid process handle */
274  &VdmPower,
275  sizeof(VdmPower),
276  NULL);
278 
279  /* Don't query anything */
282  NULL,
283  sizeof(VdmPower),
284  NULL);
286 
287  /* The buffer is misaligned and information length is wrong */
290  (PVOID)1,
291  0,
292  NULL);
294 
295  /* The buffer is misaligned */
298  (PVOID)1,
299  sizeof(VdmPower),
300  NULL);
302 
303  /* The buffer is misaligned -- try with an alignment size of 2 */
306  (PVOID)2,
307  sizeof(VdmPower),
308  NULL);
310 
311  /* Query the VDM power */
314  &VdmPower,
315  sizeof(VdmPower),
316  &ReturnLength);
318  ok(ReturnLength != 0, "ReturnLength shouldn't be 0!\n");
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  /* Trace the VDM power value and returned length */
322  trace("ReturnLength = %lu\n", ReturnLength);
323  trace("VdmPower = %lu\n", VdmPower);
324 }
325 
327 {
329 
332 
336 }
IN CINT OUT PVOID IN ULONG OUT PULONG ReturnLength
Definition: dumpinfo.c:39
#define LL
Definition: tui.h:84
#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
smooth NULL
Definition: ftsmooth.c:416
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
#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
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
Status
Definition: gdiplustypes.h:24
#define STATUS_ACCESS_VIOLATION
Definition: ntstatus.h:242
#define ros_skip_flaky
Definition: test.h:166
#define ok(value,...)
Definition: atltest.h:57
#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:417
#define malloc
Definition: debug_ros.c:4
return STATUS_SUCCESS
Definition: btrfs.c:3014
#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)