[REACTOS]
[reactos.git] / rostests / kmtests / ntos_ke / KeApc.c
1 /*
2 * PROJECT: ReactOS kernel-mode tests
3 * LICENSE: GPLv2+ - See COPYING in the top level directory
4 * PURPOSE: Kernel-Mode Test Suite Asynchronous Procedure Call test
5 * PROGRAMMER: Thomas Faber <thomas.faber@reactos.org>
6 */
7
8 #include <kmt_test.h>
9
10 #define CheckApcs(KernelApcsDisabled, SpecialApcsDisabled, AllApcsDisabled, Irql) do \
11 { \
12 ok_eq_bool(KeAreApcsDisabled(), KernelApcsDisabled || SpecialApcsDisabled); \
13 ok_eq_int(Thread->KernelApcDisable, KernelApcsDisabled); \
14 ok_eq_bool(KeAreAllApcsDisabled(), AllApcsDisabled); \
15 ok_eq_int(Thread->SpecialApcDisable, SpecialApcsDisabled); \
16 ok_irql(Irql); \
17 } while (0)
18
19 START_TEST(KeApc)
20 {
21 KIRQL Irql;
22 PKTHREAD Thread = KeGetCurrentThread();
23
24 CheckApcs(0, 0, FALSE, PASSIVE_LEVEL);
25
26 /* critical region */
27 KeEnterCriticalRegion();
28 CheckApcs(-1, 0, FALSE, PASSIVE_LEVEL);
29 KeEnterCriticalRegion();
30 CheckApcs(-2, 0, FALSE, PASSIVE_LEVEL);
31 KeEnterCriticalRegion();
32 CheckApcs(-3, 0, FALSE, PASSIVE_LEVEL);
33 KeLeaveCriticalRegion();
34 CheckApcs(-2, 0, FALSE, PASSIVE_LEVEL);
35 KeLeaveCriticalRegion();
36 CheckApcs(-1, 0, FALSE, PASSIVE_LEVEL);
37 KeLeaveCriticalRegion();
38 CheckApcs(0, 0, FALSE, PASSIVE_LEVEL);
39
40 /* guarded region */
41 KeEnterGuardedRegion();
42 CheckApcs(0, -1, TRUE, PASSIVE_LEVEL);
43 KeEnterGuardedRegion();
44 CheckApcs(0, -2, TRUE, PASSIVE_LEVEL);
45 KeEnterGuardedRegion();
46 CheckApcs(0, -3, TRUE, PASSIVE_LEVEL);
47 KeLeaveGuardedRegion();
48 CheckApcs(0, -2, TRUE, PASSIVE_LEVEL);
49 KeLeaveGuardedRegion();
50 CheckApcs(0, -1, TRUE, PASSIVE_LEVEL);
51 KeLeaveGuardedRegion();
52 CheckApcs(0, 0, FALSE, PASSIVE_LEVEL);
53
54 /* mix them */
55 KeEnterGuardedRegion();
56 CheckApcs(0, -1, TRUE, PASSIVE_LEVEL);
57 KeEnterCriticalRegion();
58 CheckApcs(-1, -1, TRUE, PASSIVE_LEVEL);
59 KeLeaveCriticalRegion();
60 CheckApcs(0, -1, TRUE, PASSIVE_LEVEL);
61 KeLeaveGuardedRegion();
62 CheckApcs(0, 0, FALSE, PASSIVE_LEVEL);
63
64 KeEnterCriticalRegion();
65 CheckApcs(-1, 0, FALSE, PASSIVE_LEVEL);
66 KeEnterGuardedRegion();
67 CheckApcs(-1, -1, TRUE, PASSIVE_LEVEL);
68 KeLeaveGuardedRegion();
69 CheckApcs(-1, 0, FALSE, PASSIVE_LEVEL);
70 KeLeaveCriticalRegion();
71 CheckApcs(0, 0, FALSE, PASSIVE_LEVEL);
72
73 /* leave without entering */
74 if (!KmtIsCheckedBuild)
75 {
76 KeLeaveCriticalRegion();
77 CheckApcs(1, 0, FALSE, PASSIVE_LEVEL);
78 KeEnterCriticalRegion();
79 CheckApcs(0, 0, FALSE, PASSIVE_LEVEL);
80
81 KeLeaveGuardedRegion();
82 CheckApcs(0, 1, TRUE, PASSIVE_LEVEL);
83 KeEnterGuardedRegion();
84 CheckApcs(0, 0, FALSE, PASSIVE_LEVEL);
85
86 KeLeaveCriticalRegion();
87 CheckApcs(1, 0, FALSE, PASSIVE_LEVEL);
88 KeLeaveGuardedRegion();
89 CheckApcs(1, 1, TRUE, PASSIVE_LEVEL);
90 KeEnterCriticalRegion();
91 CheckApcs(0, 1, TRUE, PASSIVE_LEVEL);
92 KeEnterGuardedRegion();
93 CheckApcs(0, 0, FALSE, PASSIVE_LEVEL);
94 }
95
96 /* manually disable APCs */
97 Thread->KernelApcDisable = -1;
98 CheckApcs(-1, 0, FALSE, PASSIVE_LEVEL);
99 Thread->SpecialApcDisable = -1;
100 CheckApcs(-1, -1, TRUE, PASSIVE_LEVEL);
101 Thread->KernelApcDisable = 0;
102 CheckApcs(0, -1, TRUE, PASSIVE_LEVEL);
103 Thread->SpecialApcDisable = 0;
104 CheckApcs(0, 0, FALSE, PASSIVE_LEVEL);
105
106 /* raised irql - APC_LEVEL should disable APCs */
107 KeRaiseIrql(APC_LEVEL, &Irql);
108 CheckApcs(0, 0, TRUE, APC_LEVEL);
109 KeLowerIrql(Irql);
110 CheckApcs(0, 0, FALSE, PASSIVE_LEVEL);
111
112 /* KeAre*ApcsDisabled are documented to work up to DISPATCH_LEVEL... */
113 KeRaiseIrql(DISPATCH_LEVEL, &Irql);
114 CheckApcs(0, 0, TRUE, DISPATCH_LEVEL);
115 KeLowerIrql(Irql);
116 CheckApcs(0, 0, FALSE, PASSIVE_LEVEL);
117
118 /* ... but also work on higher levels! */
119 KeRaiseIrql(HIGH_LEVEL, &Irql);
120 CheckApcs(0, 0, TRUE, HIGH_LEVEL);
121 KeLowerIrql(Irql);
122 CheckApcs(0, 0, FALSE, PASSIVE_LEVEL);
123
124 /* now comes the crazy stuff */
125 KeRaiseIrql(HIGH_LEVEL, &Irql);
126 CheckApcs(0, 0, TRUE, HIGH_LEVEL);
127 KeEnterCriticalRegion();
128 CheckApcs(-1, 0, TRUE, HIGH_LEVEL);
129 KeLeaveCriticalRegion();
130 CheckApcs(0, 0, TRUE, HIGH_LEVEL);
131
132 /* Ke*GuardedRegion assert at > APC_LEVEL */
133 if (!KmtIsCheckedBuild)
134 {
135 KeEnterGuardedRegion();
136 CheckApcs(0, -1, TRUE, HIGH_LEVEL);
137 KeLeaveGuardedRegion();
138 }
139 CheckApcs(0, 0, TRUE, HIGH_LEVEL);
140 KeLowerIrql(Irql);
141 CheckApcs(0, 0, FALSE, PASSIVE_LEVEL);
142
143 if (!KmtIsCheckedBuild)
144 {
145 KeRaiseIrql(HIGH_LEVEL, &Irql);
146 CheckApcs(0, 0, TRUE, HIGH_LEVEL);
147 KeEnterCriticalRegion();
148 CheckApcs(-1, 0, TRUE, HIGH_LEVEL);
149 KeEnterGuardedRegion();
150 CheckApcs(-1, -1, TRUE, HIGH_LEVEL);
151 KeLowerIrql(Irql);
152 CheckApcs(-1, -1, TRUE, PASSIVE_LEVEL);
153 KeLeaveCriticalRegion();
154 CheckApcs(0, -1, TRUE, PASSIVE_LEVEL);
155 KeLeaveGuardedRegion();
156 CheckApcs(0, 0, FALSE, PASSIVE_LEVEL);
157
158 KeEnterGuardedRegion();
159 CheckApcs(0, -1, TRUE, PASSIVE_LEVEL);
160 KeRaiseIrql(HIGH_LEVEL, &Irql);
161 CheckApcs(0, -1, TRUE, HIGH_LEVEL);
162 KeEnterCriticalRegion();
163 CheckApcs(-1, -1, TRUE, HIGH_LEVEL);
164 KeLeaveGuardedRegion();
165 CheckApcs(-1, 0, TRUE, HIGH_LEVEL);
166 KeLowerIrql(Irql);
167 CheckApcs(-1, 0, FALSE, PASSIVE_LEVEL);
168 KeLeaveCriticalRegion();
169 CheckApcs(0, 0, FALSE, PASSIVE_LEVEL);
170
171 KeEnterCriticalRegion();
172 CheckApcs(-1, 0, FALSE, PASSIVE_LEVEL);
173 KeRaiseIrql(HIGH_LEVEL, &Irql);
174 CheckApcs(-1, 0, TRUE, HIGH_LEVEL);
175 KeEnterGuardedRegion();
176 CheckApcs(-1, -1, TRUE, HIGH_LEVEL);
177 KeLeaveCriticalRegion();
178 CheckApcs(0, -1, TRUE, HIGH_LEVEL);
179 KeLowerIrql(Irql);
180 CheckApcs(0, -1, TRUE, PASSIVE_LEVEL);
181 KeLeaveGuardedRegion();
182 CheckApcs(0, 0, FALSE, PASSIVE_LEVEL);
183 }
184
185 KeEnterCriticalRegion();
186 CheckApcs(-1, 0, FALSE, PASSIVE_LEVEL);
187 KeRaiseIrql(HIGH_LEVEL, &Irql);
188 CheckApcs(-1, 0, TRUE, HIGH_LEVEL);
189 KeLeaveCriticalRegion();
190 CheckApcs(0, 0, TRUE, HIGH_LEVEL);
191 KeLowerIrql(Irql);
192 CheckApcs(0, 0, FALSE, PASSIVE_LEVEL);
193 }