Author: tfaber
Date: Sun Feb 15 10:23:21 2015
New Revision: 66281
URL:
http://svn.reactos.org/svn/reactos?rev=66281&view=rev
Log:
[KMTESTS]
- Add KmtGetSystemRoutineAddress and use it to avoid importing functions that are not
available in some versions of Windows. This allows running kmtests on Windows XP SP3 (and
probably Server 2003 SP0/SP2). Note that failures on XP are still not valid bugs, this is
purely for convenience! Dedicated to Jérôme.
ROSTESTS-150
Modified:
trunk/rostests/kmtests/include/kmt_test.h
trunk/rostests/kmtests/include/kmt_test_kernel.h
trunk/rostests/kmtests/kmtest_drv/testlist.c
trunk/rostests/kmtests/ntos_ex/ExFastMutex.c
trunk/rostests/kmtests/ntos_ex/ExResource.c
trunk/rostests/kmtests/ntos_ke/KeApc.c
trunk/rostests/kmtests/ntos_ke/KeGuardedMutex.c
trunk/rostests/kmtests/ntos_ke/KeMutex.c
trunk/rostests/kmtests/ntos_ke/KeSpinLock.c
Modified: trunk/rostests/kmtests/include/kmt_test.h
URL:
http://svn.reactos.org/svn/reactos/trunk/rostests/kmtests/include/kmt_test.…
==============================================================================
--- trunk/rostests/kmtests/include/kmt_test.h [iso-8859-1] (original)
+++ trunk/rostests/kmtests/include/kmt_test.h [iso-8859-1] Sun Feb 15 10:23:21 2015
@@ -132,6 +132,7 @@
BOOLEAN KmtAreInterruptsEnabled(VOID);
ULONG KmtGetPoolTag(PVOID Memory);
USHORT KmtGetPoolType(PVOID Memory);
+PVOID KmtGetSystemRoutineAddress(IN PCWSTR RoutineName);
PKTHREAD KmtStartThread(IN PKSTART_ROUTINE StartRoutine, IN PVOID StartContext
OPTIONAL);
VOID KmtFinishThread(IN PKTHREAD Thread OPTIONAL, IN PKEVENT Event OPTIONAL);
#elif defined KMT_USER_MODE
Modified: trunk/rostests/kmtests/include/kmt_test_kernel.h
URL:
http://svn.reactos.org/svn/reactos/trunk/rostests/kmtests/include/kmt_test_…
==============================================================================
--- trunk/rostests/kmtests/include/kmt_test_kernel.h [iso-8859-1] (original)
+++ trunk/rostests/kmtests/include/kmt_test_kernel.h [iso-8859-1] Sun Feb 15 10:23:21
2015
@@ -126,6 +126,13 @@
return Header->PoolType;
}
+PVOID KmtGetSystemRoutineAddress(IN PCWSTR RoutineName)
+{
+ UNICODE_STRING RoutineNameString;
+ RtlInitUnicodeString(&RoutineNameString, (PWSTR)RoutineName);
+ return MmGetSystemRoutineAddress(&RoutineNameString);
+}
+
PKTHREAD KmtStartThread(IN PKSTART_ROUTINE StartRoutine, IN PVOID StartContext OPTIONAL)
{
NTSTATUS Status;
Modified: trunk/rostests/kmtests/kmtest_drv/testlist.c
URL:
http://svn.reactos.org/svn/reactos/trunk/rostests/kmtests/kmtest_drv/testli…
==============================================================================
--- trunk/rostests/kmtests/kmtest_drv/testlist.c [iso-8859-1] (original)
+++ trunk/rostests/kmtests/kmtest_drv/testlist.c [iso-8859-1] Sun Feb 15 10:23:21 2015
@@ -94,7 +94,7 @@
{ "KeIrql", Test_KeIrql },
{ "KeMutex", Test_KeMutex },
{ "-KeProcessor", Test_KeProcessor },
- { "KeSpinLock", Test_KeSpinLock },
+ { "KeSpinLock", Test_KeSpinLock },
{ "KeTimer", Test_KeTimer },
{ "-KernelType", Test_KernelType },
{ "MmSection", Test_MmSection },
Modified: trunk/rostests/kmtests/ntos_ex/ExFastMutex.c
URL:
http://svn.reactos.org/svn/reactos/trunk/rostests/kmtests/ntos_ex/ExFastMut…
==============================================================================
--- trunk/rostests/kmtests/ntos_ex/ExFastMutex.c [iso-8859-1] (original)
+++ trunk/rostests/kmtests/ntos_ex/ExFastMutex.c [iso-8859-1] Sun Feb 15 10:23:21 2015
@@ -10,9 +10,23 @@
//#define NDEBUG
#include <debug.h>
-NTKERNELAPI VOID FASTCALL ExiAcquireFastMutex(IN OUT PFAST_MUTEX FastMutex);
-NTKERNELAPI VOID FASTCALL ExiReleaseFastMutex(IN OUT PFAST_MUTEX FastMutex);
-NTKERNELAPI BOOLEAN FASTCALL ExiTryToAcquireFastMutex(IN OUT PFAST_MUTEX FastMutex);
+static
+VOID
+(FASTCALL
+*pExEnterCriticalRegionAndAcquireFastMutexUnsafe)(
+ _Inout_ PFAST_MUTEX FastMutex
+);
+
+static
+VOID
+(FASTCALL
+*pExReleaseFastMutexUnsafeAndLeaveCriticalRegion)(
+ _Inout_ PFAST_MUTEX FastMutex
+);
+
+static VOID (FASTCALL *pExiAcquireFastMutex)(IN OUT PFAST_MUTEX FastMutex);
+static VOID (FASTCALL *pExiReleaseFastMutex)(IN OUT PFAST_MUTEX FastMutex);
+static BOOLEAN (FASTCALL *pExiTryToAcquireFastMutex)(IN OUT PFAST_MUTEX FastMutex);
#define CheckMutex(Mutex, ExpectedCount, ExpectedOwner, \
ExpectedContention, ExpectedOldIrql, \
@@ -44,15 +58,18 @@
ExReleaseFastMutex(Mutex);
CheckMutex(Mutex, 1L, NULL, 0LU, OriginalIrql, OriginalIrql);
-#ifdef _M_IX86
/* ntoskrnl's fastcall version */
- ExiAcquireFastMutex(Mutex);
- CheckMutex(Mutex, 0L, Thread, 0LU, OriginalIrql, APC_LEVEL);
- ok_bool_false(ExiTryToAcquireFastMutex(Mutex), "ExiTryToAcquireFastMutex
returned");
- CheckMutex(Mutex, 0L, Thread, 0LU, OriginalIrql, APC_LEVEL);
- ExiReleaseFastMutex(Mutex);
- CheckMutex(Mutex, 1L, NULL, 0LU, OriginalIrql, OriginalIrql);
-#endif
+ if (!skip(pExiAcquireFastMutex &&
+ pExiReleaseFastMutex &&
+ pExiTryToAcquireFastMutex, "No fastcall fast mutex
functions\n"))
+ {
+ pExiAcquireFastMutex(Mutex);
+ CheckMutex(Mutex, 0L, Thread, 0LU, OriginalIrql, APC_LEVEL);
+ ok_bool_false(pExiTryToAcquireFastMutex(Mutex), "ExiTryToAcquireFastMutex
returned");
+ CheckMutex(Mutex, 0L, Thread, 0LU, OriginalIrql, APC_LEVEL);
+ pExiReleaseFastMutex(Mutex);
+ CheckMutex(Mutex, 1L, NULL, 0LU, OriginalIrql, OriginalIrql);
+ }
/* try to acquire */
ok_bool_true(ExTryToAcquireFastMutex(Mutex), "ExTryToAcquireFastMutex
returned");
@@ -61,9 +78,14 @@
CheckMutex(Mutex, 1L, NULL, 0LU, OriginalIrql, OriginalIrql);
/* shortcut functions with critical region */
- ExEnterCriticalRegionAndAcquireFastMutexUnsafe(Mutex);
- ok_bool_true(KeAreApcsDisabled(), "KeAreApcsDisabled returned");
- ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(Mutex);
+ if (!skip(pExEnterCriticalRegionAndAcquireFastMutexUnsafe &&
+ pExReleaseFastMutexUnsafeAndLeaveCriticalRegion,
+ "Shortcut functions not available"))
+ {
+ pExEnterCriticalRegionAndAcquireFastMutexUnsafe(Mutex);
+ ok_bool_true(KeAreApcsDisabled(), "KeAreApcsDisabled returned");
+ pExReleaseFastMutexUnsafeAndLeaveCriticalRegion(Mutex);
+ }
/* acquire/release unsafe */
if (!KmtIsCheckedBuild || OriginalIrql == APC_LEVEL)
@@ -291,6 +313,13 @@
FAST_MUTEX Mutex;
KIRQL Irql;
+ pExEnterCriticalRegionAndAcquireFastMutexUnsafe =
KmtGetSystemRoutineAddress(L"ExEnterCriticalRegionAndAcquireFastMutexUnsafe");
+ pExReleaseFastMutexUnsafeAndLeaveCriticalRegion =
KmtGetSystemRoutineAddress(L"ExReleaseFastMutexUnsafeAndLeaveCriticalRegion");
+
+ pExiAcquireFastMutex = KmtGetSystemRoutineAddress(L"ExiAcquireFastMutex");
+ pExiReleaseFastMutex = KmtGetSystemRoutineAddress(L"ExiReleaseFastMutex");
+ pExiTryToAcquireFastMutex =
KmtGetSystemRoutineAddress(L"ExiTryToAcquireFastMutex");
+
memset(&Mutex, 0x55, sizeof Mutex);
ExInitializeFastMutex(&Mutex);
CheckMutex(&Mutex, 1L, NULL, 0LU, 0x55555555LU, PASSIVE_LEVEL);
Modified: trunk/rostests/kmtests/ntos_ex/ExResource.c
URL:
http://svn.reactos.org/svn/reactos/trunk/rostests/kmtests/ntos_ex/ExResourc…
==============================================================================
--- trunk/rostests/kmtests/ntos_ex/ExResource.c [iso-8859-1] (original)
+++ trunk/rostests/kmtests/ntos_ex/ExResource.c [iso-8859-1] Sun Feb 15 10:23:21 2015
@@ -9,6 +9,49 @@
//#define NDEBUG
#include <debug.h>
+
+static
+_IRQL_requires_max_(APC_LEVEL)
+_Acquires_lock_(_Global_critical_region_)
+PVOID
+(NTAPI
+*pExEnterCriticalRegionAndAcquireResourceShared)(
+ _Inout_ _Requires_lock_not_held_(*_Curr_) _Acquires_shared_lock_(*_Curr_)
+ PERESOURCE Resource);
+
+static
+_IRQL_requires_max_(APC_LEVEL)
+_Acquires_lock_(_Global_critical_region_)
+PVOID
+(NTAPI
+*pExEnterCriticalRegionAndAcquireResourceExclusive)(
+ _Inout_ _Requires_lock_not_held_(*_Curr_) _Acquires_exclusive_lock_(*_Curr_)
+ PERESOURCE Resource);
+
+static
+_IRQL_requires_max_(APC_LEVEL)
+_Acquires_lock_(_Global_critical_region_)
+PVOID
+(NTAPI
+*pExEnterCriticalRegionAndAcquireSharedWaitForExclusive)(
+ _Inout_ _Requires_lock_not_held_(*_Curr_) _Acquires_lock_(*_Curr_)
+ PERESOURCE Resource);
+
+static
+_IRQL_requires_max_(DISPATCH_LEVEL)
+_Releases_lock_(_Global_critical_region_)
+VOID
+(FASTCALL
+*pExReleaseResourceAndLeaveCriticalRegion)(
+ _Inout_ _Requires_lock_held_(*_Curr_) _Releases_lock_(*_Curr_)
+ PERESOURCE Resource);
+
+static
+_IRQL_requires_min_(PASSIVE_LEVEL)
+_IRQL_requires_max_(DISPATCH_LEVEL)
+BOOLEAN
+(NTAPI
+*pKeAreAllApcsDisabled)(VOID);
/* TODO: This is getting pretty long, make it somehow easier to read if possible */
@@ -137,65 +180,83 @@
LONG Count = 0;
ok_bool_false(KeAreApcsDisabled(), "KeAreApcsDisabled returned");
- ok_eq_uint(KeAreAllApcsDisabled(), AreApcsDisabled);
-
+ if (pKeAreAllApcsDisabled)
+ ok_eq_uint(pKeAreAllApcsDisabled(), AreApcsDisabled);
+
+ if (skip(pExEnterCriticalRegionAndAcquireResourceShared &&
+ pExEnterCriticalRegionAndAcquireSharedWaitForExclusive &&
+ pExEnterCriticalRegionAndAcquireResourceExclusive &&
+ pExReleaseResourceAndLeaveCriticalRegion, "No shortcuts\n"))
+ {
+ return;
+ }
/* ExEnterCriticalRegionAndAcquireResourceShared,
ExEnterCriticalRegionAndAcquireSharedWaitForExclusive */
Count = 0;
- Ret = ExEnterCriticalRegionAndAcquireResourceShared(Res); ++Count;
+ Ret = pExEnterCriticalRegionAndAcquireResourceShared(Res); ++Count;
ok_eq_pointer(Ret, KeGetCurrentThread()->Win32Thread);
ok_bool_true(KeAreApcsDisabled(), "KeAreApcsDisabled returned");
- ok_eq_bool(KeAreAllApcsDisabled(), AreApcsDisabled);
- CheckResourceStatus(Res, FALSE, Count, 0LU, 0LU);
-
- Ret = ExEnterCriticalRegionAndAcquireResourceShared(Res); ++Count;
+ if (pKeAreAllApcsDisabled)
+ ok_eq_bool(pKeAreAllApcsDisabled(), AreApcsDisabled);
+ CheckResourceStatus(Res, FALSE, Count, 0LU, 0LU);
+
+ Ret = pExEnterCriticalRegionAndAcquireResourceShared(Res); ++Count;
ok_eq_pointer(Ret, KeGetCurrentThread()->Win32Thread);
ok_bool_true(KeAreApcsDisabled(), "KeAreApcsDisabled returned");
- ok_eq_bool(KeAreAllApcsDisabled(), AreApcsDisabled);
- CheckResourceStatus(Res, FALSE, Count, 0LU, 0LU);
-
- ExEnterCriticalRegionAndAcquireSharedWaitForExclusive(Res); ++Count;
+ if (pKeAreAllApcsDisabled)
+ ok_eq_bool(pKeAreAllApcsDisabled(), AreApcsDisabled);
+ CheckResourceStatus(Res, FALSE, Count, 0LU, 0LU);
+
+ pExEnterCriticalRegionAndAcquireSharedWaitForExclusive(Res); ++Count;
ok_eq_pointer(Ret, KeGetCurrentThread()->Win32Thread);
ok_bool_true(KeAreApcsDisabled(), "KeAreApcsDisabled returned");
- ok_eq_bool(KeAreAllApcsDisabled(), AreApcsDisabled);
+ if (pKeAreAllApcsDisabled)
+ ok_eq_bool(pKeAreAllApcsDisabled(), AreApcsDisabled);
CheckResourceStatus(Res, FALSE, Count, 0LU, 0LU);
while (Count-- > 1)
{
- ExReleaseResourceAndLeaveCriticalRegion(Res);
+ pExReleaseResourceAndLeaveCriticalRegion(Res);
ok_bool_true(KeAreApcsDisabled(), "KeAreApcsDisabled returned");
- ok_eq_bool(KeAreAllApcsDisabled(), AreApcsDisabled);
+ if (pKeAreAllApcsDisabled)
+ ok_eq_bool(pKeAreAllApcsDisabled(), AreApcsDisabled);
CheckResourceStatus(Res, FALSE, Count, 0LU, 0LU);
}
- ExReleaseResourceAndLeaveCriticalRegion(Res);
+ pExReleaseResourceAndLeaveCriticalRegion(Res);
ok_bool_false(KeAreApcsDisabled(), "KeAreApcsDisabled returned");
- ok_eq_bool(KeAreAllApcsDisabled(), AreApcsDisabled);
+ if (pKeAreAllApcsDisabled)
+ ok_eq_bool(pKeAreAllApcsDisabled(), AreApcsDisabled);
CheckResourceStatus(Res, FALSE, Count, 0LU, 0LU);
/* ExEnterCriticalRegionAndAcquireResourceExclusive */
Count = 0;
ok_bool_false(KeAreApcsDisabled(), "KeAreApcsDisabled returned");
- ok_eq_bool(KeAreAllApcsDisabled(), AreApcsDisabled);
- Ret = ExEnterCriticalRegionAndAcquireResourceExclusive(Res); ++Count;
+ if (pKeAreAllApcsDisabled)
+ ok_eq_bool(pKeAreAllApcsDisabled(), AreApcsDisabled);
+ Ret = pExEnterCriticalRegionAndAcquireResourceExclusive(Res); ++Count;
ok_eq_pointer(Ret, KeGetCurrentThread()->Win32Thread);
ok_bool_true(KeAreApcsDisabled(), "KeAreApcsDisabled returned");
- ok_eq_bool(KeAreAllApcsDisabled(), AreApcsDisabled);
+ if (pKeAreAllApcsDisabled)
+ ok_eq_bool(pKeAreAllApcsDisabled(), AreApcsDisabled);
CheckResourceStatus(Res, TRUE, Count, 0LU, 0LU);
- Ret = ExEnterCriticalRegionAndAcquireResourceExclusive(Res); ++Count;
+ Ret = pExEnterCriticalRegionAndAcquireResourceExclusive(Res); ++Count;
ok_eq_pointer(Ret, KeGetCurrentThread()->Win32Thread);
ok_bool_true(KeAreApcsDisabled(), "KeAreApcsDisabled returned");
- ok_eq_bool(KeAreAllApcsDisabled(), AreApcsDisabled);
+ if (pKeAreAllApcsDisabled)
+ ok_eq_bool(pKeAreAllApcsDisabled(), AreApcsDisabled);
CheckResourceStatus(Res, TRUE, Count, 0LU, 0LU);
- ExReleaseResourceAndLeaveCriticalRegion(Res); --Count;
+ pExReleaseResourceAndLeaveCriticalRegion(Res); --Count;
ok_bool_true(KeAreApcsDisabled(), "KeAreApcsDisabled returned");
- ok_eq_bool(KeAreAllApcsDisabled(), AreApcsDisabled);
+ if (pKeAreAllApcsDisabled)
+ ok_eq_bool(pKeAreAllApcsDisabled(), AreApcsDisabled);
CheckResourceStatus(Res, TRUE, Count, 0LU, 0LU);
- ExReleaseResourceAndLeaveCriticalRegion(Res); --Count;
+ pExReleaseResourceAndLeaveCriticalRegion(Res); --Count;
ok_bool_false(KeAreApcsDisabled(), "KeAreApcsDisabled returned");
- ok_eq_uint(KeAreAllApcsDisabled(), AreApcsDisabled);
+ if (pKeAreAllApcsDisabled)
+ ok_eq_uint(pKeAreAllApcsDisabled(), AreApcsDisabled);
CheckResourceStatus(Res, FALSE, Count, 0LU, 0LU);
}
@@ -400,6 +461,17 @@
ERESOURCE Res;
KIRQL Irql;
+ pExEnterCriticalRegionAndAcquireResourceShared =
KmtGetSystemRoutineAddress(L"ExEnterCriticalRegionAndAcquireResourceShared");
+ pExEnterCriticalRegionAndAcquireSharedWaitForExclusive =
KmtGetSystemRoutineAddress(L"ExEnterCriticalRegionAndAcquireSharedWaitForExclusive");
+ pExEnterCriticalRegionAndAcquireResourceExclusive =
KmtGetSystemRoutineAddress(L"ExEnterCriticalRegionAndAcquireResourceExclusive");
+ pExReleaseResourceAndLeaveCriticalRegion =
KmtGetSystemRoutineAddress(L"ExReleaseResourceAndLeaveCriticalRegion");
+ pKeAreAllApcsDisabled =
KmtGetSystemRoutineAddress(L"KeAreAllApcsDisabled");
+
+ if (skip(pKeAreAllApcsDisabled != NULL, "KeAreAllApcsDisabled
unavailable\n"))
+ {
+ /* We can live without this function here */
+ }
+
/* this must be true even with the different structure versions */
ASSERT(sizeof(ERESOURCE) == sizeof(ERESOURCE_2K3));
Modified: trunk/rostests/kmtests/ntos_ke/KeApc.c
URL:
http://svn.reactos.org/svn/reactos/trunk/rostests/kmtests/ntos_ke/KeApc.c?r…
==============================================================================
--- trunk/rostests/kmtests/ntos_ke/KeApc.c [iso-8859-1] (original)
+++ trunk/rostests/kmtests/ntos_ke/KeApc.c [iso-8859-1] Sun Feb 15 10:23:21 2015
@@ -7,11 +7,33 @@
#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)
@@ -19,7 +41,18 @@
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);
@@ -38,37 +71,41 @@
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);
-
- /* 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);
-
- 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);
+ 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 */
+ 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);
+ 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)
@@ -78,19 +115,23 @@
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 */
@@ -130,38 +171,42 @@
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();
- CheckApcs(0, 0, FALSE, PASSIVE_LEVEL);
-
- KeEnterGuardedRegion();
+ pKeLeaveGuardedRegion();
+ CheckApcs(0, 0, FALSE, PASSIVE_LEVEL);
+
+ 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);
@@ -172,13 +217,13 @@
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);
}
Modified: trunk/rostests/kmtests/ntos_ke/KeGuardedMutex.c
URL:
http://svn.reactos.org/svn/reactos/trunk/rostests/kmtests/ntos_ke/KeGuarded…
==============================================================================
--- trunk/rostests/kmtests/ntos_ke/KeGuardedMutex.c [iso-8859-1] (original)
+++ trunk/rostests/kmtests/ntos_ke/KeGuardedMutex.c [iso-8859-1] Sun Feb 15 10:23:21 2015
@@ -9,6 +9,86 @@
#define NDEBUG
#include <debug.h>
+
+static
+_IRQL_requires_min_(PASSIVE_LEVEL)
+_IRQL_requires_max_(DISPATCH_LEVEL)
+BOOLEAN
+(NTAPI
+*pKeAreAllApcsDisabled)(VOID);
+
+static
+_Acquires_lock_(_Global_critical_region_)
+_Requires_lock_not_held_(*Mutex)
+_Acquires_lock_(*Mutex)
+_IRQL_requires_max_(APC_LEVEL)
+_IRQL_requires_min_(PASSIVE_LEVEL)
+VOID
+(FASTCALL
+*pKeAcquireGuardedMutex)(
+ _Inout_ PKGUARDED_MUTEX GuardedMutex);
+
+static
+_Requires_lock_not_held_(*FastMutex)
+_Acquires_lock_(*FastMutex)
+_IRQL_requires_max_(APC_LEVEL)
+_IRQL_requires_min_(PASSIVE_LEVEL)
+VOID
+(FASTCALL
+*pKeAcquireGuardedMutexUnsafe)(
+ _Inout_ PKGUARDED_MUTEX GuardedMutex);
+
+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);
+
+static
+_IRQL_requires_max_(APC_LEVEL)
+_IRQL_requires_min_(PASSIVE_LEVEL)
+VOID
+(FASTCALL
+*pKeInitializeGuardedMutex)(
+ _Out_ PKGUARDED_MUTEX GuardedMutex);
+
+static
+_Requires_lock_held_(*FastMutex)
+_Releases_lock_(*FastMutex)
+_IRQL_requires_max_(APC_LEVEL)
+VOID
+(FASTCALL
+*pKeReleaseGuardedMutexUnsafe)(
+ _Inout_ PKGUARDED_MUTEX GuardedMutex);
+
+static
+_Releases_lock_(_Global_critical_region_)
+_Requires_lock_held_(*Mutex)
+_Releases_lock_(*Mutex)
+_IRQL_requires_max_(APC_LEVEL)
+VOID
+(FASTCALL
+*pKeReleaseGuardedMutex)(
+ _Inout_ PKGUARDED_MUTEX GuardedMutex);
+
+static
+_Must_inspect_result_
+_Success_(return != FALSE)
+_IRQL_requires_max_(APC_LEVEL)
+_Post_satisfies_(return == 1 || return == 0)
+BOOLEAN
+(FASTCALL
+*pKeTryToAcquireGuardedMutex)(
+ _When_ (return, _Requires_lock_not_held_(*_Curr_) _Acquires_exclusive_lock_(*_Curr_))
_Acquires_lock_(_Global_critical_region_)
+ _Inout_ PKGUARDED_MUTEX GuardedMutex);
#define CheckMutex(Mutex, ExpectedCount, ExpectedOwner, ExpectedContention, \
ExpectedKernelApcDisable, ExpectedSpecialApcDisable, \
@@ -25,7 +105,7 @@
ok_eq_int((Mutex)->SpecialApcDisable, 0x5555); \
ok_eq_bool(KeAreApcsDisabled(), KernelApcsDisabled || SpecialApcsDisabled); \
ok_eq_int(Thread->KernelApcDisable, KernelApcsDisabled); \
- ok_eq_bool(KeAreAllApcsDisabled(), AllApcsDisabled); \
+ ok_eq_bool(pKeAreAllApcsDisabled(), AllApcsDisabled); \
ok_eq_int(Thread->SpecialApcDisable, SpecialApcsDisabled); \
ok_irql(ExpectedIrql); \
} while (0)
@@ -48,17 +128,17 @@
if (!KmtIsCheckedBuild || OriginalIrql <= APC_LEVEL)
{
/* acquire/release normally */
- KeAcquireGuardedMutex(Mutex);
+ pKeAcquireGuardedMutex(Mutex);
CheckMutex(Mutex, 0L, Thread, 0LU, 0x5555, SpecialApcsDisabled - 1,
KernelApcsDisabled, SpecialApcsDisabled - 1, TRUE, OriginalIrql);
- ok_bool_false(KeTryToAcquireGuardedMutex(Mutex), "KeTryToAcquireGuardedMutex
returned");
+ ok_bool_false(pKeTryToAcquireGuardedMutex(Mutex),
"KeTryToAcquireGuardedMutex returned");
CheckMutex(Mutex, 0L, Thread, 0LU, 0x5555, SpecialApcsDisabled - 1,
KernelApcsDisabled, SpecialApcsDisabled - 1, TRUE, OriginalIrql);
- KeReleaseGuardedMutex(Mutex);
+ pKeReleaseGuardedMutex(Mutex);
CheckMutex(Mutex, 1L, NULL, 0LU, 0x5555, SpecialApcsDisabled - 1,
KernelApcsDisabled, SpecialApcsDisabled, AllApcsDisabled, OriginalIrql);
/* try to acquire */
- ok_bool_true(KeTryToAcquireGuardedMutex(Mutex), "KeTryToAcquireGuardedMutex
returned");
+ ok_bool_true(pKeTryToAcquireGuardedMutex(Mutex), "KeTryToAcquireGuardedMutex
returned");
CheckMutex(Mutex, 0L, Thread, 0LU, 0x5555, SpecialApcsDisabled - 1,
KernelApcsDisabled, SpecialApcsDisabled - 1, TRUE, OriginalIrql);
- KeReleaseGuardedMutex(Mutex);
+ pKeReleaseGuardedMutex(Mutex);
CheckMutex(Mutex, 1L, NULL, 0LU, 0x5555, SpecialApcsDisabled - 1,
KernelApcsDisabled, SpecialApcsDisabled, AllApcsDisabled, OriginalIrql);
}
else
@@ -69,9 +149,9 @@
if (!KmtIsCheckedBuild || OriginalIrql == APC_LEVEL || SpecialApcsDisabled < 0)
{
/* acquire/release unsafe */
- KeAcquireGuardedMutexUnsafe(Mutex);
+ pKeAcquireGuardedMutexUnsafe(Mutex);
CheckMutex(Mutex, 0L, Thread, 0LU, 0x5555, SpecialApcsDisabled - 1,
KernelApcsDisabled, SpecialApcsDisabled, AllApcsDisabled, OriginalIrql);
- KeReleaseGuardedMutexUnsafe(Mutex);
+ pKeReleaseGuardedMutexUnsafe(Mutex);
CheckMutex(Mutex, 1L, NULL, 0LU, 0x5555, SpecialApcsDisabled - 1,
KernelApcsDisabled, SpecialApcsDisabled, AllApcsDisabled, OriginalIrql);
}
@@ -79,29 +159,29 @@
if (!KmtIsCheckedBuild)
{
/* mismatched acquire/release */
- KeAcquireGuardedMutex(Mutex);
+ pKeAcquireGuardedMutex(Mutex);
CheckMutex(Mutex, 0L, Thread, 0LU, 0x5555, SpecialApcsDisabled - 1,
KernelApcsDisabled, SpecialApcsDisabled - 1, TRUE, OriginalIrql);
- KeReleaseGuardedMutexUnsafe(Mutex);
+ pKeReleaseGuardedMutexUnsafe(Mutex);
CheckMutex(Mutex, 1L, NULL, 0LU, 0x5555, SpecialApcsDisabled - 1,
KernelApcsDisabled, SpecialApcsDisabled - 1, TRUE, OriginalIrql);
- KeLeaveGuardedRegion();
+ pKeLeaveGuardedRegion();
CheckMutex(Mutex, 1L, NULL, 0LU, 0x5555, SpecialApcsDisabled - 1,
KernelApcsDisabled, SpecialApcsDisabled, AllApcsDisabled, OriginalIrql);
- KeAcquireGuardedMutexUnsafe(Mutex);
+ pKeAcquireGuardedMutexUnsafe(Mutex);
CheckMutex(Mutex, 0L, Thread, 0LU, 0x5555, SpecialApcsDisabled - 1,
KernelApcsDisabled, SpecialApcsDisabled, AllApcsDisabled, OriginalIrql);
- KeReleaseGuardedMutex(Mutex);
+ pKeReleaseGuardedMutex(Mutex);
CheckMutex(Mutex, 1L, NULL, 0LU, 0x5555, SpecialApcsDisabled - 1,
KernelApcsDisabled, SpecialApcsDisabled + 1, OriginalIrql >= APC_LEVEL ||
SpecialApcsDisabled != -1, OriginalIrql);
- KeEnterGuardedRegion();
+ pKeEnterGuardedRegion();
CheckMutex(Mutex, 1L, NULL, 0LU, 0x5555, SpecialApcsDisabled - 1,
KernelApcsDisabled, SpecialApcsDisabled, AllApcsDisabled, OriginalIrql);
/* release without acquire */
- KeReleaseGuardedMutexUnsafe(Mutex);
+ pKeReleaseGuardedMutexUnsafe(Mutex);
CheckMutex(Mutex, 0L, NULL, 0LU, 0x5555, SpecialApcsDisabled - 1,
KernelApcsDisabled, SpecialApcsDisabled, AllApcsDisabled, OriginalIrql);
- KeReleaseGuardedMutex(Mutex);
+ pKeReleaseGuardedMutex(Mutex);
CheckMutex(Mutex, 1L, NULL, 0LU, 0x5555, SpecialApcsDisabled, KernelApcsDisabled,
SpecialApcsDisabled + 1, OriginalIrql >= APC_LEVEL || SpecialApcsDisabled != -1,
OriginalIrql);
- KeReleaseGuardedMutex(Mutex);
+ pKeReleaseGuardedMutex(Mutex);
/* TODO: here we see that Mutex->Count isn't actually just a count. Test
the bits correctly! */
CheckMutex(Mutex, 0L, NULL, 0LU, 0x5555, SpecialApcsDisabled, KernelApcsDisabled,
SpecialApcsDisabled + 2, OriginalIrql >= APC_LEVEL || SpecialApcsDisabled != -2,
OriginalIrql);
- KeReleaseGuardedMutex(Mutex);
+ pKeReleaseGuardedMutex(Mutex);
CheckMutex(Mutex, 1L, NULL, 0LU, 0x5555, SpecialApcsDisabled, KernelApcsDisabled,
SpecialApcsDisabled + 3, OriginalIrql >= APC_LEVEL || SpecialApcsDisabled != -3,
OriginalIrql);
Thread->SpecialApcDisable -= 3;
}
@@ -242,10 +322,10 @@
LARGE_INTEGER Timeout;
Timeout.QuadPart = -50 * 1000 * 10; /* 50 ms */
- InitThreadData(&ThreadData, Mutex, KeAcquireGuardedMutex, NULL,
KeReleaseGuardedMutex);
- InitThreadData(&ThreadData2, Mutex, KeAcquireGuardedMutex, NULL,
KeReleaseGuardedMutex);
- InitThreadData(&ThreadDataUnsafe, Mutex, KeAcquireGuardedMutexUnsafe, NULL,
KeReleaseGuardedMutexUnsafe);
- InitThreadData(&ThreadDataTry, Mutex, NULL, KeTryToAcquireGuardedMutex,
KeReleaseGuardedMutex);
+ InitThreadData(&ThreadData, Mutex, pKeAcquireGuardedMutex, NULL,
pKeReleaseGuardedMutex);
+ InitThreadData(&ThreadData2, Mutex, pKeAcquireGuardedMutex, NULL,
pKeReleaseGuardedMutex);
+ InitThreadData(&ThreadDataUnsafe, Mutex, pKeAcquireGuardedMutexUnsafe, NULL,
pKeReleaseGuardedMutexUnsafe);
+ InitThreadData(&ThreadDataTry, Mutex, NULL, pKeTryToAcquireGuardedMutex,
pKeReleaseGuardedMutex);
/* have a thread acquire the mutex */
Status = StartThread(&ThreadData, NULL, PASSIVE_LEVEL, FALSE, FALSE);
@@ -337,6 +417,29 @@
};
int i;
+ pKeAreAllApcsDisabled =
KmtGetSystemRoutineAddress(L"KeAreAllApcsDisabled");
+ pKeInitializeGuardedMutex =
KmtGetSystemRoutineAddress(L"KeInitializeGuardedMutex");
+ pKeAcquireGuardedMutex =
KmtGetSystemRoutineAddress(L"KeAcquireGuardedMutex");
+ pKeAcquireGuardedMutexUnsafe =
KmtGetSystemRoutineAddress(L"KeAcquireGuardedMutexUnsafe");
+ pKeEnterGuardedRegion =
KmtGetSystemRoutineAddress(L"KeEnterGuardedRegion");
+ pKeLeaveGuardedRegion =
KmtGetSystemRoutineAddress(L"KeLeaveGuardedRegion");
+ pKeReleaseGuardedMutex =
KmtGetSystemRoutineAddress(L"KeReleaseGuardedMutex");
+ pKeReleaseGuardedMutexUnsafe =
KmtGetSystemRoutineAddress(L"KeReleaseGuardedMutexUnsafe");
+ pKeTryToAcquireGuardedMutex =
KmtGetSystemRoutineAddress(L"KeTryToAcquireGuardedMutex");
+
+ if (skip(pKeAreAllApcsDisabled &&
+ pKeInitializeGuardedMutex &&
+ pKeAcquireGuardedMutex &&
+ pKeAcquireGuardedMutexUnsafe &&
+ pKeEnterGuardedRegion &&
+ pKeLeaveGuardedRegion &&
+ pKeReleaseGuardedMutex &&
+ pKeReleaseGuardedMutexUnsafe &&
+ pKeTryToAcquireGuardedMutex, "No guarded mutexes\n"))
+ {
+ return;
+ }
+
for (i = 0; i < sizeof TestIterations / sizeof TestIterations[0]; ++i)
{
trace("Run %d\n", i);
@@ -345,7 +448,7 @@
Thread->SpecialApcDisable = TestIterations[i].SpecialApcsDisabled;
RtlFillMemory(&Mutex, sizeof Mutex, 0x55);
- KeInitializeGuardedMutex(&Mutex);
+ pKeInitializeGuardedMutex(&Mutex);
CheckMutex(&Mutex, 1L, NULL, 0LU, 0x5555, 0x5555,
TestIterations[i].KernelApcsDisabled, TestIterations[i].SpecialApcsDisabled,
TestIterations[i].AllApcsDisabled, TestIterations[i].Irql);
TestGuardedMutex(&Mutex, TestIterations[i].KernelApcsDisabled,
TestIterations[i].SpecialApcsDisabled, TestIterations[i].AllApcsDisabled,
TestIterations[i].Irql);
@@ -356,6 +459,6 @@
trace("Concurrent test\n");
RtlFillMemory(&Mutex, sizeof Mutex, 0x55);
- KeInitializeGuardedMutex(&Mutex);
+ pKeInitializeGuardedMutex(&Mutex);
TestGuardedMutexConcurrent(&Mutex);
}
Modified: trunk/rostests/kmtests/ntos_ke/KeMutex.c
URL:
http://svn.reactos.org/svn/reactos/trunk/rostests/kmtests/ntos_ke/KeMutex.c…
==============================================================================
--- trunk/rostests/kmtests/ntos_ke/KeMutex.c [iso-8859-1] (original)
+++ trunk/rostests/kmtests/ntos_ke/KeMutex.c [iso-8859-1] Sun Feb 15 10:23:21 2015
@@ -6,6 +6,13 @@
*/
#include <kmt_test.h>
+
+static
+_IRQL_requires_min_(PASSIVE_LEVEL)
+_IRQL_requires_max_(DISPATCH_LEVEL)
+BOOLEAN
+(NTAPI
+*pKeAreAllApcsDisabled)(VOID);
#define ULONGS_PER_POINTER (sizeof(PVOID) / sizeof(ULONG))
#define MUTANT_SIZE (2 + 6 * ULONGS_PER_POINTER)
@@ -55,7 +62,8 @@
{
\
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)
@@ -137,6 +145,12 @@
START_TEST(KeMutex)
{
+ pKeAreAllApcsDisabled =
KmtGetSystemRoutineAddress(L"KeAreAllApcsDisabled");
+ if (skip(pKeAreAllApcsDisabled != NULL, "KeAreAllApcsDisabled
unavailable\n"))
+ {
+ /* We can live without this function here */
+ }
+
TestMutant();
TestMutex();
}
Modified: trunk/rostests/kmtests/ntos_ke/KeSpinLock.c
URL:
http://svn.reactos.org/svn/reactos/trunk/rostests/kmtests/ntos_ke/KeSpinLoc…
==============================================================================
--- trunk/rostests/kmtests/ntos_ke/KeSpinLock.c [iso-8859-1] (original)
+++ trunk/rostests/kmtests/ntos_ke/KeSpinLock.c [iso-8859-1] Sun Feb 15 10:23:21 2015
@@ -20,19 +20,36 @@
//#define NDEBUG
#include <debug.h>
-/* TODO: these are documented for Vista+ */
-NTKERNELAPI
+static
+_Must_inspect_result_
+_IRQL_requires_min_(DISPATCH_LEVEL)
+_Post_satisfies_(return == 1 || return == 0)
+BOOLEAN
+(FASTCALL
+*pKeTryToAcquireSpinLockAtDpcLevel)(
+ _Inout_ _Requires_lock_not_held_(*_Curr_)
+ _When_(return!=0, _Acquires_lock_(*_Curr_))
+ PKSPIN_LOCK SpinLock);
+
+static
VOID
-FASTCALL
-KeAcquireInStackQueuedSpinLockForDpc(
+(FASTCALL
+*pKeAcquireInStackQueuedSpinLockForDpc)(
IN OUT PKSPIN_LOCK SpinLock,
OUT PKLOCK_QUEUE_HANDLE LockHandle);
-NTKERNELAPI
+static
VOID
-FASTCALL
-KeReleaseInStackQueuedSpinLockForDpc(
+(FASTCALL
+*pKeReleaseInStackQueuedSpinLockForDpc)(
IN PKLOCK_QUEUE_HANDLE LockHandle);
+
+static
+_Must_inspect_result_
+BOOLEAN
+(FASTCALL
+*pKeTestSpinLock)(
+ _In_ PKSPIN_LOCK SpinLock);
/* TODO: multiprocessor testing */
@@ -119,8 +136,8 @@
DEFINE_RELEASE(ReleaseForDpc, TRUE, KeReleaseSpinLockForDpc(SpinLock,
CheckData->Irql))
#endif
-DEFINE_ACQUIRE(AcquireInStackForDpc, FALSE,
KeAcquireInStackQueuedSpinLockForDpc(SpinLock, &CheckData->QueueHandle))
-DEFINE_RELEASE(ReleaseInStackForDpc, FALSE,
KeReleaseInStackQueuedSpinLockForDpc(&CheckData->QueueHandle))
+DEFINE_ACQUIRE(AcquireInStackForDpc, FALSE,
pKeAcquireInStackQueuedSpinLockForDpc(SpinLock, &CheckData->QueueHandle))
+DEFINE_RELEASE(ReleaseInStackForDpc, FALSE,
pKeReleaseInStackQueuedSpinLockForDpc(&CheckData->QueueHandle))
#ifdef _X86_
DEFINE_ACQUIRE(AcquireInt, FALSE, KiAcquireSpinLock(SpinLock))
@@ -142,7 +159,7 @@
return Ret;
}
BOOLEAN TryNoRaise(PKSPIN_LOCK SpinLock, PCHECK_DATA CheckData) {
- BOOLEAN Ret = KeTryToAcquireSpinLockAtDpcLevel(SpinLock);
+ BOOLEAN Ret = pKeTryToAcquireSpinLockAtDpcLevel(SpinLock);
return Ret;
}
@@ -197,7 +214,7 @@
#define CheckSpinLock(SpinLock, CheckData, Value) do \
{ \
- BOOLEAN Ret = SpinLock ? KeTestSpinLock(SpinLock) : TRUE; \
+ BOOLEAN Ret = SpinLock && pKeTestSpinLock ? pKeTestSpinLock(SpinLock) : TRUE;
\
KIRQL ExpectedIrql = (CheckData)->OriginalIrql; \
\
switch ((CheckData)->Check) \
@@ -257,7 +274,10 @@
}
if (CheckData->AcquireNoRaise &&
- (CheckData->OriginalIrql >= DISPATCH_LEVEL || !KmtIsCheckedBuild))
+ (CheckData->OriginalIrql >= DISPATCH_LEVEL || !KmtIsCheckedBuild)
&&
+ (CheckData->AcquireNoRaise != AcquireInStackForDpc ||
+ !skip(pKeAcquireInStackQueuedSpinLockForDpc &&
+ pKeReleaseInStackQueuedSpinLockForDpc, "No DPC spinlock
functions\n")))
{
/* acquire/release without irql change */
CheckData->AcquireNoRaise(SpinLock, CheckData);
@@ -279,7 +299,8 @@
CheckData->IsAcquired = FALSE;
KmtSetIrql(CheckData->OriginalIrql);
- if (CheckData->TryAcquireNoRaise)
+ if (CheckData->TryAcquireNoRaise &&
+ !skip(pKeTryToAcquireSpinLockAtDpcLevel != NULL,
"KeTryToAcquireSpinLockAtDpcLevel unavailable\n"))
{
CheckSpinLock(SpinLock, CheckData, 0);
ok_bool_true(CheckData->TryAcquireNoRaise(SpinLock, CheckData),
"TryAcquireNoRaise returned");
@@ -320,7 +341,14 @@
{ CheckQueue, SynchIrql, AcquireQueuedSynch, ReleaseQueued,
TryQueuedSynch, NULL, NULL, NULL, LockQueuePfnLock
},
};
int i, iIrql;
- PKPRCB Prcb = KeGetCurrentPrcb();
+ PKPRCB Prcb;
+
+ pKeTryToAcquireSpinLockAtDpcLevel =
KmtGetSystemRoutineAddress(L"KeTryToAcquireSpinLockAtDpcLevel");
+ pKeAcquireInStackQueuedSpinLockForDpc =
KmtGetSystemRoutineAddress(L"KeAcquireInStackQueuedSpinLockForDpc");
+ pKeReleaseInStackQueuedSpinLockForDpc =
KmtGetSystemRoutineAddress(L"KeReleaseInStackQueuedSpinLockForDpc");
+ pKeTestSpinLock = KmtGetSystemRoutineAddress(L"KeTestSpinLock");
+
+ Prcb = KeGetCurrentPrcb();
/* KeInitializeSpinLock */
memset(&SpinLock, 0x55, sizeof SpinLock);
@@ -328,17 +356,20 @@
ok_eq_ulongptr(SpinLock, 0);
/* KeTestSpinLock */
- ok_bool_true(KeTestSpinLock(&SpinLock), "KeTestSpinLock returned");
- SpinLock = 1;
- ok_bool_false(KeTestSpinLock(&SpinLock), "KeTestSpinLock returned");
- SpinLock = 2;
- ok_bool_false(KeTestSpinLock(&SpinLock), "KeTestSpinLock returned");
- SpinLock = (ULONG_PTR)-1;
- ok_bool_false(KeTestSpinLock(&SpinLock), "KeTestSpinLock returned");
- SpinLock = (ULONG_PTR)1 << (sizeof(ULONG_PTR) * CHAR_BIT - 1);
- ok_bool_false(KeTestSpinLock(&SpinLock), "KeTestSpinLock returned");
- SpinLock = 0;
- ok_bool_true(KeTestSpinLock(&SpinLock), "KeTestSpinLock returned");
+ if (!skip(pKeTestSpinLock != NULL, "KeTestSpinLock unavailable\n"))
+ {
+ ok_bool_true(pKeTestSpinLock(&SpinLock), "KeTestSpinLock
returned");
+ SpinLock = 1;
+ ok_bool_false(pKeTestSpinLock(&SpinLock), "KeTestSpinLock
returned");
+ SpinLock = 2;
+ ok_bool_false(pKeTestSpinLock(&SpinLock), "KeTestSpinLock
returned");
+ SpinLock = (ULONG_PTR)-1;
+ ok_bool_false(pKeTestSpinLock(&SpinLock), "KeTestSpinLock
returned");
+ SpinLock = (ULONG_PTR)1 << (sizeof(ULONG_PTR) * CHAR_BIT - 1);
+ ok_bool_false(pKeTestSpinLock(&SpinLock), "KeTestSpinLock
returned");
+ SpinLock = 0;
+ ok_bool_true(pKeTestSpinLock(&SpinLock), "KeTestSpinLock
returned");
+ }
/* on UP none of the following functions actually looks at the spinlock! */
if (!KmtIsMultiProcessorBuild && !KmtIsCheckedBuild)