18*pExEnterCriticalRegionAndAcquireResourceShared)(
27*pExEnterCriticalRegionAndAcquireResourceExclusive)(
36*pExEnterCriticalRegionAndAcquireSharedWaitForExclusive)(
45*pExReleaseResourceAndLeaveCriticalRegion)(
54*pKeAreAllApcsDisabled)(
VOID);
60typedef struct _ERESOURCE_2K3 {
66 volatile PKEVENT ExclusiveWaiters;
68 ULONG ContentionCount;
69 USHORT NumberOfSharedWaiters;
70 USHORT NumberOfExclusiveWaiters;
78#define CheckResourceFields(Res, Reinit) do \
80 ok_eq_pointer((Res)->SystemResourcesList.Flink->Blink, &(Res)->SystemResourcesList); \
81 ok_eq_pointer((Res)->SystemResourcesList.Blink->Flink, &(Res)->SystemResourcesList); \
82 if (!Reinit) ok_eq_pointer((Res)->OwnerTable, NULL); \
83 ok_eq_int((Res)->ActiveCount, 0); \
84 ok_eq_uint((Res)->Flag, 0); \
85 if (!Reinit) ok_eq_pointer((Res)->SharedWaiters, NULL); \
86 if (!Reinit) ok_eq_pointer((Res)->ExclusiveWaiters, NULL); \
87 ok_eq_ulongptr((Res)->OwnerThreads[0].OwnerThread, 0); \
88 ok_eq_ulong((Res)->OwnerThreads[0].TableSize, 0LU); \
89 ok_eq_ulongptr((Res)->OwnerThreads[1].OwnerThread, 0); \
90 ok_eq_ulong((Res)->OwnerThreads[1].TableSize, 0LU); \
91 ok_eq_ulong((Res)->ContentionCount, 0LU); \
92 ok_eq_uint((Res)->NumberOfSharedWaiters, 0); \
93 ok_eq_uint((Res)->NumberOfExclusiveWaiters, 0); \
94 ok_eq_pointer((Res)->Address, NULL); \
95 ok_eq_ulongptr((Res)->SpinLock, 0); \
98#define CheckResourceStatus(Res, Exclusive, Shared, ExclusiveWaiters, SharedWaiters) do \
101 ok_bool_true(ExIsResourceAcquiredExclusiveLite(Res), "ExIsResourceAcquiredExclusiveLite returned"); \
103 ok_bool_false(ExIsResourceAcquiredExclusiveLite(Res), "ExIsResourceAcquiredExclusiveLite returned"); \
104 ok_eq_ulong(ExIsResourceAcquiredSharedLite(Res), Shared); \
105 ok_eq_ulong(ExGetExclusiveWaiterCount(Res), ExclusiveWaiters); \
106 ok_eq_ulong(ExGetSharedWaiterCount(Res), SharedWaiters); \
183 if (pKeAreAllApcsDisabled)
184 ok_eq_uint(pKeAreAllApcsDisabled(), AreApcsDisabled);
186 if (
skip(pExEnterCriticalRegionAndAcquireResourceShared &&
187 pExEnterCriticalRegionAndAcquireSharedWaitForExclusive &&
188 pExEnterCriticalRegionAndAcquireResourceExclusive &&
189 pExReleaseResourceAndLeaveCriticalRegion,
"No shortcuts\n"))
195 Ret = pExEnterCriticalRegionAndAcquireResourceShared(Res); ++
Count;
198 if (pKeAreAllApcsDisabled)
199 ok_eq_bool(pKeAreAllApcsDisabled(), AreApcsDisabled);
202 Ret = pExEnterCriticalRegionAndAcquireResourceShared(Res); ++
Count;
205 if (pKeAreAllApcsDisabled)
206 ok_eq_bool(pKeAreAllApcsDisabled(), AreApcsDisabled);
209 pExEnterCriticalRegionAndAcquireSharedWaitForExclusive(Res); ++
Count;
212 if (pKeAreAllApcsDisabled)
213 ok_eq_bool(pKeAreAllApcsDisabled(), AreApcsDisabled);
218 pExReleaseResourceAndLeaveCriticalRegion(Res);
220 if (pKeAreAllApcsDisabled)
221 ok_eq_bool(pKeAreAllApcsDisabled(), AreApcsDisabled);
225 pExReleaseResourceAndLeaveCriticalRegion(Res);
227 if (pKeAreAllApcsDisabled)
228 ok_eq_bool(pKeAreAllApcsDisabled(), AreApcsDisabled);
234 if (pKeAreAllApcsDisabled)
235 ok_eq_bool(pKeAreAllApcsDisabled(), AreApcsDisabled);
236 Ret = pExEnterCriticalRegionAndAcquireResourceExclusive(Res); ++
Count;
239 if (pKeAreAllApcsDisabled)
240 ok_eq_bool(pKeAreAllApcsDisabled(), AreApcsDisabled);
243 Ret = pExEnterCriticalRegionAndAcquireResourceExclusive(Res); ++
Count;
246 if (pKeAreAllApcsDisabled)
247 ok_eq_bool(pKeAreAllApcsDisabled(), AreApcsDisabled);
250 pExReleaseResourceAndLeaveCriticalRegion(Res); --
Count;
252 if (pKeAreAllApcsDisabled)
253 ok_eq_bool(pKeAreAllApcsDisabled(), AreApcsDisabled);
256 pExReleaseResourceAndLeaveCriticalRegion(Res); --
Count;
258 if (pKeAreAllApcsDisabled)
259 ok_eq_uint(pKeAreAllApcsDisabled(), AreApcsDisabled);
315 ThreadData->AcquireResource = AcquireFunction;
381 Timeout.QuadPart = -10 * 1000 * 10;
528 pExEnterCriticalRegionAndAcquireSharedWaitForExclusive =
KmtGetSystemRoutineAddress(
L"ExEnterCriticalRegionAndAcquireSharedWaitForExclusive");
529 pExEnterCriticalRegionAndAcquireResourceExclusive =
KmtGetSystemRoutineAddress(
L"ExEnterCriticalRegionAndAcquireResourceExclusive");
533 if (
skip(pKeAreAllApcsDisabled !=
NULL,
"KeAreAllApcsDisabled unavailable\n"))
551 memset(&Res, 0x55,
sizeof Res);
static VOID InitThreadData(PTHREAD_DATA ThreadData, PERESOURCE Res, PACQUIRE_FUNCTION AcquireFunction)
static VOID TestResourceWithThreads(IN PERESOURCE Res)
static VOID FinishThread(PTHREAD_DATA ThreadData)
static VOID InitThreadDataEx(PTHREAD_DATA ThreadData, PERESOURCE Res, PACQUIRE_FUNCTION AcquireFunction, PKSTART_ROUTINE StartRoutine)
static VOID NTAPI AcquireResourceThread(PVOID Context)
static VOID TestResourceExclusiveAccess(IN PERESOURCE Res)
static VOID NTAPI TestOwnerRes(PVOID Context)
static VOID TestResourceSharedAccess(IN PERESOURCE Res)
#define CheckResourceFields(Res, Reinit)
static VOID TestResourceUndocumentedShortcuts(IN PERESOURCE Res, IN BOOLEAN AreApcsDisabled)
static NTSTATUS StartThread(PTHREAD_DATA ThreadData, PLARGE_INTEGER Timeout, BOOLEAN Wait, BOOLEAN RetExpected)
struct THREAD_DATA * PTHREAD_DATA
static VOID TestResourceWithOwner(IN PERESOURCE Res)
BOOLEAN(NTAPI * PACQUIRE_FUNCTION)(PERESOURCE, BOOLEAN)
#define CheckResourceStatus(Res, Exclusive, Shared, ExclusiveWaiters, SharedWaiters)
#define ok_eq_pointer(value, expected)
#define ok_eq_hex(value, expected)
#define ok_bool_false(value, desc)
#define ok_eq_uint(value, expected)
#define ok_bool_true(value, desc)
#define ok_eq_int(value, expected)
#define ok_eq_bool(value, expected)
_Acquires_exclusive_lock_ Resource _Acquires_shared_lock_ Resource _Inout_ PERESOURCE Resource
#define _Acquires_lock_(lock)
#define _Requires_lock_held_(lock)
#define _Acquires_exclusive_lock_(lock)
#define _Acquires_shared_lock_(lock)
#define _Requires_lock_not_held_(lock)
#define _Releases_lock_(lock)
#define ResourceOwnedExclusive
#define _IRQL_requires_min_(irql)
#define _IRQL_requires_max_(irql)
#define ExReleaseResourceForThreadLite(res, thrdID)
#define KeRaiseIrql(irql, oldIrql)
NTSTATUS ExInitializeResourceLite(PULONG res)
#define KeWaitForSingleObject(pEvt, foo, a, b, c)
#define KeInitializeEvent(pEvt, foo, foo2)
#define KeLowerIrql(oldIrql)
#define ExConvertExclusiveToSharedLite(res)
#define KeSetEvent(pEvt, foo, foo2)
#define ExAcquireResourceExclusiveLite(res, wait)
#define ExDeleteResourceLite(res)
#define ExAcquireResourceSharedLite(res, wait)
VOID NTAPI KeClearEvent(IN PKEVENT Event)
IN OUT PLONG IN OUT PLONG Addend IN OUT PLONG IN LONG IN OUT PLONG IN LONG Increment KeRaiseIrqlToDpcLevel
_In_opt_ PFILE_OBJECT _In_opt_ PETHREAD Thread
#define KeGetCurrentThread
#define OBJ_KERNEL_HANDLE
#define EXCEPTION_EXECUTE_HANDLER
#define KeLeaveCriticalRegion()
#define KeEnterCriticalRegion()
PVOID KmtGetSystemRoutineAddress(IN PCWSTR RoutineName)
BOOLEAN KmtIsCheckedBuild
#define InitializeObjectAttributes(p, n, a, r, s)
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
VOID NTAPI ExSetResourceOwnerPointer(IN PERESOURCE Resource, IN PVOID OwnerPointer)
BOOLEAN NTAPI ExAcquireSharedWaitForExclusive(IN PERESOURCE Resource, IN BOOLEAN Wait)
NTSTATUS NTAPI ExReinitializeResourceLite(IN PERESOURCE Resource)
BOOLEAN NTAPI ExAcquireSharedStarveExclusive(IN PERESOURCE Resource, IN BOOLEAN Wait)
VOID FASTCALL ExReleaseResourceLite(IN PERESOURCE Resource)
BOOLEAN NTAPI KeAreApcsDisabled(VOID)
POBJECT_TYPE PsThreadType
NTSTATUS NTAPI PsCreateSystemThread(OUT PHANDLE ThreadHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes, IN HANDLE ProcessHandle, IN PCLIENT_ID ClientId, IN PKSTART_ROUTINE StartRoutine, IN PVOID StartContext)
#define STATUS_ACCESS_VIOLATION
NTSTATUS NTAPI ObReferenceObjectByHandle(IN HANDLE Handle, IN ACCESS_MASK DesiredAccess, IN POBJECT_TYPE ObjectType, IN KPROCESSOR_MODE AccessMode, OUT PVOID *Object, OUT POBJECT_HANDLE_INFORMATION HandleInformation OPTIONAL)
#define _SEH2_GetExceptionCode()
#define _SEH2_EXCEPT(...)
PKSTART_ROUTINE StartRoutine
PACQUIRE_FUNCTION AcquireResource
_Must_inspect_result_ _In_ WDFDMAENABLER _In_ _In_opt_ PWDF_OBJECT_ATTRIBUTES Attributes
_In_ WDFDPC _In_ BOOLEAN Wait
_Must_inspect_result_ _In_opt_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFSPINLOCK * SpinLock
#define ExReleaseResource(R)
KSTART_ROUTINE * PKSTART_ROUTINE
#define ObDereferenceObject
_In_ ULONG _In_opt_ POBJECT_ATTRIBUTES _In_opt_ HANDLE _Out_opt_ PCLIENT_ID _In_ PKSTART_ROUTINE StartRoutine