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>
11 _IRQL_requires_min_(PASSIVE_LEVEL
)
12 _IRQL_requires_max_(DISPATCH_LEVEL
)
15 *pKeAreAllApcsDisabled
)(VOID
);
18 _Acquires_lock_(_Global_critical_region_
)
19 _IRQL_requires_max_(APC_LEVEL
)
22 *pKeEnterGuardedRegion
)(VOID
);
25 _Releases_lock_(_Global_critical_region_
)
26 _IRQL_requires_max_(APC_LEVEL
)
29 *pKeLeaveGuardedRegion
)(VOID
);
31 #define CheckApcs(KernelApcsDisabled, SpecialApcsDisabled, AllApcsDisabled, Irql) do \
33 ok_eq_bool(KeAreApcsDisabled(), KernelApcsDisabled || SpecialApcsDisabled); \
34 ok_eq_int(Thread->KernelApcDisable, KernelApcsDisabled); \
35 if (pKeAreAllApcsDisabled) \
36 ok_eq_bool(pKeAreAllApcsDisabled(), AllApcsDisabled); \
37 ok_eq_int(Thread->SpecialApcDisable, SpecialApcsDisabled); \
46 pKeAreAllApcsDisabled
= KmtGetSystemRoutineAddress(L
"KeAreAllApcsDisabled");
47 pKeEnterGuardedRegion
= KmtGetSystemRoutineAddress(L
"KeEnterGuardedRegion");
48 pKeLeaveGuardedRegion
= KmtGetSystemRoutineAddress(L
"KeLeaveGuardedRegion");
50 if (skip(pKeAreAllApcsDisabled
!= NULL
, "KeAreAllApcsDisabled unavailable\n"))
52 /* We can live without this function here */
55 Thread
= KeGetCurrentThread();
57 CheckApcs(0, 0, FALSE
, PASSIVE_LEVEL
);
60 KeEnterCriticalRegion();
61 CheckApcs(-1, 0, FALSE
, PASSIVE_LEVEL
);
62 KeEnterCriticalRegion();
63 CheckApcs(-2, 0, FALSE
, PASSIVE_LEVEL
);
64 KeEnterCriticalRegion();
65 CheckApcs(-3, 0, FALSE
, PASSIVE_LEVEL
);
66 KeLeaveCriticalRegion();
67 CheckApcs(-2, 0, FALSE
, PASSIVE_LEVEL
);
68 KeLeaveCriticalRegion();
69 CheckApcs(-1, 0, FALSE
, PASSIVE_LEVEL
);
70 KeLeaveCriticalRegion();
71 CheckApcs(0, 0, FALSE
, PASSIVE_LEVEL
);
74 if (!skip(pKeEnterGuardedRegion
&&
75 pKeLeaveGuardedRegion
, "Guarded regions not available\n"))
77 pKeEnterGuardedRegion();
78 CheckApcs(0, -1, TRUE
, PASSIVE_LEVEL
);
79 pKeEnterGuardedRegion();
80 CheckApcs(0, -2, TRUE
, PASSIVE_LEVEL
);
81 pKeEnterGuardedRegion();
82 CheckApcs(0, -3, TRUE
, PASSIVE_LEVEL
);
83 pKeLeaveGuardedRegion();
84 CheckApcs(0, -2, TRUE
, PASSIVE_LEVEL
);
85 pKeLeaveGuardedRegion();
86 CheckApcs(0, -1, TRUE
, PASSIVE_LEVEL
);
87 pKeLeaveGuardedRegion();
88 CheckApcs(0, 0, FALSE
, PASSIVE_LEVEL
);
91 pKeEnterGuardedRegion();
92 CheckApcs(0, -1, TRUE
, PASSIVE_LEVEL
);
93 KeEnterCriticalRegion();
94 CheckApcs(-1, -1, TRUE
, PASSIVE_LEVEL
);
95 KeLeaveCriticalRegion();
96 CheckApcs(0, -1, TRUE
, PASSIVE_LEVEL
);
97 pKeLeaveGuardedRegion();
98 CheckApcs(0, 0, FALSE
, PASSIVE_LEVEL
);
100 KeEnterCriticalRegion();
101 CheckApcs(-1, 0, FALSE
, PASSIVE_LEVEL
);
102 pKeEnterGuardedRegion();
103 CheckApcs(-1, -1, TRUE
, PASSIVE_LEVEL
);
104 pKeLeaveGuardedRegion();
105 CheckApcs(-1, 0, FALSE
, PASSIVE_LEVEL
);
106 KeLeaveCriticalRegion();
107 CheckApcs(0, 0, FALSE
, PASSIVE_LEVEL
);
110 /* leave without entering */
111 if (!KmtIsCheckedBuild
)
113 KeLeaveCriticalRegion();
114 CheckApcs(1, 0, FALSE
, PASSIVE_LEVEL
);
115 KeEnterCriticalRegion();
116 CheckApcs(0, 0, FALSE
, PASSIVE_LEVEL
);
118 if (!skip(pKeEnterGuardedRegion
&&
119 pKeLeaveGuardedRegion
, "Guarded regions not available\n"))
121 pKeLeaveGuardedRegion();
122 CheckApcs(0, 1, TRUE
, PASSIVE_LEVEL
);
123 pKeEnterGuardedRegion();
124 CheckApcs(0, 0, FALSE
, PASSIVE_LEVEL
);
126 KeLeaveCriticalRegion();
127 CheckApcs(1, 0, FALSE
, PASSIVE_LEVEL
);
128 pKeLeaveGuardedRegion();
129 CheckApcs(1, 1, TRUE
, PASSIVE_LEVEL
);
130 KeEnterCriticalRegion();
131 CheckApcs(0, 1, TRUE
, PASSIVE_LEVEL
);
132 pKeEnterGuardedRegion();
133 CheckApcs(0, 0, FALSE
, PASSIVE_LEVEL
);
137 /* manually disable APCs */
138 Thread
->KernelApcDisable
= -1;
139 CheckApcs(-1, 0, FALSE
, PASSIVE_LEVEL
);
140 Thread
->SpecialApcDisable
= -1;
141 CheckApcs(-1, -1, TRUE
, PASSIVE_LEVEL
);
142 Thread
->KernelApcDisable
= 0;
143 CheckApcs(0, -1, TRUE
, PASSIVE_LEVEL
);
144 Thread
->SpecialApcDisable
= 0;
145 CheckApcs(0, 0, FALSE
, PASSIVE_LEVEL
);
147 /* raised irql - APC_LEVEL should disable APCs */
148 KeRaiseIrql(APC_LEVEL
, &Irql
);
149 CheckApcs(0, 0, TRUE
, APC_LEVEL
);
151 CheckApcs(0, 0, FALSE
, PASSIVE_LEVEL
);
153 /* KeAre*ApcsDisabled are documented to work up to DISPATCH_LEVEL... */
154 KeRaiseIrql(DISPATCH_LEVEL
, &Irql
);
155 CheckApcs(0, 0, TRUE
, DISPATCH_LEVEL
);
157 CheckApcs(0, 0, FALSE
, PASSIVE_LEVEL
);
159 /* ... but also work on higher levels! */
160 KeRaiseIrql(HIGH_LEVEL
, &Irql
);
161 CheckApcs(0, 0, TRUE
, HIGH_LEVEL
);
163 CheckApcs(0, 0, FALSE
, PASSIVE_LEVEL
);
165 /* now comes the crazy stuff */
166 KeRaiseIrql(HIGH_LEVEL
, &Irql
);
167 CheckApcs(0, 0, TRUE
, HIGH_LEVEL
);
168 KeEnterCriticalRegion();
169 CheckApcs(-1, 0, TRUE
, HIGH_LEVEL
);
170 KeLeaveCriticalRegion();
171 CheckApcs(0, 0, TRUE
, HIGH_LEVEL
);
173 /* Ke*GuardedRegion assert at > APC_LEVEL */
174 if (!KmtIsCheckedBuild
&&
175 !skip(pKeEnterGuardedRegion
&&
176 pKeLeaveGuardedRegion
, "Guarded regions not available\n"))
178 pKeEnterGuardedRegion();
179 CheckApcs(0, -1, TRUE
, HIGH_LEVEL
);
180 pKeLeaveGuardedRegion();
182 CheckApcs(0, 0, TRUE
, HIGH_LEVEL
);
184 CheckApcs(0, 0, FALSE
, PASSIVE_LEVEL
);
186 if (!KmtIsCheckedBuild
&&
187 !skip(pKeEnterGuardedRegion
&&
188 pKeLeaveGuardedRegion
, "Guarded regions not available\n"))
190 KeRaiseIrql(HIGH_LEVEL
, &Irql
);
191 CheckApcs(0, 0, TRUE
, HIGH_LEVEL
);
192 KeEnterCriticalRegion();
193 CheckApcs(-1, 0, TRUE
, HIGH_LEVEL
);
194 pKeEnterGuardedRegion();
195 CheckApcs(-1, -1, TRUE
, HIGH_LEVEL
);
197 CheckApcs(-1, -1, TRUE
, PASSIVE_LEVEL
);
198 KeLeaveCriticalRegion();
199 CheckApcs(0, -1, TRUE
, PASSIVE_LEVEL
);
200 pKeLeaveGuardedRegion();
201 CheckApcs(0, 0, FALSE
, PASSIVE_LEVEL
);
203 pKeEnterGuardedRegion();
204 CheckApcs(0, -1, TRUE
, PASSIVE_LEVEL
);
205 KeRaiseIrql(HIGH_LEVEL
, &Irql
);
206 CheckApcs(0, -1, TRUE
, HIGH_LEVEL
);
207 KeEnterCriticalRegion();
208 CheckApcs(-1, -1, TRUE
, HIGH_LEVEL
);
209 pKeLeaveGuardedRegion();
210 CheckApcs(-1, 0, TRUE
, HIGH_LEVEL
);
212 CheckApcs(-1, 0, FALSE
, PASSIVE_LEVEL
);
213 KeLeaveCriticalRegion();
214 CheckApcs(0, 0, FALSE
, PASSIVE_LEVEL
);
216 KeEnterCriticalRegion();
217 CheckApcs(-1, 0, FALSE
, PASSIVE_LEVEL
);
218 KeRaiseIrql(HIGH_LEVEL
, &Irql
);
219 CheckApcs(-1, 0, TRUE
, HIGH_LEVEL
);
220 pKeEnterGuardedRegion();
221 CheckApcs(-1, -1, TRUE
, HIGH_LEVEL
);
222 KeLeaveCriticalRegion();
223 CheckApcs(0, -1, TRUE
, HIGH_LEVEL
);
225 CheckApcs(0, -1, TRUE
, PASSIVE_LEVEL
);
226 pKeLeaveGuardedRegion();
227 CheckApcs(0, 0, FALSE
, PASSIVE_LEVEL
);
230 KeEnterCriticalRegion();
231 CheckApcs(-1, 0, FALSE
, PASSIVE_LEVEL
);
232 KeRaiseIrql(HIGH_LEVEL
, &Irql
);
233 CheckApcs(-1, 0, TRUE
, HIGH_LEVEL
);
234 KeLeaveCriticalRegion();
235 CheckApcs(0, 0, TRUE
, HIGH_LEVEL
);
237 CheckApcs(0, 0, FALSE
, PASSIVE_LEVEL
);