#include <kmt_test.h>
+static
+_IRQL_requires_min_(PASSIVE_LEVEL)
+_IRQL_requires_max_(DISPATCH_LEVEL)
+BOOLEAN
+(NTAPI
+*pKeAreAllApcsDisabled)(VOID);
+
+static
+_Acquires_lock_(_Global_critical_region_)
+_IRQL_requires_max_(APC_LEVEL)
+VOID
+(NTAPI
+*pKeEnterGuardedRegion)(VOID);
+
+static
+_Releases_lock_(_Global_critical_region_)
+_IRQL_requires_max_(APC_LEVEL)
+VOID
+(NTAPI
+*pKeLeaveGuardedRegion)(VOID);
+
#define CheckApcs(KernelApcsDisabled, SpecialApcsDisabled, AllApcsDisabled, Irql) do \
{ \
ok_eq_bool(KeAreApcsDisabled(), KernelApcsDisabled || SpecialApcsDisabled); \
ok_eq_int(Thread->KernelApcDisable, KernelApcsDisabled); \
- ok_eq_bool(KeAreAllApcsDisabled(), AllApcsDisabled); \
+ if (pKeAreAllApcsDisabled) \
+ ok_eq_bool(pKeAreAllApcsDisabled(), AllApcsDisabled); \
ok_eq_int(Thread->SpecialApcDisable, SpecialApcsDisabled); \
ok_irql(Irql); \
} while (0)
START_TEST(KeApc)
{
KIRQL Irql;
- PKTHREAD Thread = KeGetCurrentThread();
+ PKTHREAD Thread;
+
+ pKeAreAllApcsDisabled = KmtGetSystemRoutineAddress(L"KeAreAllApcsDisabled");
+ pKeEnterGuardedRegion = KmtGetSystemRoutineAddress(L"KeEnterGuardedRegion");
+ pKeLeaveGuardedRegion = KmtGetSystemRoutineAddress(L"KeLeaveGuardedRegion");
+
+ if (skip(pKeAreAllApcsDisabled != NULL, "KeAreAllApcsDisabled unavailable\n"))
+ {
+ /* We can live without this function here */
+ }
+
+ Thread = KeGetCurrentThread();
CheckApcs(0, 0, FALSE, PASSIVE_LEVEL);
CheckApcs(0, 0, FALSE, PASSIVE_LEVEL);
/* guarded region */
- KeEnterGuardedRegion();
- CheckApcs(0, -1, TRUE, PASSIVE_LEVEL);
- KeEnterGuardedRegion();
- CheckApcs(0, -2, TRUE, PASSIVE_LEVEL);
- KeEnterGuardedRegion();
- CheckApcs(0, -3, TRUE, PASSIVE_LEVEL);
- KeLeaveGuardedRegion();
- CheckApcs(0, -2, TRUE, PASSIVE_LEVEL);
- KeLeaveGuardedRegion();
- CheckApcs(0, -1, TRUE, PASSIVE_LEVEL);
- KeLeaveGuardedRegion();
- CheckApcs(0, 0, FALSE, PASSIVE_LEVEL);
+ if (!skip(pKeEnterGuardedRegion &&
+ pKeLeaveGuardedRegion, "Guarded regions not available\n"))
+ {
+ pKeEnterGuardedRegion();
+ CheckApcs(0, -1, TRUE, PASSIVE_LEVEL);
+ pKeEnterGuardedRegion();
+ CheckApcs(0, -2, TRUE, PASSIVE_LEVEL);
+ pKeEnterGuardedRegion();
+ CheckApcs(0, -3, TRUE, PASSIVE_LEVEL);
+ pKeLeaveGuardedRegion();
+ CheckApcs(0, -2, TRUE, PASSIVE_LEVEL);
+ pKeLeaveGuardedRegion();
+ CheckApcs(0, -1, TRUE, PASSIVE_LEVEL);
+ pKeLeaveGuardedRegion();
+ CheckApcs(0, 0, FALSE, PASSIVE_LEVEL);
- /* mix them */
- KeEnterGuardedRegion();
- CheckApcs(0, -1, TRUE, PASSIVE_LEVEL);
- KeEnterCriticalRegion();
- CheckApcs(-1, -1, TRUE, PASSIVE_LEVEL);
- KeLeaveCriticalRegion();
- CheckApcs(0, -1, TRUE, PASSIVE_LEVEL);
- KeLeaveGuardedRegion();
- CheckApcs(0, 0, FALSE, PASSIVE_LEVEL);
+ /* mix them */
+ pKeEnterGuardedRegion();
+ CheckApcs(0, -1, TRUE, PASSIVE_LEVEL);
+ KeEnterCriticalRegion();
+ CheckApcs(-1, -1, TRUE, PASSIVE_LEVEL);
+ KeLeaveCriticalRegion();
+ CheckApcs(0, -1, TRUE, PASSIVE_LEVEL);
+ pKeLeaveGuardedRegion();
+ CheckApcs(0, 0, FALSE, PASSIVE_LEVEL);
- KeEnterCriticalRegion();
- CheckApcs(-1, 0, FALSE, PASSIVE_LEVEL);
- KeEnterGuardedRegion();
- CheckApcs(-1, -1, TRUE, PASSIVE_LEVEL);
- KeLeaveGuardedRegion();
- CheckApcs(-1, 0, FALSE, PASSIVE_LEVEL);
- KeLeaveCriticalRegion();
- CheckApcs(0, 0, FALSE, PASSIVE_LEVEL);
+ KeEnterCriticalRegion();
+ CheckApcs(-1, 0, FALSE, PASSIVE_LEVEL);
+ pKeEnterGuardedRegion();
+ CheckApcs(-1, -1, TRUE, PASSIVE_LEVEL);
+ pKeLeaveGuardedRegion();
+ CheckApcs(-1, 0, FALSE, PASSIVE_LEVEL);
+ KeLeaveCriticalRegion();
+ CheckApcs(0, 0, FALSE, PASSIVE_LEVEL);
+ }
/* leave without entering */
if (!KmtIsCheckedBuild)
KeEnterCriticalRegion();
CheckApcs(0, 0, FALSE, PASSIVE_LEVEL);
- KeLeaveGuardedRegion();
- CheckApcs(0, 1, TRUE, PASSIVE_LEVEL);
- KeEnterGuardedRegion();
- CheckApcs(0, 0, FALSE, PASSIVE_LEVEL);
-
- KeLeaveCriticalRegion();
- CheckApcs(1, 0, FALSE, PASSIVE_LEVEL);
- KeLeaveGuardedRegion();
- CheckApcs(1, 1, TRUE, PASSIVE_LEVEL);
- KeEnterCriticalRegion();
- CheckApcs(0, 1, TRUE, PASSIVE_LEVEL);
- KeEnterGuardedRegion();
- CheckApcs(0, 0, FALSE, PASSIVE_LEVEL);
+ if (!skip(pKeEnterGuardedRegion &&
+ pKeLeaveGuardedRegion, "Guarded regions not available\n"))
+ {
+ pKeLeaveGuardedRegion();
+ CheckApcs(0, 1, TRUE, PASSIVE_LEVEL);
+ pKeEnterGuardedRegion();
+ CheckApcs(0, 0, FALSE, PASSIVE_LEVEL);
+
+ KeLeaveCriticalRegion();
+ CheckApcs(1, 0, FALSE, PASSIVE_LEVEL);
+ pKeLeaveGuardedRegion();
+ CheckApcs(1, 1, TRUE, PASSIVE_LEVEL);
+ KeEnterCriticalRegion();
+ CheckApcs(0, 1, TRUE, PASSIVE_LEVEL);
+ pKeEnterGuardedRegion();
+ CheckApcs(0, 0, FALSE, PASSIVE_LEVEL);
+ }
}
/* manually disable APCs */
CheckApcs(0, 0, TRUE, HIGH_LEVEL);
/* Ke*GuardedRegion assert at > APC_LEVEL */
- if (!KmtIsCheckedBuild)
+ if (!KmtIsCheckedBuild &&
+ !skip(pKeEnterGuardedRegion &&
+ pKeLeaveGuardedRegion, "Guarded regions not available\n"))
{
- KeEnterGuardedRegion();
+ pKeEnterGuardedRegion();
CheckApcs(0, -1, TRUE, HIGH_LEVEL);
- KeLeaveGuardedRegion();
+ pKeLeaveGuardedRegion();
}
CheckApcs(0, 0, TRUE, HIGH_LEVEL);
KeLowerIrql(Irql);
CheckApcs(0, 0, FALSE, PASSIVE_LEVEL);
- if (!KmtIsCheckedBuild)
+ if (!KmtIsCheckedBuild &&
+ !skip(pKeEnterGuardedRegion &&
+ pKeLeaveGuardedRegion, "Guarded regions not available\n"))
{
KeRaiseIrql(HIGH_LEVEL, &Irql);
CheckApcs(0, 0, TRUE, HIGH_LEVEL);
KeEnterCriticalRegion();
CheckApcs(-1, 0, TRUE, HIGH_LEVEL);
- KeEnterGuardedRegion();
+ pKeEnterGuardedRegion();
CheckApcs(-1, -1, TRUE, HIGH_LEVEL);
KeLowerIrql(Irql);
CheckApcs(-1, -1, TRUE, PASSIVE_LEVEL);
KeLeaveCriticalRegion();
CheckApcs(0, -1, TRUE, PASSIVE_LEVEL);
- KeLeaveGuardedRegion();
+ pKeLeaveGuardedRegion();
CheckApcs(0, 0, FALSE, PASSIVE_LEVEL);
- KeEnterGuardedRegion();
+ pKeEnterGuardedRegion();
CheckApcs(0, -1, TRUE, PASSIVE_LEVEL);
KeRaiseIrql(HIGH_LEVEL, &Irql);
CheckApcs(0, -1, TRUE, HIGH_LEVEL);
KeEnterCriticalRegion();
CheckApcs(-1, -1, TRUE, HIGH_LEVEL);
- KeLeaveGuardedRegion();
+ pKeLeaveGuardedRegion();
CheckApcs(-1, 0, TRUE, HIGH_LEVEL);
KeLowerIrql(Irql);
CheckApcs(-1, 0, FALSE, PASSIVE_LEVEL);
CheckApcs(-1, 0, FALSE, PASSIVE_LEVEL);
KeRaiseIrql(HIGH_LEVEL, &Irql);
CheckApcs(-1, 0, TRUE, HIGH_LEVEL);
- KeEnterGuardedRegion();
+ pKeEnterGuardedRegion();
CheckApcs(-1, -1, TRUE, HIGH_LEVEL);
KeLeaveCriticalRegion();
CheckApcs(0, -1, TRUE, HIGH_LEVEL);
KeLowerIrql(Irql);
CheckApcs(0, -1, TRUE, PASSIVE_LEVEL);
- KeLeaveGuardedRegion();
+ pKeLeaveGuardedRegion();
CheckApcs(0, 0, FALSE, PASSIVE_LEVEL);
}