Rebase against 5ed7a61de7e72ecf4cf6ef76d4044f32640b93cb

This commit is contained in:
Alistair Leslie-Hughes 2019-04-10 09:43:50 +10:00
parent 52a77f6b00
commit a8556b9c25
10 changed files with 3 additions and 1187 deletions

View File

@ -1,132 +0,0 @@
From 635759b4f374469956488aaf6fa4c6307a542ee9 Mon Sep 17 00:00:00 2001
From: Zebediah Figura <z.figura12@gmail.com>
Date: Tue, 29 Jan 2019 21:33:08 -0600
Subject: [PATCH 01/13] ntoskrnl.exe: Implement ExInitializeResourceLite().
Signed-off-by: Zebediah Figura <z.figura12@gmail.com>
---
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

View File

@ -1,143 +0,0 @@
From 0a7df47900ff847f137836341d086dc5690f97d7 Mon Sep 17 00:00:00 2001
From: Zebediah Figura <z.figura12@gmail.com>
Date: Tue, 29 Jan 2019 21:35:44 -0600
Subject: [PATCH 02/13] ntoskrnl.exe: Implement
ExAcquireResourceExclusiveLite().
Signed-off-by: Zebediah Figura <z.figura12@gmail.com>
---
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

View File

@ -1,141 +0,0 @@
From a1fc7aa628beedda24325ce4de8231ed03b2b184 Mon Sep 17 00:00:00 2001
From: Zebediah Figura <z.figura12@gmail.com>
Date: Tue, 29 Jan 2019 21:37:38 -0600
Subject: [PATCH 03/13] ntoskrnl.exe: Implement ExAcquireResourceSharedLite().
Signed-off-by: Zebediah Figura <z.figura12@gmail.com>
---
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 <limits.h>
#include <stdarg.h>
#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

View File

@ -1,110 +0,0 @@
From d57ba73e962955d928a72d7fa23a90b3dbb6e50c Mon Sep 17 00:00:00 2001
From: Zebediah Figura <z.figura12@gmail.com>
Date: Tue, 29 Jan 2019 21:39:05 -0600
Subject: [PATCH 04/13] ntoskrnl.exe: Implement
ExAcquireSharedStarveExclusive().
Signed-off-by: Zebediah Figura <z.figura12@gmail.com>
---
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

View File

@ -1,108 +0,0 @@
From 3503f4db49ee2c4602fc1af38c97f456a1dea76a Mon Sep 17 00:00:00 2001
From: Zebediah Figura <z.figura12@gmail.com>
Date: Tue, 29 Jan 2019 21:40:19 -0600
Subject: [PATCH 05/13] ntoskrnl.exe: Implement
ExAcquireSharedWaitForExclusive().
Signed-off-by: Zebediah Figura <z.figura12@gmail.com>
---
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

View File

@ -1,115 +0,0 @@
From 3342ffc67dd4df100c164335a024c072a784256b Mon Sep 17 00:00:00 2001
From: Zebediah Figura <z.figura12@gmail.com>
Date: Tue, 29 Jan 2019 21:41:46 -0600
Subject: [PATCH] ntoskrnl.exe: Implement ExReleaseResourceForThreadLite().
Signed-off-by: Zebediah Figura <z.figura12@gmail.com>
---
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 887fdb1..9fbfed2 100644
--- a/dlls/ntoskrnl.exe/ntoskrnl.c
+++ b/dlls/ntoskrnl.exe/ntoskrnl.c
@@ -3256,14 +3256,6 @@ NTSTATUS WINAPI ExDeleteResourceLite(PERESOURCE resource)
}
/***********************************************************************
- * ExReleaseResourceForThreadLite (NTOSKRNL.EXE.@)
- */
-void WINAPI ExReleaseResourceForThreadLite( PERESOURCE resource, ERESOURCE_THREAD tid )
-{
- FIXME( "stub: %p %lu\n", resource, tid );
-}
-
-/***********************************************************************
* KeEnterCriticalRegion (NTOSKRNL.EXE.@)
*/
void WINAPI KeEnterCriticalRegion(void)
diff --git a/dlls/ntoskrnl.exe/sync.c b/dlls/ntoskrnl.exe/sync.c
index 8644562..540093d 100644
--- a/dlls/ntoskrnl.exe/sync.c
+++ b/dlls/ntoskrnl.exe/sync.c
@@ -925,3 +925,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 4dada66..58e60d2 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);
ULONG WINAPI ExSetTimerResolution(ULONG,BOOLEAN);
void WINAPI IoAcquireCancelSpinLock(KIRQL*);
--
1.9.1

