ReactOS  0.4.13-dev-479-gec9c8fd
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 
10 static
13 BOOLEAN
14 (NTAPI
15 *pKeAreAllApcsDisabled)(VOID);
16 
17 static
18 _Acquires_lock_(_Global_critical_region_)
20 VOID
21 (NTAPI
22 *pKeEnterGuardedRegion)(VOID);
23 
24 static
25 _Releases_lock_(_Global_critical_region_)
27 VOID
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 
41 START_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 */
61  CheckApcs(-1, 0, FALSE, PASSIVE_LEVEL);
63  CheckApcs(-2, 0, FALSE, PASSIVE_LEVEL);
65  CheckApcs(-3, 0, FALSE, PASSIVE_LEVEL);
67  CheckApcs(-2, 0, FALSE, PASSIVE_LEVEL);
69  CheckApcs(-1, 0, FALSE, PASSIVE_LEVEL);
72 
73  /* guarded region */
74  if (!skip(pKeEnterGuardedRegion &&
75  pKeLeaveGuardedRegion, "Guarded regions not available\n"))
76  {
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();
89 
90  /* mix them */
91  pKeEnterGuardedRegion();
92  CheckApcs(0, -1, TRUE, PASSIVE_LEVEL);
94  CheckApcs(-1, -1, TRUE, PASSIVE_LEVEL);
96  CheckApcs(0, -1, TRUE, PASSIVE_LEVEL);
97  pKeLeaveGuardedRegion();
99 
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);
107  CheckApcs(0, 0, FALSE, PASSIVE_LEVEL);
108  }
109 
110  /* leave without entering */
111  if (!KmtIsCheckedBuild)
112  {
114  CheckApcs(1, 0, FALSE, PASSIVE_LEVEL);
116  CheckApcs(0, 0, FALSE, PASSIVE_LEVEL);
117 
118  if (!skip(pKeEnterGuardedRegion &&
119  pKeLeaveGuardedRegion, "Guarded regions not available\n"))
120  {
121  pKeLeaveGuardedRegion();
122  CheckApcs(0, 1, TRUE, PASSIVE_LEVEL);
123  pKeEnterGuardedRegion();
124  CheckApcs(0, 0, FALSE, PASSIVE_LEVEL);
125 
127  CheckApcs(1, 0, FALSE, PASSIVE_LEVEL);
128  pKeLeaveGuardedRegion();
129  CheckApcs(1, 1, TRUE, PASSIVE_LEVEL);
131  CheckApcs(0, 1, TRUE, PASSIVE_LEVEL);
132  pKeEnterGuardedRegion();
133  CheckApcs(0, 0, FALSE, PASSIVE_LEVEL);
134  }
135  }
136 
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);
146 
147  /* raised irql - APC_LEVEL should disable APCs */
149  CheckApcs(0, 0, TRUE, APC_LEVEL);
150  KeLowerIrql(Irql);
151  CheckApcs(0, 0, FALSE, PASSIVE_LEVEL);
152 
153  /* KeAre*ApcsDisabled are documented to work up to DISPATCH_LEVEL... */
155  CheckApcs(0, 0, TRUE, DISPATCH_LEVEL);
156  KeLowerIrql(Irql);
157  CheckApcs(0, 0, FALSE, PASSIVE_LEVEL);
158 
159  /* ... but also work on higher levels! */
161  CheckApcs(0, 0, TRUE, HIGH_LEVEL);
162  KeLowerIrql(Irql);
163  CheckApcs(0, 0, FALSE, PASSIVE_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);
183  KeLowerIrql(Irql);
184  CheckApcs(0, 0, FALSE, PASSIVE_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);
196  KeLowerIrql(Irql);
197  CheckApcs(-1, -1, TRUE, PASSIVE_LEVEL);
199  CheckApcs(0, -1, TRUE, PASSIVE_LEVEL);
200  pKeLeaveGuardedRegion();
201  CheckApcs(0, 0, FALSE, PASSIVE_LEVEL);
202 
203  pKeEnterGuardedRegion();
204  CheckApcs(0, -1, TRUE, PASSIVE_LEVEL);
206  CheckApcs(0, -1, TRUE, HIGH_LEVEL);
208  CheckApcs(-1, -1, TRUE, HIGH_LEVEL);
209  pKeLeaveGuardedRegion();
210  CheckApcs(-1, 0, TRUE, HIGH_LEVEL);
211  KeLowerIrql(Irql);
212  CheckApcs(-1, 0, FALSE, PASSIVE_LEVEL);
214  CheckApcs(0, 0, FALSE, PASSIVE_LEVEL);
215 
217  CheckApcs(-1, 0, FALSE, PASSIVE_LEVEL);
219  CheckApcs(-1, 0, TRUE, HIGH_LEVEL);
220  pKeEnterGuardedRegion();
221  CheckApcs(-1, -1, TRUE, HIGH_LEVEL);
223  CheckApcs(0, -1, TRUE, HIGH_LEVEL);
224  KeLowerIrql(Irql);
225  CheckApcs(0, -1, TRUE, PASSIVE_LEVEL);
226  pKeLeaveGuardedRegion();
227  CheckApcs(0, 0, FALSE, PASSIVE_LEVEL);
228  }
229 
231  CheckApcs(-1, 0, FALSE, PASSIVE_LEVEL);
233  CheckApcs(-1, 0, TRUE, HIGH_LEVEL);
235  CheckApcs(0, 0, TRUE, HIGH_LEVEL);
236  KeLowerIrql(Irql);
237  CheckApcs(0, 0, FALSE, PASSIVE_LEVEL);
238 }
#define KeRaiseIrql(irql, oldIrql)
Definition: env_spec_w32.h:597
#define TRUE
Definition: types.h:120
#define KeLowerIrql(oldIrql)
Definition: env_spec_w32.h:602
#define _IRQL_requires_max_(irql)
Definition: no_sal2.h:650
#define CheckApcs(KernelApcsDisabled, SpecialApcsDisabled, AllApcsDisabled, Irql)
_Out_ PKIRQL Irql
Definition: csq.h:179
UCHAR KIRQL
Definition: env_spec_w32.h:591
BOOLEAN KmtIsCheckedBuild
#define _Acquires_lock_(lock)
Definition: no_sal2.h:677
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
#define _Releases_lock_(a)
Definition: btrfs_drv.h:181
smooth NULL
Definition: ftsmooth.c:416
_In_opt_ PFILE_OBJECT _In_opt_ PETHREAD Thread
Definition: fltkernel.h:2653
PVOID KmtGetSystemRoutineAddress(IN PCWSTR RoutineName)
static const WCHAR L[]
Definition: oid.c:1250
#define VOID
Definition: acefi.h:82
#define KeEnterCriticalRegion()
Definition: ke_x.h:83
#define PASSIVE_LEVEL
Definition: env_spec_w32.h:693
#define DISPATCH_LEVEL
Definition: env_spec_w32.h:696
static _IRQL_requires_min_(PASSIVE_LEVEL)
Definition: KeApc.c:11
#define HIGH_LEVEL
Definition: env_spec_w32.h:703
#define KeLeaveCriticalRegion()
Definition: ke_x.h:114
#define START_TEST(x)
#define skip(...)
#define BOOLEAN
Definition: pedump.c:73
#define KeGetCurrentThread
Definition: hal.h:44
#define APC_LEVEL
Definition: env_spec_w32.h:695