From d57ba73e962955d928a72d7fa23a90b3dbb6e50c Mon Sep 17 00:00:00 2001 From: Zebediah Figura Date: Tue, 29 Jan 2019 21:39:05 -0600 Subject: [PATCH 04/13] ntoskrnl.exe: Implement ExAcquireSharedStarveExclusive(). Signed-off-by: Zebediah Figura --- dlls/ntoskrnl.exe/ntoskrnl.exe.spec | 2 +- dlls/ntoskrnl.exe/sync.c | 61 +++++++++++++++++++++++++++++ include/ddk/wdm.h | 1 + 3 files changed, 63 insertions(+), 1 deletion(-) diff --git a/dlls/ntoskrnl.exe/ntoskrnl.exe.spec b/dlls/ntoskrnl.exe/ntoskrnl.exe.spec index 217f27ff..4609c86d 100644 --- a/dlls/ntoskrnl.exe/ntoskrnl.exe.spec +++ b/dlls/ntoskrnl.exe/ntoskrnl.exe.spec @@ -122,7 +122,7 @@ @ stub DbgSetDebugFilterState @ stdcall ExAcquireResourceExclusiveLite(ptr long) @ stdcall ExAcquireResourceSharedLite(ptr long) -@ stub ExAcquireSharedStarveExclusive +@ stdcall ExAcquireSharedStarveExclusive(ptr long) @ stub ExAcquireSharedWaitForExclusive @ stub ExAllocateFromPagedLookasideList @ stdcall ExAllocatePool(long long) diff --git a/dlls/ntoskrnl.exe/sync.c b/dlls/ntoskrnl.exe/sync.c index b37a46e4..3033c8a2 100644 --- a/dlls/ntoskrnl.exe/sync.c +++ b/dlls/ntoskrnl.exe/sync.c @@ -825,3 +825,64 @@ BOOLEAN WINAPI ExAcquireResourceSharedLite( ERESOURCE *resource, BOOLEAN wait ) return TRUE; } + +/*********************************************************************** + * ExAcquireSharedStarveExclusive (NTOSKRNL.EXE.@) + */ +BOOLEAN WINAPI ExAcquireSharedStarveExclusive( ERESOURCE *resource, BOOLEAN wait ) +{ + OWNER_ENTRY *entry; + KIRQL irql; + + TRACE("resource %p, wait %u.\n", resource, wait); + + KeAcquireSpinLock( &resource->SpinLock, &irql ); + + entry = resource_get_shared_entry( resource, (ERESOURCE_THREAD)KeGetCurrentThread() ); + + if (resource->Flag & ResourceOwnedExclusive) + { + if (resource->OwnerEntry.OwnerThread == (ERESOURCE_THREAD)KeGetCurrentThread()) + { + resource->ActiveEntries++; + KeReleaseSpinLock( &resource->SpinLock, irql ); + return TRUE; + } + } + else if (resource->ActiveEntries || !resource->NumberOfExclusiveWaiters) + { + /* We are starving exclusive waiters, but we cannot steal the resource + * out from under an exclusive waiter who is about to acquire it. */ + entry->OwnerCount++; + resource->ActiveEntries++; + KeReleaseSpinLock( &resource->SpinLock, irql ); + return TRUE; + } + + if (!wait) + { + KeReleaseSpinLock( &resource->SpinLock, irql ); + return FALSE; + } + + if (!resource->SharedWaiters) + { + resource->SharedWaiters = heap_alloc( sizeof(*resource->SharedWaiters) ); + KeInitializeSemaphore( resource->SharedWaiters, 0, INT_MAX ); + } + resource->NumberOfSharedWaiters++; + + KeReleaseSpinLock( &resource->SpinLock, irql ); + + KeWaitForSingleObject( resource->SharedWaiters, Executive, KernelMode, FALSE, NULL ); + + KeAcquireSpinLock( &resource->SpinLock, &irql ); + + entry->OwnerCount++; + resource->ActiveEntries++; + resource->NumberOfSharedWaiters--; + + KeReleaseSpinLock( &resource->SpinLock, irql ); + + return TRUE; +} diff --git a/include/ddk/wdm.h b/include/ddk/wdm.h index 14d4ba4e..a65974da 100644 --- a/include/ddk/wdm.h +++ b/include/ddk/wdm.h @@ -1514,6 +1514,7 @@ NTSTATUS WINAPI DbgQueryDebugFilterState(ULONG, ULONG); void WINAPI ExAcquireFastMutexUnsafe(PFAST_MUTEX); BOOLEAN WINAPI ExAcquireResourceExclusiveLite(ERESOURCE*,BOOLEAN); BOOLEAN WINAPI ExAcquireResourceSharedLite(ERESOURCE*,BOOLEAN); +BOOLEAN WINAPI ExAcquireSharedStarveExclusive(ERESOURCE*,BOOLEAN); PVOID WINAPI ExAllocatePool(POOL_TYPE,SIZE_T); PVOID WINAPI ExAllocatePoolWithQuota(POOL_TYPE,SIZE_T); PVOID WINAPI ExAllocatePoolWithTag(POOL_TYPE,SIZE_T,ULONG); -- 2.20.1