ReactOS 0.4.16-dev-91-g764881a
KeApc.c
Go to the documentation of this file.
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
10static
14(NTAPI
15*pKeAreAllApcsDisabled)(VOID);
16
17static
18_Acquires_lock_(_Global_critical_region_)
20VOID
21(NTAPI
22*pKeEnterGuardedRegion)(VOID);
23
24static
25_Releases_lock_(_Global_critical_region_)
27VOID
28(NTAPI
29*pKeLeaveGuardedRegion)(VOID);
30
31#define CheckApcs(KernelApcsDisabled, SpecialApcsDisabled, AllApcsDisabled, Irql) do \
32{ \
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); \
38 ok_irql(Irql); \
39} while (0)
40
41START_TEST(KeApc)
42{
43 KIRQL Irql;
45
46 pKeAreAllApcsDisabled = KmtGetSystemRoutineAddress(L"KeAreAllApcsDisabled");
47 pKeEnterGuardedRegion = KmtGetSystemRoutineAddress(L"KeEnterGuardedRegion");
48 pKeLeaveGuardedRegion = KmtGetSystemRoutineAddress(L"KeLeaveGuardedRegion");
49
50 if (skip(pKeAreAllApcsDisabled != NULL, "KeAreAllApcsDisabled unavailable\n"))
51 {
52 /* We can live without this function here */
53 }
54
56
58
59 /* critical region */
72
73 /* guarded region */
74 if (!skip(pKeEnterGuardedRegion &&
75 pKeLeaveGuardedRegion, "Guarded regions not available\n"))
76 {
77 pKeEnterGuardedRegion();
79 pKeEnterGuardedRegion();
81 pKeEnterGuardedRegion();
83 pKeLeaveGuardedRegion();
85 pKeLeaveGuardedRegion();
87 pKeLeaveGuardedRegion();
89
90 /* mix them */
91 pKeEnterGuardedRegion();
97 pKeLeaveGuardedRegion();
99
102 pKeEnterGuardedRegion();
103 CheckApcs(-1, -1, TRUE, PASSIVE_LEVEL);
104 pKeLeaveGuardedRegion();
108 }
109
110 /* leave without entering */
112 {
117
118 if (!skip(pKeEnterGuardedRegion &&
119 pKeLeaveGuardedRegion, "Guarded regions not available\n"))
120 {
121 pKeLeaveGuardedRegion();
123 pKeEnterGuardedRegion();
125
128 pKeLeaveGuardedRegion();
132 pKeEnterGuardedRegion();
134 }
135 }
136
137 /* manually disable APCs */
138 Thread->KernelApcDisable = -1;
140 Thread->SpecialApcDisable = -1;
141 CheckApcs(-1, -1, TRUE, PASSIVE_LEVEL);
142 Thread->KernelApcDisable = 0;
144 Thread->SpecialApcDisable = 0;
146
147 /* raised irql - APC_LEVEL should disable APCs */
149 CheckApcs(0, 0, TRUE, APC_LEVEL);
152
153 /* KeAre*ApcsDisabled are documented to work up to DISPATCH_LEVEL... */
158
159 /* ... but also work on higher levels! */
161 CheckApcs(0, 0, TRUE, HIGH_LEVEL);
164
165 /* now comes the crazy stuff */
167 CheckApcs(0, 0, TRUE, HIGH_LEVEL);
169 CheckApcs(-1, 0, TRUE, HIGH_LEVEL);
171 CheckApcs(0, 0, TRUE, HIGH_LEVEL);
172
173 /* Ke*GuardedRegion assert at > APC_LEVEL */
174 if (!KmtIsCheckedBuild &&
175 !skip(pKeEnterGuardedRegion &&
176 pKeLeaveGuardedRegion, "Guarded regions not available\n"))
177 {
178 pKeEnterGuardedRegion();
179 CheckApcs(0, -1, TRUE, HIGH_LEVEL);
180 pKeLeaveGuardedRegion();
181 }
182 CheckApcs(0, 0, TRUE, HIGH_LEVEL);
185
186 if (!KmtIsCheckedBuild &&
187 !skip(pKeEnterGuardedRegion &&
188 pKeLeaveGuardedRegion, "Guarded regions not available\n"))
189 {
191 CheckApcs(0, 0, TRUE, HIGH_LEVEL);
193 CheckApcs(-1, 0, TRUE, HIGH_LEVEL);
194 pKeEnterGuardedRegion();
195 CheckApcs(-1, -1, TRUE, HIGH_LEVEL);
197 CheckApcs(-1, -1, TRUE, PASSIVE_LEVEL);
200 pKeLeaveGuardedRegion();
202
203 pKeEnterGuardedRegion();
206 CheckApcs(0, -1, TRUE, HIGH_LEVEL);
208 CheckApcs(-1, -1, TRUE, HIGH_LEVEL);
209 pKeLeaveGuardedRegion();
210 CheckApcs(-1, 0, TRUE, HIGH_LEVEL);
215
219 CheckApcs(-1, 0, TRUE, HIGH_LEVEL);
220 pKeEnterGuardedRegion();
221 CheckApcs(-1, -1, TRUE, HIGH_LEVEL);
223 CheckApcs(0, -1, TRUE, HIGH_LEVEL);
226 pKeLeaveGuardedRegion();
228 }
229
233 CheckApcs(-1, 0, TRUE, HIGH_LEVEL);
235 CheckApcs(0, 0, TRUE, HIGH_LEVEL);
238}
#define CheckApcs(KernelApcsDisabled, SpecialApcsDisabled, AllApcsDisabled, Irql)
#define VOID
Definition: acefi.h:82
#define skip(...)
Definition: atltest.h:64
#define START_TEST(x)
Definition: atltest.h:75
#define _Acquires_lock_(lock)
#define _Releases_lock_(lock)
_Out_ PKIRQL Irql
Definition: csq.h:179
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define _IRQL_requires_min_(irql)
Definition: driverspecs.h:231
#define _IRQL_requires_max_(irql)
Definition: driverspecs.h:230
#define PASSIVE_LEVEL
Definition: env_spec_w32.h:693
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define KeRaiseIrql(irql, oldIrql)
Definition: env_spec_w32.h:597
#define HIGH_LEVEL
Definition: env_spec_w32.h:703
#define APC_LEVEL
Definition: env_spec_w32.h:695
#define KeLowerIrql(oldIrql)
Definition: env_spec_w32.h:602
#define DISPATCH_LEVEL
Definition: env_spec_w32.h:696
_In_opt_ PFILE_OBJECT _In_opt_ PETHREAD Thread
Definition: fltkernel.h:2653
#define KeGetCurrentThread
Definition: hal.h:55
#define KeLeaveCriticalRegion()
Definition: ke_x.h:119
#define KeEnterCriticalRegion()
Definition: ke_x.h:88
PVOID KmtGetSystemRoutineAddress(IN PCWSTR RoutineName)
BOOLEAN KmtIsCheckedBuild
#define L(x)
Definition: ntvdm.h:50
#define BOOLEAN
Definition: pedump.c:73
#define NTAPI
Definition: typedefs.h:36