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 #include <internal/ps_i.h>
10 
11 static
12 void
13 Test_ThreadBasicInformationClass(void)
14 {
15     NTSTATUS Status;
16     PTHREAD_BASIC_INFORMATION ThreadInfoBasic;
17     ULONG ReturnedLength;
18 
19     ThreadInfoBasic = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(THREAD_BASIC_INFORMATION));
20     if (!ThreadInfoBasic)
21     {
22         skip("Failed to allocate memory for THREAD_BASIC_INFORMATION!\n");
23         return;
24     }
25 
26     /* Everything is NULL */
27     Status = NtQueryInformationThread(NULL,
28                                       ThreadBasicInformation,
29                                       NULL,
30                                       0,
31                                       NULL);
32     ok_hex(Status, STATUS_INFO_LENGTH_MISMATCH);
33 
34     /* Don't give a valid thread handle */
35     Status = NtQueryInformationThread(NULL,
36                                       ThreadBasicInformation,
37                                       ThreadInfoBasic,
38                                       sizeof(THREAD_BASIC_INFORMATION),
39                                       NULL);
40     ok_hex(Status, STATUS_INVALID_HANDLE);
41 
42     /* The information length is incorrect */
43     Status = NtQueryInformationThread(GetCurrentThread(),
44                                       ThreadBasicInformation,
45                                       ThreadInfoBasic,
46                                       0,
47                                       NULL);
48     ok_hex(Status, STATUS_INFO_LENGTH_MISMATCH);
49 
50     /* Don't query anything from the function */
51     Status = NtQueryInformationThread(GetCurrentThread(),
52                                       ThreadBasicInformation,
53                                       NULL,
54                                       sizeof(THREAD_BASIC_INFORMATION),
55                                       NULL);
56     ok_hex(Status, STATUS_ACCESS_VIOLATION);
57 
58     /* The buffer is misaligned and length information is wrong */
59     Status = NtQueryInformationThread(GetCurrentThread(),
60                                       ThreadBasicInformation,
61                                       (PVOID)1,
62                                       0,
63                                       NULL);
64     ok_hex(Status, STATUS_INFO_LENGTH_MISMATCH);
65 
66     /* The buffer is misaligned */
67     Status = NtQueryInformationThread(GetCurrentThread(),
68                                       ThreadBasicInformation,
69                                       (PVOID)1,
70                                       sizeof(THREAD_BASIC_INFORMATION),
71                                       NULL);
72     ok_hex(Status, STATUS_DATATYPE_MISALIGNMENT);
73 
74     /* The buffer is misaligned, try with an alignment size of 2 */
75     Status = NtQueryInformationThread(GetCurrentThread(),
76                                       ThreadBasicInformation,
77                                       (PVOID)2,
78                                       sizeof(THREAD_BASIC_INFORMATION),
79                                       NULL);
80     ok_hex(Status, STATUS_DATATYPE_MISALIGNMENT);
81 
82     /* Query the basic information we need from the thread */
83     Status = NtQueryInformationThread(GetCurrentThread(),
84                                       ThreadBasicInformation,
85                                       ThreadInfoBasic,
86                                       sizeof(THREAD_BASIC_INFORMATION),
87                                       &ReturnedLength);
88     ok_hex(Status, STATUS_SUCCESS);
89     ok(ReturnedLength != 0, "The size of the buffer pointed by ThreadInformation shouldn't be 0!\n");
90 
91     /* Output the thread basic information details */
92     trace("ReturnedLength = %lu\n", ReturnedLength);
93     trace("ThreadInfoBasic->ExitStatus = 0x%08lx\n", ThreadInfoBasic->ExitStatus);
94     trace("ThreadInfoBasic->TebBaseAddress = %p\n", ThreadInfoBasic->TebBaseAddress);
95     trace("ThreadInfoBasic->ClientId.UniqueProcess = %p\n", ThreadInfoBasic->ClientId.UniqueProcess);
96     trace("ThreadInfoBasic->ClientId.UniqueThread = %p\n", ThreadInfoBasic->ClientId.UniqueThread);
97     trace("ThreadInfoBasic->AffinityMask = %lu\n", ThreadInfoBasic->AffinityMask);
98     trace("ThreadInfoBasic->Priority = %li\n", ThreadInfoBasic->Priority);
99     trace("ThreadInfoBasic->BasePriority = %li\n", ThreadInfoBasic->BasePriority);
100 
101     HeapFree(GetProcessHeap(), 0, ThreadInfoBasic);
102 }
103 
104 static
105 void
106 Test_ThreadQueryAlignmentProbe(void)
107 {
108     ULONG InfoClass;
109 
110     /* Iterate over the process info classes and begin the tests */
111     for (InfoClass = 0; InfoClass < _countof(PsThreadInfoClass); InfoClass++)
112     {
113         /* The buffer is misaligned */
114         QuerySetThreadValidator(QUERY,
115                                 InfoClass,
116                                 (PVOID)(ULONG_PTR)1,
117                                 PsThreadInfoClass[InfoClass].RequiredSizeQUERY,
118                                 STATUS_DATATYPE_MISALIGNMENT);
119 
120         /* We query an invalid buffer address */
121         QuerySetThreadValidator(QUERY,
122                                 InfoClass,
123                                 (PVOID)(ULONG_PTR)PsThreadInfoClass[InfoClass].AlignmentQUERY,
124                                 PsThreadInfoClass[InfoClass].RequiredSizeQUERY,
125                                 STATUS_ACCESS_VIOLATION);
126 
127         /* The information length is wrong */
128         QuerySetThreadValidator(QUERY,
129                                 InfoClass,
130                                 (PVOID)(ULONG_PTR)PsThreadInfoClass[InfoClass].AlignmentQUERY,
131                                 PsThreadInfoClass[InfoClass].RequiredSizeQUERY - 1,
132                                 STATUS_INFO_LENGTH_MISMATCH);
133     }
134 }
135 
136 START_TEST(NtQueryInformationThread)
137 {
138     Test_ThreadBasicInformationClass();
139     Test_ThreadQueryAlignmentProbe();
140 }
141