View File

@ -1,64 +0,0 @@
From 356adef44cc8267ae73cbbb6bc250ac8bc993e75 Mon Sep 17 00:00:00 2001
From: Zebediah Figura <z.figura12@gmail.com>
Date: Tue, 29 Jan 2019 21:44:23 -0600
Subject: [PATCH 07/13] ntoskrnl.exe: Implement ExReleaseResourceLite().
Signed-off-by: Zebediah Figura <z.figura12@gmail.com>
---
dlls/ntoskrnl.exe/ntoskrnl.c | 8 --------
dlls/ntoskrnl.exe/ntoskrnl.exe.spec | 2 +-
dlls/ntoskrnl.exe/sync.c | 9 +++++++++
3 files changed, 10 insertions(+), 9 deletions(-)
diff --git a/dlls/ntoskrnl.exe/ntoskrnl.c b/dlls/ntoskrnl.exe/ntoskrnl.c
index e2a838cc..d310b7e4 100644
--- a/dlls/ntoskrnl.exe/ntoskrnl.c
+++ b/dlls/ntoskrnl.exe/ntoskrnl.c
@@ -4048,14 +4048,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 ea543025..f57352f2 100644
--- a/dlls/ntoskrnl.exe/ntoskrnl.exe.spec
+++ b/dlls/ntoskrnl.exe/ntoskrnl.exe.spec
@@ -9,7 +9,7 @@
@ stdcall -fastcall -arch=i386 ExInterlockedPushEntrySList (ptr ptr ptr) NTOSKRNL_ExInterlockedPushEntrySList
@ stub ExReInitializeRundownProtection
@ stdcall -fastcall ExReleaseFastMutexUnsafe(ptr)
-@ stdcall ExReleaseResourceLite(ptr)
+@ stdcall -fastcall ExReleaseResourceLite(ptr)
@ stub ExReleaseRundownProtection
@ stub ExReleaseRundownProtectionEx
@ stub ExRundownCompleted
diff --git a/dlls/ntoskrnl.exe/sync.c b/dlls/ntoskrnl.exe/sync.c
index 540093d7..02f96c3c 100644
--- a/dlls/ntoskrnl.exe/sync.c
+++ b/dlls/ntoskrnl.exe/sync.c
@@ -986,3 +986,12 @@ void WINAPI ExReleaseResourceForThreadLite( ERESOURCE *resource, ERESOURCE_THREA
KeReleaseSpinLock( &resource->SpinLock, irql );
}
+
+/***********************************************************************
+ * ExReleaseResourceLite (NTOSKRNL.EXE.@)
+ */
+DEFINE_FASTCALL1_WRAPPER( ExReleaseResourceLite )
+void WINAPI ExReleaseResourceLite( ERESOURCE *resource )
+{
+ ExReleaseResourceForThreadLite( resource, (ERESOURCE_THREAD)KeGetCurrentThread() );
+}
--
2.20.1

View File

@ -1,70 +0,0 @@
From 977a76e8ed97d3dee870738b6fecfd3bc515e270 Mon Sep 17 00:00:00 2001
From: Zebediah Figura <z.figura12@gmail.com>
Date: Tue, 29 Jan 2019 21:47:14 -0600
Subject: [PATCH 08/13] ntoskrnl.exe: Implement ExDeleteResourceLite().
Signed-off-by: Zebediah Figura <z.figura12@gmail.com>
---
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

View File

@ -52,7 +52,7 @@ usage()
# Get the upstream commit sha
upstream_commit()
{
echo "18883a76762afab3e18e1279a9666240e19d4d03"
echo "5ed7a61de7e72ecf4cf6ef76d4044f32640b93cb"
}
# Show version information
@ -5258,32 +5258,15 @@ fi
# | '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
# | * 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 },';
@ -7447,13 +7430,11 @@ fi
# | * [#42518] Implement image hash verification in WinVerifyTrust
# |
# | Modified files:
# | * dlls/wintrust/softpub.c, dlls/wintrust/tests/softpub.c
# | * dlls/wintrust/softpub.c
# |
if test "$enable_wintrust_WinVerifyTrust" -eq 1; then
patch_apply wintrust-WinVerifyTrust/0003-wintrust-Verify-image-hash-in-WinVerifyTrust.patch
patch_apply wintrust-WinVerifyTrust/0004-wintrust-use-enhanced-crypto-provider-in-VerifyImage.patch
(
printf '%s\n' '+ { "Mark Jansen", "wintrust: Verify image hash in WinVerifyTrust.", 2 },';
printf '%s\n' '+ { "Marko Friedemann", "wintrust: Use enhanced crypto provider in VerifyImageHash.", 1 },';
) >> "$patchlist"
fi

