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 NtSetInformationThread 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_ThreadPriorityClass(void)
14 {
15     NTSTATUS Status;
16     KPRIORITY *Priority;
17 
18     Priority = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(KPRIORITY));
19     if (Priority == NULL)
20     {
21         skip("Failed to allocate memory for thread priority variable!\n");
22         return;
23     }
24 
25     /* Assign a priority */
26     *Priority = 11;
27 
28     /* Everything is NULL */
29     Status = NtSetInformationThread(NULL,
30                                     ThreadPriority,
31                                     NULL,
32                                     0);
33     ok_hex(Status, STATUS_INFO_LENGTH_MISMATCH);
34 
35     /* Give an invalid thread handle */
36     Status = NtSetInformationThread(NULL,
37                                     ThreadPriority,
38                                     Priority,
39                                     sizeof(KPRIORITY));
40     ok_hex(Status, STATUS_INVALID_HANDLE);
41 
42     /* Don't set any priority to the thread */
43     Status = NtSetInformationThread(GetCurrentThread(),
44                                     ThreadPriority,
45                                     NULL,
46                                     sizeof(KPRIORITY));
47     ok_hex(Status, STATUS_ACCESS_VIOLATION);
48 
49     /* The information length is incorrect */
50     Status = NtSetInformationThread(GetCurrentThread(),
51                                     ThreadPriority,
52                                     Priority,
53                                     0);
54     ok_hex(Status, STATUS_INFO_LENGTH_MISMATCH);
55 
56     /* The buffer is misaligned and information length is incorrect */
57     Status = NtSetInformationThread(GetCurrentThread(),
58                                     ThreadPriority,
59                                     (PVOID)1,
60                                     0);
61     ok_hex(Status, STATUS_INFO_LENGTH_MISMATCH);
62 
63     /* The buffer is misaligned */
64     Status = NtSetInformationThread(GetCurrentThread(),
65                                     ThreadPriority,
66                                     (PVOID)1,
67                                     sizeof(KPRIORITY));
68     ok_hex(Status, STATUS_DATATYPE_MISALIGNMENT);
69 
70     /* The buffer is misaligned -- try with an alignment size of 2 */
71     Status = NtSetInformationThread(GetCurrentThread(),
72                                     ThreadPriority,
73                                     (PVOID)2,
74                                     sizeof(KPRIORITY));
75     ok_hex(Status, STATUS_DATATYPE_MISALIGNMENT);
76 
77     /* Set the priority to the current thread */
78     Status = NtSetInformationThread(GetCurrentThread(),
79                                     ThreadPriority,
80                                     Priority,
81                                     sizeof(KPRIORITY));
82     ok_hex(Status, STATUS_SUCCESS);
83 
84     /*
85      * Set the priority as LOW_REALTIME_PRIORITY,
86      * we don't have privileges to do so.
87     */
88     *Priority = LOW_REALTIME_PRIORITY;
89     Status = NtSetInformationThread(GetCurrentThread(),
90                                     ThreadPriority,
91                                     Priority,
92                                     sizeof(KPRIORITY));
93     ok_hex(Status, STATUS_PRIVILEGE_NOT_HELD);
94 
95     HeapFree(GetProcessHeap(), 0, Priority);
96 }
97 
98 static
99 void
100 Test_ThreadSetAlignmentProbe(void)
101 {
102     ULONG InfoClass;
103 
104     /* Iterate over the process info classes and begin the tests */
105     for (InfoClass = 0; InfoClass < _countof(PsThreadInfoClass); InfoClass++)
106     {
107         /* The buffer is misaligned */
108         QuerySetThreadValidator(SET,
109                                 InfoClass,
110                                 (PVOID)(ULONG_PTR)1,
111                                 PsThreadInfoClass[InfoClass].RequiredSizeSET,
112                                 STATUS_DATATYPE_MISALIGNMENT);
113 
114         /* We set an invalid buffer address */
115         QuerySetThreadValidator(SET,
116                                 InfoClass,
117                                 (PVOID)(ULONG_PTR)PsThreadInfoClass[InfoClass].AlignmentSET,
118                                 PsThreadInfoClass[InfoClass].RequiredSizeSET,
119                                 STATUS_ACCESS_VIOLATION);
120 
121         /* The information length is wrong */
122         QuerySetThreadValidator(SET,
123                                 InfoClass,
124                                 (PVOID)(ULONG_PTR)PsThreadInfoClass[InfoClass].AlignmentSET,
125                                 PsThreadInfoClass[InfoClass].RequiredSizeSET - 1,
126                                 STATUS_INFO_LENGTH_MISMATCH);
127     }
128 }
129 
130 START_TEST(NtSetInformationThread)
131 {
132     Test_ThreadPriorityClass();
133     Test_ThreadSetAlignmentProbe();
134 }
135