diff --git a/patches/ntoskrnl-Stubs/definition b/patches/ntoskrnl-Stubs/definition index 125866aa..a03b480e 100644 --- a/patches/ntoskrnl-Stubs/definition +++ b/patches/ntoskrnl-Stubs/definition @@ -1,3 +1,2 @@ Fixes: Add stub for ntoskrnl.Mm{Map,Unmap}LockedPages Fixes: Add stub for ntoskrnl.IoGetDeviceAttachmentBaseRef -Fixes: Implement ntoskrnl.NtBuildNumber diff --git a/patches/ntoskrnl.exe-Resources/0001-ntoskrnl.exe-Implement-ExInitializeResourceLite.patch b/patches/ntoskrnl.exe-Resources/0001-ntoskrnl.exe-Implement-ExInitializeResourceLite.patch new file mode 100644 index 00000000..aa9083c7 --- /dev/null +++ b/patches/ntoskrnl.exe-Resources/0001-ntoskrnl.exe-Implement-ExInitializeResourceLite.patch @@ -0,0 +1,132 @@ +From 635759b4f374469956488aaf6fa4c6307a542ee9 Mon Sep 17 00:00:00 2001 +From: Zebediah Figura +Date: Tue, 29 Jan 2019 21:33:08 -0600 +Subject: [PATCH 01/13] ntoskrnl.exe: Implement ExInitializeResourceLite(). + +Signed-off-by: Zebediah Figura +--- + dlls/ntoskrnl.exe/ntoskrnl.c | 11 -------- + dlls/ntoskrnl.exe/sync.c | 10 +++++++ + include/ddk/wdm.h | 54 +++++++++++++++++++++++++++++++++++- + 3 files changed, 63 insertions(+), 12 deletions(-) + +diff --git a/dlls/ntoskrnl.exe/ntoskrnl.c b/dlls/ntoskrnl.exe/ntoskrnl.c +index 4b626607..93ba89be 100644 +--- a/dlls/ntoskrnl.exe/ntoskrnl.c ++++ b/dlls/ntoskrnl.exe/ntoskrnl.c +@@ -2081,17 +2081,6 @@ void WINAPI ExFreePoolWithTag( void *ptr, ULONG tag ) + HeapFree( GetProcessHeap(), 0, ptr ); + } + +- +-/*********************************************************************** +- * ExInitializeResourceLite (NTOSKRNL.EXE.@) +- */ +-NTSTATUS WINAPI ExInitializeResourceLite(PERESOURCE Resource) +-{ +- FIXME( "stub: %p\n", Resource ); +- return STATUS_NOT_IMPLEMENTED; +-} +- +- + /*********************************************************************** + * ExInitializeNPagedLookasideList (NTOSKRNL.EXE.@) + */ +diff --git a/dlls/ntoskrnl.exe/sync.c b/dlls/ntoskrnl.exe/sync.c +index 98b3f9d9..56d46a86 100644 +--- a/dlls/ntoskrnl.exe/sync.c ++++ b/dlls/ntoskrnl.exe/sync.c +@@ -663,3 +663,13 @@ void WINAPI ExReleaseFastMutexUnsafe( FAST_MUTEX *mutex ) + if (count < 1) + KeSetEvent( &mutex->Event, IO_NO_INCREMENT, FALSE ); + } ++ ++/*********************************************************************** ++ * ExInitializeResourceLite (NTOSKRNL.EXE.@) ++ */ ++NTSTATUS WINAPI ExInitializeResourceLite( ERESOURCE *resource ) ++{ ++ TRACE("resource %p.\n", resource); ++ memset(resource, 0, sizeof(*resource)); ++ return STATUS_SUCCESS; ++} +diff --git a/include/ddk/wdm.h b/include/ddk/wdm.h +index 293da50c..f76444f1 100644 +--- a/include/ddk/wdm.h ++++ b/include/ddk/wdm.h +@@ -153,12 +153,63 @@ typedef struct _KWAIT_BLOCK { + USHORT WaitType; + } KWAIT_BLOCK, *PKWAIT_BLOCK, *RESTRICTED_POINTER PRKWAIT_BLOCK; + ++typedef struct _OWNER_ENTRY ++{ ++ ERESOURCE_THREAD OwnerThread; ++ union ++ { ++ struct ++ { ++ ULONG IoPriorityBoosted : 1; ++ ULONG OwnerReferenced : 1; ++ ULONG IoQoSPriorityBoosted : 1; ++ ULONG OwnerCount : 29; ++ }; ++ ULONG TableSize; ++ }; ++} OWNER_ENTRY, *POWNER_ENTRY; ++ ++#define ResourceNeverExclusive 0x0010 ++#define ResourceReleaseByOtherThread 0x0020 ++#define ResourceOwnedExclusive 0x0080 ++ ++typedef struct _ERESOURCE ++{ ++ LIST_ENTRY SystemResourcesList; ++ OWNER_ENTRY *OwnerTable; ++ SHORT ActiveCount; ++ union ++ { ++ USHORT Flag; ++ struct ++ { ++ UCHAR ReservedLowFlags; ++ UCHAR WaiterPriority; ++ }; ++ }; ++ KSEMAPHORE *SharedWaiters; ++ KEVENT *ExclusiveWaiters; ++ OWNER_ENTRY OwnerEntry; ++ ULONG ActiveEntries; ++ ULONG ContentionCount; ++ ULONG NumberOfSharedWaiters; ++ ULONG NumberOfExclusiveWaiters; ++#ifdef _WIN64 ++ void *Reserved2; ++#endif ++ union ++ { ++ void *Address; ++ ULONG_PTR CreatorBackTraceIndex; ++ }; ++ KSPIN_LOCK SpinLock; ++} ERESOURCE, *PERESOURCE; ++ + typedef struct _IO_TIMER *PIO_TIMER; + typedef struct _IO_TIMER_ROUTINE *PIO_TIMER_ROUTINE; + typedef struct _ETHREAD *PETHREAD; + typedef struct _KTHREAD *PKTHREAD, *PRKTHREAD; + typedef struct _EPROCESS *PEPROCESS; +-typedef struct _ERESOURCE *PERESOURCE; + typedef struct _IO_WORKITEM *PIO_WORKITEM; + typedef struct _PAGED_LOOKASIDE_LIST *PPAGED_LOOKASIDE_LIST; + typedef struct _OBJECT_TYPE *POBJECT_TYPE; +@@ -1469,6 +1520,7 @@ void WINAPI ExDeleteNPagedLookasideList(PNPAGED_LOOKASIDE_LIST); + void WINAPI ExFreePool(PVOID); + void WINAPI ExFreePoolWithTag(PVOID,ULONG); + void WINAPI ExInitializeNPagedLookasideList(PNPAGED_LOOKASIDE_LIST,PALLOCATE_FUNCTION,PFREE_FUNCTION,ULONG,SIZE_T,ULONG,USHORT); ++NTSTATUS WINAPI ExInitializeResourceLite(ERESOURCE*); + PSLIST_ENTRY WINAPI ExInterlockedPopEntrySList(PSLIST_HEADER,PKSPIN_LOCK); + PSLIST_ENTRY WINAPI ExInterlockedPushEntrySList(PSLIST_HEADER,PSLIST_ENTRY,PKSPIN_LOCK); + LIST_ENTRY * WINAPI ExInterlockedRemoveHeadList(LIST_ENTRY*,KSPIN_LOCK*); +-- +2.20.1 + diff --git a/patches/ntoskrnl.exe-Resources/0002-ntoskrnl.exe-Implement-ExAcquireResourceExclusiveLit.patch b/patches/ntoskrnl.exe-Resources/0002-ntoskrnl.exe-Implement-ExAcquireResourceExclusiveLit.patch new file mode 100644 index 00000000..a3e847bb --- /dev/null +++ b/patches/ntoskrnl.exe-Resources/0002-ntoskrnl.exe-Implement-ExAcquireResourceExclusiveLit.patch @@ -0,0 +1,143 @@ +From 0a7df47900ff847f137836341d086dc5690f97d7 Mon Sep 17 00:00:00 2001 +From: Zebediah Figura +Date: Tue, 29 Jan 2019 21:35:44 -0600 +Subject: [PATCH 02/13] ntoskrnl.exe: Implement + ExAcquireResourceExclusiveLite(). + +Signed-off-by: Zebediah Figura +--- + dlls/ntoskrnl.exe/ntoskrnl.c | 9 ----- + dlls/ntoskrnl.exe/sync.c | 73 ++++++++++++++++++++++++++++++++++++ + include/ddk/wdm.h | 1 + + 3 files changed, 74 insertions(+), 9 deletions(-) + +diff --git a/dlls/ntoskrnl.exe/ntoskrnl.c b/dlls/ntoskrnl.exe/ntoskrnl.c +index 93ba89be..d6c35d1c 100644 +--- a/dlls/ntoskrnl.exe/ntoskrnl.c ++++ b/dlls/ntoskrnl.exe/ntoskrnl.c +@@ -3038,15 +3038,6 @@ NTSTATUS WINAPI IoCsqInitialize(PIO_CSQ csq, PIO_CSQ_INSERT_IRP insert_irp, PIO_ + return STATUS_SUCCESS; + } + +-/*********************************************************************** +- * ExAcquireResourceExclusiveLite (NTOSKRNL.EXE.@) +- */ +-BOOLEAN WINAPI ExAcquireResourceExclusiveLite( PERESOURCE resource, BOOLEAN wait ) +-{ +- FIXME( ":%p %u stub\n", resource, wait ); +- return TRUE; +-} +- + /*********************************************************************** + * ExDeleteResourceLite (NTOSKRNL.EXE.@) + */ +diff --git a/dlls/ntoskrnl.exe/sync.c b/dlls/ntoskrnl.exe/sync.c +index 56d46a86..205914a7 100644 +--- a/dlls/ntoskrnl.exe/sync.c ++++ b/dlls/ntoskrnl.exe/sync.c +@@ -30,6 +30,7 @@ + #include "ddk/wdm.h" + + #include "wine/debug.h" ++#include "wine/heap.h" + + #include "ntoskrnl_private.h" + +@@ -664,6 +665,18 @@ void WINAPI ExReleaseFastMutexUnsafe( FAST_MUTEX *mutex ) + KeSetEvent( &mutex->Event, IO_NO_INCREMENT, FALSE ); + } + ++/* Use of the fields of an ERESOURCE structure seems to vary wildly between ++ * Windows versions. The below implementation uses them as follows: ++ * ++ * OwnerTable - contains a list of shared owners (TID and recursion count), ++ * including threads which do not currently own the resource ++ * (recursion count == 0) ++ * OwnerEntry.OwnerThread - the owner TID if exclusively owned ++ * OwnerEntry.TableSize - the number of entries in OwnerTable, including threads ++ * which do not currently own the resource ++ * ActiveEntries - total number of acquisitions (incl. recursive ones) ++ */ ++ + /*********************************************************************** + * ExInitializeResourceLite (NTOSKRNL.EXE.@) + */ +@@ -673,3 +686,63 @@ NTSTATUS WINAPI ExInitializeResourceLite( ERESOURCE *resource ) + memset(resource, 0, sizeof(*resource)); + return STATUS_SUCCESS; + } ++ ++/*********************************************************************** ++ * ExAcquireResourceExclusiveLite (NTOSKRNL.EXE.@) ++ */ ++BOOLEAN WINAPI ExAcquireResourceExclusiveLite( ERESOURCE *resource, BOOLEAN wait ) ++{ ++ KIRQL irql; ++ ++ TRACE("resource %p, wait %u.\n", resource, wait); ++ ++ KeAcquireSpinLock( &resource->SpinLock, &irql ); ++ ++ FIXME("%#lx/%d/%d/%d\n", resource->OwnerEntry.OwnerThread, resource->ActiveEntries, ++ resource->NumberOfExclusiveWaiters, resource->NumberOfSharedWaiters); ++ ++ if (resource->OwnerEntry.OwnerThread == (ERESOURCE_THREAD)KeGetCurrentThread()) ++ { ++ resource->ActiveEntries++; ++ KeReleaseSpinLock( &resource->SpinLock, irql ); ++ return TRUE; ++ } ++ else if (!resource->ActiveEntries && !resource->NumberOfExclusiveWaiters && !resource->NumberOfSharedWaiters) ++ { ++ /* In order to avoid a race between waiting for the ExclusiveWaiters ++ * event and grabbing the lock, do not grab the resource if it is ++ * unclaimed but has waiters; instead queue ourselves. */ ++ resource->Flag |= ResourceOwnedExclusive; ++ resource->OwnerEntry.OwnerThread = (ERESOURCE_THREAD)KeGetCurrentThread(); ++ resource->ActiveEntries++; ++ KeReleaseSpinLock( &resource->SpinLock, irql ); ++ return TRUE; ++ } ++ else if (!wait) ++ { ++ KeReleaseSpinLock( &resource->SpinLock, irql ); ++ return FALSE; ++ } ++ ++ if (!resource->ExclusiveWaiters) ++ { ++ resource->ExclusiveWaiters = heap_alloc( sizeof(*resource->ExclusiveWaiters) ); ++ KeInitializeEvent( resource->ExclusiveWaiters, SynchronizationEvent, FALSE ); ++ } ++ resource->NumberOfExclusiveWaiters++; ++ ++ KeReleaseSpinLock( &resource->SpinLock, irql ); ++ ++ KeWaitForSingleObject( resource->ExclusiveWaiters, Executive, KernelMode, FALSE, NULL ); ++ ++ KeAcquireSpinLock( &resource->SpinLock, &irql ); ++ ++ resource->Flag |= ResourceOwnedExclusive; ++ resource->OwnerEntry.OwnerThread = (ERESOURCE_THREAD)KeGetCurrentThread(); ++ resource->ActiveEntries++; ++ resource->NumberOfExclusiveWaiters--; ++ ++ KeReleaseSpinLock( &resource->SpinLock, irql ); ++ ++ return TRUE; ++} +diff --git a/include/ddk/wdm.h b/include/ddk/wdm.h +index f76444f1..a8cbdc2e 100644 +--- a/include/ddk/wdm.h ++++ b/include/ddk/wdm.h +@@ -1512,6 +1512,7 @@ static inline void IoSetCompletionRoutine(IRP *irp, PIO_COMPLETION_ROUTINE routi + + NTSTATUS WINAPI DbgQueryDebugFilterState(ULONG, ULONG); + void WINAPI ExAcquireFastMutexUnsafe(PFAST_MUTEX); ++BOOLEAN WINAPI ExAcquireResourceExclusiveLite(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 + diff --git a/patches/ntoskrnl.exe-Resources/0003-ntoskrnl.exe-Implement-ExAcquireResourceSharedLite.patch b/patches/ntoskrnl.exe-Resources/0003-ntoskrnl.exe-Implement-ExAcquireResourceSharedLite.patch new file mode 100644 index 00000000..f38f56fa --- /dev/null +++ b/patches/ntoskrnl.exe-Resources/0003-ntoskrnl.exe-Implement-ExAcquireResourceSharedLite.patch @@ -0,0 +1,141 @@ +From a1fc7aa628beedda24325ce4de8231ed03b2b184 Mon Sep 17 00:00:00 2001 +From: Zebediah Figura +Date: Tue, 29 Jan 2019 21:37:38 -0600 +Subject: [PATCH 03/13] ntoskrnl.exe: Implement ExAcquireResourceSharedLite(). + +Signed-off-by: Zebediah Figura +--- + dlls/ntoskrnl.exe/ntoskrnl.exe.spec | 2 +- + dlls/ntoskrnl.exe/sync.c | 79 +++++++++++++++++++++++++++++ + include/ddk/wdm.h | 1 + + 3 files changed, 81 insertions(+), 1 deletion(-) + +diff --git a/dlls/ntoskrnl.exe/ntoskrnl.exe.spec b/dlls/ntoskrnl.exe/ntoskrnl.exe.spec +index d0874226..217f27ff 100644 +--- a/dlls/ntoskrnl.exe/ntoskrnl.exe.spec ++++ b/dlls/ntoskrnl.exe/ntoskrnl.exe.spec +@@ -121,7 +121,7 @@ + @ stdcall DbgQueryDebugFilterState(long long) + @ stub DbgSetDebugFilterState + @ stdcall ExAcquireResourceExclusiveLite(ptr long) +-@ stub ExAcquireResourceSharedLite ++@ stdcall ExAcquireResourceSharedLite(ptr long) + @ stub ExAcquireSharedStarveExclusive + @ stub ExAcquireSharedWaitForExclusive + @ stub ExAllocateFromPagedLookasideList +diff --git a/dlls/ntoskrnl.exe/sync.c b/dlls/ntoskrnl.exe/sync.c +index 205914a7..b37a46e4 100644 +--- a/dlls/ntoskrnl.exe/sync.c ++++ b/dlls/ntoskrnl.exe/sync.c +@@ -19,6 +19,7 @@ + */ + + #include "config.h" ++#include + #include + + #include "ntstatus.h" +@@ -687,6 +688,25 @@ NTSTATUS WINAPI ExInitializeResourceLite( ERESOURCE *resource ) + return STATUS_SUCCESS; + } + ++/* Find an existing entry in the shared owner list, or create a new one. */ ++static OWNER_ENTRY *resource_get_shared_entry( ERESOURCE *resource, ERESOURCE_THREAD thread ) ++{ ++ ULONG i, count; ++ ++ for (i = 0; i < resource->OwnerEntry.TableSize; ++i) ++ { ++ if (resource->OwnerTable[i].OwnerThread == thread) ++ return &resource->OwnerTable[i]; ++ } ++ ++ count = ++resource->OwnerEntry.TableSize; ++ resource->OwnerTable = heap_realloc(resource->OwnerTable, count * sizeof(*resource->OwnerTable)); ++ resource->OwnerTable[count - 1].OwnerThread = thread; ++ resource->OwnerTable[count - 1].OwnerCount = 0; ++ ++ return &resource->OwnerTable[count - 1]; ++} ++ + /*********************************************************************** + * ExAcquireResourceExclusiveLite (NTOSKRNL.EXE.@) + */ +@@ -746,3 +766,62 @@ BOOLEAN WINAPI ExAcquireResourceExclusiveLite( ERESOURCE *resource, BOOLEAN wait + + return TRUE; + } ++ ++/*********************************************************************** ++ * ExAcquireResourceSharedLite (NTOSKRNL.EXE.@) ++ */ ++BOOLEAN WINAPI ExAcquireResourceSharedLite( 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 (entry->OwnerCount || !resource->NumberOfExclusiveWaiters) ++ { ++ 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 a8cbdc2e..14d4ba4e 100644 +--- a/include/ddk/wdm.h ++++ b/include/ddk/wdm.h +@@ -1513,6 +1513,7 @@ static inline void IoSetCompletionRoutine(IRP *irp, PIO_COMPLETION_ROUTINE routi + NTSTATUS WINAPI DbgQueryDebugFilterState(ULONG, ULONG); + void WINAPI ExAcquireFastMutexUnsafe(PFAST_MUTEX); + BOOLEAN WINAPI ExAcquireResourceExclusiveLite(ERESOURCE*,BOOLEAN); ++BOOLEAN WINAPI ExAcquireResourceSharedLite(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 + diff --git a/patches/ntoskrnl.exe-Resources/0004-ntoskrnl.exe-Implement-ExAcquireSharedStarveExclusiv.patch b/patches/ntoskrnl.exe-Resources/0004-ntoskrnl.exe-Implement-ExAcquireSharedStarveExclusiv.patch new file mode 100644 index 00000000..8bf33e75 --- /dev/null +++ b/patches/ntoskrnl.exe-Resources/0004-ntoskrnl.exe-Implement-ExAcquireSharedStarveExclusiv.patch @@ -0,0 +1,110 @@ +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 + diff --git a/patches/ntoskrnl.exe-Resources/0005-ntoskrnl.exe-Implement-ExAcquireSharedWaitForExclusi.patch b/patches/ntoskrnl.exe-Resources/0005-ntoskrnl.exe-Implement-ExAcquireSharedWaitForExclusi.patch new file mode 100644 index 00000000..7e418443 --- /dev/null +++ b/patches/ntoskrnl.exe-Resources/0005-ntoskrnl.exe-Implement-ExAcquireSharedWaitForExclusi.patch @@ -0,0 +1,108 @@ +From 3503f4db49ee2c4602fc1af38c97f456a1dea76a Mon Sep 17 00:00:00 2001 +From: Zebediah Figura +Date: Tue, 29 Jan 2019 21:40:19 -0600 +Subject: [PATCH 05/13] ntoskrnl.exe: Implement + ExAcquireSharedWaitForExclusive(). + +Signed-off-by: Zebediah Figura +--- + dlls/ntoskrnl.exe/ntoskrnl.exe.spec | 2 +- + dlls/ntoskrnl.exe/sync.c | 59 +++++++++++++++++++++++++++++ + include/ddk/wdm.h | 1 + + 3 files changed, 61 insertions(+), 1 deletion(-) + +diff --git a/dlls/ntoskrnl.exe/ntoskrnl.exe.spec b/dlls/ntoskrnl.exe/ntoskrnl.exe.spec +index 4609c86d..c32f4590 100644 +--- a/dlls/ntoskrnl.exe/ntoskrnl.exe.spec ++++ b/dlls/ntoskrnl.exe/ntoskrnl.exe.spec +@@ -123,7 +123,7 @@ + @ stdcall ExAcquireResourceExclusiveLite(ptr long) + @ stdcall ExAcquireResourceSharedLite(ptr long) + @ stdcall ExAcquireSharedStarveExclusive(ptr long) +-@ stub ExAcquireSharedWaitForExclusive ++@ stdcall ExAcquireSharedWaitForExclusive(ptr long) + @ stub ExAllocateFromPagedLookasideList + @ stdcall ExAllocatePool(long long) + @ stdcall ExAllocatePoolWithQuota(long long) +diff --git a/dlls/ntoskrnl.exe/sync.c b/dlls/ntoskrnl.exe/sync.c +index 3033c8a2..2fd7f903 100644 +--- a/dlls/ntoskrnl.exe/sync.c ++++ b/dlls/ntoskrnl.exe/sync.c +@@ -886,3 +886,62 @@ BOOLEAN WINAPI ExAcquireSharedStarveExclusive( ERESOURCE *resource, BOOLEAN wait + + return TRUE; + } ++ ++/*********************************************************************** ++ * ExAcquireSharedWaitForExclusive (NTOSKRNL.EXE.@) ++ */ ++BOOLEAN WINAPI ExAcquireSharedWaitForExclusive( 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->NumberOfExclusiveWaiters) ++ { ++ 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 a65974da..010c1ee4 100644 +--- a/include/ddk/wdm.h ++++ b/include/ddk/wdm.h +@@ -1515,6 +1515,7 @@ void WINAPI ExAcquireFastMutexUnsafe(PFAST_MUTEX); + BOOLEAN WINAPI ExAcquireResourceExclusiveLite(ERESOURCE*,BOOLEAN); + BOOLEAN WINAPI ExAcquireResourceSharedLite(ERESOURCE*,BOOLEAN); + BOOLEAN WINAPI ExAcquireSharedStarveExclusive(ERESOURCE*,BOOLEAN); ++BOOLEAN WINAPI ExAcquireSharedWaitForExclusive(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 + diff --git a/patches/ntoskrnl.exe-Resources/0006-ntoskrnl.exe-Implement-ExReleaseResourceForThreadLit.patch b/patches/ntoskrnl.exe-Resources/0006-ntoskrnl.exe-Implement-ExReleaseResourceForThreadLit.patch new file mode 100644 index 00000000..56ecb694 --- /dev/null +++ b/patches/ntoskrnl.exe-Resources/0006-ntoskrnl.exe-Implement-ExReleaseResourceForThreadLit.patch @@ -0,0 +1,116 @@ +From 25b736d558aba82da91d004b8976471df6ef0a64 Mon Sep 17 00:00:00 2001 +From: Zebediah Figura +Date: Tue, 29 Jan 2019 21:41:46 -0600 +Subject: [PATCH 06/13] ntoskrnl.exe: Implement + ExReleaseResourceForThreadLite(). + +Signed-off-by: Zebediah Figura +--- + dlls/ntoskrnl.exe/ntoskrnl.c | 8 ----- + dlls/ntoskrnl.exe/sync.c | 61 ++++++++++++++++++++++++++++++++++++ + include/ddk/wdm.h | 1 + + 3 files changed, 62 insertions(+), 8 deletions(-) + +diff --git a/dlls/ntoskrnl.exe/ntoskrnl.c b/dlls/ntoskrnl.exe/ntoskrnl.c +index d6c35d1c..5ab4db12 100644 +--- a/dlls/ntoskrnl.exe/ntoskrnl.c ++++ b/dlls/ntoskrnl.exe/ntoskrnl.c +@@ -3047,14 +3047,6 @@ NTSTATUS WINAPI ExDeleteResourceLite(PERESOURCE resource) + return STATUS_NOT_IMPLEMENTED; + } + +-/*********************************************************************** +- * ExReleaseResourceForThreadLite (NTOSKRNL.EXE.@) +- */ +-void WINAPI ExReleaseResourceForThreadLite( PERESOURCE resource, ERESOURCE_THREAD tid ) +-{ +- FIXME( "stub: %p %lu\n", resource, tid ); +-} +- + /*********************************************************************** + * KeEnterCriticalRegion (NTOSKRNL.EXE.@) + */ +diff --git a/dlls/ntoskrnl.exe/sync.c b/dlls/ntoskrnl.exe/sync.c +index 2fd7f903..450e4417 100644 +--- a/dlls/ntoskrnl.exe/sync.c ++++ b/dlls/ntoskrnl.exe/sync.c +@@ -945,3 +945,64 @@ BOOLEAN WINAPI ExAcquireSharedWaitForExclusive( ERESOURCE *resource, BOOLEAN wai + + return TRUE; + } ++ ++/*********************************************************************** ++ * ExReleaseResourceForThreadLite (NTOSKRNL.EXE.@) ++ */ ++void WINAPI ExReleaseResourceForThreadLite( ERESOURCE *resource, ERESOURCE_THREAD thread ) ++{ ++ OWNER_ENTRY *entry; ++ KIRQL irql; ++ ++ TRACE("resource %p, thread %#lx.\n", resource, thread); ++ ++ KeAcquireSpinLock( &resource->SpinLock, &irql ); ++ ++ if (resource->Flag & ResourceOwnedExclusive) ++ { ++ if (resource->OwnerEntry.OwnerThread == thread) ++ { ++ if (!--resource->ActiveEntries) ++ { ++ resource->OwnerEntry.OwnerThread = 0; ++ resource->Flag &= ~ResourceOwnedExclusive; ++ } ++ } ++ else ++ { ++ ERR("Attempt to release %p for thread %#lx, but resource is exclusively owned by %#lx.\n", ++ resource, thread, resource->OwnerEntry.OwnerThread); ++ return; ++ } ++ } ++ else ++ { ++ entry = resource_get_shared_entry( resource, thread ); ++ if (entry->OwnerCount) ++ { ++ entry->OwnerCount--; ++ resource->ActiveEntries--; ++ } ++ else ++ { ++ ERR("Attempt to release %p for thread %#lx, but resource is not owned by that thread.\n", ++ resource, thread); ++ return; ++ } ++ } ++ ++ if (!resource->ActiveEntries) ++ { ++ if (resource->NumberOfExclusiveWaiters) ++ { ++ KeSetEvent( resource->ExclusiveWaiters, IO_NO_INCREMENT, FALSE ); ++ } ++ else if (resource->NumberOfSharedWaiters) ++ { ++ KeReleaseSemaphore( resource->SharedWaiters, IO_NO_INCREMENT, ++ resource->NumberOfSharedWaiters, FALSE ); ++ } ++ } ++ ++ KeReleaseSpinLock( &resource->SpinLock, irql ); ++} +diff --git a/include/ddk/wdm.h b/include/ddk/wdm.h +index 010c1ee4..e95458bf 100644 +--- a/include/ddk/wdm.h ++++ b/include/ddk/wdm.h +@@ -1529,6 +1529,7 @@ PSLIST_ENTRY WINAPI ExInterlockedPopEntrySList(PSLIST_HEADER,PKSPIN_LOCK); + PSLIST_ENTRY WINAPI ExInterlockedPushEntrySList(PSLIST_HEADER,PSLIST_ENTRY,PKSPIN_LOCK); + LIST_ENTRY * WINAPI ExInterlockedRemoveHeadList(LIST_ENTRY*,KSPIN_LOCK*); + void WINAPI ExReleaseFastMutexUnsafe(PFAST_MUTEX); ++void WINAPI ExReleaseResourceForThreadLite(ERESOURCE*,ERESOURCE_THREAD); + + void WINAPI IoAcquireCancelSpinLock(KIRQL*); + NTSTATUS WINAPI IoAllocateDriverObjectExtension(PDRIVER_OBJECT,PVOID,ULONG,PVOID*); +-- +2.20.1 + diff --git a/patches/ntoskrnl.exe-Resources/0007-ntoskrnl.exe-Implement-ExReleaseResourceLite.patch b/patches/ntoskrnl.exe-Resources/0007-ntoskrnl.exe-Implement-ExReleaseResourceLite.patch new file mode 100644 index 00000000..f71e7d42 --- /dev/null +++ b/patches/ntoskrnl.exe-Resources/0007-ntoskrnl.exe-Implement-ExReleaseResourceLite.patch @@ -0,0 +1,68 @@ +From d211d0b1843d4bea1502be6b3bd236ab893b19c2 Mon Sep 17 00:00:00 2001 +From: Zebediah Figura +Date: Tue, 29 Jan 2019 21:44:23 -0600 +Subject: [PATCH 07/13] ntoskrnl.exe: Implement ExReleaseResourceLite(). + +Signed-off-by: Zebediah Figura +--- + dlls/ntoskrnl.exe/ntoskrnl.c | 8 -------- + dlls/ntoskrnl.exe/ntoskrnl.exe.spec | 2 +- + dlls/ntoskrnl.exe/sync.c | 13 +++++++++++++ + 3 files changed, 14 insertions(+), 9 deletions(-) + +diff --git a/dlls/ntoskrnl.exe/ntoskrnl.c b/dlls/ntoskrnl.exe/ntoskrnl.c +index 5ab4db12..556b2ae8 100644 +--- a/dlls/ntoskrnl.exe/ntoskrnl.c ++++ b/dlls/ntoskrnl.exe/ntoskrnl.c +@@ -3912,14 +3912,6 @@ NTSTATUS WINAPI DbgQueryDebugFilterState(ULONG component, ULONG level) + return STATUS_NOT_IMPLEMENTED; + } + +-/********************************************************************* +- * ExReleaseResourceLite (NTOSKRNL.@) +- */ +-void WINAPI ExReleaseResourceLite(PERESOURCE resource) +-{ +- FIXME("stub: %p\n", resource); +-} +- + /********************************************************************* + * PsGetProcessWow64Process (NTOSKRNL.@) + */ +diff --git a/dlls/ntoskrnl.exe/ntoskrnl.exe.spec b/dlls/ntoskrnl.exe/ntoskrnl.exe.spec +index c32f4590..79db7ee8 100644 +--- a/dlls/ntoskrnl.exe/ntoskrnl.exe.spec ++++ b/dlls/ntoskrnl.exe/ntoskrnl.exe.spec +@@ -9,7 +9,7 @@ + @ stdcall -arch=i386 -norelay ExInterlockedPushEntrySList (ptr ptr ptr) NTOSKRNL_ExInterlockedPushEntrySList + @ stub ExReInitializeRundownProtection + @ stdcall -norelay ExReleaseFastMutexUnsafe(ptr) +-@ stdcall ExReleaseResourceLite(ptr) ++@ stdcall -norelay ExReleaseResourceLite(ptr) + @ stub ExReleaseRundownProtection + @ stub ExReleaseRundownProtectionEx + @ stub ExRundownCompleted +diff --git a/dlls/ntoskrnl.exe/sync.c b/dlls/ntoskrnl.exe/sync.c +index 450e4417..0553db7f 100644 +--- a/dlls/ntoskrnl.exe/sync.c ++++ b/dlls/ntoskrnl.exe/sync.c +@@ -1006,3 +1006,16 @@ void WINAPI ExReleaseResourceForThreadLite( ERESOURCE *resource, ERESOURCE_THREA + + KeReleaseSpinLock( &resource->SpinLock, irql ); + } ++ ++/*********************************************************************** ++ * ExReleaseResourceLite (NTOSKRNL.EXE.@) ++ */ ++#ifdef DEFINE_FASTCALL1_ENTRYPOINT ++DEFINE_FASTCALL1_ENTRYPOINT( ExReleaseResourceLite ) ++void WINAPI DECLSPEC_HIDDEN __regs_ExReleaseResourceLite( ERESOURCE *resource ) ++#else ++void WINAPI ExReleaseResourceLite( ERESOURCE *resource ) ++#endif ++{ ++ ExReleaseResourceForThreadLite( resource, (ERESOURCE_THREAD)KeGetCurrentThread() ); ++} +-- +2.20.1 + diff --git a/patches/ntoskrnl.exe-Resources/0008-ntoskrnl.exe-Implement-ExDeleteResourceLite.patch b/patches/ntoskrnl.exe-Resources/0008-ntoskrnl.exe-Implement-ExDeleteResourceLite.patch new file mode 100644 index 00000000..04a01292 --- /dev/null +++ b/patches/ntoskrnl.exe-Resources/0008-ntoskrnl.exe-Implement-ExDeleteResourceLite.patch @@ -0,0 +1,70 @@ +From 977a76e8ed97d3dee870738b6fecfd3bc515e270 Mon Sep 17 00:00:00 2001 +From: Zebediah Figura +Date: Tue, 29 Jan 2019 21:47:14 -0600 +Subject: [PATCH 08/13] ntoskrnl.exe: Implement ExDeleteResourceLite(). + +Signed-off-by: Zebediah Figura +--- + dlls/ntoskrnl.exe/ntoskrnl.c | 9 --------- + dlls/ntoskrnl.exe/sync.c | 12 ++++++++++++ + include/ddk/wdm.h | 1 + + 3 files changed, 13 insertions(+), 9 deletions(-) + +diff --git a/dlls/ntoskrnl.exe/ntoskrnl.c b/dlls/ntoskrnl.exe/ntoskrnl.c +index 556b2ae8..3cae33c9 100644 +--- a/dlls/ntoskrnl.exe/ntoskrnl.c ++++ b/dlls/ntoskrnl.exe/ntoskrnl.c +@@ -3038,15 +3038,6 @@ NTSTATUS WINAPI IoCsqInitialize(PIO_CSQ csq, PIO_CSQ_INSERT_IRP insert_irp, PIO_ + return STATUS_SUCCESS; + } + +-/*********************************************************************** +- * ExDeleteResourceLite (NTOSKRNL.EXE.@) +- */ +-NTSTATUS WINAPI ExDeleteResourceLite(PERESOURCE resource) +-{ +- FIXME("(%p): stub\n", resource); +- return STATUS_NOT_IMPLEMENTED; +-} +- + /*********************************************************************** + * KeEnterCriticalRegion (NTOSKRNL.EXE.@) + */ +diff --git a/dlls/ntoskrnl.exe/sync.c b/dlls/ntoskrnl.exe/sync.c +index 0553db7f..705ea2c7 100644 +--- a/dlls/ntoskrnl.exe/sync.c ++++ b/dlls/ntoskrnl.exe/sync.c +@@ -688,6 +688,18 @@ NTSTATUS WINAPI ExInitializeResourceLite( ERESOURCE *resource ) + return STATUS_SUCCESS; + } + ++/*********************************************************************** ++ * ExDeleteResourceLite (NTOSKRNL.EXE.@) ++ */ ++NTSTATUS WINAPI ExDeleteResourceLite( ERESOURCE *resource ) ++{ ++ TRACE("resource %p.\n", resource); ++ heap_free(resource->OwnerTable); ++ heap_free(resource->ExclusiveWaiters); ++ heap_free(resource->SharedWaiters); ++ return STATUS_SUCCESS; ++} ++ + /* Find an existing entry in the shared owner list, or create a new one. */ + static OWNER_ENTRY *resource_get_shared_entry( ERESOURCE *resource, ERESOURCE_THREAD thread ) + { +diff --git a/include/ddk/wdm.h b/include/ddk/wdm.h +index e95458bf..69efdb7a 100644 +--- a/include/ddk/wdm.h ++++ b/include/ddk/wdm.h +@@ -1521,6 +1521,7 @@ PVOID WINAPI ExAllocatePoolWithQuota(POOL_TYPE,SIZE_T); + PVOID WINAPI ExAllocatePoolWithTag(POOL_TYPE,SIZE_T,ULONG); + PVOID WINAPI ExAllocatePoolWithQuotaTag(POOL_TYPE,SIZE_T,ULONG); + void WINAPI ExDeleteNPagedLookasideList(PNPAGED_LOOKASIDE_LIST); ++NTSTATUS WINAPI ExDeleteResourceLite(ERESOURCE*); + void WINAPI ExFreePool(PVOID); + void WINAPI ExFreePoolWithTag(PVOID,ULONG); + void WINAPI ExInitializeNPagedLookasideList(PNPAGED_LOOKASIDE_LIST,PALLOCATE_FUNCTION,PFREE_FUNCTION,ULONG,SIZE_T,ULONG,USHORT); +-- +2.20.1 + diff --git a/patches/ntoskrnl.exe-Resources/0009-ntoskrnl.exe-Implement-ExGetExclusiveWaiterCount.patch b/patches/ntoskrnl.exe-Resources/0009-ntoskrnl.exe-Implement-ExGetExclusiveWaiterCount.patch new file mode 100644 index 00000000..4e33ad9a --- /dev/null +++ b/patches/ntoskrnl.exe-Resources/0009-ntoskrnl.exe-Implement-ExGetExclusiveWaiterCount.patch @@ -0,0 +1,67 @@ +From 15fd135cd7bc46416235eee58ebac0d35d8e0d9e Mon Sep 17 00:00:00 2001 +From: Zebediah Figura +Date: Tue, 29 Jan 2019 21:48:49 -0600 +Subject: [PATCH 09/13] ntoskrnl.exe: Implement ExGetExclusiveWaiterCount(). + +Signed-off-by: Zebediah Figura +--- + dlls/ntoskrnl.exe/ntoskrnl.exe.spec | 2 +- + dlls/ntoskrnl.exe/sync.c | 19 +++++++++++++++++++ + include/ddk/wdm.h | 1 + + 3 files changed, 21 insertions(+), 1 deletion(-) + +diff --git a/dlls/ntoskrnl.exe/ntoskrnl.exe.spec b/dlls/ntoskrnl.exe/ntoskrnl.exe.spec +index 79db7ee8..3d6ed649 100644 +--- a/dlls/ntoskrnl.exe/ntoskrnl.exe.spec ++++ b/dlls/ntoskrnl.exe/ntoskrnl.exe.spec +@@ -146,7 +146,7 @@ + @ stub ExFreeToPagedLookasideList + @ stub ExGetCurrentProcessorCounts + @ stub ExGetCurrentProcessorCpuUsage +-@ stub ExGetExclusiveWaiterCount ++@ stdcall ExGetExclusiveWaiterCount(ptr) + @ stub ExGetPreviousMode + @ stub ExGetSharedWaiterCount + @ stdcall ExInitializeNPagedLookasideList(ptr ptr ptr long long long long) +diff --git a/dlls/ntoskrnl.exe/sync.c b/dlls/ntoskrnl.exe/sync.c +index 705ea2c7..d024ee9f 100644 +--- a/dlls/ntoskrnl.exe/sync.c ++++ b/dlls/ntoskrnl.exe/sync.c +@@ -1031,3 +1031,22 @@ void WINAPI ExReleaseResourceLite( ERESOURCE *resource ) + { + ExReleaseResourceForThreadLite( resource, (ERESOURCE_THREAD)KeGetCurrentThread() ); + } ++ ++/*********************************************************************** ++ * ExGetExclusiveWaiterCount (NTOSKRNL.EXE.@) ++ */ ++ULONG WINAPI ExGetExclusiveWaiterCount( ERESOURCE *resource ) ++{ ++ ULONG count; ++ KIRQL irql; ++ ++ TRACE("resource %p.\n", resource); ++ ++ KeAcquireSpinLock( &resource->SpinLock, &irql ); ++ ++ count = resource->NumberOfExclusiveWaiters; ++ ++ KeReleaseSpinLock( &resource->SpinLock, irql ); ++ ++ return count; ++} +diff --git a/include/ddk/wdm.h b/include/ddk/wdm.h +index 69efdb7a..f7ced72a 100644 +--- a/include/ddk/wdm.h ++++ b/include/ddk/wdm.h +@@ -1524,6 +1524,7 @@ void WINAPI ExDeleteNPagedLookasideList(PNPAGED_LOOKASIDE_LIST); + NTSTATUS WINAPI ExDeleteResourceLite(ERESOURCE*); + void WINAPI ExFreePool(PVOID); + void WINAPI ExFreePoolWithTag(PVOID,ULONG); ++ULONG WINAPI ExGetExclusiveWaiterCount(ERESOURCE*); + void WINAPI ExInitializeNPagedLookasideList(PNPAGED_LOOKASIDE_LIST,PALLOCATE_FUNCTION,PFREE_FUNCTION,ULONG,SIZE_T,ULONG,USHORT); + NTSTATUS WINAPI ExInitializeResourceLite(ERESOURCE*); + PSLIST_ENTRY WINAPI ExInterlockedPopEntrySList(PSLIST_HEADER,PKSPIN_LOCK); +-- +2.20.1 + diff --git a/patches/ntoskrnl.exe-Resources/0010-ntoskrnl.exe-Implement-ExGetSharedWaiterCount.patch b/patches/ntoskrnl.exe-Resources/0010-ntoskrnl.exe-Implement-ExGetSharedWaiterCount.patch new file mode 100644 index 00000000..5075fc3e --- /dev/null +++ b/patches/ntoskrnl.exe-Resources/0010-ntoskrnl.exe-Implement-ExGetSharedWaiterCount.patch @@ -0,0 +1,67 @@ +From c497239999dfae6e989f27118c5289e2d0bf5c0d Mon Sep 17 00:00:00 2001 +From: Zebediah Figura +Date: Tue, 29 Jan 2019 21:49:26 -0600 +Subject: [PATCH 10/13] ntoskrnl.exe: Implement ExGetSharedWaiterCount(). + +Signed-off-by: Zebediah Figura +--- + dlls/ntoskrnl.exe/ntoskrnl.exe.spec | 2 +- + dlls/ntoskrnl.exe/sync.c | 19 +++++++++++++++++++ + include/ddk/wdm.h | 1 + + 3 files changed, 21 insertions(+), 1 deletion(-) + +diff --git a/dlls/ntoskrnl.exe/ntoskrnl.exe.spec b/dlls/ntoskrnl.exe/ntoskrnl.exe.spec +index 3d6ed649..45553e06 100644 +--- a/dlls/ntoskrnl.exe/ntoskrnl.exe.spec ++++ b/dlls/ntoskrnl.exe/ntoskrnl.exe.spec +@@ -148,7 +148,7 @@ + @ stub ExGetCurrentProcessorCpuUsage + @ stdcall ExGetExclusiveWaiterCount(ptr) + @ stub ExGetPreviousMode +-@ stub ExGetSharedWaiterCount ++@ stdcall ExGetSharedWaiterCount(ptr) + @ stdcall ExInitializeNPagedLookasideList(ptr ptr ptr long long long long) + @ stdcall ExInitializePagedLookasideList(ptr ptr ptr long long long long) + @ stdcall ExInitializeResourceLite(ptr) +diff --git a/dlls/ntoskrnl.exe/sync.c b/dlls/ntoskrnl.exe/sync.c +index d024ee9f..ad68e7ea 100644 +--- a/dlls/ntoskrnl.exe/sync.c ++++ b/dlls/ntoskrnl.exe/sync.c +@@ -1050,3 +1050,22 @@ ULONG WINAPI ExGetExclusiveWaiterCount( ERESOURCE *resource ) + + return count; + } ++ ++/*********************************************************************** ++ * ExGetSharedWaiterCount (NTOSKRNL.EXE.@) ++ */ ++ULONG WINAPI ExGetSharedWaiterCount( ERESOURCE *resource ) ++{ ++ ULONG count; ++ KIRQL irql; ++ ++ TRACE("resource %p.\n", resource); ++ ++ KeAcquireSpinLock( &resource->SpinLock, &irql ); ++ ++ count = resource->NumberOfSharedWaiters; ++ ++ KeReleaseSpinLock( &resource->SpinLock, irql ); ++ ++ return count; ++} +diff --git a/include/ddk/wdm.h b/include/ddk/wdm.h +index f7ced72a..7a4be723 100644 +--- a/include/ddk/wdm.h ++++ b/include/ddk/wdm.h +@@ -1525,6 +1525,7 @@ NTSTATUS WINAPI ExDeleteResourceLite(ERESOURCE*); + void WINAPI ExFreePool(PVOID); + void WINAPI ExFreePoolWithTag(PVOID,ULONG); + ULONG WINAPI ExGetExclusiveWaiterCount(ERESOURCE*); ++ULONG WINAPI ExGetSharedWaiterCount(ERESOURCE*); + void WINAPI ExInitializeNPagedLookasideList(PNPAGED_LOOKASIDE_LIST,PALLOCATE_FUNCTION,PFREE_FUNCTION,ULONG,SIZE_T,ULONG,USHORT); + NTSTATUS WINAPI ExInitializeResourceLite(ERESOURCE*); + PSLIST_ENTRY WINAPI ExInterlockedPopEntrySList(PSLIST_HEADER,PKSPIN_LOCK); +-- +2.20.1 + diff --git a/patches/ntoskrnl.exe-Resources/0011-ntoskrnl.exe-Implement-ExIsResourceAcquiredExclusive.patch b/patches/ntoskrnl.exe-Resources/0011-ntoskrnl.exe-Implement-ExIsResourceAcquiredExclusive.patch new file mode 100644 index 00000000..67cbb0d5 --- /dev/null +++ b/patches/ntoskrnl.exe-Resources/0011-ntoskrnl.exe-Implement-ExIsResourceAcquiredExclusive.patch @@ -0,0 +1,68 @@ +From 7a4285a1f926b9a1caba1f815b9b781857a0997e Mon Sep 17 00:00:00 2001 +From: Zebediah Figura +Date: Tue, 29 Jan 2019 21:50:37 -0600 +Subject: [PATCH 11/13] ntoskrnl.exe: Implement + ExIsResourceAcquiredExclusiveLite(). + +Signed-off-by: Zebediah Figura +--- + dlls/ntoskrnl.exe/ntoskrnl.exe.spec | 2 +- + dlls/ntoskrnl.exe/sync.c | 19 +++++++++++++++++++ + include/ddk/wdm.h | 1 + + 3 files changed, 21 insertions(+), 1 deletion(-) + +diff --git a/dlls/ntoskrnl.exe/ntoskrnl.exe.spec b/dlls/ntoskrnl.exe/ntoskrnl.exe.spec +index 45553e06..66f0b7d9 100644 +--- a/dlls/ntoskrnl.exe/ntoskrnl.exe.spec ++++ b/dlls/ntoskrnl.exe/ntoskrnl.exe.spec +@@ -165,7 +165,7 @@ + @ stub ExInterlockedPushEntryList + @ stdcall ExInterlockedRemoveHeadList(ptr ptr) + @ stub ExIsProcessorFeaturePresent +-@ stub ExIsResourceAcquiredExclusiveLite ++@ stdcall ExIsResourceAcquiredExclusiveLite(ptr) + @ stub ExIsResourceAcquiredSharedLite + @ stdcall ExLocalTimeToSystemTime(ptr ptr) RtlLocalTimeToSystemTime + @ stub ExNotifyCallback +diff --git a/dlls/ntoskrnl.exe/sync.c b/dlls/ntoskrnl.exe/sync.c +index ad68e7ea..cee15605 100644 +--- a/dlls/ntoskrnl.exe/sync.c ++++ b/dlls/ntoskrnl.exe/sync.c +@@ -1069,3 +1069,22 @@ ULONG WINAPI ExGetSharedWaiterCount( ERESOURCE *resource ) + + return count; + } ++ ++/*********************************************************************** ++ * ExIsResourceAcquiredExclusiveLite (NTOSKRNL.EXE.@) ++ */ ++BOOLEAN WINAPI ExIsResourceAcquiredExclusiveLite( ERESOURCE *resource ) ++{ ++ BOOLEAN ret; ++ KIRQL irql; ++ ++ TRACE("resource %p.\n", resource); ++ ++ KeAcquireSpinLock( &resource->SpinLock, &irql ); ++ ++ ret = (resource->OwnerEntry.OwnerThread == (ERESOURCE_THREAD)KeGetCurrentThread()); ++ ++ KeReleaseSpinLock( &resource->SpinLock, irql ); ++ ++ return ret; ++} +diff --git a/include/ddk/wdm.h b/include/ddk/wdm.h +index 7a4be723..76eb6117 100644 +--- a/include/ddk/wdm.h ++++ b/include/ddk/wdm.h +@@ -1531,6 +1531,7 @@ NTSTATUS WINAPI ExInitializeResourceLite(ERESOURCE*); + PSLIST_ENTRY WINAPI ExInterlockedPopEntrySList(PSLIST_HEADER,PKSPIN_LOCK); + PSLIST_ENTRY WINAPI ExInterlockedPushEntrySList(PSLIST_HEADER,PSLIST_ENTRY,PKSPIN_LOCK); + LIST_ENTRY * WINAPI ExInterlockedRemoveHeadList(LIST_ENTRY*,KSPIN_LOCK*); ++BOOLEAN WINAPI ExIsResourceAcquiredExclusiveLite(ERESOURCE*); + void WINAPI ExReleaseFastMutexUnsafe(PFAST_MUTEX); + void WINAPI ExReleaseResourceForThreadLite(ERESOURCE*,ERESOURCE_THREAD); + +-- +2.20.1 + diff --git a/patches/ntoskrnl.exe-Resources/0012-ntoskrnl.exe-Implement-ExIsResourceAcquiredSharedLit.patch b/patches/ntoskrnl.exe-Resources/0012-ntoskrnl.exe-Implement-ExIsResourceAcquiredSharedLit.patch new file mode 100644 index 00000000..fa748bab --- /dev/null +++ b/patches/ntoskrnl.exe-Resources/0012-ntoskrnl.exe-Implement-ExIsResourceAcquiredSharedLit.patch @@ -0,0 +1,74 @@ +From 5203c63e18a2461b1909996ec1ffbcc662d57865 Mon Sep 17 00:00:00 2001 +From: Zebediah Figura +Date: Tue, 29 Jan 2019 21:51:08 -0600 +Subject: [PATCH 12/13] ntoskrnl.exe: Implement + ExIsResourceAcquiredSharedLite(). + +Signed-off-by: Zebediah Figura +--- + dlls/ntoskrnl.exe/ntoskrnl.exe.spec | 2 +- + dlls/ntoskrnl.exe/sync.c | 25 +++++++++++++++++++++++++ + include/ddk/wdm.h | 1 + + 3 files changed, 27 insertions(+), 1 deletion(-) + +diff --git a/dlls/ntoskrnl.exe/ntoskrnl.exe.spec b/dlls/ntoskrnl.exe/ntoskrnl.exe.spec +index 66f0b7d9..127c5ef3 100644 +--- a/dlls/ntoskrnl.exe/ntoskrnl.exe.spec ++++ b/dlls/ntoskrnl.exe/ntoskrnl.exe.spec +@@ -166,7 +166,7 @@ + @ stdcall ExInterlockedRemoveHeadList(ptr ptr) + @ stub ExIsProcessorFeaturePresent + @ stdcall ExIsResourceAcquiredExclusiveLite(ptr) +-@ stub ExIsResourceAcquiredSharedLite ++@ stdcall ExIsResourceAcquiredSharedLite(ptr) + @ stdcall ExLocalTimeToSystemTime(ptr ptr) RtlLocalTimeToSystemTime + @ stub ExNotifyCallback + @ stub ExQueryPoolBlockSize +diff --git a/dlls/ntoskrnl.exe/sync.c b/dlls/ntoskrnl.exe/sync.c +index cee15605..5154ea5c 100644 +--- a/dlls/ntoskrnl.exe/sync.c ++++ b/dlls/ntoskrnl.exe/sync.c +@@ -1088,3 +1088,28 @@ BOOLEAN WINAPI ExIsResourceAcquiredExclusiveLite( ERESOURCE *resource ) + + return ret; + } ++ ++/*********************************************************************** ++ * ExIsResourceAcquiredSharedLite (NTOSKRNL.EXE.@) ++ */ ++ULONG WINAPI ExIsResourceAcquiredSharedLite( ERESOURCE *resource ) ++{ ++ ULONG ret; ++ KIRQL irql; ++ ++ TRACE("resource %p.\n", resource); ++ ++ KeAcquireSpinLock( &resource->SpinLock, &irql ); ++ ++ if (resource->OwnerEntry.OwnerThread == (ERESOURCE_THREAD)KeGetCurrentThread()) ++ ret = resource->ActiveEntries; ++ else ++ { ++ OWNER_ENTRY *entry = resource_get_shared_entry( resource, (ERESOURCE_THREAD)KeGetCurrentThread() ); ++ ret = entry->OwnerCount; ++ } ++ ++ KeReleaseSpinLock( &resource->SpinLock, irql ); ++ ++ return ret; ++} +diff --git a/include/ddk/wdm.h b/include/ddk/wdm.h +index 76eb6117..e5a2906f 100644 +--- a/include/ddk/wdm.h ++++ b/include/ddk/wdm.h +@@ -1532,6 +1532,7 @@ PSLIST_ENTRY WINAPI ExInterlockedPopEntrySList(PSLIST_HEADER,PKSPIN_LOCK); + PSLIST_ENTRY WINAPI ExInterlockedPushEntrySList(PSLIST_HEADER,PSLIST_ENTRY,PKSPIN_LOCK); + LIST_ENTRY * WINAPI ExInterlockedRemoveHeadList(LIST_ENTRY*,KSPIN_LOCK*); + BOOLEAN WINAPI ExIsResourceAcquiredExclusiveLite(ERESOURCE*); ++ULONG WINAPI ExIsResourceAcquiredSharedLite(ERESOURCE*); + void WINAPI ExReleaseFastMutexUnsafe(PFAST_MUTEX); + void WINAPI ExReleaseResourceForThreadLite(ERESOURCE*,ERESOURCE_THREAD); + +-- +2.20.1 + diff --git a/patches/ntoskrnl.exe-Resources/0013-ntoskrnl.exe-tests-Add-tests-for-ERESOURCE-functions.patch b/patches/ntoskrnl.exe-Resources/0013-ntoskrnl.exe-tests-Add-tests-for-ERESOURCE-functions.patch new file mode 100644 index 00000000..b8ece9cd --- /dev/null +++ b/patches/ntoskrnl.exe-Resources/0013-ntoskrnl.exe-tests-Add-tests-for-ERESOURCE-functions.patch @@ -0,0 +1,383 @@ +From 85acc986954ed6476fe459fc60fafee7211eb556 Mon Sep 17 00:00:00 2001 +From: Zebediah Figura +Date: Tue, 29 Jan 2019 21:54:39 -0600 +Subject: [PATCH 13/13] ntoskrnl.exe/tests: Add tests for ERESOURCE functions. + +Signed-off-by: Zebediah Figura +--- + dlls/ntoskrnl.exe/tests/driver.c | 311 ++++++++++++++++++++++++++++++- + include/ddk/wdm.h | 2 + + 2 files changed, 312 insertions(+), 1 deletion(-) + +diff --git a/dlls/ntoskrnl.exe/tests/driver.c b/dlls/ntoskrnl.exe/tests/driver.c +index 3984240e..6d64cc8e 100644 +--- a/dlls/ntoskrnl.exe/tests/driver.c ++++ b/dlls/ntoskrnl.exe/tests/driver.c +@@ -289,7 +289,14 @@ static NTSTATUS wait_multiple(ULONG count, void *objs[], WAIT_TYPE wait_type, UL + return KeWaitForMultipleObjects(count, objs, wait_type, Executive, KernelMode, FALSE, &integer, NULL); + } + +-static void run_thread(PKSTART_ROUTINE proc, void *arg) ++static void sleep(void) ++{ ++ LARGE_INTEGER timeout; ++ timeout.QuadPart = -2000; ++ KeDelayExecutionThread( KernelMode, FALSE, &timeout ); ++} ++ ++static HANDLE create_thread(PKSTART_ROUTINE proc, void *arg) + { + OBJECT_ATTRIBUTES attr = {0}; + HANDLE thread; +@@ -300,12 +307,25 @@ static void run_thread(PKSTART_ROUTINE proc, void *arg) + ret = PsCreateSystemThread(&thread, THREAD_ALL_ACCESS, &attr, NULL, NULL, proc, arg); + ok(!ret, "got %#x\n", ret); + ++ return thread; ++} ++ ++static void join_thread(HANDLE thread) ++{ ++ NTSTATUS ret; ++ + ret = ZwWaitForSingleObject(thread, FALSE, NULL); + ok(!ret, "got %#x\n", ret); + ret = ZwClose(thread); + ok(!ret, "got %#x\n", ret); + } + ++static void run_thread(PKSTART_ROUTINE proc, void *arg) ++{ ++ HANDLE thread = create_thread(proc, arg); ++ join_thread(thread); ++} ++ + static KMUTEX test_mutex; + + static void WINAPI mutex_thread(void *arg) +@@ -636,6 +656,294 @@ static void test_version(void) + ok(*pNtBuildNumber == build, "Expected build number %u, got %u\n", build, *pNtBuildNumber); + } + ++static void check_resource_(int line, ERESOURCE *resource, ULONG exclusive_waiters, ++ ULONG shared_waiters, BOOLEAN exclusive, ULONG shared_count) ++{ ++ BOOLEAN ret; ++ ULONG count; ++ ++ count = ExGetExclusiveWaiterCount(resource); ++ ok_(__FILE__, line, count == exclusive_waiters, ++ "expected %u exclusive waiters, got %u\n", exclusive_waiters, count); ++ count = ExGetSharedWaiterCount(resource); ++ ok_(__FILE__, line, count == shared_waiters, ++ "expected %u shared waiters, got %u\n", shared_waiters, count); ++ ret = ExIsResourceAcquiredExclusiveLite(resource); ++ ok_(__FILE__, line, ret == exclusive, ++ "expected exclusive %u, got %u\n", exclusive, ret); ++ count = ExIsResourceAcquiredSharedLite(resource); ++ ok_(__FILE__, line, count == shared_count, ++ "expected shared %u, got %u\n", shared_count, count); ++} ++#define check_resource(a,b,c,d,e) check_resource_(__LINE__,a,b,c,d,e) ++ ++static KEVENT resource_shared_ready, resource_shared_done, resource_exclusive_ready, resource_exclusive_done; ++ ++static void WINAPI resource_shared_thread(void *arg) ++{ ++ ERESOURCE *resource = arg; ++ BOOLEAN ret; ++ ++ check_resource(resource, 0, 0, FALSE, 0); ++ ++ ret = ExAcquireResourceSharedLite(resource, TRUE); ++ ok(ret == TRUE, "got ret %u\n", ret); ++ ++ check_resource(resource, 0, 0, FALSE, 1); ++ ++ KeSetEvent(&resource_shared_ready, IO_NO_INCREMENT, FALSE); ++ KeWaitForSingleObject(&resource_shared_done, Executive, KernelMode, FALSE, NULL); ++ ++ ExReleaseResourceForThreadLite(resource, (ULONG_PTR)PsGetCurrentThread()); ++ ++ PsTerminateSystemThread(STATUS_SUCCESS); ++} ++ ++static void WINAPI resource_exclusive_thread(void *arg) ++{ ++ ERESOURCE *resource = arg; ++ BOOLEAN ret; ++ ++ check_resource(resource, 0, 0, FALSE, 0); ++ ++ ret = ExAcquireResourceExclusiveLite(resource, TRUE); ++ ok(ret == TRUE, "got ret %u\n", ret); ++ ++ check_resource(resource, 0, 0, TRUE, 1); ++ ++ KeSetEvent(&resource_exclusive_ready, IO_NO_INCREMENT, FALSE); ++ KeWaitForSingleObject(&resource_exclusive_done, Executive, KernelMode, FALSE, NULL); ++ ++ ExReleaseResourceForThreadLite(resource, (ULONG_PTR)PsGetCurrentThread()); ++ ++ PsTerminateSystemThread(STATUS_SUCCESS); ++} ++ ++static void test_resource(void) ++{ ++ ERESOURCE resource; ++ NTSTATUS status; ++ BOOLEAN ret; ++ HANDLE thread, thread2; ++ ++ memset(&resource, 0xcc, sizeof(resource)); ++ ++ status = ExInitializeResourceLite(&resource); ++ ok(status == STATUS_SUCCESS, "got status %#x\n", status); ++ check_resource(&resource, 0, 0, FALSE, 0); ++ ++ KeEnterCriticalRegion(); ++ ++ ret = ExAcquireResourceExclusiveLite(&resource, FALSE); ++ ok(ret == TRUE, "got ret %u\n", ret); ++ check_resource(&resource, 0, 0, TRUE, 1); ++ ++ ret = ExAcquireResourceExclusiveLite(&resource, FALSE); ++ ok(ret == TRUE, "got ret %u\n", ret); ++ check_resource(&resource, 0, 0, TRUE, 2); ++ ++ ret = ExAcquireResourceSharedLite(&resource, FALSE); ++ ok(ret == TRUE, "got ret %u\n", ret); ++ check_resource(&resource, 0, 0, TRUE, 3); ++ ++ ExReleaseResourceForThreadLite(&resource, (ULONG_PTR)PsGetCurrentThread()); ++ check_resource(&resource, 0, 0, TRUE, 2); ++ ++ ExReleaseResourceForThreadLite(&resource, (ULONG_PTR)PsGetCurrentThread()); ++ check_resource(&resource, 0, 0, TRUE, 1); ++ ++ ExReleaseResourceForThreadLite(&resource, (ULONG_PTR)PsGetCurrentThread()); ++ check_resource(&resource, 0, 0, FALSE, 0); ++ ++ ret = ExAcquireResourceSharedLite(&resource, FALSE); ++ ok(ret == TRUE, "got ret %u\n", ret); ++ check_resource(&resource, 0, 0, FALSE, 1); ++ ++ ret = ExAcquireResourceSharedLite(&resource, FALSE); ++ ok(ret == TRUE, "got ret %u\n", ret); ++ check_resource(&resource, 0, 0, FALSE, 2); ++ ++ ret = ExAcquireResourceExclusiveLite(&resource, FALSE); ++ ok(ret == FALSE, "got ret %u\n", ret); ++ check_resource(&resource, 0, 0, FALSE, 2); ++ ++ ExReleaseResourceForThreadLite(&resource, (ULONG_PTR)PsGetCurrentThread()); ++ check_resource(&resource, 0, 0, FALSE, 1); ++ ++ ExReleaseResourceForThreadLite(&resource, (ULONG_PTR)PsGetCurrentThread()); ++ check_resource(&resource, 0, 0, FALSE, 0); ++ ++ ret = ExAcquireSharedStarveExclusive(&resource, FALSE); ++ ok(ret == TRUE, "got ret %u\n", ret); ++ check_resource(&resource, 0, 0, FALSE, 1); ++ ++ ExReleaseResourceForThreadLite(&resource, (ULONG_PTR)PsGetCurrentThread()); ++ check_resource(&resource, 0, 0, FALSE, 0); ++ ++ ret = ExAcquireSharedWaitForExclusive(&resource, FALSE); ++ ok(ret == TRUE, "got ret %u\n", ret); ++ check_resource(&resource, 0, 0, FALSE, 1); ++ ++ ExReleaseResourceForThreadLite(&resource, (ULONG_PTR)PsGetCurrentThread()); ++ check_resource(&resource, 0, 0, FALSE, 0); ++ ++ /* Do not acquire the resource ourselves, but spawn a shared thread holding it. */ ++ ++ KeInitializeEvent(&resource_shared_ready, SynchronizationEvent, FALSE); ++ KeInitializeEvent(&resource_shared_done, SynchronizationEvent, FALSE); ++ thread = create_thread(resource_shared_thread, &resource); ++ KeWaitForSingleObject(&resource_shared_ready, Executive, KernelMode, FALSE, NULL); ++ check_resource(&resource, 0, 0, FALSE, 0); ++ ++ ret = ExAcquireResourceExclusiveLite(&resource, FALSE); ++ ok(ret == FALSE, "got ret %u\n", ret); ++ ++ ret = ExAcquireResourceSharedLite(&resource, FALSE); ++ ok(ret == TRUE, "got ret %u\n", ret); ++ check_resource(&resource, 0, 0, FALSE, 1); ++ ++ ExReleaseResourceForThreadLite(&resource, (ULONG_PTR)PsGetCurrentThread()); ++ check_resource(&resource, 0, 0, FALSE, 0); ++ ++ ret = ExAcquireSharedStarveExclusive(&resource, FALSE); ++ ok(ret == TRUE, "got ret %u\n", ret); ++ check_resource(&resource, 0, 0, FALSE, 1); ++ ++ ExReleaseResourceForThreadLite(&resource, (ULONG_PTR)PsGetCurrentThread()); ++ check_resource(&resource, 0, 0, FALSE, 0); ++ ++ ret = ExAcquireSharedWaitForExclusive(&resource, FALSE); ++ ok(ret == TRUE, "got ret %u\n", ret); ++ check_resource(&resource, 0, 0, FALSE, 1); ++ ++ ExReleaseResourceForThreadLite(&resource, (ULONG_PTR)PsGetCurrentThread()); ++ check_resource(&resource, 0, 0, FALSE, 0); ++ ++ KeSetEvent(&resource_shared_done, IO_NO_INCREMENT, FALSE); ++ join_thread(thread); ++ check_resource(&resource, 0, 0, FALSE, 0); ++ ++ /* Acquire the resource as exclusive, and then spawn a shared thread. */ ++ ++ ret = ExAcquireResourceExclusiveLite(&resource, FALSE); ++ ok(ret == TRUE, "got ret %u\n", ret); ++ check_resource(&resource, 0, 0, TRUE, 1); ++ ++ thread = create_thread(resource_shared_thread, &resource); ++ sleep(); ++ check_resource(&resource, 0, 1, TRUE, 1); ++ ++ ret = ExAcquireResourceExclusiveLite(&resource, FALSE); ++ ok(ret == TRUE, "got ret %u\n", ret); ++ check_resource(&resource, 0, 1, TRUE, 2); ++ ++ ExReleaseResourceForThreadLite(&resource, (ULONG_PTR)PsGetCurrentThread()); ++ ExReleaseResourceForThreadLite(&resource, (ULONG_PTR)PsGetCurrentThread()); ++ KeWaitForSingleObject(&resource_shared_ready, Executive, KernelMode, FALSE, NULL); ++ KeSetEvent(&resource_shared_done, IO_NO_INCREMENT, FALSE); ++ join_thread(thread); ++ check_resource(&resource, 0, 0, FALSE, 0); ++ ++ /* Do not acquire the resource ourselves, but spawn an exclusive thread holding it. */ ++ ++ KeInitializeEvent(&resource_exclusive_ready, SynchronizationEvent, FALSE); ++ KeInitializeEvent(&resource_exclusive_done, SynchronizationEvent, FALSE); ++ thread = create_thread(resource_exclusive_thread, &resource); ++ KeWaitForSingleObject(&resource_exclusive_ready, Executive, KernelMode, FALSE, NULL); ++ check_resource(&resource, 0, 0, FALSE, 0); ++ ++ ret = ExAcquireResourceExclusiveLite(&resource, FALSE); ++ ok(ret == FALSE, "got ret %u\n", ret); ++ check_resource(&resource, 0, 0, FALSE, 0); ++ ++ ret = ExAcquireResourceSharedLite(&resource, FALSE); ++ ok(ret == FALSE, "got ret %u\n", ret); ++ check_resource(&resource, 0, 0, FALSE, 0); ++ ++ ret = ExAcquireSharedStarveExclusive(&resource, FALSE); ++ ok(ret == FALSE, "got ret %u\n", ret); ++ check_resource(&resource, 0, 0, FALSE, 0); ++ ++ ret = ExAcquireSharedWaitForExclusive(&resource, FALSE); ++ ok(ret == FALSE, "got ret %u\n", ret); ++ check_resource(&resource, 0, 0, FALSE, 0); ++ ++ KeSetEvent(&resource_exclusive_done, IO_NO_INCREMENT, FALSE); ++ join_thread(thread); ++ check_resource(&resource, 0, 0, FALSE, 0); ++ ++ /* Acquire the resource as shared, and then spawn an exclusive waiter. */ ++ ++ ret = ExAcquireResourceSharedLite(&resource, FALSE); ++ ok(ret == TRUE, "got ret %u\n", ret); ++ check_resource(&resource, 0, 0, FALSE, 1); ++ ++ thread = create_thread(resource_exclusive_thread, &resource); ++ sleep(); ++ check_resource(&resource, 1, 0, FALSE, 1); ++ ++ ret = ExAcquireResourceSharedLite(&resource, FALSE); ++ ok(ret == TRUE, "got ret %u\n", ret); ++ check_resource(&resource, 1, 0, FALSE, 2); ++ ExReleaseResourceForThreadLite(&resource, (ULONG_PTR)PsGetCurrentThread()); ++ ++ ret = ExAcquireSharedStarveExclusive(&resource, FALSE); ++ ok(ret == TRUE, "got ret %u\n", ret); ++ check_resource(&resource, 1, 0, FALSE, 2); ++ ExReleaseResourceForThreadLite(&resource, (ULONG_PTR)PsGetCurrentThread()); ++ ++ ret = ExAcquireSharedWaitForExclusive(&resource, FALSE); ++ ok(ret == FALSE, "got ret %u\n", ret); ++ check_resource(&resource, 1, 0, FALSE, 1); ++ ++ ExReleaseResourceForThreadLite(&resource, (ULONG_PTR)PsGetCurrentThread()); ++ KeWaitForSingleObject(&resource_exclusive_ready, Executive, KernelMode, FALSE, NULL); ++ KeSetEvent(&resource_exclusive_done, IO_NO_INCREMENT, FALSE); ++ join_thread(thread); ++ check_resource(&resource, 0, 0, FALSE, 0); ++ ++ /* Spawn a shared and then exclusive waiter. */ ++ ++ KeInitializeEvent(&resource_shared_ready, SynchronizationEvent, FALSE); ++ KeInitializeEvent(&resource_shared_done, SynchronizationEvent, FALSE); ++ thread = create_thread(resource_shared_thread, &resource); ++ KeWaitForSingleObject(&resource_shared_ready, Executive, KernelMode, FALSE, NULL); ++ check_resource(&resource, 0, 0, FALSE, 0); ++ ++ thread2 = create_thread(resource_exclusive_thread, &resource); ++ sleep(); ++ check_resource(&resource, 1, 0, FALSE, 0); ++ ++ ret = ExAcquireResourceExclusiveLite(&resource, FALSE); ++ ok(ret == FALSE, "got ret %u\n", ret); ++ check_resource(&resource, 1, 0, FALSE, 0); ++ ++ ret = ExAcquireResourceSharedLite(&resource, FALSE); ++ ok(ret == FALSE, "got ret %u\n", ret); ++ check_resource(&resource, 1, 0, FALSE, 0); ++ ++ ret = ExAcquireSharedStarveExclusive(&resource, FALSE); ++ ok(ret == TRUE, "got ret %u\n", ret); ++ check_resource(&resource, 1, 0, FALSE, 1); ++ ExReleaseResourceForThreadLite(&resource, (ULONG_PTR)PsGetCurrentThread()); ++ ++ ret = ExAcquireSharedWaitForExclusive(&resource, FALSE); ++ ok(ret == FALSE, "got ret %u\n", ret); ++ check_resource(&resource, 1, 0, FALSE, 0); ++ ++ KeSetEvent(&resource_shared_done, IO_NO_INCREMENT, FALSE); ++ join_thread(thread); ++ KeWaitForSingleObject(&resource_exclusive_ready, Executive, KernelMode, FALSE, NULL); ++ KeSetEvent(&resource_exclusive_done, IO_NO_INCREMENT, FALSE); ++ join_thread(thread2); ++ check_resource(&resource, 0, 0, FALSE, 0); ++ ++ KeLeaveCriticalRegion(); ++ ++ status = ExDeleteResourceLite(&resource); ++ ok(status == STATUS_SUCCESS, "got status %#x\n", status); ++} ++ + static NTSTATUS main_test(DEVICE_OBJECT *device, IRP *irp, IO_STACK_LOCATION *stack, ULONG_PTR *info) + { + ULONG length = stack->Parameters.DeviceIoControl.OutputBufferLength; +@@ -669,6 +977,7 @@ static NTSTATUS main_test(DEVICE_OBJECT *device, IRP *irp, IO_STACK_LOCATION *st + test_version(); + test_stack_callout(); + test_lookaside_list(); ++ test_resource(); + + /* print process report */ + if (test_input->winetest_debug) +diff --git a/include/ddk/wdm.h b/include/ddk/wdm.h +index e5a2906f..0677be69 100644 +--- a/include/ddk/wdm.h ++++ b/include/ddk/wdm.h +@@ -1578,6 +1578,7 @@ void WINAPI KeAcquireSpinLockAtDpcLevel(KSPIN_LOCK*); + BOOLEAN WINAPI KeCancelTimer(KTIMER*); + void WINAPI KeClearEvent(PRKEVENT); + NTSTATUS WINAPI KeDelayExecutionThread(KPROCESSOR_MODE,BOOLEAN,LARGE_INTEGER*); ++void WINAPI KeEnterCriticalRegion(void); + PKTHREAD WINAPI KeGetCurrentThread(void); + void WINAPI KeInitializeEvent(PRKEVENT,EVENT_TYPE,BOOLEAN); + void WINAPI KeInitializeMutex(PRKMUTEX,ULONG); +@@ -1585,6 +1586,7 @@ void WINAPI KeInitializeSemaphore(PRKSEMAPHORE,LONG,LONG); + void WINAPI KeInitializeSpinLock(KSPIN_LOCK*); + void WINAPI KeInitializeTimerEx(PKTIMER,TIMER_TYPE); + void WINAPI KeInitializeTimer(KTIMER*); ++void WINAPI KeLeaveCriticalRegion(void); + void WINAPI KeQuerySystemTime(LARGE_INTEGER*); + void WINAPI KeQueryTickCount(LARGE_INTEGER*); + ULONG WINAPI KeQueryTimeIncrement(void); +-- +2.20.1 + diff --git a/patches/ntoskrnl.exe-Resources/definition b/patches/ntoskrnl.exe-Resources/definition new file mode 100644 index 00000000..82dbe57e --- /dev/null +++ b/patches/ntoskrnl.exe-Resources/definition @@ -0,0 +1,4 @@ +Fixes: [45819] Symantec Eraser Control Driver 'eeCtrl64.sys' (Norton 360) fails in driver entry point due to 'ntoskrnl.exe.ExInitializeResourceLite' stub (needs STATUS_SUCCESS) +# This patch is fit for submission as far as I'm concerned, but it can't really +# be submitted yet, since it depends on a working implementation of +# KeGetCurrentThread() [at least, one that distinguishes different threads]. diff --git a/patches/patchinstall.sh b/patches/patchinstall.sh index 13f42e94..a71e1aca 100755 --- a/patches/patchinstall.sh +++ b/patches/patchinstall.sh @@ -236,6 +236,7 @@ patch_enable_all () enable_ntdll_set_full_cpu_context="$1" enable_ntoskrnl_Stubs="$1" enable_ntoskrnl_exe_Fix_Relocation="$1" + enable_ntoskrnl_exe_Resources="$1" enable_nvapi_Stub_DLL="$1" enable_nvcuda_CUDA_Support="$1" enable_nvcuvid_CUDA_Video_Support="$1" @@ -861,6 +862,9 @@ patch_enable () ntoskrnl.exe-Fix_Relocation) enable_ntoskrnl_exe_Fix_Relocation="$2" ;; + ntoskrnl.exe-Resources) + enable_ntoskrnl_exe_Resources="$2" + ;; nvapi-Stub_DLL) enable_nvapi_Stub_DLL="$2" ;; @@ -1742,8 +1746,12 @@ if test "$enable_winedevice_Default_Drivers" -eq 1; then if test "$enable_ntoskrnl_Stubs" -gt 1; then abort "Patchset ntoskrnl-Stubs disabled, but winedevice-Default_Drivers depends on that." fi + if test "$enable_ntoskrnl_exe_Resources" -gt 1; then + abort "Patchset ntoskrnl.exe-Resources disabled, but winedevice-Default_Drivers depends on that." + fi enable_dxva2_Video_Decoder=1 enable_ntoskrnl_Stubs=1 + enable_ntoskrnl_exe_Resources=1 fi if test "$enable_wined3d_Indexed_Vertex_Blending" -eq 1; then @@ -5056,6 +5064,47 @@ if test "$enable_ntoskrnl_exe_Fix_Relocation" -eq 1; then ) >> "$patchlist" fi +# Patchset ntoskrnl.exe-Resources +# | +# | This patchset fixes the following Wine bugs: +# | * [#45819] Symantec Eraser Control Driver 'eeCtrl64.sys' (Norton 360) fails in driver entry point due to +# | 'ntoskrnl.exe.ExInitializeResourceLite' stub (needs STATUS_SUCCESS) +# | +# | Modified files: +# | * dlls/ntoskrnl.exe/ntoskrnl.c, dlls/ntoskrnl.exe/ntoskrnl.exe.spec, dlls/ntoskrnl.exe/sync.c, +# | dlls/ntoskrnl.exe/tests/driver.c, include/ddk/wdm.h +# | +if test "$enable_ntoskrnl_exe_Resources" -eq 1; then + patch_apply ntoskrnl.exe-Resources/0001-ntoskrnl.exe-Implement-ExInitializeResourceLite.patch + patch_apply ntoskrnl.exe-Resources/0002-ntoskrnl.exe-Implement-ExAcquireResourceExclusiveLit.patch + patch_apply ntoskrnl.exe-Resources/0003-ntoskrnl.exe-Implement-ExAcquireResourceSharedLite.patch + patch_apply ntoskrnl.exe-Resources/0004-ntoskrnl.exe-Implement-ExAcquireSharedStarveExclusiv.patch + patch_apply ntoskrnl.exe-Resources/0005-ntoskrnl.exe-Implement-ExAcquireSharedWaitForExclusi.patch + patch_apply ntoskrnl.exe-Resources/0006-ntoskrnl.exe-Implement-ExReleaseResourceForThreadLit.patch + patch_apply ntoskrnl.exe-Resources/0007-ntoskrnl.exe-Implement-ExReleaseResourceLite.patch + patch_apply ntoskrnl.exe-Resources/0008-ntoskrnl.exe-Implement-ExDeleteResourceLite.patch + patch_apply ntoskrnl.exe-Resources/0009-ntoskrnl.exe-Implement-ExGetExclusiveWaiterCount.patch + patch_apply ntoskrnl.exe-Resources/0010-ntoskrnl.exe-Implement-ExGetSharedWaiterCount.patch + patch_apply ntoskrnl.exe-Resources/0011-ntoskrnl.exe-Implement-ExIsResourceAcquiredExclusive.patch + patch_apply ntoskrnl.exe-Resources/0012-ntoskrnl.exe-Implement-ExIsResourceAcquiredSharedLit.patch + patch_apply ntoskrnl.exe-Resources/0013-ntoskrnl.exe-tests-Add-tests-for-ERESOURCE-functions.patch + ( + printf '%s\n' '+ { "Zebediah Figura", "ntoskrnl.exe: Implement ExInitializeResourceLite().", 1 },'; + printf '%s\n' '+ { "Zebediah Figura", "ntoskrnl.exe: Implement ExAcquireResourceExclusiveLite().", 1 },'; + printf '%s\n' '+ { "Zebediah Figura", "ntoskrnl.exe: Implement ExAcquireResourceSharedLite().", 1 },'; + printf '%s\n' '+ { "Zebediah Figura", "ntoskrnl.exe: Implement ExAcquireSharedStarveExclusive().", 1 },'; + printf '%s\n' '+ { "Zebediah Figura", "ntoskrnl.exe: Implement ExAcquireSharedWaitForExclusive().", 1 },'; + printf '%s\n' '+ { "Zebediah Figura", "ntoskrnl.exe: Implement ExReleaseResourceForThreadLite().", 1 },'; + printf '%s\n' '+ { "Zebediah Figura", "ntoskrnl.exe: Implement ExReleaseResourceLite().", 1 },'; + printf '%s\n' '+ { "Zebediah Figura", "ntoskrnl.exe: Implement ExDeleteResourceLite().", 1 },'; + printf '%s\n' '+ { "Zebediah Figura", "ntoskrnl.exe: Implement ExGetExclusiveWaiterCount().", 1 },'; + printf '%s\n' '+ { "Zebediah Figura", "ntoskrnl.exe: Implement ExGetSharedWaiterCount().", 1 },'; + printf '%s\n' '+ { "Zebediah Figura", "ntoskrnl.exe: Implement ExIsResourceAcquiredExclusiveLite().", 1 },'; + printf '%s\n' '+ { "Zebediah Figura", "ntoskrnl.exe: Implement ExIsResourceAcquiredSharedLite().", 1 },'; + printf '%s\n' '+ { "Zebediah Figura", "ntoskrnl.exe/tests: Add tests for ERESOURCE functions.", 1 },'; + ) >> "$patchlist" +fi + # Patchset nvcuvid-CUDA_Video_Support # | # | This patchset has the following (direct or indirect) dependencies: @@ -6967,7 +7016,7 @@ fi # Patchset winedevice-Default_Drivers # | # | This patchset has the following (direct or indirect) dependencies: -# | * dxva2-Video_Decoder, ntoskrnl-Stubs +# | * dxva2-Video_Decoder, ntoskrnl-Stubs, ntoskrnl.exe-Resources # | # | Modified files: # | * configure.ac, dlls/dxgkrnl.sys/Makefile.in, dlls/dxgkrnl.sys/dxgkrnl.sys.spec, dlls/dxgkrnl.sys/main.c, diff --git a/patches/winedevice-Default_Drivers/0004-programs-winedevice-Load-some-common-drivers-and-fix.patch b/patches/winedevice-Default_Drivers/0004-programs-winedevice-Load-some-common-drivers-and-fix.patch index 0bbeb99a..72da3b1b 100644 --- a/patches/winedevice-Default_Drivers/0004-programs-winedevice-Load-some-common-drivers-and-fix.patch +++ b/patches/winedevice-Default_Drivers/0004-programs-winedevice-Load-some-common-drivers-and-fix.patch @@ -1,16 +1,16 @@ -From 6ac70538d8f1989386bfe95bdbdc61af60b482c7 Mon Sep 17 00:00:00 2001 +From 63ae0e1dd59a078db172a96b3c1d63db4e9d8245 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20M=C3=BCller?= Date: Thu, 8 Jun 2017 23:50:03 +0200 Subject: [PATCH] programs/winedevice: Load some common drivers and fix ldr order. --- - dlls/ntoskrnl.exe/tests/driver.c | 51 ++++++++++++++++++++++++++++++++++++++++ - programs/winedevice/device.c | 26 ++++++++++++++++++++ + dlls/ntoskrnl.exe/tests/driver.c | 51 ++++++++++++++++++++++++++++++++ + programs/winedevice/device.c | 26 ++++++++++++++++ 2 files changed, 77 insertions(+) diff --git a/dlls/ntoskrnl.exe/tests/driver.c b/dlls/ntoskrnl.exe/tests/driver.c -index 3984240..c467ac5 100644 +index 6d64cc8e..f3465b77 100644 --- a/dlls/ntoskrnl.exe/tests/driver.c +++ b/dlls/ntoskrnl.exe/tests/driver.c @@ -38,6 +38,8 @@ static const WCHAR driver_device[] = {'\\','D','e','v','i','c','e', @@ -22,8 +22,8 @@ index 3984240..c467ac5 100644 static HANDLE okfile; static LONG successes; static LONG failures; -@@ -636,6 +638,52 @@ static void test_version(void) - ok(*pNtBuildNumber == build, "Expected build number %u, got %u\n", build, *pNtBuildNumber); +@@ -944,6 +946,52 @@ static void test_resource(void) + ok(status == STATUS_SUCCESS, "got status %#x\n", status); } +static void test_default_modules(void) @@ -75,15 +75,15 @@ index 3984240..c467ac5 100644 static NTSTATUS main_test(DEVICE_OBJECT *device, IRP *irp, IO_STACK_LOCATION *stack, ULONG_PTR *info) { ULONG length = stack->Parameters.DeviceIoControl.OutputBufferLength; -@@ -669,6 +717,7 @@ static NTSTATUS main_test(DEVICE_OBJECT *device, IRP *irp, IO_STACK_LOCATION *st - test_version(); +@@ -978,6 +1026,7 @@ static NTSTATUS main_test(DEVICE_OBJECT *device, IRP *irp, IO_STACK_LOCATION *st test_stack_callout(); test_lookaside_list(); + test_resource(); + test_default_modules(); /* print process report */ if (test_input->winetest_debug) -@@ -781,6 +830,8 @@ NTSTATUS WINAPI DriverEntry(DRIVER_OBJECT *driver, PUNICODE_STRING registry) +@@ -1090,6 +1139,8 @@ NTSTATUS WINAPI DriverEntry(DRIVER_OBJECT *driver, PUNICODE_STRING registry) DbgPrint("loading driver\n"); @@ -93,7 +93,7 @@ index 3984240..c467ac5 100644 driver->DriverUnload = driver_Unload; diff --git a/programs/winedevice/device.c b/programs/winedevice/device.c -index 201a041..33b332d 100644 +index 201a0411..33b332da 100644 --- a/programs/winedevice/device.c +++ b/programs/winedevice/device.c @@ -124,7 +124,33 @@ static DWORD WINAPI service_handler( DWORD ctrl, DWORD event_type, LPVOID event_ @@ -131,5 +131,5 @@ index 201a041..33b332d 100644 if (!(stop_event = CreateEventW( NULL, TRUE, FALSE, NULL ))) return; -- -1.9.1 +2.20.1 diff --git a/patches/winedevice-Default_Drivers/definition b/patches/winedevice-Default_Drivers/definition index aab320de..04caf8bb 100644 --- a/patches/winedevice-Default_Drivers/definition +++ b/patches/winedevice-Default_Drivers/definition @@ -1,3 +1,4 @@ Fixes: Simulate a more realistic kernel environment in ntoskrnl/winedevice Depends: dxva2-Video_Decoder -Depends: ntoskrnl-Stubs \ No newline at end of file +Depends: ntoskrnl-Stubs +Depends: ntoskrnl.exe-Resources \ No newline at end of file