From 20207ace2ee21a22f2dc7095fd70364d54f53127 Mon Sep 17 00:00:00 2001
From: Zebediah Figura <z.figura12@gmail.com>
Date: Wed, 13 Jun 2018 15:08:26 -0500
Subject: [PATCH 44/83] server, ntdll: Pass the shared memory index back from
 get_esync_fd.

This should let DuplicateHandle() work completely correctly for semaphores and mutexes.
---
 dlls/ntdll/esync.c  | 6 +++---
 server/esync.c      | 7 +++++++
 server/protocol.def | 1 +
 3 files changed, 11 insertions(+), 3 deletions(-)

diff --git a/dlls/ntdll/esync.c b/dlls/ntdll/esync.c
index 6bfe24413..227dd3df0 100644
--- a/dlls/ntdll/esync.c
+++ b/dlls/ntdll/esync.c
@@ -214,6 +214,7 @@ static NTSTATUS get_waitable_object( HANDLE handle, struct esync **obj )
 {
     obj_handle_t fd_handle;
     enum esync_type type;
+    unsigned int shm_idx;
     struct esync *esync;
     sigset_t sigset;
     NTSTATUS ret;
@@ -231,6 +232,7 @@ static NTSTATUS get_waitable_object( HANDLE handle, struct esync **obj )
             if (!(ret = wine_server_call( req )))
             {
                 type = reply->type;
+                shm_idx = reply->shm_idx;
                 fd = receive_fd( &fd_handle );
                 assert( wine_server_ptr_handle(fd_handle) == handle );
             }
@@ -259,9 +261,7 @@ static NTSTATUS get_waitable_object( HANDLE handle, struct esync **obj )
     esync->fd = fd;
     esync->type = type;
 
-    if (type == ESYNC_SEMAPHORE || type == ESYNC_MUTEX)
-        FIXME("Attempt to duplicate a semaphore or mutex; this will not work.\n");
-    esync->shm = NULL;
+    esync->shm = shm_idx ? get_shm( shm_idx ) : 0;
 
     add_to_list( handle, esync );
 
diff --git a/server/esync.c b/server/esync.c
index e9a1ec15e..5ef4dd282 100644
--- a/server/esync.c
+++ b/server/esync.c
@@ -364,6 +364,13 @@ DECL_HANDLER(get_esync_fd)
     {
         fd = obj->ops->get_esync_fd( obj, &type );
         reply->type = type;
+        if (obj->ops == &esync_ops)
+        {
+            struct esync *esync = (struct esync *)obj;
+            reply->shm_idx = esync->shm_idx;
+        }
+        else
+            reply->shm_idx = 0;
         send_client_fd( current->process, fd, req->handle );
     }
     else
diff --git a/server/protocol.def b/server/protocol.def
index c2b554490..3037b8161 100644
--- a/server/protocol.def
+++ b/server/protocol.def
@@ -4073,6 +4073,7 @@ struct handle_info
     obj_handle_t handle;        /* handle to the object */
 @REPLY
     int          type;          /* esync type (defined below) */
+    unsigned int shm_idx;       /* this object's index into the shm section */
 @END
 
 enum esync_type
-- 
2.20.1

