Use a separate FIFO pair for server requests that don't need to pass a
file descriptor.
Associate file descriptors with handles on the server side so that we
don't need to pass the fd every time the client wants to use it.
diff --git a/server/console.c b/server/console.c
index 6f72ade..dcdc287 100644
--- a/server/console.c
+++ b/server/console.c
@@ -419,7 +419,7 @@
if ((out = alloc_handle( current->process, current->process->console_out,
req->access, req->inherit )) != -1)
goto done; /* everything is fine */
- close_handle( current->process, in );
+ close_handle( current->process, in, NULL );
in = -1;
}
free_console( current->process );
diff --git a/server/debugger.c b/server/debugger.c
index c88f82e..7f84410 100644
--- a/server/debugger.c
+++ b/server/debugger.c
@@ -118,7 +118,7 @@
/* documented: THREAD_GET_CONTEXT | THREAD_SET_CONTEXT | THREAD_SUSPEND_RESUME */
if ((handle = alloc_handle( debugger, thread, THREAD_ALL_ACCESS, FALSE )) == -1)
{
- close_handle( debugger, event->data.info.create_process.process );
+ close_handle( debugger, event->data.info.create_process.process, NULL );
return 0;
}
event->data.info.create_process.thread = handle;
@@ -128,8 +128,8 @@
/* the doc says write access too, but this doesn't seem a good idea */
((handle = alloc_handle( debugger, process->exe.file, GENERIC_READ, FALSE )) == -1))
{
- close_handle( debugger, event->data.info.create_process.process );
- close_handle( debugger, event->data.info.create_process.thread );
+ close_handle( debugger, event->data.info.create_process.process, NULL );
+ close_handle( debugger, event->data.info.create_process.thread, NULL );
return 0;
}
event->data.info.create_process.file = handle;
@@ -316,17 +316,17 @@
switch(event->data.code)
{
case CREATE_THREAD_DEBUG_EVENT:
- close_handle( debugger, event->data.info.create_thread.handle );
+ close_handle( debugger, event->data.info.create_thread.handle, NULL );
break;
case CREATE_PROCESS_DEBUG_EVENT:
if (event->data.info.create_process.file != -1)
- close_handle( debugger, event->data.info.create_process.file );
- close_handle( debugger, event->data.info.create_process.thread );
- close_handle( debugger, event->data.info.create_process.process );
+ close_handle( debugger, event->data.info.create_process.file, NULL );
+ close_handle( debugger, event->data.info.create_process.thread, NULL );
+ close_handle( debugger, event->data.info.create_process.process, NULL );
break;
case LOAD_DLL_DEBUG_EVENT:
if (event->data.info.load_dll.handle != -1)
- close_handle( debugger, event->data.info.load_dll.handle );
+ close_handle( debugger, event->data.info.load_dll.handle, NULL );
break;
}
}
diff --git a/server/file.c b/server/file.c
index 5c0f59a..e0ce8a7 100644
--- a/server/file.c
+++ b/server/file.c
@@ -325,11 +325,6 @@
return (struct file *)get_handle_obj( process, handle, access, &file_ops );
}
-int file_get_mmap_fd( struct file *file )
-{
- return dup( file->obj.fd );
-}
-
static int set_file_pointer( int handle, int *low, int *high, int whence )
{
struct file *file;
@@ -479,7 +474,8 @@
req->fd = -1;
if ((obj = get_handle_obj( current->process, req->handle, req->access, NULL )))
{
- set_reply_fd( current, obj->ops->get_fd( obj ) );
+ if ((req->fd = get_handle_fd( current->process, req->handle, req->access )) == -1)
+ send_client_fd( current, obj->ops->get_fd( obj ), req->handle );
release_object( obj );
}
}
diff --git a/server/handle.c b/server/handle.c
index 1d1317f..6a3e1f6 100644
--- a/server/handle.c
+++ b/server/handle.c
@@ -19,8 +19,9 @@
struct handle_entry
{
- struct object *ptr;
- unsigned int access;
+ struct object *ptr; /* object */
+ unsigned int access; /* access rights */
+ int fd; /* file descriptor (in client process) */
};
struct handle_table
@@ -173,6 +174,7 @@
table->free = i + 1;
entry->ptr = grab_object( obj );
entry->access = access;
+ entry->fd = -1;
return index_to_handle(i);
}
@@ -269,6 +271,7 @@
for (i = 0; i <= table->last; i++, ptr++)
{
if (!ptr->ptr) continue;
+ ptr->fd = -1;
if (ptr->access & RESERVED_INHERIT) grab_object( ptr->ptr );
else ptr->ptr = NULL; /* don't inherit this entry */
}
@@ -280,7 +283,7 @@
/* close a handle and decrement the refcount of the associated object */
/* return 1 if OK, 0 on error */
-int close_handle( struct process *process, int handle )
+int close_handle( struct process *process, int handle, int *fd )
{
struct handle_table *table;
struct handle_entry *entry;
@@ -294,6 +297,9 @@
}
obj = entry->ptr;
entry->ptr = NULL;
+ if (fd) *fd = entry->fd;
+ else if (entry->fd != -1) return 1; /* silently ignore close attempt if we cannot close the fd */
+ entry->fd = -1;
table = HANDLE_IS_GLOBAL(handle) ? global_table : (struct handle_table *)process->handles;
if (entry < table->entries + table->free) table->free = entry - table->entries;
if (entry == table->entries + table->last) shrink_handle_table( table );
@@ -351,12 +357,28 @@
return grab_object( obj );
}
-/* get/set the handle reserved flags */
-/* return the new flags (or -1 on error) */
-static int set_handle_info( struct process *process, int handle, int mask, int flags )
+/* retrieve the cached fd for a given handle */
+int get_handle_fd( struct process *process, int handle, unsigned int access )
{
struct handle_entry *entry;
+ if (HANDLE_IS_GLOBAL(handle)) return -1; /* no fd cache for global handles */
+ if (!(entry = get_handle( process, handle ))) return -1;
+ if ((entry->access & access) != access)
+ {
+ set_error( STATUS_ACCESS_DENIED );
+ return -1;
+ }
+ return entry->fd;
+}
+
+/* get/set the handle reserved flags */
+/* return the old flags (or -1 on error) */
+static int set_handle_info( struct process *process, int handle, int mask, int flags, int *fd )
+{
+ struct handle_entry *entry;
+ unsigned int old_access;
+
if (get_magic_handle( handle ))
{
/* we can retrieve but not set info for magic handles */
@@ -364,10 +386,14 @@
return 0;
}
if (!(entry = get_handle( process, handle ))) return -1;
+ old_access = entry->access;
mask = (mask << RESERVED_SHIFT) & RESERVED_ALL;
flags = (flags << RESERVED_SHIFT) & mask;
entry->access = (entry->access & ~mask) | flags;
- return (entry->access & RESERVED_ALL) >> RESERVED_SHIFT;
+ /* 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;
}
/* duplicate a handle */
@@ -420,19 +446,17 @@
/* close a handle */
DECL_HANDLER(close_handle)
{
- close_handle( current->process, req->handle );
-}
-
-/* get information about a handle */
-DECL_HANDLER(get_handle_info)
-{
- req->flags = set_handle_info( current->process, req->handle, 0, 0 );
+ close_handle( current->process, req->handle, &req->fd );
}
/* set a handle information */
DECL_HANDLER(set_handle_info)
{
- set_handle_info( current->process, req->handle, req->mask, req->flags );
+ int fd = req->fd;
+
+ if (HANDLE_IS_GLOBAL(req->handle)) fd = -1; /* no fd cache for global handles */
+ req->old_flags = set_handle_info( current->process, req->handle, req->mask, req->flags, &fd );
+ req->cur_fd = fd;
}
/* duplicate a handle */
@@ -441,6 +465,7 @@
struct process *src, *dst;
req->handle = -1;
+ req->fd = -1;
if ((src = get_process_from_handle( req->src_process, PROCESS_DUP_HANDLE )))
{
if (req->options & DUP_HANDLE_MAKE_GLOBAL)
@@ -456,7 +481,10 @@
}
/* close the handle no matter what happened */
if (req->options & DUP_HANDLE_CLOSE_SOURCE)
- close_handle( src, req->src_handle );
+ {
+ if (src == current->process) close_handle( src, req->src_handle, &req->fd );
+ else close_handle( src, req->src_handle, NULL );
+ }
release_object( src );
}
}
diff --git a/server/handle.h b/server/handle.h
index 7bba30b..d648dd7 100644
--- a/server/handle.h
+++ b/server/handle.h
@@ -23,9 +23,10 @@
/* that the thing pointed to starts with a struct object... */
extern int alloc_handle( struct process *process, void *obj,
unsigned int access, int inherit );
-extern int close_handle( struct process *process, int handle );
+extern int close_handle( struct process *process, int handle, int *fd );
extern struct object *get_handle_obj( struct process *process, int handle,
unsigned int access, const struct object_ops *ops );
+extern int get_handle_fd( struct process *process, int handle, unsigned int access );
extern int duplicate_handle( struct process *src, int src_handle, struct process *dst,
unsigned int access, int inherit, int options );
extern int open_object( const WCHAR *name, size_t len, const struct object_ops *ops,
diff --git a/server/mapping.c b/server/mapping.c
index a68e8fb..38d1d89 100644
--- a/server/mapping.c
+++ b/server/mapping.c
@@ -30,6 +30,7 @@
int shared_size; /* shared mapping total size */
};
+static int mapping_get_fd( struct object *obj );
static void mapping_dump( struct object *obj, int verbose );
static void mapping_destroy( struct object *obj );
@@ -43,7 +44,7 @@
NULL, /* satisfied */
NULL, /* get_poll_events */
NULL, /* poll_event */
- no_get_fd, /* get_fd */
+ mapping_get_fd, /* get_fd */
no_flush, /* flush */
no_get_file_info, /* get_file_info */
mapping_destroy /* destroy */
@@ -86,6 +87,13 @@
#define ROUND_SIZE(addr,size) \
(((int)(size) + ((int)(addr) & page_mask) + page_mask) & ~page_mask)
+/* get the fd to use for mmaping a file */
+inline static int get_mmap_fd( struct file *file )
+{
+ struct object *obj;
+ if (!(obj = (struct object *)file)) return -1;
+ return obj->ops->get_fd( obj );
+}
/* allocate and fill the temp file for a shared PE image mapping */
static int build_shared_mapping( struct mapping *mapping, int fd,
@@ -115,7 +123,7 @@
if (!(mapping->shared_file = create_temp_file( GENERIC_READ|GENERIC_WRITE ))) goto error;
if (!grow_file( mapping->shared_file, 0, total_size )) goto error;
- if ((shared_fd = file_get_mmap_fd( mapping->shared_file )) == -1) goto error;
+ if ((shared_fd = get_mmap_fd( mapping->shared_file )) == -1) goto error;
if (!(buffer = malloc( max_size ))) goto error;
@@ -159,7 +167,7 @@
/* load the headers */
- if ((fd = file_get_mmap_fd( mapping->file )) == -1) return 0;
+ if ((fd = get_mmap_fd( mapping->file )) == -1) return 0;
filepos = lseek( fd, 0, SEEK_SET );
if (read( fd, &dos, sizeof(dos) ) != sizeof(dos)) goto error;
if (dos.e_magic != IMAGE_DOS_SIGNATURE) goto error;
@@ -270,6 +278,13 @@
fputc( '\n', stderr );
}
+static int mapping_get_fd( struct object *obj )
+{
+ struct mapping *mapping = (struct mapping *)obj;
+ assert( obj->ops == &mapping_ops );
+ return get_mmap_fd( mapping->file );
+}
+
static void mapping_destroy( struct object *obj )
{
struct mapping *mapping = (struct mapping *)obj;
@@ -323,11 +338,10 @@
req->base = mapping->base;
req->shared_file = -1;
req->shared_size = mapping->shared_size;
+ req->anonymous = !mapping->file;
if (mapping->shared_file)
req->shared_file = alloc_handle( current->process, mapping->shared_file,
GENERIC_READ|GENERIC_WRITE, 0 );
- if (mapping->file) set_reply_fd( current, file_get_mmap_fd( mapping->file ) );
release_object( mapping );
}
}
-
diff --git a/server/object.h b/server/object.h
index 7a7d1a3..deec306 100644
--- a/server/object.h
+++ b/server/object.h
@@ -148,7 +148,6 @@
extern struct file *get_file_obj( struct process *process, int handle,
unsigned int access );
-extern int file_get_mmap_fd( struct file *file );
extern int grow_file( struct file *file, int size_high, int size_low );
extern int create_anonymous_file(void);
extern struct file *create_temp_file( int access );
diff --git a/server/pipe.c b/server/pipe.c
index 5c830c0..7838c12 100644
--- a/server/pipe.c
+++ b/server/pipe.c
@@ -165,7 +165,7 @@
STANDARD_RIGHTS_REQUIRED|SYNCHRONIZE|GENERIC_WRITE,
req->inherit );
if (hwrite == -1)
- close_handle( current->process, hread );
+ close_handle( current->process, hread, NULL );
}
release_object( obj[0] );
release_object( obj[1] );
diff --git a/server/request.c b/server/request.c
index c3928e5..fff02dd4 100644
--- a/server/request.c
+++ b/server/request.c
@@ -71,6 +71,32 @@
};
+struct request_socket
+{
+ struct object obj; /* object header */
+ struct thread *thread; /* owning thread */
+};
+
+static void request_socket_dump( struct object *obj, int verbose );
+static void request_socket_poll_event( struct object *obj, int event );
+
+static const struct object_ops request_socket_ops =
+{
+ sizeof(struct request_socket), /* size */
+ request_socket_dump, /* dump */
+ no_add_queue, /* add_queue */
+ NULL, /* remove_queue */
+ NULL, /* signaled */
+ NULL, /* satisfied */
+ NULL, /* get_poll_events */
+ request_socket_poll_event, /* poll_event */
+ no_get_fd, /* get_fd */
+ no_flush, /* flush */
+ no_get_file_info, /* get_file_info */
+ no_destroy /* destroy */
+};
+
+
struct thread *current = NULL; /* thread handling the current request */
unsigned int global_error = 0; /* global error code for when no thread is current */
@@ -149,13 +175,6 @@
fatal_protocol_error( current, "bad request %d\n", req );
}
-/* set the fd to pass to the thread */
-void set_reply_fd( struct thread *thread, int pass_fd )
-{
- assert( thread->pass_fd == -1 );
- thread->pass_fd = pass_fd;
-}
-
/* send a reply to a thread */
void send_reply( struct thread *thread )
{
@@ -213,29 +232,9 @@
header->error = thread->error;
- if (thread->pass_fd == -1)
- {
- /* write a single byte; the value is ignored anyway */
- ret = write( thread->obj.fd, header, 1 );
- }
- else /* we have an fd to send */
- {
-#ifdef HAVE_MSGHDR_ACCRIGHTS
- msghdr.msg_accrightslen = sizeof(int);
- msghdr.msg_accrights = (void *)&thread->pass_fd;
-#else /* HAVE_MSGHDR_ACCRIGHTS */
- msghdr.msg_control = &cmsg;
- msghdr.msg_controllen = sizeof(cmsg);
- cmsg.fd = thread->pass_fd;
-#endif /* HAVE_MSGHDR_ACCRIGHTS */
+ assert (thread->pass_fd == -1);
- myiovec.iov_base = (void *)header;
- myiovec.iov_len = 1;
-
- ret = sendmsg( thread->obj.fd, &msghdr, 0 );
- close( thread->pass_fd );
- thread->pass_fd = -1;
- }
+ ret = write( thread->reply_fd, header, 1 );
if (ret > 0)
{
set_select_events( &thread->obj, POLLIN );
@@ -255,6 +254,40 @@
return -1;
}
+/* send an fd to a client */
+int send_client_fd( struct thread *thread, int fd, int handle )
+{
+ int ret;
+
+#ifdef HAVE_MSGHDR_ACCRIGHTS
+ msghdr.msg_accrightslen = sizeof(fd);
+ msghdr.msg_accrights = (void *)&fd;
+#else /* HAVE_MSGHDR_ACCRIGHTS */
+ msghdr.msg_control = &cmsg;
+ msghdr.msg_controllen = sizeof(cmsg);
+ cmsg.fd = fd;
+#endif /* HAVE_MSGHDR_ACCRIGHTS */
+
+ myiovec.iov_base = (void *)&handle;
+ myiovec.iov_len = sizeof(handle);
+
+ ret = sendmsg( thread->obj.fd, &msghdr, 0 );
+ close( fd );
+
+ if (ret > 0) return 0;
+ if (errno == EPIPE)
+ {
+ kill_thread( thread, 0 ); /* normal death */
+ }
+ else
+ {
+ perror("sendmsg");
+ thread->exit_code = 1;
+ kill_thread( thread, 1 );
+ }
+ return -1;
+}
+
static void master_socket_dump( struct object *obj, int verbose )
{
struct master_socket *sock = (struct master_socket *)obj;
@@ -297,6 +330,61 @@
socket_cleanup();
}
+static void request_socket_dump( struct object *obj, int verbose )
+{
+ struct request_socket *sock = (struct request_socket *)obj;
+ assert( obj->ops == &request_socket_ops );
+ fprintf( stderr, "Request socket fd=%d thread=%p\n", sock->obj.fd, sock->thread );
+}
+
+/* handle a request socket event */
+static void request_socket_poll_event( struct object *obj, int event )
+{
+ struct request_socket *sock = (struct request_socket *)obj;
+ assert( obj->ops == &request_socket_ops );
+
+ if (event & (POLLERR | POLLHUP)) kill_thread( sock->thread, 0 );
+ else if (event & POLLIN)
+ {
+ struct thread *thread = sock->thread;
+ int ret;
+ char dummy[1];
+
+ ret = read( sock->obj.fd, &dummy, 1 );
+ if (ret > 0)
+ {
+ call_req_handler( thread );
+ return;
+ }
+ if (!ret) /* closed pipe */
+ {
+ kill_thread( thread, 0 );
+ return;
+ }
+ perror("read");
+ thread->exit_code = 1;
+ kill_thread( thread, 1 );
+ }
+}
+
+/* create a request socket and send the fd to the client thread */
+struct object *create_request_socket( struct thread *thread )
+{
+ struct request_socket *sock;
+ int fd[2];
+
+ if (pipe( fd )) return NULL;
+ if (!(sock = alloc_object( &request_socket_ops, fd[0] )))
+ {
+ close( fd[1] );
+ return NULL;
+ }
+ sock->thread = thread;
+ send_client_fd( thread, fd[1], -1 );
+ set_select_events( &sock->obj, POLLIN );
+ return &sock->obj;
+}
+
/* return the configuration directory ($WINEPREFIX or $HOME/.wine) */
const char *get_config_dir(void)
{
diff --git a/server/request.h b/server/request.h
index ef856f3..c58d5fb 100644
--- a/server/request.h
+++ b/server/request.h
@@ -33,11 +33,12 @@
extern const char *get_config_dir(void);
extern void read_request( struct thread *thread );
extern int write_request( struct thread *thread );
-extern void set_reply_fd( struct thread *thread, int pass_fd );
+extern int send_client_fd( struct thread *thread, int fd, int handle );
extern void send_reply( struct thread *thread );
extern void open_master_socket(void);
extern void close_master_socket(void);
extern void lock_master_socket( int locked );
+extern struct object *create_request_socket( struct thread *thread );
extern void trace_request( enum request req );
extern void trace_reply( struct thread *thread );
@@ -90,7 +91,6 @@
DECL_HANDLER(queue_apc);
DECL_HANDLER(get_apc);
DECL_HANDLER(close_handle);
-DECL_HANDLER(get_handle_info);
DECL_HANDLER(set_handle_info);
DECL_HANDLER(dup_handle);
DECL_HANDLER(open_process);
@@ -205,7 +205,6 @@
(req_handler)req_queue_apc,
(req_handler)req_get_apc,
(req_handler)req_close_handle,
- (req_handler)req_get_handle_info,
(req_handler)req_set_handle_info,
(req_handler)req_dup_handle,
(req_handler)req_open_process,
diff --git a/server/thread.c b/server/thread.c
index 7cfacdc..12e9377 100644
--- a/server/thread.c
+++ b/server/thread.c
@@ -89,26 +89,33 @@
static int alloc_client_buffer( struct thread *thread )
{
struct get_thread_buffer_request *req;
- int fd;
+ int fd, fd_pipe[2];
- if ((fd = create_anonymous_file()) == -1) return -1;
+ if (pipe( fd_pipe ) == -1) return -1;
+ if ((fd = create_anonymous_file()) == -1) goto error;
if (ftruncate( fd, MAX_REQUEST_LENGTH ) == -1) goto error;
if ((thread->buffer = mmap( 0, MAX_REQUEST_LENGTH, PROT_READ | PROT_WRITE,
MAP_SHARED, fd, 0 )) == (void*)-1) goto error;
thread->buffer_info = (struct server_buffer_info *)((char *)thread->buffer + MAX_REQUEST_LENGTH) - 1;
+ if (!(thread->request_fd = create_request_socket( thread ))) goto error;
+ thread->reply_fd = fd_pipe[1];
/* build the first request into the buffer and send it */
req = thread->buffer;
req->pid = get_process_id( thread->process );
req->tid = get_thread_id( thread );
req->boot = (thread == booting_thread);
req->version = SERVER_PROTOCOL_VERSION;
- set_reply_fd( thread, fd );
+
+ send_client_fd( thread, fd_pipe[0], -1 );
+ send_client_fd( thread, fd, -1 );
send_reply( thread );
return 1;
error:
file_set_error();
if (fd != -1) close( fd );
+ close( fd_pipe[0] );
+ close( fd_pipe[1] );
return 0;
}
@@ -135,6 +142,8 @@
thread->apc_tail = NULL;
thread->error = 0;
thread->pass_fd = -1;
+ thread->request_fd = NULL;
+ thread->reply_fd = -1;
thread->state = RUNNING;
thread->attached = 0;
thread->exit_code = 0;
@@ -197,7 +206,9 @@
if (thread->info) release_object( thread->info );
if (thread->queue) release_object( thread->queue );
if (thread->buffer != (void *)-1) munmap( thread->buffer, MAX_REQUEST_LENGTH );
+ if (thread->reply_fd != -1) close( thread->reply_fd );
if (thread->pass_fd != -1) close( thread->pass_fd );
+ if (thread->request_fd) release_object( thread->request_fd );
}
/* dump a thread on stdout for debugging purposes */
@@ -618,7 +629,11 @@
wake_up( &thread->obj, 0 );
detach_thread( thread, violent_death ? SIGTERM : 0 );
remove_select_user( &thread->obj );
+ release_object( thread->request_fd );
+ close( thread->reply_fd );
munmap( thread->buffer, MAX_REQUEST_LENGTH );
+ thread->request_fd = NULL;
+ thread->reply_fd = -1;
thread->buffer = (void *)-1;
release_object( thread );
}
@@ -675,7 +690,7 @@
if ((req->handle = alloc_handle( current->process, thread,
THREAD_ALL_ACCESS, req->inherit )) != -1)
{
- set_reply_fd( current, sock[1] );
+ send_client_fd( current, sock[1], req->handle );
/* thread object will be released when the thread gets killed */
add_process_thread( current->process, thread );
return;
diff --git a/server/thread.h b/server/thread.h
index c0db481..8e36569 100644
--- a/server/thread.h
+++ b/server/thread.h
@@ -48,7 +48,9 @@
struct thread_apc *apc_head; /* queue of async procedure calls */
struct thread_apc *apc_tail; /* queue of async procedure calls */
unsigned int error; /* current error code */
- int pass_fd; /* fd to pass to the client */
+ struct object *request_fd; /* fd for receiving client requests */
+ int pass_fd; /* fd to pass to the client */
+ int reply_fd; /* fd to use to wake a client waiting on a reply */
enum run_state state; /* running state */
int attached; /* is thread attached with ptrace? */
int exit_code; /* thread exit code */
diff --git a/server/trace.c b/server/trace.c
index bad07e8..534f4d43 100644
--- a/server/trace.c
+++ b/server/trace.c
@@ -471,21 +471,23 @@
fprintf( stderr, " handle=%d", req->handle );
}
-static void dump_get_handle_info_request( const struct get_handle_info_request *req )
+static void dump_close_handle_reply( const struct close_handle_request *req )
{
- fprintf( stderr, " handle=%d", req->handle );
-}
-
-static void dump_get_handle_info_reply( const struct get_handle_info_request *req )
-{
- fprintf( stderr, " flags=%d", req->flags );
+ fprintf( stderr, " fd=%d", req->fd );
}
static void dump_set_handle_info_request( const struct set_handle_info_request *req )
{
fprintf( stderr, " handle=%d,", req->handle );
fprintf( stderr, " flags=%d,", req->flags );
- fprintf( stderr, " mask=%d", req->mask );
+ fprintf( stderr, " mask=%d,", req->mask );
+ fprintf( stderr, " fd=%d", req->fd );
+}
+
+static void dump_set_handle_info_reply( const struct set_handle_info_request *req )
+{
+ fprintf( stderr, " old_flags=%d,", req->old_flags );
+ fprintf( stderr, " cur_fd=%d", req->cur_fd );
}
static void dump_dup_handle_request( const struct dup_handle_request *req )
@@ -500,7 +502,8 @@
static void dump_dup_handle_reply( const struct dup_handle_request *req )
{
- fprintf( stderr, " handle=%d", req->handle );
+ fprintf( stderr, " handle=%d,", req->handle );
+ fprintf( stderr, " fd=%d", req->fd );
}
static void dump_open_process_request( const struct open_process_request *req )
@@ -957,7 +960,8 @@
fprintf( stderr, " header_size=%d,", req->header_size );
fprintf( stderr, " base=%p,", req->base );
fprintf( stderr, " shared_file=%d,", req->shared_file );
- fprintf( stderr, " shared_size=%d", req->shared_size );
+ fprintf( stderr, " shared_size=%d,", req->shared_size );
+ fprintf( stderr, " anonymous=%d", req->anonymous );
}
static void dump_create_device_request( const struct create_device_request *req )
@@ -1471,7 +1475,6 @@
(dump_func)dump_queue_apc_request,
(dump_func)dump_get_apc_request,
(dump_func)dump_close_handle_request,
- (dump_func)dump_get_handle_info_request,
(dump_func)dump_set_handle_info_request,
(dump_func)dump_dup_handle_request,
(dump_func)dump_open_process_request,
@@ -1582,9 +1585,8 @@
(dump_func)0,
(dump_func)0,
(dump_func)dump_get_apc_reply,
- (dump_func)0,
- (dump_func)dump_get_handle_info_reply,
- (dump_func)0,
+ (dump_func)dump_close_handle_reply,
+ (dump_func)dump_set_handle_info_reply,
(dump_func)dump_dup_handle_reply,
(dump_func)dump_open_process_reply,
(dump_func)dump_select_reply,
@@ -1695,7 +1697,6 @@
"queue_apc",
"get_apc",
"close_handle",
- "get_handle_info",
"set_handle_info",
"dup_handle",
"open_process",