From 0ab9981b2309831fb12ee778e026cb1b4651dab6 Mon Sep 17 00:00:00 2001
From: Zebediah Figura <z.figura12@gmail.com>
Date: Fri, 8 Jun 2018 15:33:46 -0500
Subject: [PATCH 08/83] ntdll: Create esync objects for events.

---
 dlls/ntdll/esync.c | 34 ++++++++++++++++++++++++++++++++++
 dlls/ntdll/esync.h |  2 ++
 dlls/ntdll/sync.c  |  3 +++
 3 files changed, 39 insertions(+)

diff --git a/dlls/ntdll/esync.c b/dlls/ntdll/esync.c
index 0950d8b5a..ace2f4a45 100644
--- a/dlls/ntdll/esync.c
+++ b/dlls/ntdll/esync.c
@@ -77,6 +77,8 @@ int do_esync(void)
 enum esync_type
 {
     ESYNC_SEMAPHORE = 1,
+    ESYNC_AUTO_EVENT,
+    ESYNC_MANUAL_EVENT,
 };
 
 struct esync
@@ -91,6 +93,11 @@ struct semaphore
     int max;
 };
 
+struct event
+{
+    struct esync obj;
+};
+
 /* We'd like lookup to be fast. To that end, we use a static list indexed by handle.
  * This is copied and adapted from the fd cache code. */
 
@@ -248,6 +255,33 @@ NTSTATUS esync_release_semaphore( HANDLE handle, ULONG count, ULONG *prev )
     return STATUS_SUCCESS;
 }
 
+NTSTATUS esync_create_event( HANDLE *handle, ACCESS_MASK access,
+    const OBJECT_ATTRIBUTES *attr, EVENT_TYPE type, BOOLEAN initial )
+{
+    struct event *event;
+    NTSTATUS ret;
+    int fd;
+
+    TRACE("name %s, %s-reset, initial %d.\n",
+        attr ? debugstr_us(attr->ObjectName) : "<no name>",
+        type == NotificationEvent ? "manual" : "auto", initial);
+
+    ret = create_esync( &fd, handle, access, attr, initial, 0 );
+    if (!ret || ret == STATUS_OBJECT_NAME_EXISTS)
+    {
+        event = RtlAllocateHeap( GetProcessHeap(), 0, sizeof(*event) );
+        if (!event)
+            return STATUS_NO_MEMORY;
+
+        event->obj.type = (type == NotificationEvent ? ESYNC_MANUAL_EVENT : ESYNC_AUTO_EVENT);
+        event->obj.fd = fd;
+
+        add_to_list( *handle, &event->obj);
+    }
+
+    return ret;
+}
+
 #define TICKSPERSEC        10000000
 #define TICKSPERMSEC       10000
 
diff --git a/dlls/ntdll/esync.h b/dlls/ntdll/esync.h
index 8f7f9b030..32a259e39 100644
--- a/dlls/ntdll/esync.h
+++ b/dlls/ntdll/esync.h
@@ -24,6 +24,8 @@ extern NTSTATUS esync_close( HANDLE handle ) DECLSPEC_HIDDEN;
 extern NTSTATUS esync_create_semaphore(HANDLE *handle, ACCESS_MASK access,
     const OBJECT_ATTRIBUTES *attr, LONG initial, LONG max) DECLSPEC_HIDDEN;
 extern NTSTATUS esync_release_semaphore( HANDLE handle, ULONG count, ULONG *prev ) DECLSPEC_HIDDEN;
+extern NTSTATUS esync_create_event( HANDLE *handle, ACCESS_MASK access,
+    const OBJECT_ATTRIBUTES *attr, EVENT_TYPE type, BOOLEAN initial ) DECLSPEC_HIDDEN;
 
 extern NTSTATUS esync_wait_objects( DWORD count, const HANDLE *handles, BOOLEAN wait_any,
                                     BOOLEAN alertable, const LARGE_INTEGER *timeout ) DECLSPEC_HIDDEN;
diff --git a/dlls/ntdll/sync.c b/dlls/ntdll/sync.c
index 40bc619a2..6f0e72125 100644
--- a/dlls/ntdll/sync.c
+++ b/dlls/ntdll/sync.c
@@ -365,6 +365,9 @@ NTSTATUS WINAPI NtCreateEvent( PHANDLE EventHandle, ACCESS_MASK DesiredAccess,
     data_size_t len;
     struct object_attributes *objattr;
 
+    if (do_esync())
+        return esync_create_event( EventHandle, DesiredAccess, attr, type, InitialState );
+
     if ((ret = alloc_object_attributes( attr, &objattr, &len ))) return ret;
 
     SERVER_START_REQ( create_event )
-- 
2.20.1

