From 38502f70eb6accac1931e6e4e18f295de72d7c06 Mon Sep 17 00:00:00 2001
From: Alexandre Julliard <julliard@winehq.org>
Date: Tue, 23 Aug 2005 18:43:50 +0000
Subject: [PATCH] Added a separate set_handle_cached_fd request instead of
 abusing set_handle_info for that.

---
 dlls/ntdll/om.c                |  2 --
 dlls/ntdll/server.c            |  4 +---
 include/wine/server_protocol.h | 19 +++++++++++++++++--
 server/handle.c                | 26 +++++++++++++++++++-------
 server/handle.h                |  1 -
 server/protocol.def            |  9 ++++++++-
 server/request.h               |  2 ++
 server/trace.c                 | 18 +++++++++++++++---
 8 files changed, 62 insertions(+), 19 deletions(-)

diff --git a/dlls/ntdll/om.c b/dlls/ntdll/om.c
index 459afb42064..d22234f17bd 100644
--- a/dlls/ntdll/om.c
+++ b/dlls/ntdll/om.c
@@ -71,7 +71,6 @@ NTSTATUS WINAPI NtQueryObject(IN HANDLE handle,
                 req->handle = handle;
                 req->flags  = 0;
                 req->mask   = 0;
-                req->fd     = -1;
                 status = wine_server_call( req );
                 if (status == STATUS_SUCCESS)
                 {
@@ -118,7 +117,6 @@ NTSTATUS WINAPI NtSetInformationObject(IN HANDLE handle,
                 req->handle = handle;
                 req->flags  = 0;
                 req->mask   = HANDLE_FLAG_INHERIT | HANDLE_FLAG_PROTECT_FROM_CLOSE;
-                req->fd     = -1;
                 if (p->InheritHandle)    req->flags |= HANDLE_FLAG_INHERIT;
                 if (p->ProtectFromClose) req->flags |= HANDLE_FLAG_PROTECT_FROM_CLOSE;
                 status = wine_server_call( req );
diff --git a/dlls/ntdll/server.c b/dlls/ntdll/server.c
index 35f11875850..f10bf2c6c56 100644
--- a/dlls/ntdll/server.c
+++ b/dlls/ntdll/server.c
@@ -428,11 +428,9 @@ inline static int store_cached_fd( int *fd, obj_handle_t handle )
 {
     int ret;
 
-    SERVER_START_REQ( set_handle_info )
+    SERVER_START_REQ( set_handle_cached_fd )
     {
         req->handle = handle;
-        req->flags  = 0;
-        req->mask   = 0;
         req->fd     = *fd;
         if (!(ret = wine_server_call( req )))
         {
diff --git a/include/wine/server_protocol.h b/include/wine/server_protocol.h
index 332cad51613..444e6fd663f 100644
--- a/include/wine/server_protocol.h
+++ b/include/wine/server_protocol.h
@@ -529,12 +529,24 @@ struct set_handle_info_request
     obj_handle_t handle;
     int          flags;
     int          mask;
-    int          fd;
 };
 struct set_handle_info_reply
 {
     struct reply_header __header;
     int          old_flags;
+};
+
+
+
+struct set_handle_cached_fd_request
+{
+    struct request_header __header;
+    obj_handle_t handle;
+    int          fd;
+};
+struct set_handle_cached_fd_reply
+{
+    struct reply_header __header;
     int          cur_fd;
 };
 
@@ -3585,6 +3597,7 @@ enum request
     REQ_get_apc,
     REQ_close_handle,
     REQ_set_handle_info,
+    REQ_set_handle_cached_fd,
     REQ_dup_handle,
     REQ_open_process,
     REQ_open_thread,
@@ -3796,6 +3809,7 @@ union generic_request
     struct get_apc_request get_apc_request;
     struct close_handle_request close_handle_request;
     struct set_handle_info_request set_handle_info_request;
+    struct set_handle_cached_fd_request set_handle_cached_fd_request;
     struct dup_handle_request dup_handle_request;
     struct open_process_request open_process_request;
     struct open_thread_request open_thread_request;
@@ -4005,6 +4019,7 @@ union generic_reply
     struct get_apc_reply get_apc_reply;
     struct close_handle_reply close_handle_reply;
     struct set_handle_info_reply set_handle_info_reply;
+    struct set_handle_cached_fd_reply set_handle_cached_fd_reply;
     struct dup_handle_reply dup_handle_reply;
     struct open_process_reply open_process_reply;
     struct open_thread_reply open_thread_reply;
@@ -4190,6 +4205,6 @@ union generic_reply
     struct set_mailslot_info_reply set_mailslot_info_reply;
 };
 
-#define SERVER_PROTOCOL_VERSION 189
+#define SERVER_PROTOCOL_VERSION 190
 
 #endif /* __WINE_WINE_SERVER_PROTOCOL_H */
diff --git a/server/handle.c b/server/handle.c
index 1baa523e808..e54678370a7 100644
--- a/server/handle.c
+++ b/server/handle.c
@@ -425,6 +425,17 @@ int get_handle_unix_fd( struct process *process, obj_handle_t handle, unsigned i
     return entry->fd;
 }
 
+/* set the cached fd for a handle if not set already, and return the current value */
+static int set_handle_unix_fd( struct process *process, obj_handle_t handle, int fd )
+{
+    struct handle_entry *entry;
+
+    if (!(entry = get_handle( process, handle ))) return -1;
+    /* if no current fd set it, otherwise return current fd */
+    if (entry->fd == -1) entry->fd = fd;
+    return entry->fd;
+}
+
 /* remove the cached fd and return it */
 int flush_cached_fd( struct process *process, obj_handle_t handle )
 {
@@ -460,7 +471,7 @@ obj_handle_t find_inherited_handle( struct process *process, const struct object
 
 /* get/set the handle reserved flags */
 /* return the old flags (or -1 on error) */
-int set_handle_info( struct process *process, obj_handle_t handle, int mask, int flags, int *fd )
+static int set_handle_flags( struct process *process, obj_handle_t handle, int mask, int flags )
 {
     struct handle_entry *entry;
     unsigned int old_access;
@@ -476,9 +487,6 @@ int set_handle_info( struct process *process, obj_handle_t handle, int mask, int
     mask  = (mask << RESERVED_SHIFT) & RESERVED_ALL;
     flags = (flags << RESERVED_SHIFT) & mask;
     entry->access = (entry->access & ~mask) | flags;
-    /* if no current fd set it, otherwise return current fd */
-    if (entry->fd == -1) entry->fd = *fd;
-    *fd = entry->fd;
     return (old_access & RESERVED_ALL) >> RESERVED_SHIFT;
 }
 
@@ -544,13 +552,17 @@ DECL_HANDLER(close_handle)
 
 /* set a handle information */
 DECL_HANDLER(set_handle_info)
+{
+    reply->old_flags = set_handle_flags( current->process, req->handle, req->mask, req->flags );
+}
+
+/* set the cached file descriptor of a handle */
+DECL_HANDLER(set_handle_cached_fd)
 {
     int fd = req->fd;
 
     if (handle_is_global(req->handle)) fd = -1;  /* no fd cache for global handles */
-    reply->old_flags = set_handle_info( current->process, req->handle,
-                                        req->mask, req->flags, &fd );
-    reply->cur_fd = fd;
+    reply->cur_fd = set_handle_unix_fd( current->process, req->handle, fd );
 }
 
 /* duplicate a handle */
diff --git a/server/handle.h b/server/handle.h
index 94912584a8e..d90a47eaeb4 100644
--- a/server/handle.h
+++ b/server/handle.h
@@ -40,7 +40,6 @@ extern struct object *get_handle_obj( struct process *process, obj_handle_t hand
                                       unsigned int access, const struct object_ops *ops );
 extern unsigned int get_handle_access( struct process *process, obj_handle_t handle );
 extern int get_handle_unix_fd( struct process *process, obj_handle_t handle, unsigned int access );
-extern int set_handle_info( struct process *process, obj_handle_t handle, int mask, int flags, int *fd );
 extern obj_handle_t duplicate_handle( struct process *src, obj_handle_t src_handle, struct process *dst,
                                   unsigned int access, int inherit, int options );
 extern obj_handle_t open_object( const struct namespace *namespace, const WCHAR *name, size_t len,
diff --git a/server/protocol.def b/server/protocol.def
index d4b52ccd83a..06747cc2968 100644
--- a/server/protocol.def
+++ b/server/protocol.def
@@ -437,9 +437,16 @@ enum apc_type { APC_NONE, APC_USER, APC_TIMER, APC_ASYNC_IO };
     obj_handle_t handle;       /* handle we are interested in */
     int          flags;        /* new handle flags */
     int          mask;         /* mask for flags to set */
-    int          fd;           /* file descriptor or -1 */
 @REPLY
     int          old_flags;    /* old flag value */
+@END
+
+
+/* Set the cached file descriptor of a handle */
+@REQ(set_handle_cached_fd)
+    obj_handle_t handle;       /* handle we are interested in */
+    int          fd;           /* file descriptor */
+@REPLY
     int          cur_fd;       /* current file descriptor */
 @END
 
diff --git a/server/request.h b/server/request.h
index 740a4175039..01dc7f0051c 100644
--- a/server/request.h
+++ b/server/request.h
@@ -124,6 +124,7 @@ DECL_HANDLER(queue_apc);
 DECL_HANDLER(get_apc);
 DECL_HANDLER(close_handle);
 DECL_HANDLER(set_handle_info);
+DECL_HANDLER(set_handle_cached_fd);
 DECL_HANDLER(dup_handle);
 DECL_HANDLER(open_process);
 DECL_HANDLER(open_thread);
@@ -334,6 +335,7 @@ static const req_handler req_handlers[REQ_NB_REQUESTS] =
     (req_handler)req_get_apc,
     (req_handler)req_close_handle,
     (req_handler)req_set_handle_info,
+    (req_handler)req_set_handle_cached_fd,
     (req_handler)req_dup_handle,
     (req_handler)req_open_process,
     (req_handler)req_open_thread,
diff --git a/server/trace.c b/server/trace.c
index 17b2544ad47..d648cfa20ec 100644
--- a/server/trace.c
+++ b/server/trace.c
@@ -828,13 +828,22 @@ static void dump_set_handle_info_request( const struct set_handle_info_request *
 {
     fprintf( stderr, " handle=%p,", req->handle );
     fprintf( stderr, " flags=%d,", req->flags );
-    fprintf( stderr, " mask=%d,", req->mask );
-    fprintf( stderr, " fd=%d", req->fd );
+    fprintf( stderr, " mask=%d", req->mask );
 }
 
 static void dump_set_handle_info_reply( const struct set_handle_info_reply *req )
 {
-    fprintf( stderr, " old_flags=%d,", req->old_flags );
+    fprintf( stderr, " old_flags=%d", req->old_flags );
+}
+
+static void dump_set_handle_cached_fd_request( const struct set_handle_cached_fd_request *req )
+{
+    fprintf( stderr, " handle=%p,", req->handle );
+    fprintf( stderr, " fd=%d", req->fd );
+}
+
+static void dump_set_handle_cached_fd_reply( const struct set_handle_cached_fd_reply *req )
+{
     fprintf( stderr, " cur_fd=%d", req->cur_fd );
 }
 
@@ -3100,6 +3109,7 @@ static const dump_func req_dumpers[REQ_NB_REQUESTS] = {
     (dump_func)dump_get_apc_request,
     (dump_func)dump_close_handle_request,
     (dump_func)dump_set_handle_info_request,
+    (dump_func)dump_set_handle_cached_fd_request,
     (dump_func)dump_dup_handle_request,
     (dump_func)dump_open_process_request,
     (dump_func)dump_open_thread_request,
@@ -3307,6 +3317,7 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] = {
     (dump_func)dump_get_apc_reply,
     (dump_func)dump_close_handle_reply,
     (dump_func)dump_set_handle_info_reply,
+    (dump_func)dump_set_handle_cached_fd_reply,
     (dump_func)dump_dup_handle_reply,
     (dump_func)dump_open_process_reply,
     (dump_func)dump_open_thread_reply,
@@ -3514,6 +3525,7 @@ static const char * const req_names[REQ_NB_REQUESTS] = {
     "get_apc",
     "close_handle",
     "set_handle_info",
+    "set_handle_cached_fd",
     "dup_handle",
     "open_process",
     "open_thread",
-- 
GitLab