[KMTESTS]
[reactos.git] / 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 <thfabba@gmx.de>
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 KeLeaveCriticalRegion();
75 CheckApcs(1, 0, FALSE, PASSIVE_LEVEL);
76 KeEnterCriticalRegion();
77 CheckApcs(0, 0, FALSE, PASSIVE_LEVEL);
78
79 KeLeaveGuardedRegion();
80 CheckApcs(0, 1, TRUE, PASSIVE_LEVEL);
81 KeEnterGuardedRegion();
82 CheckApcs(0, 0, FALSE, PASSIVE_LEVEL);
83
84 KeLeaveCriticalRegion();
85 CheckApcs(1, 0, FALSE, PASSIVE_LEVEL);
86 KeLeaveGuardedRegion();
87 CheckApcs(1, 1, TRUE, PASSIVE_LEVEL);
88 KeEnterCriticalRegion();
89 CheckApcs(0, 1, TRUE, PASSIVE_LEVEL);
90 KeEnterGuardedRegion();
91 CheckApcs(0, 0, FALSE, PASSIVE_LEVEL);
92
93 /* manually disable APCs */
94 Thread->KernelApcDisable = -1;
95 CheckApcs(-1, 0, FALSE, PASSIVE_LEVEL);
96 Thread->SpecialApcDisable = -1;
97 CheckApcs(-1, -1, TRUE, PASSIVE_LEVEL);
98 Thread->KernelApcDisable = 0;
99 CheckApcs(0, -1, TRUE, PASSIVE_LEVEL);
100 Thread->SpecialApcDisable = 0;
101 CheckApcs(0, 0, FALSE, PASSIVE_LEVEL);
102
103 /* raised irql - APC_LEVEL should disable APCs */
104 KeRaiseIrql(APC_LEVEL, &Irql);
105 CheckApcs(0, 0, TRUE, APC_LEVEL);
106 KeLowerIrql(Irql);
107 CheckApcs(0, 0, FALSE, PASSIVE_LEVEL);
108
109 /* KeAre*ApcsDisabled are documented to work up to DISPATCH_LEVEL... */
110 KeRaiseIrql(DISPATCH_LEVEL, &Irql);
111 CheckApcs(0, 0, TRUE, DISPATCH_LEVEL);
112 KeLowerIrql(Irql);
113 CheckApcs(0, 0, FALSE, PASSIVE_LEVEL);
114
115 /* ... but also work on higher levels! */
116 KeRaiseIrql(HIGH_LEVEL, &Irql);
117 CheckApcs(0, 0, TRUE, HIGH_LEVEL);
118 KeLowerIrql(Irql);
119 CheckApcs(0, 0, FALSE, PASSIVE_LEVEL);
120
121 /* now comes the crazy stuff */
122 KeRaiseIrql(HIGH_LEVEL, &Irql);
123 CheckApcs(0, 0, TRUE, HIGH_LEVEL);
124 KeEnterCriticalRegion();
125 CheckApcs(-1, 0, TRUE, HIGH_LEVEL);
126 KeLeaveCriticalRegion();
127 CheckApcs(0, 0, TRUE, HIGH_LEVEL);
128
129 KeEnterGuardedRegion();
130 CheckApcs(0, -1, TRUE, HIGH_LEVEL);
131 KeLeaveGuardedRegion();
132 CheckApcs(0, 0, TRUE, HIGH_LEVEL);
133 KeLowerIrql(Irql);
134 CheckApcs(0, 0, FALSE, PASSIVE_LEVEL);
135
136 KeRaiseIrql(HIGH_LEVEL, &Irql);
137 CheckApcs(0, 0, TRUE, HIGH_LEVEL);
138 KeEnterCriticalRegion();
139 CheckApcs(-1, 0, TRUE, HIGH_LEVEL);
140 KeEnterGuardedRegion();
141 CheckApcs(-1, -1, TRUE, HIGH_LEVEL);
142 KeLowerIrql(Irql);
143 CheckApcs(-1, -1, TRUE, PASSIVE_LEVEL);
144 KeLeaveCriticalRegion();
145 CheckApcs(0, -1, TRUE, PASSIVE_LEVEL);
146 KeLeaveGuardedRegion();
147 CheckApcs(0, 0, FALSE, PASSIVE_LEVEL);
148
149 KeEnterGuardedRegion();
150 CheckApcs(0, -1, TRUE, PASSIVE_LEVEL);
151 KeRaiseIrql(HIGH_LEVEL, &Irql);
152 CheckApcs(0, -1, TRUE, HIGH_LEVEL);
153 KeEnterCriticalRegion();
154 CheckApcs(-1, -1, TRUE, HIGH_LEVEL);
155 KeLeaveGuardedRegion();
156 CheckApcs(-1, 0, TRUE, HIGH_LEVEL);
157 KeLowerIrql(Irql);
158 CheckApcs(-1, 0, FALSE, PASSIVE_LEVEL);
159 KeLeaveCriticalRegion();
160 CheckApcs(0, 0, FALSE, PASSIVE_LEVEL);
161
162 KeEnterCriticalRegion();
163 CheckApcs(-1, 0, FALSE, PASSIVE_LEVEL);
164 KeRaiseIrql(HIGH_LEVEL, &Irql);
165 CheckApcs(-1, 0, TRUE, HIGH_LEVEL);
166 KeEnterGuardedRegion();
167 CheckApcs(-1, -1, TRUE, HIGH_LEVEL);
168 KeLeaveCriticalRegion();
169 CheckApcs(0, -1, TRUE, HIGH_LEVEL);
170 KeLowerIrql(Irql);
171 CheckApcs(0, -1, TRUE, PASSIVE_LEVEL);
172 KeLeaveGuardedRegion();
173 CheckApcs(0, 0, FALSE, PASSIVE_LEVEL);
174
175 KeEnterCriticalRegion();
176 CheckApcs(-1, 0, FALSE, PASSIVE_LEVEL);
177 KeRaiseIrql(HIGH_LEVEL, &Irql);
178 CheckApcs(-1, 0, TRUE, HIGH_LEVEL);
179 KeLeaveCriticalRegion();
180 CheckApcs(0, 0, TRUE, HIGH_LEVEL);
181 KeLowerIrql(Irql);
182 CheckApcs(0, 0, FALSE, PASSIVE_LEVEL);
183 }