View File

@ -1,282 +0,0 @@
From 34d2916d1616b418395c6f543ba9cd362a82d7ab Mon Sep 17 00:00:00 2001
From: Mark Jansen <learn0more+wine@gmail.com>
Date: Sat, 2 Apr 2016 02:57:47 +0200
Subject: wintrust: Verify image hash in WinVerifyTrust. (v2)
Includes various improvements by Sebastian Lackner <sebastian@fds-team.de>.
Changes in v2:
* Do not use memory mapping (based on a patch by Mark Jansen).
---
dlls/wintrust/softpub.c | 194 ++++++++++++++++++++++++++++++++++++++++++
dlls/wintrust/tests/softpub.c | 8 +-
2 files changed, 198 insertions(+), 4 deletions(-)
diff --git a/dlls/wintrust/softpub.c b/dlls/wintrust/softpub.c
index 4e8582e2183..35c0d7b5abb 100644
--- a/dlls/wintrust/softpub.c
+++ b/dlls/wintrust/softpub.c
@@ -1,5 +1,6 @@
/*
* Copyright 2007 Juan Lang
+ * Copyright 2016 Mark Jansen
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -21,6 +22,7 @@
#include "windef.h"
#include "winbase.h"
+#include "winternl.h"
#include "wintrust.h"
#include "mssip.h"
#include "softpub.h"
@@ -208,6 +210,195 @@ static DWORD SOFTPUB_GetMessageFromFile(CRYPT_PROVIDER_DATA *data, HANDLE file,
return err;
}
+/* See https://www.cs.auckland.ac.nz/~pgut001/pubs/authenticode.txt
+ * for details about the hashing.
+ */
+static BOOL SOFTPUB_HashPEFile(HANDLE file, HCRYPTHASH hash)
+{
+ DWORD pos, checksum, security_dir;
+ IMAGE_DOS_HEADER dos_header;
+ union
+ {
+ IMAGE_NT_HEADERS32 nt32;
+ IMAGE_NT_HEADERS64 nt64;
+ } nt_header;
+ IMAGE_DATA_DIRECTORY secdir;
+ LARGE_INTEGER file_size;
+ DWORD bytes_read;
+ BYTE buffer[1024];
+ BOOL ret;
+
+ if (!GetFileSizeEx(file, &file_size))
+ return FALSE;
+
+ SetFilePointer(file, 0, NULL, FILE_BEGIN);
+ ret = ReadFile(file, &dos_header, sizeof(dos_header), &bytes_read, NULL);
+ if (!ret || bytes_read != sizeof(dos_header))
+ return FALSE;
+
+ if (dos_header.e_magic != IMAGE_DOS_SIGNATURE)
+ {
+ ERR("Unrecognized IMAGE_DOS_HEADER magic %04x\n", dos_header.e_magic);
+ return FALSE;
+ }
+ if (dos_header.e_lfanew >= 256 * 1024 * 1024) /* see RtlImageNtHeaderEx */
+ return FALSE;
+ if (dos_header.e_lfanew + FIELD_OFFSET(IMAGE_NT_HEADERS, OptionalHeader.MajorLinkerVersion) > file_size.QuadPart)
+ return FALSE;
+
+ SetFilePointer(file, dos_header.e_lfanew, NULL, FILE_BEGIN);
+ ret = ReadFile(file, &nt_header, sizeof(nt_header), &bytes_read, NULL);
+ if (!ret || bytes_read < FIELD_OFFSET(IMAGE_NT_HEADERS32, OptionalHeader.Magic) +
+ sizeof(nt_header.nt32.OptionalHeader.Magic))
+ return FALSE;
+
+ if (nt_header.nt32.Signature != IMAGE_NT_SIGNATURE)
+ {
+ ERR("Unrecognized IMAGE_NT_HEADERS signature %08x\n", nt_header.nt32.Signature);
+ return FALSE;
+ }
+
+ if (nt_header.nt32.OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR32_MAGIC)
+ {
+ if (bytes_read < sizeof(nt_header.nt32))
+ return FALSE;
+
+ checksum = dos_header.e_lfanew + FIELD_OFFSET(IMAGE_NT_HEADERS32, OptionalHeader.CheckSum);
+ security_dir = dos_header.e_lfanew + FIELD_OFFSET(IMAGE_NT_HEADERS32, OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_SECURITY]);
+ secdir = nt_header.nt32.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_SECURITY];
+ }
+ else if (nt_header.nt32.OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR64_MAGIC)
+ {
+ if (bytes_read < sizeof(nt_header.nt64))
+ return FALSE;
+
+ checksum = dos_header.e_lfanew + FIELD_OFFSET(IMAGE_NT_HEADERS64, OptionalHeader.CheckSum);
+ security_dir = dos_header.e_lfanew + FIELD_OFFSET(IMAGE_NT_HEADERS64, OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_SECURITY]);
+ secdir = nt_header.nt64.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_SECURITY];
+ }
+ else
+ {
+ ERR("Unrecognized OptionalHeader magic %04x\n", nt_header.nt32.OptionalHeader.Magic);
+ return FALSE;
+ }
+
+ if (secdir.VirtualAddress < security_dir + sizeof(IMAGE_DATA_DIRECTORY))
+ return FALSE;
+ if (secdir.VirtualAddress > file_size.QuadPart)
+ return FALSE;
+ if (secdir.VirtualAddress + secdir.Size != file_size.QuadPart)
+ return FALSE;
+
+ /* Hash until checksum. */
+ SetFilePointer(file, 0, NULL, FILE_BEGIN);
+ for (pos = 0; pos < checksum; pos += bytes_read)
+ {
+ ret = ReadFile(file, buffer, min(sizeof(buffer), checksum - pos), &bytes_read, NULL);
+ if (!ret || !bytes_read)
+ return FALSE;
+ if (!CryptHashData(hash, buffer, bytes_read, 0))
+ return FALSE;
+ }
+
+ /* Hash until the DataDirectory[IMAGE_DIRECTORY_ENTRY_SECURITY] entry. */
+ checksum += sizeof(DWORD);
+ SetFilePointer(file, checksum, NULL, FILE_BEGIN);
+ for (pos = checksum; pos < security_dir; pos += bytes_read)
+ {
+ ret = ReadFile(file, buffer, min(sizeof(buffer), security_dir - pos), &bytes_read, NULL);
+ if (!ret || !bytes_read)
+ return FALSE;
+ if (!CryptHashData(hash, buffer, bytes_read, 0))
+ return FALSE;
+ }
+
+ /* Hash until the end of the file. */
+ security_dir += sizeof(IMAGE_DATA_DIRECTORY);
+ SetFilePointer(file, security_dir, NULL, FILE_BEGIN);
+ for (pos = security_dir; pos < secdir.VirtualAddress; pos += bytes_read)
+ {
+ ret = ReadFile(file, buffer, min(sizeof(buffer), secdir.VirtualAddress - pos), &bytes_read, NULL);
+ if (!ret || !bytes_read)
+ return FALSE;
+ if (!CryptHashData(hash, buffer, bytes_read, 0))
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static DWORD SOFTPUB_VerifyImageHash(CRYPT_PROVIDER_DATA *data, HANDLE file)
+{
+ SPC_INDIRECT_DATA_CONTENT *indirect = (SPC_INDIRECT_DATA_CONTENT *)data->u.pPDSip->psIndirectData;
+ DWORD err, hash_size, length;
+ BYTE *hash_data;
+ BOOL release_prov = FALSE;
+ HCRYPTPROV prov = data->hProv;
+ HCRYPTHASH hash = 0;
+ ALG_ID algID;
+
+ if (((ULONG_PTR)indirect->Data.pszObjId >> 16) == 0 ||
+ strcmp(indirect->Data.pszObjId, SPC_PE_IMAGE_DATA_OBJID))
+ {
+ FIXME("Cannot verify hash for pszObjId=%s\n", debugstr_a(indirect->Data.pszObjId));
+ return ERROR_SUCCESS;
+ }
+
+ if (!(algID = CertOIDToAlgId(indirect->DigestAlgorithm.pszObjId)))
+ return TRUST_E_SYSTEM_ERROR; /* FIXME */
+
+ if (!prov)
+ {
+ if (!CryptAcquireContextW(&prov, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
+ return GetLastError();
+ release_prov = TRUE;
+ }
+
+ if (!CryptCreateHash(prov, algID, 0, 0, &hash))
+ {
+ err = GetLastError();
+ goto done;
+ }
+
+ if (!SOFTPUB_HashPEFile(file, hash))
+ {
+ err = TRUST_E_NOSIGNATURE;
+ goto done;
+ }
+
+ length = sizeof(hash_size);
+ if (!CryptGetHashParam(hash, HP_HASHSIZE, (BYTE *)&hash_size, &length, 0))
+ {
+ err = GetLastError();
+ goto done;
+ }
+
+ if (!(hash_data = data->psPfns->pfnAlloc(hash_size)))
+ {
+ err = ERROR_OUTOFMEMORY;
+ goto done;
+ }
+
+ if (!CryptGetHashParam(hash, HP_HASHVAL, hash_data, &hash_size, 0))
+ {
+ err = GetLastError();
+ data->psPfns->pfnFree(hash_data);
+ goto done;
+ }
+
+ err = (hash_size == indirect->Digest.cbData &&
+ !memcmp(hash_data, indirect->Digest.pbData, hash_size)) ? S_OK : TRUST_E_BAD_DIGEST;
+ data->psPfns->pfnFree(hash_data);
+
+done:
+ if (hash)
+ CryptDestroyHash(hash);
+ if (release_prov)
+ CryptReleaseContext(prov, 0);
+ return err;
+}
+
+
static DWORD SOFTPUB_CreateStoreFromMessage(CRYPT_PROVIDER_DATA *data)
{
DWORD err = ERROR_SUCCESS;
@@ -371,6 +562,9 @@ static DWORD SOFTPUB_LoadFileMessage(CRYPT_PROVIDER_DATA *data)
if (err)
goto error;
err = SOFTPUB_DecodeInnerContent(data);
+ if (err)
+ goto error;
+ err = SOFTPUB_VerifyImageHash(data, data->pWintrustData->u.pFile->hFile);
error:
if (err && data->fOpenedFile && data->pWintrustData->u.pFile)
diff --git a/dlls/wintrust/tests/softpub.c b/dlls/wintrust/tests/softpub.c
index aa481e407fc..1f872341357 100644
--- a/dlls/wintrust/tests/softpub.c
+++ b/dlls/wintrust/tests/softpub.c
@@ -1152,7 +1152,7 @@ static void test_wintrust_digest(void)
{
{{ SelfSignedFile32, sizeof(SelfSignedFile32) },
{ Dummy, sizeof(Dummy) }},
- { TRUST_E_NOSIGNATURE, TRUE }, { TRUST_E_NOSIGNATURE, TRUE }
+ { TRUST_E_NOSIGNATURE, FALSE }, { TRUST_E_NOSIGNATURE, FALSE }
},
{
{{ Dummy, sizeof(Dummy) },
@@ -1163,7 +1163,7 @@ static void test_wintrust_digest(void)
{{ SelfSignedFile32, 19 },
{ Dummy, sizeof(Dummy) },
{ SelfSignedFile32 + 19 + sizeof(Dummy), sizeof(SelfSignedFile32) - 19 - sizeof(Dummy) }},
- { TRUST_E_BAD_DIGEST, TRUE }, { TRUST_E_NOSIGNATURE, TRUE }
+ { TRUST_E_BAD_DIGEST, FALSE }, { TRUST_E_NOSIGNATURE, TRUE }
},
{
{{ SelfSignedFile32, sizeof(IMAGE_DOS_HEADER) }},
@@ -1182,7 +1182,7 @@ static void test_wintrust_digest(void)
{
{{ SelfSignedFile64, sizeof(SelfSignedFile64) },
{ Dummy, sizeof(Dummy) }},
- { TRUST_E_NOSIGNATURE, TRUE }, { TRUST_E_NOSIGNATURE, TRUE }
+ { TRUST_E_NOSIGNATURE, FALSE }, { TRUST_E_NOSIGNATURE, FALSE }
},
{
{{ Dummy, sizeof(Dummy) },
@@ -1193,7 +1193,7 @@ static void test_wintrust_digest(void)
{{ SelfSignedFile64, 19 },
{ Dummy, sizeof(Dummy) },
{ SelfSignedFile64 + 19 + sizeof(Dummy), sizeof(SelfSignedFile64) - 19 - sizeof(Dummy) }},
- { TRUST_E_BAD_DIGEST, TRUE }, { TRUST_E_NOSIGNATURE, TRUE }
+ { TRUST_E_BAD_DIGEST, FALSE }, { TRUST_E_NOSIGNATURE, TRUE }
},
{
{{ SelfSignedFile64, sizeof(IMAGE_DOS_HEADER) }},
--
2.11.0