1c2c66affSColin Finck /* 2c2c66affSColin Finck * PROJECT: ReactOS API tests 3c2c66affSColin Finck * LICENSE: LGPLv2.1+ - See COPYING.LIB in the top level directory 4c2c66affSColin Finck * PURPOSE: Tests for the NtQueryInformationProcess API 5c2c66affSColin Finck * PROGRAMMER: Thomas Faber <thomas.faber@reactos.org> 6c2c66affSColin Finck */ 7c2c66affSColin Finck 8*283bbe73SAmine Khaldi #include "precomp.h" 9c2c66affSColin Finck 10c2c66affSColin Finck static LARGE_INTEGER TestStartTime; 11c2c66affSColin Finck 12c2c66affSColin Finck static 13c2c66affSColin Finck void 14c2c66affSColin Finck Test_ProcessTimes(void) 15c2c66affSColin Finck { 16c2c66affSColin Finck #define SPIN_TIME 1000000 17c2c66affSColin Finck NTSTATUS Status; 18c2c66affSColin Finck KERNEL_USER_TIMES Times1; 19c2c66affSColin Finck KERNEL_USER_TIMES Times2; 20c2c66affSColin Finck ULONG Length; 21c2c66affSColin Finck LARGE_INTEGER Time1, Time2; 22c2c66affSColin Finck 23c2c66affSColin Finck /* Everything is NULL */ 24c2c66affSColin Finck Status = NtQueryInformationProcess(NULL, 25c2c66affSColin Finck ProcessTimes, 26c2c66affSColin Finck NULL, 27c2c66affSColin Finck 0, 28c2c66affSColin Finck NULL); 29c2c66affSColin Finck ok_hex(Status, STATUS_INFO_LENGTH_MISMATCH); 30c2c66affSColin Finck 31c2c66affSColin Finck /* Right size, invalid process */ 32c2c66affSColin Finck Status = NtQueryInformationProcess(NULL, 33c2c66affSColin Finck ProcessTimes, 34c2c66affSColin Finck NULL, 35c2c66affSColin Finck sizeof(KERNEL_USER_TIMES), 36c2c66affSColin Finck NULL); 37c2c66affSColin Finck ok_hex(Status, STATUS_INVALID_HANDLE); 38c2c66affSColin Finck 39c2c66affSColin Finck /* Valid process, no buffer */ 40c2c66affSColin Finck Status = NtQueryInformationProcess(NtCurrentProcess(), 41c2c66affSColin Finck ProcessTimes, 42c2c66affSColin Finck NULL, 43c2c66affSColin Finck 0, 44c2c66affSColin Finck NULL); 45c2c66affSColin Finck ok_hex(Status, STATUS_INFO_LENGTH_MISMATCH); 46c2c66affSColin Finck 47c2c66affSColin Finck /* Unaligned buffer, wrong size */ 48c2c66affSColin Finck Status = NtQueryInformationProcess(NtCurrentProcess(), 49c2c66affSColin Finck ProcessTimes, 50c2c66affSColin Finck (PVOID)2, 51c2c66affSColin Finck 0, 52c2c66affSColin Finck NULL); 53c2c66affSColin Finck ok_hex(Status, STATUS_INFO_LENGTH_MISMATCH); 54c2c66affSColin Finck 55c2c66affSColin Finck /* Unaligned buffer, correct size */ 56c2c66affSColin Finck Status = NtQueryInformationProcess(NtCurrentProcess(), 57c2c66affSColin Finck ProcessTimes, 58c2c66affSColin Finck (PVOID)2, 59c2c66affSColin Finck sizeof(KERNEL_USER_TIMES), 60c2c66affSColin Finck NULL); 61c2c66affSColin Finck ok_hex(Status, STATUS_DATATYPE_MISALIGNMENT); 62c2c66affSColin Finck 63c2c66affSColin Finck /* Buffer too small */ 64c2c66affSColin Finck Status = NtQueryInformationProcess(NtCurrentProcess(), 65c2c66affSColin Finck ProcessTimes, 66c2c66affSColin Finck NULL, 67c2c66affSColin Finck sizeof(KERNEL_USER_TIMES) - 1, 68c2c66affSColin Finck NULL); 69c2c66affSColin Finck ok_hex(Status, STATUS_INFO_LENGTH_MISMATCH); 70c2c66affSColin Finck 71c2c66affSColin Finck /* Right buffer size but NULL pointer */ 72c2c66affSColin Finck Status = NtQueryInformationProcess(NtCurrentProcess(), 73c2c66affSColin Finck ProcessTimes, 74c2c66affSColin Finck NULL, 75c2c66affSColin Finck sizeof(KERNEL_USER_TIMES), 76c2c66affSColin Finck NULL); 77c2c66affSColin Finck ok_hex(Status, STATUS_ACCESS_VIOLATION); 78c2c66affSColin Finck 79c2c66affSColin Finck /* Buffer too large */ 80c2c66affSColin Finck Status = NtQueryInformationProcess(NtCurrentProcess(), 81c2c66affSColin Finck ProcessTimes, 82c2c66affSColin Finck NULL, 83c2c66affSColin Finck sizeof(KERNEL_USER_TIMES) + 1, 84c2c66affSColin Finck NULL); 85c2c66affSColin Finck ok_hex(Status, STATUS_INFO_LENGTH_MISMATCH); 86c2c66affSColin Finck 87c2c66affSColin Finck /* Buffer too small, ask for length */ 88c2c66affSColin Finck Length = 0x55555555; 89c2c66affSColin Finck Status = NtQueryInformationProcess(NtCurrentProcess(), 90c2c66affSColin Finck ProcessTimes, 91c2c66affSColin Finck NULL, 92c2c66affSColin Finck sizeof(KERNEL_USER_TIMES) - 1, 93c2c66affSColin Finck &Length); 94c2c66affSColin Finck ok_hex(Status, STATUS_INFO_LENGTH_MISMATCH); 95c2c66affSColin Finck ok_dec(Length, 0x55555555); 96c2c66affSColin Finck 97c2c66affSColin Finck Status = NtQuerySystemTime(&Time1); 98c2c66affSColin Finck ok_hex(Status, STATUS_SUCCESS); 99c2c66affSColin Finck 100c2c66affSColin Finck /* Do some busy waiting to increase UserTime */ 101c2c66affSColin Finck do 102c2c66affSColin Finck { 103c2c66affSColin Finck Status = NtQuerySystemTime(&Time2); 104c2c66affSColin Finck if (!NT_SUCCESS(Status)) 105c2c66affSColin Finck { 106c2c66affSColin Finck ok(0, "NtQuerySystemTime failed with %lx\n", Status); 107c2c66affSColin Finck break; 108c2c66affSColin Finck } 109c2c66affSColin Finck } while (Time2.QuadPart - Time1.QuadPart < SPIN_TIME); 110c2c66affSColin Finck 111c2c66affSColin Finck /* Valid parameters, no return length */ 112c2c66affSColin Finck Status = NtQuerySystemTime(&Time1); 113c2c66affSColin Finck ok_hex(Status, STATUS_SUCCESS); 114c2c66affSColin Finck 115c2c66affSColin Finck RtlFillMemory(&Times1, sizeof(Times1), 0x55); 116c2c66affSColin Finck Status = NtQueryInformationProcess(NtCurrentProcess(), 117c2c66affSColin Finck ProcessTimes, 118c2c66affSColin Finck &Times1, 119c2c66affSColin Finck sizeof(KERNEL_USER_TIMES), 120c2c66affSColin Finck NULL); 121c2c66affSColin Finck ok_hex(Status, STATUS_SUCCESS); 122c2c66affSColin Finck ok(Times1.CreateTime.QuadPart < TestStartTime.QuadPart, 123c2c66affSColin Finck "CreateTime is %I64u, expected < %I64u\n", Times1.CreateTime.QuadPart, TestStartTime.QuadPart); 124c2c66affSColin Finck ok(Times1.CreateTime.QuadPart > TestStartTime.QuadPart - 100000000LL, 125c2c66affSColin Finck "CreateTime is %I64u, expected > %I64u\n", Times1.CreateTime.QuadPart, TestStartTime.QuadPart - 100000000LL); 126c2c66affSColin Finck ok(Times1.ExitTime.QuadPart == 0, 127c2c66affSColin Finck "ExitTime is %I64u, expected 0\n", Times1.ExitTime.QuadPart); 128c2c66affSColin Finck ok(Times1.KernelTime.QuadPart != 0, "KernelTime is 0\n"); 129c2c66affSColin Finck ok(Times1.UserTime.QuadPart != 0, "UserTime is 0\n"); 130c2c66affSColin Finck 131c2c66affSColin Finck /* Do some busy waiting to increase UserTime */ 132c2c66affSColin Finck do 133c2c66affSColin Finck { 134c2c66affSColin Finck Status = NtQuerySystemTime(&Time2); 135c2c66affSColin Finck if (!NT_SUCCESS(Status)) 136c2c66affSColin Finck { 137c2c66affSColin Finck ok(0, "NtQuerySystemTime failed with %lx\n", Status); 138c2c66affSColin Finck break; 139c2c66affSColin Finck } 140c2c66affSColin Finck } while (Time2.QuadPart - Time1.QuadPart < SPIN_TIME); 141c2c66affSColin Finck 142c2c66affSColin Finck /* Again, this time with a return length */ 143c2c66affSColin Finck Length = 0x55555555; 144c2c66affSColin Finck RtlFillMemory(&Times2, sizeof(Times2), 0x55); 145c2c66affSColin Finck Status = NtQueryInformationProcess(NtCurrentProcess(), 146c2c66affSColin Finck ProcessTimes, 147c2c66affSColin Finck &Times2, 148c2c66affSColin Finck sizeof(KERNEL_USER_TIMES), 149c2c66affSColin Finck &Length); 150c2c66affSColin Finck ok_hex(Status, STATUS_SUCCESS); 151c2c66affSColin Finck ok_dec(Length, sizeof(KERNEL_USER_TIMES)); 152c2c66affSColin Finck ok(Times1.CreateTime.QuadPart == Times2.CreateTime.QuadPart, 153c2c66affSColin Finck "CreateTimes not equal: %I64u != %I64u\n", Times1.CreateTime.QuadPart, Times2.CreateTime.QuadPart); 154c2c66affSColin Finck ok(Times2.ExitTime.QuadPart == 0, 155c2c66affSColin Finck "ExitTime is %I64u, expected 0\n", Times2.ExitTime.QuadPart); 156c2c66affSColin Finck ok(Times2.KernelTime.QuadPart != 0, "KernelTime is 0\n"); 157c2c66affSColin Finck ok(Times2.UserTime.QuadPart != 0, "UserTime is 0\n"); 158c2c66affSColin Finck 159c2c66affSColin Finck /* Compare the two sets of KernelTime/UserTime values */ 160c2c66affSColin Finck Status = NtQuerySystemTime(&Time2); 161c2c66affSColin Finck ok_hex(Status, STATUS_SUCCESS); 162c2c66affSColin Finck /* Time values must have increased */ 163c2c66affSColin Finck ok(Times2.KernelTime.QuadPart > Times1.KernelTime.QuadPart, 164c2c66affSColin Finck "KernelTime values inconsistent. Expected %I64u > %I64u\n", Times2.KernelTime.QuadPart, Times1.KernelTime.QuadPart); 165c2c66affSColin Finck ok(Times2.UserTime.QuadPart > Times1.UserTime.QuadPart, 166c2c66affSColin Finck "UserTime values inconsistent. Expected %I64u > %I64u\n", Times2.UserTime.QuadPart, Times1.UserTime.QuadPart); 167c2c66affSColin Finck /* They can't have increased by more than wall clock time difference (we only have one thread) */ 168c2c66affSColin Finck ok(Times2.KernelTime.QuadPart - Times1.KernelTime.QuadPart < Time2.QuadPart - Time1.QuadPart, 169c2c66affSColin Finck "KernelTime values inconsistent. Expected %I64u - %I64u < %I64u\n", 170c2c66affSColin Finck Times2.KernelTime.QuadPart, Times1.KernelTime.QuadPart, Time2.QuadPart - Time1.QuadPart); 171c2c66affSColin Finck ok(Times2.UserTime.QuadPart - Times1.UserTime.QuadPart < Time2.QuadPart - Time1.QuadPart, 172c2c66affSColin Finck "UserTime values inconsistent. Expected %I64u - %I64u < %I64u\n", 173c2c66affSColin Finck Times2.UserTime.QuadPart, Times1.UserTime.QuadPart, Time2.QuadPart - Time1.QuadPart); 174c2c66affSColin Finck 175c2c66affSColin Finck trace("KernelTime1 = %I64u\n", Times1.KernelTime.QuadPart); 176c2c66affSColin Finck trace("KernelTime2 = %I64u\n", Times2.KernelTime.QuadPart); 177c2c66affSColin Finck trace("UserTime1 = %I64u\n", Times1.UserTime.QuadPart); 178c2c66affSColin Finck trace("UserTime2 = %I64u\n", Times2.UserTime.QuadPart); 179c2c66affSColin Finck 180c2c66affSColin Finck /* TODO: Test ExitTime on a terminated process */ 181c2c66affSColin Finck #undef SPIN_TIME 182c2c66affSColin Finck } 183c2c66affSColin Finck 184c2c66affSColin Finck START_TEST(NtQueryInformationProcess) 185c2c66affSColin Finck { 186c2c66affSColin Finck NTSTATUS Status; 187c2c66affSColin Finck 188c2c66affSColin Finck Status = NtQuerySystemTime(&TestStartTime); 189c2c66affSColin Finck ok_hex(Status, STATUS_SUCCESS); 190c2c66affSColin Finck 191c2c66affSColin Finck Test_ProcessTimes(); 192c2c66affSColin Finck } 193