1 /*
2  * PROJECT:         ReactOS API tests
3  * LICENSE:         GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
4  * PURPOSE:         Tests for the NtQueryInformationThread API
5  * COPYRIGHT:       Copyright 2020 George Bișoc <george.bisoc@reactos.org>
6  */
7 
8 #include "precomp.h"
9 
10 static
11 void
12 Test_ThreadBasicInformationClass(void)
13 {
14     NTSTATUS Status;
15     PTHREAD_BASIC_INFORMATION ThreadInfoBasic;
16     ULONG ReturnedLength;
17 
18     ThreadInfoBasic = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(THREAD_BASIC_INFORMATION));
19     if (!ThreadInfoBasic)
20     {
21         skip("Failed to allocate memory for THREAD_BASIC_INFORMATION!\n");
22         return;
23     }
24 
25     /* Everything is NULL */
26     Status = NtQueryInformationThread(NULL,
27                                       ThreadBasicInformation,
28                                       NULL,
29                                       0,
30                                       NULL);
31     ok_hex(Status, STATUS_INFO_LENGTH_MISMATCH);
32 
33     /* Don't give a valid thread handle */
34     Status = NtQueryInformationThread(NULL,
35                                       ThreadBasicInformation,
36                                       ThreadInfoBasic,
37                                       sizeof(THREAD_BASIC_INFORMATION),
38                                       NULL);
39     ok_hex(Status, STATUS_INVALID_HANDLE);
40 
41     /* The information length is incorrect */
42     Status = NtQueryInformationThread(GetCurrentThread(),
43                                       ThreadBasicInformation,
44                                       ThreadInfoBasic,
45                                       0,
46                                       NULL);
47     ok_hex(Status, STATUS_INFO_LENGTH_MISMATCH);
48 
49     /* Don't query anything from the function */
50     Status = NtQueryInformationThread(GetCurrentThread(),
51                                       ThreadBasicInformation,
52                                       NULL,
53                                       sizeof(THREAD_BASIC_INFORMATION),
54                                       NULL);
55     ok_hex(Status, STATUS_ACCESS_VIOLATION);
56 
57     /* The buffer is misaligned and length information is wrong */
58     Status = NtQueryInformationThread(GetCurrentThread(),
59                                       ThreadBasicInformation,
60                                       (PVOID)1,
61                                       0,
62                                       NULL);
63     ok_hex(Status, STATUS_INFO_LENGTH_MISMATCH);
64 
65     /* The buffer is misaligned */
66     Status = NtQueryInformationThread(GetCurrentThread(),
67                                       ThreadBasicInformation,
68                                       (PVOID)1,
69                                       sizeof(THREAD_BASIC_INFORMATION),
70                                       NULL);
71     ok_hex(Status, STATUS_DATATYPE_MISALIGNMENT);
72 
73     /* The buffer is misaligned, try with an alignment size of 2 */
74     Status = NtQueryInformationThread(GetCurrentThread(),
75                                       ThreadBasicInformation,
76                                       (PVOID)2,
77                                       sizeof(THREAD_BASIC_INFORMATION),
78                                       NULL);
79     ok_hex(Status, STATUS_DATATYPE_MISALIGNMENT);
80 
81     /* Query the basic information we need from the thread */
82     Status = NtQueryInformationThread(GetCurrentThread(),
83                                       ThreadBasicInformation,
84                                       ThreadInfoBasic,
85                                       sizeof(THREAD_BASIC_INFORMATION),
86                                       &ReturnedLength);
87     ok_hex(Status, STATUS_SUCCESS);
88     ok(ReturnedLength != 0, "The size of the buffer pointed by ThreadInformation shouldn't be 0!\n");
89 
90     /* Output the thread basic information details */
91     trace("ReturnedLength = %lu\n", ReturnedLength);
92     trace("ThreadInfoBasic->ExitStatus = 0x%08lx\n", ThreadInfoBasic->ExitStatus);
93     trace("ThreadInfoBasic->TebBaseAddress = %p\n", ThreadInfoBasic->TebBaseAddress);
94     trace("ThreadInfoBasic->ClientId.UniqueProcess = %p\n", ThreadInfoBasic->ClientId.UniqueProcess);
95     trace("ThreadInfoBasic->ClientId.UniqueThread = %p\n", ThreadInfoBasic->ClientId.UniqueThread);
96     trace("ThreadInfoBasic->AffinityMask = %lu\n", ThreadInfoBasic->AffinityMask);
97     trace("ThreadInfoBasic->Priority = %li\n", ThreadInfoBasic->Priority);
98     trace("ThreadInfoBasic->BasePriority = %li\n", ThreadInfoBasic->BasePriority);
99 
100     HeapFree(GetProcessHeap(), 0, ThreadInfoBasic);
101 }
102 
103 START_TEST(NtQueryInformationThread)
104 {
105     Test_ThreadBasicInformationClass();
106 }
107