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>
10 #define WIN32_NO_STATUS
11 #include <ndk/rtlfuncs.h>
12 #include <ndk/kefuncs.h>
13 #include <ndk/psfuncs.h>
15 static LARGE_INTEGER TestStartTime
;
19 Test_ProcessTimes(void)
21 #define SPIN_TIME 1000000
23 KERNEL_USER_TIMES Times1
;
24 KERNEL_USER_TIMES Times2
;
26 LARGE_INTEGER Time1
, Time2
;
28 /* Everything is NULL */
29 Status
= NtQueryInformationProcess(NULL
,
34 ok_hex(Status
, STATUS_INFO_LENGTH_MISMATCH
);
36 /* Right size, invalid process */
37 Status
= NtQueryInformationProcess(NULL
,
40 sizeof(KERNEL_USER_TIMES
),
42 ok_hex(Status
, STATUS_INVALID_HANDLE
);
44 /* Valid process, no buffer */
45 Status
= NtQueryInformationProcess(NtCurrentProcess(),
50 ok_hex(Status
, STATUS_INFO_LENGTH_MISMATCH
);
52 /* Unaligned buffer, wrong size */
53 Status
= NtQueryInformationProcess(NtCurrentProcess(),
58 ok_hex(Status
, STATUS_INFO_LENGTH_MISMATCH
);
60 /* Unaligned buffer, correct size */
61 Status
= NtQueryInformationProcess(NtCurrentProcess(),
64 sizeof(KERNEL_USER_TIMES
),
66 ok_hex(Status
, STATUS_DATATYPE_MISALIGNMENT
);
68 /* Buffer too small */
69 Status
= NtQueryInformationProcess(NtCurrentProcess(),
72 sizeof(KERNEL_USER_TIMES
) - 1,
74 ok_hex(Status
, STATUS_INFO_LENGTH_MISMATCH
);
76 /* Right buffer size but NULL pointer */
77 Status
= NtQueryInformationProcess(NtCurrentProcess(),
80 sizeof(KERNEL_USER_TIMES
),
82 ok_hex(Status
, STATUS_ACCESS_VIOLATION
);
84 /* Buffer too large */
85 Status
= NtQueryInformationProcess(NtCurrentProcess(),
88 sizeof(KERNEL_USER_TIMES
) + 1,
90 ok_hex(Status
, STATUS_INFO_LENGTH_MISMATCH
);
92 /* Buffer too small, ask for length */
94 Status
= NtQueryInformationProcess(NtCurrentProcess(),
97 sizeof(KERNEL_USER_TIMES
) - 1,
99 ok_hex(Status
, STATUS_INFO_LENGTH_MISMATCH
);
100 ok_dec(Length
, 0x55555555);
102 Status
= NtQuerySystemTime(&Time1
);
103 ok_hex(Status
, STATUS_SUCCESS
);
105 /* Do some busy waiting to increase UserTime */
108 Status
= NtQuerySystemTime(&Time2
);
109 if (!NT_SUCCESS(Status
))
111 ok(0, "NtQuerySystemTime failed with %lx\n", Status
);
114 } while (Time2
.QuadPart
- Time1
.QuadPart
< SPIN_TIME
);
116 /* Valid parameters, no return length */
117 Status
= NtQuerySystemTime(&Time1
);
118 ok_hex(Status
, STATUS_SUCCESS
);
120 RtlFillMemory(&Times1
, sizeof(Times1
), 0x55);
121 Status
= NtQueryInformationProcess(NtCurrentProcess(),
124 sizeof(KERNEL_USER_TIMES
),
126 ok_hex(Status
, STATUS_SUCCESS
);
127 ok(Times1
.CreateTime
.QuadPart
< TestStartTime
.QuadPart
,
128 "CreateTime is %I64u, expected < %I64u\n", Times1
.CreateTime
.QuadPart
, TestStartTime
.QuadPart
);
129 ok(Times1
.CreateTime
.QuadPart
> TestStartTime
.QuadPart
- 100000000LL,
130 "CreateTime is %I64u, expected > %I64u\n", Times1
.CreateTime
.QuadPart
, TestStartTime
.QuadPart
- 100000000LL);
131 ok(Times1
.ExitTime
.QuadPart
== 0,
132 "ExitTime is %I64u, expected 0\n", Times1
.ExitTime
.QuadPart
);
133 ok(Times1
.KernelTime
.QuadPart
!= 0, "KernelTime is 0\n");
134 ok(Times1
.UserTime
.QuadPart
!= 0, "UserTime is 0\n");
136 /* Do some busy waiting to increase UserTime */
139 Status
= NtQuerySystemTime(&Time2
);
140 if (!NT_SUCCESS(Status
))
142 ok(0, "NtQuerySystemTime failed with %lx\n", Status
);
145 } while (Time2
.QuadPart
- Time1
.QuadPart
< SPIN_TIME
);
147 /* Again, this time with a return length */
149 RtlFillMemory(&Times2
, sizeof(Times2
), 0x55);
150 Status
= NtQueryInformationProcess(NtCurrentProcess(),
153 sizeof(KERNEL_USER_TIMES
),
155 ok_hex(Status
, STATUS_SUCCESS
);
156 ok_dec(Length
, sizeof(KERNEL_USER_TIMES
));
157 ok(Times1
.CreateTime
.QuadPart
== Times2
.CreateTime
.QuadPart
,
158 "CreateTimes not equal: %I64u != %I64u\n", Times1
.CreateTime
.QuadPart
, Times2
.CreateTime
.QuadPart
);
159 ok(Times2
.ExitTime
.QuadPart
== 0,
160 "ExitTime is %I64u, expected 0\n", Times2
.ExitTime
.QuadPart
);
161 ok(Times2
.KernelTime
.QuadPart
!= 0, "KernelTime is 0\n");
162 ok(Times2
.UserTime
.QuadPart
!= 0, "UserTime is 0\n");
164 /* Compare the two sets of KernelTime/UserTime values */
165 Status
= NtQuerySystemTime(&Time2
);
166 ok_hex(Status
, STATUS_SUCCESS
);
167 /* Time values must have increased */
168 ok(Times2
.KernelTime
.QuadPart
> Times1
.KernelTime
.QuadPart
,
169 "KernelTime values inconsistent. Expected %I64u > %I64u\n", Times2
.KernelTime
.QuadPart
, Times1
.KernelTime
.QuadPart
);
170 ok(Times2
.UserTime
.QuadPart
> Times1
.UserTime
.QuadPart
,
171 "UserTime values inconsistent. Expected %I64u > %I64u\n", Times2
.UserTime
.QuadPart
, Times1
.UserTime
.QuadPart
);
172 /* 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
);
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
);
185 /* TODO: Test ExitTime on a terminated process */
189 START_TEST(NtQueryInformationProcess
)
193 Status
= NtQuerySystemTime(&TestStartTime
);
194 ok_hex(Status
, STATUS_SUCCESS
);