From fafd82460f1a8ee69feb9f2921889abd884d7926 Mon Sep 17 00:00:00 2001
From: Zebediah Figura <z.figura12@gmail.com>
Date: Wed, 13 Jun 2018 14:33:38 -0500
Subject: [PATCH 39/83] ntdll, server: Allow DuplicateHandle() to succeed by
 implementing esync_get_esync_fd().

Note that this only works for events.
---
 dlls/ntdll/esync.c | 45 ++++++++++++++++++++++++++++++++++++++++++---
 server/esync.c     | 10 +++++++++-
 2 files changed, 51 insertions(+), 4 deletions(-)

diff --git a/dlls/ntdll/esync.c b/dlls/ntdll/esync.c
index 25e049291..4adf01a11 100644
--- a/dlls/ntdll/esync.c
+++ b/dlls/ntdll/esync.c
@@ -206,9 +206,48 @@ static NTSTATUS get_waitable_object( HANDLE handle, struct esync **obj )
 
     TRACE("Got fd %d for handle %p.\n", fd, handle);
 
-    esync = RtlAllocateHeap( GetProcessHeap(), 0, sizeof(*esync) );
-    esync->fd = fd;
-    esync->type = type;
+    switch (type)
+    {
+    case ESYNC_SEMAPHORE:
+    {
+        struct semaphore *semaphore = RtlAllocateHeap( GetProcessHeap(), 0, sizeof(*semaphore) );
+        semaphore->obj.type = ESYNC_SEMAPHORE;
+        semaphore->obj.fd = fd;
+
+        FIXME("Attempt to duplicate a semaphore; this will not work.\n");
+        semaphore->max = 0xdeadbeef;
+        semaphore->count = 0;
+        esync = &semaphore->obj;
+        break;
+    }
+    case ESYNC_AUTO_EVENT:
+    case ESYNC_MANUAL_EVENT:
+    {
+        struct event *event = RtlAllocateHeap( GetProcessHeap(), 0, sizeof(*event) );
+        event->obj.type = type;
+        event->obj.fd = fd;
+        esync = &event->obj;
+        break;
+    }
+    case ESYNC_MUTEX:
+    {
+        struct mutex *mutex = RtlAllocateHeap( GetProcessHeap(), 0, sizeof(*mutex) );
+        mutex->obj.type = type;
+        mutex->obj.fd = fd;
+
+        FIXME("Attempt to duplicate a mutex; this will not work.\n");
+        mutex->tid = 0;
+        mutex->count = 0;
+        esync = &mutex->obj;
+        break;
+    }
+    case ESYNC_MANUAL_SERVER:
+    case ESYNC_QUEUE:
+        esync = RtlAllocateHeap( GetProcessHeap(), 0, sizeof(*esync) );
+        esync->fd = fd;
+        esync->type = type;
+        break;
+    }
 
     add_to_list( handle, esync );
 
diff --git a/server/esync.c b/server/esync.c
index 62e6df30b..5dd38c42a 100644
--- a/server/esync.c
+++ b/server/esync.c
@@ -60,6 +60,7 @@ struct esync
 };
 
 static void esync_dump( struct object *obj, int verbose );
+static int esync_get_esync_fd( struct object *obj, enum esync_type *type );
 static unsigned int esync_map_access( struct object *obj, unsigned int access );
 static void esync_destroy( struct object *obj );
 
@@ -71,7 +72,7 @@ const struct object_ops esync_ops =
     no_add_queue,              /* add_queue */
     NULL,                      /* remove_queue */
     NULL,                      /* signaled */
-    NULL,                      /* get_esync_fd */
+    esync_get_esync_fd,        /* get_esync_fd */
     NULL,                      /* satisfied */
     no_signal,                 /* signal */
     no_get_fd,                 /* get_fd */
@@ -94,6 +95,13 @@ static void esync_dump( struct object *obj, int verbose )
     fprintf( stderr, "esync fd=%d\n", esync->fd );
 }
 
+static int esync_get_esync_fd( struct object *obj, enum esync_type *type )
+{
+    struct esync *esync = (struct esync *)obj;
+    *type = esync->type;
+    return esync->fd;
+}
+
 static unsigned int esync_map_access( struct object *obj, unsigned int access )
 {
     /* Sync objects have the same flags. */
-- 
2.20.1

