Added server-side file mapping object support.

diff --git a/include/server.h b/include/server.h
index 4c0e9ee..2e1ab61 100644
--- a/include/server.h
+++ b/include/server.h
@@ -162,9 +162,8 @@
     int          signaled;     /* signaled handle */
 };
 #define SELECT_ALL       1
-#define SELECT_MSG       2
-#define SELECT_ALERTABLE 4
-#define SELECT_TIMEOUT   8
+#define SELECT_ALERTABLE 2
+#define SELECT_TIMEOUT   4
 
 
 /* Create an event */
@@ -243,7 +242,7 @@
     int          inherit;       /* inherit flag */
     char         name[0];       /* object name */
 };
-enum open_named_obj { OPEN_EVENT, OPEN_MUTEX, OPEN_SEMAPHORE };
+enum open_named_obj { OPEN_EVENT, OPEN_MUTEX, OPEN_SEMAPHORE, OPEN_MAPPING };
 
 struct open_named_obj_reply
 {
@@ -263,14 +262,6 @@
 };
 
 
-/* Get a Unix handle to a file */
-struct get_unix_handle_request
-{
-    int          handle;        /* handle to the file */
-    unsigned int access;        /* desired access */
-};
-
-
 /* Get a Unix fd to read from a file */
 struct get_read_fd_request
 {
@@ -364,7 +355,7 @@
 };
 
 
-/* Create a console */
+/* Create a change notification */
 struct create_change_notification_request
 {
     int          subtree;       /* watch all the subtree */
@@ -376,6 +367,42 @@
 };
 
 
+/* Create a file mapping */
+struct create_mapping_request
+{
+    int          size_high;     /* mapping size */
+    int          size_low;      /* mapping size */
+    int          protect;       /* protection flags (see below) */
+    int          handle;        /* file handle */
+    char         name[0];       /* object name */
+};
+struct create_mapping_reply
+{
+    int          handle;        /* handle to the mapping */
+};
+/* protection flags */
+#define VPROT_READ       0x01
+#define VPROT_WRITE      0x02
+#define VPROT_EXEC       0x04
+#define VPROT_WRITECOPY  0x08
+#define VPROT_GUARD      0x10
+#define VPROT_NOCACHE    0x20
+#define VPROT_COMMITTED  0x40
+
+
+/* Get information about a file mapping */
+struct get_mapping_info_request
+{
+    int          handle;        /* handle to the mapping */
+};
+struct get_mapping_info_reply
+{
+    int          size_high;     /* mapping size */
+    int          size_low;      /* mapping size */
+    int          protect;       /* protection flags */
+};
+
+
 /* client-side functions */
 
 #ifndef __WINE_SERVER__
@@ -383,14 +410,11 @@
 #include "server/request.h"
 
 /* client communication functions */
-#define CHECK_LEN(len,wanted) \
-  if ((len) == (wanted)) ; \
-  else CLIENT_ProtocolError( __FUNCTION__ ": len %d != %d\n", (len), (wanted) );
-extern void CLIENT_ProtocolError( const char *err, ... );
 extern void CLIENT_SendRequest( enum request req, int pass_fd,
                                 int n, ... /* arg_1, len_1, etc. */ );
 extern unsigned int CLIENT_WaitReply( int *len, int *passed_fd,
                                       int n, ... /* arg_1, len_1, etc. */ );
+extern unsigned int CLIENT_WaitSimpleReply( void *reply, int len, int *passed_fd );
 
 struct _THDB;
 extern int CLIENT_NewThread( struct _THDB *thdb, int *thandle, int *phandle );
@@ -399,8 +423,6 @@
 extern int CLIENT_CloseHandle( int handle );
 extern int CLIENT_DuplicateHandle( int src_process, int src_handle, int dst_process,
                                    int dst_handle, DWORD access, BOOL32 inherit, DWORD options );
-extern int CLIENT_GetThreadInfo( int handle, struct get_thread_info_reply *reply );
-extern int CLIENT_GetProcessInfo( int handle, struct get_process_info_reply *reply );
 extern int CLIENT_OpenProcess( void *pid, DWORD access, BOOL32 inherit );
 extern int CLIENT_Select( int count, int *handles, int flags, int timeout );
 #endif  /* __WINE_SERVER__ */
diff --git a/include/server/object.h b/include/server/object.h
index fc34f16..67320e2 100644
--- a/include/server/object.h
+++ b/include/server/object.h
@@ -20,6 +20,7 @@
 struct object;
 struct object_name;
 struct thread;
+struct file;
 struct wait_queue_entry;
 
 struct object_ops
@@ -27,7 +28,7 @@
     /* dump the object (for debugging) */
     void (*dump)(struct object *,int);
     /* add a thread to the object wait queue */
-    void (*add_queue)(struct object *,struct wait_queue_entry *);
+    int  (*add_queue)(struct object *,struct wait_queue_entry *);
     /* remove a thread from the object wait queue */
     void (*remove_queue)(struct object *,struct wait_queue_entry *);
     /* is object signaled? */
@@ -63,6 +64,7 @@
 extern struct object *grab_object( void *obj );
 extern void release_object( void *obj );
 extern struct object *find_object( const char *name );
+extern int no_add_queue( struct object *obj, struct wait_queue_entry *entry );
 extern int no_satisfied( struct object *obj, struct thread *thread );
 extern int no_read_fd( struct object *obj );
 extern int no_write_fd( struct object *obj );
@@ -171,7 +173,9 @@
 /* file functions */
 
 extern struct object *create_file( int fd );
-extern int file_get_unix_handle( int handle, unsigned int access );
+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 set_file_pointer( int handle, int *low, int *high, int whence );
 extern int truncate_file( int handle );
 extern int get_file_info( int handle, struct get_file_info_reply *reply );
@@ -194,6 +198,13 @@
 extern struct object *create_change_notification( int subtree, int filter );
 
 
+/* file mapping functions */
+extern struct object *create_mapping( int size_high, int size_low, int protect,
+                                      int handle, const char *name );
+extern int open_mapping( unsigned int access, int inherit, const char *name );
+extern int get_mapping_info( int handle, struct get_mapping_info_reply *reply );
+
+
 extern int debug_level;
 
 #endif  /* __WINE_SERVER_OBJECT_H */
diff --git a/include/server/request.h b/include/server/request.h
index 993ae6e..40cee6f 100644
--- a/include/server/request.h
+++ b/include/server/request.h
@@ -24,7 +24,6 @@
     REQ_RELEASE_SEMAPHORE,
     REQ_OPEN_NAMED_OBJ,
     REQ_CREATE_FILE,
-    REQ_GET_UNIX_HANDLE,
     REQ_GET_READ_FD,
     REQ_GET_WRITE_FD,
     REQ_SET_FILE_POINTER,
@@ -35,6 +34,8 @@
     REQ_CREATE_CONSOLE,
     REQ_SET_CONSOLE_FD,
     REQ_CREATE_CHANGE_NOTIFICATION,
+    REQ_CREATE_MAPPING,
+    REQ_GET_MAPPING_INFO,
     REQ_NB_REQUESTS
 };
 
@@ -62,7 +63,6 @@
 DECL_HANDLER(release_semaphore);
 DECL_HANDLER(open_named_obj);
 DECL_HANDLER(create_file);
-DECL_HANDLER(get_unix_handle);
 DECL_HANDLER(get_read_fd);
 DECL_HANDLER(get_write_fd);
 DECL_HANDLER(set_file_pointer);
@@ -73,6 +73,8 @@
 DECL_HANDLER(create_console);
 DECL_HANDLER(set_console_fd);
 DECL_HANDLER(create_change_notification);
+DECL_HANDLER(create_mapping);
+DECL_HANDLER(get_mapping_info);
 
 static const struct handler {
     void       (*handler)();
@@ -97,7 +99,6 @@
     { (void(*)())req_release_semaphore, sizeof(struct release_semaphore_request) },
     { (void(*)())req_open_named_obj, sizeof(struct open_named_obj_request) },
     { (void(*)())req_create_file, sizeof(struct create_file_request) },
-    { (void(*)())req_get_unix_handle, sizeof(struct get_unix_handle_request) },
     { (void(*)())req_get_read_fd, sizeof(struct get_read_fd_request) },
     { (void(*)())req_get_write_fd, sizeof(struct get_write_fd_request) },
     { (void(*)())req_set_file_pointer, sizeof(struct set_file_pointer_request) },
@@ -108,6 +109,8 @@
     { (void(*)())req_create_console, sizeof(struct create_console_request) },
     { (void(*)())req_set_console_fd, sizeof(struct set_console_fd_request) },
     { (void(*)())req_create_change_notification, sizeof(struct create_change_notification_request) },
+    { (void(*)())req_create_mapping, sizeof(struct create_mapping_request) },
+    { (void(*)())req_get_mapping_info, sizeof(struct get_mapping_info_request) },
 };
 #endif  /* WANT_REQUEST_HANDLERS */
 
diff --git a/include/server/thread.h b/include/server/thread.h
index 9931301..1977152 100644
--- a/include/server/thread.h
+++ b/include/server/thread.h
@@ -52,7 +52,7 @@
                              struct get_thread_info_reply *reply );
 extern int send_reply( struct thread *thread, int pass_fd,
                        int n, ... /* arg_1, len_1, ..., arg_n, len_n */ );
-extern void add_queue( struct object *obj, struct wait_queue_entry *entry );
+extern int add_queue( struct object *obj, struct wait_queue_entry *entry );
 extern void remove_queue( struct object *obj, struct wait_queue_entry *entry );
 extern void kill_thread( struct thread *thread, int exit_code );
 extern void thread_killed( struct thread *thread, int exit_code );
diff --git a/server/Makefile.in b/server/Makefile.in
index 6ea40846..4a593a9 100644
--- a/server/Makefile.in
+++ b/server/Makefile.in
@@ -10,6 +10,7 @@
 	console.c \
 	event.c \
 	file.c \
+	mapping.c \
 	mutex.c \
 	object.c \
 	pipe.c \
diff --git a/server/console.c b/server/console.c
index 7ef0f92..f9f4ed7 100644
--- a/server/console.c
+++ b/server/console.c
@@ -30,7 +30,7 @@
 };
 
 static void console_dump( struct object *obj, int verbose );
-static void console_add_queue( struct object *obj, struct wait_queue_entry *entry );
+static int console_add_queue( struct object *obj, struct wait_queue_entry *entry );
 static void console_remove_queue( struct object *obj, struct wait_queue_entry *entry );
 static int console_signaled( struct object *obj, struct thread *thread );
 static int console_get_read_fd( struct object *obj );
@@ -124,15 +124,22 @@
             console->is_read ? "input" : "output", console->fd );
 }
 
-static void console_add_queue( struct object *obj, struct wait_queue_entry *entry )
+static int console_add_queue( struct object *obj, struct wait_queue_entry *entry )
 {
     struct console *console = (struct console *)obj;
     assert( obj->ops == &console_ops );
     if (!obj->head)  /* first on the queue */
-        add_select_user( console->fd,
-                         console->is_read ? READ_EVENT : WRITE_EVENT,
-                         &select_ops, console );
+    {
+        if (!add_select_user( console->fd,
+                              console->is_read ? READ_EVENT : WRITE_EVENT,
+                              &select_ops, console ))
+        {
+            SET_ERROR( ERROR_OUTOFMEMORY );
+            return 0;
+        }
+    }
     add_queue( obj, entry );
+    return 1;
 }
 
 static void console_remove_queue( struct object *obj, struct wait_queue_entry *entry )
diff --git a/server/file.c b/server/file.c
index 13988dd..3624fcb 100644
--- a/server/file.c
+++ b/server/file.c
@@ -27,7 +27,7 @@
 };
 
 static void file_dump( struct object *obj, int verbose );
-static void file_add_queue( struct object *obj, struct wait_queue_entry *entry );
+static int file_add_queue( struct object *obj, struct wait_queue_entry *entry );
 static void file_remove_queue( struct object *obj, struct wait_queue_entry *entry );
 static int file_signaled( struct object *obj, struct thread *thread );
 static int file_get_read_fd( struct object *obj );
@@ -90,13 +90,20 @@
     printf( "File fd=%d\n", file->fd );
 }
 
-static void file_add_queue( struct object *obj, struct wait_queue_entry *entry )
+static int file_add_queue( struct object *obj, struct wait_queue_entry *entry )
 {
     struct file *file = (struct file *)obj;
     assert( obj->ops == &file_ops );
     if (!obj->head)  /* first on the queue */
-        add_select_user( file->fd, READ_EVENT | WRITE_EVENT, &select_ops, file );
+    {
+        if (!add_select_user( file->fd, READ_EVENT | WRITE_EVENT, &select_ops, file ))
+        {
+            SET_ERROR( ERROR_OUTOFMEMORY );
+            return 0;
+        }
+    }
     add_queue( obj, entry );
+    return 1;
 }
 
 static void file_remove_queue( struct object *obj, struct wait_queue_entry *entry )
@@ -195,17 +202,16 @@
     }
 }
 
-int file_get_unix_handle( int handle, unsigned int access )
+struct file *get_file_obj( struct process *process, int handle,
+                           unsigned int access )
 {
-    struct file *file;
-    int unix_handle;
+    return (struct file *)get_handle_obj( current->process, handle,
+                                          access, &file_ops );
+}
 
-    if (!(file = (struct file *)get_handle_obj( current->process, handle,
-                                                access, &file_ops )))
-        return -1;
-    unix_handle = dup( file->fd );
-    release_object( file );
-    return unix_handle;
+int file_get_mmap_fd( struct file *file )
+{
+    return dup( file->fd );
 }
 
 int set_file_pointer( int handle, int *low, int *high, int whence )
@@ -220,8 +226,7 @@
         return 0;
     }
 
-    if (!(file = (struct file *)get_handle_obj( current->process, handle,
-                                                0, &file_ops )))
+    if (!(file = get_file_obj( current->process, handle, 0 )))
         return 0;
     if ((result = lseek( file->fd, *low, whence )) == -1)
     {
@@ -243,8 +248,7 @@
     struct file *file;
     int result;
 
-    if (!(file = (struct file *)get_handle_obj( current->process, handle,
-                                                GENERIC_WRITE, &file_ops )))
+    if (!(file = get_file_obj( current->process, handle, GENERIC_WRITE )))
         return 0;
     if (((result = lseek( file->fd, 0, SEEK_CUR )) == -1) ||
         (ftruncate( file->fd, result ) == -1))
@@ -263,8 +267,7 @@
     struct file *file;
     struct stat st;
 
-    if (!(file = (struct file *)get_handle_obj( current->process, handle,
-                                                0, &file_ops )))
+    if (!(file = get_file_obj( current->process, handle, 0 )))
         return 0;
     if (fstat( file->fd, &st ) == -1)
     {
diff --git a/server/main.c b/server/main.c
index c6afb77..667283a 100644
--- a/server/main.c
+++ b/server/main.c
@@ -25,10 +25,10 @@
 
     debug_level = 1;
 
-    if (debug_level) printf( "Server: starting (pid=%d)\n", getpid() );
+    if (debug_level) fprintf( stderr, "Server: starting (pid=%d)\n", getpid() );
     server_init( fd );
     select_loop();
-    if (debug_level) printf( "Server: exiting (pid=%d)\n", getpid() );
+    if (debug_level) fprintf( stderr, "Server: exiting (pid=%d)\n", getpid() );
     exit(0);
 
  error:    
diff --git a/server/mapping.c b/server/mapping.c
new file mode 100644
index 0000000..2f3dac7
--- /dev/null
+++ b/server/mapping.c
@@ -0,0 +1,106 @@
+/*
+ * Server-side file mapping management
+ *
+ * Copyright (C) 1999 Alexandre Julliard
+ */
+
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "winerror.h"
+#include "winnt.h"
+#include "server/thread.h"
+
+struct mapping
+{
+    struct object  obj;             /* object header */
+    int            size_high;       /* mapping size */
+    int            size_low;        /* mapping size */
+    int            protect;         /* protection flags */
+    struct file   *file;            /* file mapped */
+};
+
+static void mapping_dump( struct object *obj, int verbose );
+static void mapping_destroy( struct object *obj );
+
+static const struct object_ops mapping_ops =
+{
+    mapping_dump,
+    no_add_queue,
+    NULL,  /* should never get called */
+    NULL,  /* should never get called */
+    NULL,  /* should never get called */
+    no_read_fd,
+    no_write_fd,
+    no_flush,
+    mapping_destroy
+};
+
+struct object *create_mapping( int size_high, int size_low, int protect,
+                               int handle, const char *name )
+{
+    struct mapping *mapping;
+
+    if (!(mapping = (struct mapping *)create_named_object( name, &mapping_ops,
+                                                           sizeof(*mapping) )))
+        return NULL;
+    if (GET_ERROR() == ERROR_ALREADY_EXISTS)
+        return &mapping->obj;  /* Nothing else to do */
+
+    mapping->size_high = size_high;
+    mapping->size_low  = size_low;
+    mapping->protect   = protect;
+    if (handle != -1)
+    {
+        int access = 0;
+        if (protect & VPROT_READ) access |= GENERIC_READ;
+        if (protect & VPROT_WRITE) access |= GENERIC_WRITE;
+        if (!(mapping->file = get_file_obj( current->process, handle, access )))
+        {
+            release_object( mapping );
+            return NULL;
+        }
+    }
+    else mapping->file = NULL;
+    return &mapping->obj;
+}
+
+int open_mapping( unsigned int access, int inherit, const char *name )
+{
+    return open_object( name, &mapping_ops, access, inherit );
+}
+
+int get_mapping_info( int handle, struct get_mapping_info_reply *reply )
+{
+    struct mapping *mapping;
+    int fd;
+
+    if (!(mapping = (struct mapping *)get_handle_obj( current->process, handle,
+                                                      0, &mapping_ops )))
+        return -1;
+    reply->size_high = mapping->size_high;
+    reply->size_low  = mapping->size_low;
+    reply->protect   = mapping->protect;
+    if (mapping->file) fd = file_get_mmap_fd( mapping->file );
+    else fd = -1;
+    release_object( mapping );
+    return fd;
+}
+
+static void mapping_dump( struct object *obj, int verbose )
+{
+    struct mapping *mapping = (struct mapping *)obj;
+    assert( obj->ops == &mapping_ops );
+    fprintf( stderr, "Mapping size=%08x%08x prot=%08x file=%p\n",
+             mapping->size_high, mapping->size_low, mapping->protect, mapping->file );
+}
+
+static void mapping_destroy( struct object *obj )
+{
+    struct mapping *mapping = (struct mapping *)obj;
+    assert( obj->ops == &mapping_ops );
+    if (mapping->file) release_object( mapping->file );
+    free( mapping );
+}
diff --git a/server/object.c b/server/object.c
index 415bb3d..b702d8d 100644
--- a/server/object.c
+++ b/server/object.c
@@ -147,6 +147,12 @@
 
 /* functions for unimplemented object operations */
 
+int no_add_queue( struct object *obj, struct wait_queue_entry *entry )
+{
+    SET_ERROR( ERROR_INVALID_HANDLE );
+    return 0;
+}
+
 int no_satisfied( struct object *obj, struct thread *thread )
 {
     return 0;  /* not abandoned */
diff --git a/server/pipe.c b/server/pipe.c
index 7bce133..4113a68 100644
--- a/server/pipe.c
+++ b/server/pipe.c
@@ -30,7 +30,7 @@
 };
 
 static void pipe_dump( struct object *obj, int verbose );
-static void pipe_add_queue( struct object *obj, struct wait_queue_entry *entry );
+static int pipe_add_queue( struct object *obj, struct wait_queue_entry *entry );
 static void pipe_remove_queue( struct object *obj, struct wait_queue_entry *entry );
 static int pipe_signaled( struct object *obj, struct thread *thread );
 static int pipe_get_read_fd( struct object *obj );
@@ -101,15 +101,22 @@
             (pipe->side == READ_SIDE) ? "read" : "write", pipe->fd );
 }
 
-static void pipe_add_queue( struct object *obj, struct wait_queue_entry *entry )
+static int pipe_add_queue( struct object *obj, struct wait_queue_entry *entry )
 {
     struct pipe *pipe = (struct pipe *)obj;
     assert( obj->ops == &pipe_ops );
     if (!obj->head)  /* first on the queue */
-        add_select_user( pipe->fd,
-                         (pipe->side == READ_SIDE) ? READ_EVENT : WRITE_EVENT,
-                         &select_ops, pipe );
+    {
+        if (!add_select_user( pipe->fd,
+                              (pipe->side == READ_SIDE) ? READ_EVENT : WRITE_EVENT,
+                              &select_ops, pipe ))
+        {
+            SET_ERROR( ERROR_OUTOFMEMORY );
+            return 0;
+        }
+    }
     add_queue( obj, entry );
+    return 1;
 }
 
 static void pipe_remove_queue( struct object *obj, struct wait_queue_entry *entry )
diff --git a/server/request.c b/server/request.c
index 4913cf1..2240c1c 100644
--- a/server/request.c
+++ b/server/request.c
@@ -382,6 +382,9 @@
     case OPEN_SEMAPHORE:
         reply.handle = open_semaphore( req->access, req->inherit, name );
         break;
+    case OPEN_MAPPING:
+        reply.handle = open_mapping( req->access, req->inherit, name );
+        break;
     default:
         fatal_protocol_error( "open_named_obj: invalid type %d\n", req->type );
     }
@@ -409,13 +412,6 @@
     send_reply( current, -1, 1, &reply, sizeof(reply) );
 }
 
-/* get a Unix handle to a file */
-DECL_HANDLER(get_unix_handle)
-{
-    int handle = file_get_unix_handle( req->handle, req->access );
-    send_reply( current, handle, 0 );
-}
-
 /* get a Unix fd to read from a file */
 DECL_HANDLER(get_read_fd)
 {
@@ -552,3 +548,30 @@
     send_reply( current, -1, 1, &reply, sizeof(reply) );
 }
 
+/* create a file mapping */
+DECL_HANDLER(create_mapping)
+{
+    struct object *obj;
+    struct create_mapping_reply reply = { -1 };
+    char *name = (char *)data;
+    if (!len) name = NULL;
+    else CHECK_STRING( "create_mapping", name, len );
+
+    if ((obj = create_mapping( req->size_high, req->size_low,
+                               req->protect, req->handle, name )))
+    {
+        int access = FILE_MAP_ALL_ACCESS;
+        if (!(req->protect & VPROT_WRITE)) access &= ~FILE_MAP_WRITE;
+        reply.handle = alloc_handle( current->process, obj, access, 0 );
+        release_object( obj );
+    }
+    send_reply( current, -1, 1, &reply, sizeof(reply) );
+}
+
+/* get a mapping information */
+DECL_HANDLER(get_mapping_info)
+{
+    struct get_mapping_info_reply reply;
+    int map_fd = get_mapping_info( req->handle, &reply );
+    send_reply( current, map_fd, 1, &reply, sizeof(reply) );
+}
diff --git a/server/thread.c b/server/thread.c
index f7bf350..76394b3 100644
--- a/server/thread.c
+++ b/server/thread.c
@@ -199,7 +199,7 @@
 }
 
 /* add a thread to an object wait queue; return 1 if OK, 0 on error */
-void add_queue( struct object *obj, struct wait_queue_entry *entry )
+int add_queue( struct object *obj, struct wait_queue_entry *entry )
 {
     grab_object( obj );
     entry->obj    = obj;
@@ -208,6 +208,7 @@
     if (obj->tail) obj->tail->next = entry;
     else obj->head = entry;
     obj->tail = entry;
+    return 1;
 }
 
 /* remove a thread from an object wait queue */
@@ -278,7 +279,12 @@
             return 0;
         }
         entry->thread = thread;
-        obj->ops->add_queue( obj, entry );
+        if (!obj->ops->add_queue( obj, entry ))
+        {
+            wait->count = i - 1;
+            end_wait( thread );
+            return 0;
+        }
         release_object( obj );
     }
     return 1;
diff --git a/server/trace.c b/server/trace.c
index 1bc83ca..152a6bf 100644
--- a/server/trace.c
+++ b/server/trace.c
@@ -8,331 +8,354 @@
 
 static int dump_new_thread_request( struct new_thread_request *req, int len )
 {
-    printf( " pid=%p", req->pid );
+    fprintf( stderr, " pid=%p", req->pid );
     return (int)sizeof(*req);
 }
 
 static int dump_new_thread_reply( struct new_thread_reply *req, int len )
 {
-    printf( " tid=%p,", req->tid );
-    printf( " thandle=%d,", req->thandle );
-    printf( " pid=%p,", req->pid );
-    printf( " phandle=%d", req->phandle );
+    fprintf( stderr, " tid=%p,", req->tid );
+    fprintf( stderr, " thandle=%d,", req->thandle );
+    fprintf( stderr, " pid=%p,", req->pid );
+    fprintf( stderr, " phandle=%d", req->phandle );
     return (int)sizeof(*req);
 }
 
 static int dump_set_debug_request( struct set_debug_request *req, int len )
 {
-    printf( " level=%d", req->level );
+    fprintf( stderr, " level=%d", req->level );
     return (int)sizeof(*req);
 }
 
 static int dump_init_thread_request( struct init_thread_request *req, int len )
 {
-    printf( " unix_pid=%d,", req->unix_pid );
-    printf( " cmd_line=\"%.*s\"", len - (int)sizeof(*req), (char *)(req+1) );
+    fprintf( stderr, " unix_pid=%d,", req->unix_pid );
+    fprintf( stderr, " cmd_line=\"%.*s\"", len - (int)sizeof(*req), (char *)(req+1) );
     return len;
 }
 
 static int dump_terminate_process_request( struct terminate_process_request *req, int len )
 {
-    printf( " handle=%d,", req->handle );
-    printf( " exit_code=%d", req->exit_code );
+    fprintf( stderr, " handle=%d,", req->handle );
+    fprintf( stderr, " exit_code=%d", req->exit_code );
     return (int)sizeof(*req);
 }
 
 static int dump_terminate_thread_request( struct terminate_thread_request *req, int len )
 {
-    printf( " handle=%d,", req->handle );
-    printf( " exit_code=%d", req->exit_code );
+    fprintf( stderr, " handle=%d,", req->handle );
+    fprintf( stderr, " exit_code=%d", req->exit_code );
     return (int)sizeof(*req);
 }
 
 static int dump_get_process_info_request( struct get_process_info_request *req, int len )
 {
-    printf( " handle=%d", req->handle );
+    fprintf( stderr, " handle=%d", req->handle );
     return (int)sizeof(*req);
 }
 
 static int dump_get_process_info_reply( struct get_process_info_reply *req, int len )
 {
-    printf( " pid=%p,", req->pid );
-    printf( " exit_code=%d", req->exit_code );
+    fprintf( stderr, " pid=%p,", req->pid );
+    fprintf( stderr, " exit_code=%d", req->exit_code );
     return (int)sizeof(*req);
 }
 
 static int dump_get_thread_info_request( struct get_thread_info_request *req, int len )
 {
-    printf( " handle=%d", req->handle );
+    fprintf( stderr, " handle=%d", req->handle );
     return (int)sizeof(*req);
 }
 
 static int dump_get_thread_info_reply( struct get_thread_info_reply *req, int len )
 {
-    printf( " pid=%p,", req->pid );
-    printf( " exit_code=%d", req->exit_code );
+    fprintf( stderr, " pid=%p,", req->pid );
+    fprintf( stderr, " exit_code=%d", req->exit_code );
     return (int)sizeof(*req);
 }
 
 static int dump_close_handle_request( struct close_handle_request *req, int len )
 {
-    printf( " handle=%d", req->handle );
+    fprintf( stderr, " handle=%d", req->handle );
     return (int)sizeof(*req);
 }
 
 static int dump_dup_handle_request( struct dup_handle_request *req, int len )
 {
-    printf( " src_process=%d,", req->src_process );
-    printf( " src_handle=%d,", req->src_handle );
-    printf( " dst_process=%d,", req->dst_process );
-    printf( " dst_handle=%d,", req->dst_handle );
-    printf( " access=%08x,", req->access );
-    printf( " inherit=%d,", req->inherit );
-    printf( " options=%d", req->options );
+    fprintf( stderr, " src_process=%d,", req->src_process );
+    fprintf( stderr, " src_handle=%d,", req->src_handle );
+    fprintf( stderr, " dst_process=%d,", req->dst_process );
+    fprintf( stderr, " dst_handle=%d,", req->dst_handle );
+    fprintf( stderr, " access=%08x,", req->access );
+    fprintf( stderr, " inherit=%d,", req->inherit );
+    fprintf( stderr, " options=%d", req->options );
     return (int)sizeof(*req);
 }
 
 static int dump_dup_handle_reply( struct dup_handle_reply *req, int len )
 {
-    printf( " handle=%d", req->handle );
+    fprintf( stderr, " handle=%d", req->handle );
     return (int)sizeof(*req);
 }
 
 static int dump_open_process_request( struct open_process_request *req, int len )
 {
-    printf( " pid=%p,", req->pid );
-    printf( " access=%08x,", req->access );
-    printf( " inherit=%d", req->inherit );
+    fprintf( stderr, " pid=%p,", req->pid );
+    fprintf( stderr, " access=%08x,", req->access );
+    fprintf( stderr, " inherit=%d", req->inherit );
     return (int)sizeof(*req);
 }
 
 static int dump_open_process_reply( struct open_process_reply *req, int len )
 {
-    printf( " handle=%d", req->handle );
+    fprintf( stderr, " handle=%d", req->handle );
     return (int)sizeof(*req);
 }
 
 static int dump_select_request( struct select_request *req, int len )
 {
-    printf( " count=%d,", req->count );
-    printf( " flags=%d,", req->flags );
-    printf( " timeout=%d", req->timeout );
+    fprintf( stderr, " count=%d,", req->count );
+    fprintf( stderr, " flags=%d,", req->flags );
+    fprintf( stderr, " timeout=%d", req->timeout );
     return (int)sizeof(*req);
 }
 
 static int dump_select_reply( struct select_reply *req, int len )
 {
-    printf( " signaled=%d", req->signaled );
+    fprintf( stderr, " signaled=%d", req->signaled );
     return (int)sizeof(*req);
 }
 
 static int dump_create_event_request( struct create_event_request *req, int len )
 {
-    printf( " manual_reset=%d,", req->manual_reset );
-    printf( " initial_state=%d,", req->initial_state );
-    printf( " inherit=%d,", req->inherit );
-    printf( " name=\"%.*s\"", len - (int)sizeof(*req), (char *)(req+1) );
+    fprintf( stderr, " manual_reset=%d,", req->manual_reset );
+    fprintf( stderr, " initial_state=%d,", req->initial_state );
+    fprintf( stderr, " inherit=%d,", req->inherit );
+    fprintf( stderr, " name=\"%.*s\"", len - (int)sizeof(*req), (char *)(req+1) );
     return len;
 }
 
 static int dump_create_event_reply( struct create_event_reply *req, int len )
 {
-    printf( " handle=%d", req->handle );
+    fprintf( stderr, " handle=%d", req->handle );
     return (int)sizeof(*req);
 }
 
 static int dump_event_op_request( struct event_op_request *req, int len )
 {
-    printf( " handle=%d,", req->handle );
-    printf( " op=%d", req->op );
+    fprintf( stderr, " handle=%d,", req->handle );
+    fprintf( stderr, " op=%d", req->op );
     return (int)sizeof(*req);
 }
 
 static int dump_create_mutex_request( struct create_mutex_request *req, int len )
 {
-    printf( " owned=%d,", req->owned );
-    printf( " inherit=%d,", req->inherit );
-    printf( " name=\"%.*s\"", len - (int)sizeof(*req), (char *)(req+1) );
+    fprintf( stderr, " owned=%d,", req->owned );
+    fprintf( stderr, " inherit=%d,", req->inherit );
+    fprintf( stderr, " name=\"%.*s\"", len - (int)sizeof(*req), (char *)(req+1) );
     return len;
 }
 
 static int dump_create_mutex_reply( struct create_mutex_reply *req, int len )
 {
-    printf( " handle=%d", req->handle );
+    fprintf( stderr, " handle=%d", req->handle );
     return (int)sizeof(*req);
 }
 
 static int dump_release_mutex_request( struct release_mutex_request *req, int len )
 {
-    printf( " handle=%d", req->handle );
+    fprintf( stderr, " handle=%d", req->handle );
     return (int)sizeof(*req);
 }
 
 static int dump_create_semaphore_request( struct create_semaphore_request *req, int len )
 {
-    printf( " initial=%08x,", req->initial );
-    printf( " max=%08x,", req->max );
-    printf( " inherit=%d,", req->inherit );
-    printf( " name=\"%.*s\"", len - (int)sizeof(*req), (char *)(req+1) );
+    fprintf( stderr, " initial=%08x,", req->initial );
+    fprintf( stderr, " max=%08x,", req->max );
+    fprintf( stderr, " inherit=%d,", req->inherit );
+    fprintf( stderr, " name=\"%.*s\"", len - (int)sizeof(*req), (char *)(req+1) );
     return len;
 }
 
 static int dump_create_semaphore_reply( struct create_semaphore_reply *req, int len )
 {
-    printf( " handle=%d", req->handle );
+    fprintf( stderr, " handle=%d", req->handle );
     return (int)sizeof(*req);
 }
 
 static int dump_release_semaphore_request( struct release_semaphore_request *req, int len )
 {
-    printf( " handle=%d,", req->handle );
-    printf( " count=%08x", req->count );
+    fprintf( stderr, " handle=%d,", req->handle );
+    fprintf( stderr, " count=%08x", req->count );
     return (int)sizeof(*req);
 }
 
 static int dump_release_semaphore_reply( struct release_semaphore_reply *req, int len )
 {
-    printf( " prev_count=%08x", req->prev_count );
+    fprintf( stderr, " prev_count=%08x", req->prev_count );
     return (int)sizeof(*req);
 }
 
 static int dump_open_named_obj_request( struct open_named_obj_request *req, int len )
 {
-    printf( " type=%d,", req->type );
-    printf( " access=%08x,", req->access );
-    printf( " inherit=%d,", req->inherit );
-    printf( " name=\"%.*s\"", len - (int)sizeof(*req), (char *)(req+1) );
+    fprintf( stderr, " type=%d,", req->type );
+    fprintf( stderr, " access=%08x,", req->access );
+    fprintf( stderr, " inherit=%d,", req->inherit );
+    fprintf( stderr, " name=\"%.*s\"", len - (int)sizeof(*req), (char *)(req+1) );
     return len;
 }
 
 static int dump_open_named_obj_reply( struct open_named_obj_reply *req, int len )
 {
-    printf( " handle=%d", req->handle );
+    fprintf( stderr, " handle=%d", req->handle );
     return (int)sizeof(*req);
 }
 
 static int dump_create_file_request( struct create_file_request *req, int len )
 {
-    printf( " access=%08x,", req->access );
-    printf( " inherit=%d", req->inherit );
+    fprintf( stderr, " access=%08x,", req->access );
+    fprintf( stderr, " inherit=%d", req->inherit );
     return (int)sizeof(*req);
 }
 
 static int dump_create_file_reply( struct create_file_reply *req, int len )
 {
-    printf( " handle=%d", req->handle );
-    return (int)sizeof(*req);
-}
-
-static int dump_get_unix_handle_request( struct get_unix_handle_request *req, int len )
-{
-    printf( " handle=%d,", req->handle );
-    printf( " access=%08x", req->access );
+    fprintf( stderr, " handle=%d", req->handle );
     return (int)sizeof(*req);
 }
 
 static int dump_get_read_fd_request( struct get_read_fd_request *req, int len )
 {
-    printf( " handle=%d", req->handle );
+    fprintf( stderr, " handle=%d", req->handle );
     return (int)sizeof(*req);
 }
 
 static int dump_get_write_fd_request( struct get_write_fd_request *req, int len )
 {
-    printf( " handle=%d", req->handle );
+    fprintf( stderr, " handle=%d", req->handle );
     return (int)sizeof(*req);
 }
 
 static int dump_set_file_pointer_request( struct set_file_pointer_request *req, int len )
 {
-    printf( " handle=%d,", req->handle );
-    printf( " low=%d,", req->low );
-    printf( " high=%d,", req->high );
-    printf( " whence=%d", req->whence );
+    fprintf( stderr, " handle=%d,", req->handle );
+    fprintf( stderr, " low=%d,", req->low );
+    fprintf( stderr, " high=%d,", req->high );
+    fprintf( stderr, " whence=%d", req->whence );
     return (int)sizeof(*req);
 }
 
 static int dump_set_file_pointer_reply( struct set_file_pointer_reply *req, int len )
 {
-    printf( " low=%d,", req->low );
-    printf( " high=%d", req->high );
+    fprintf( stderr, " low=%d,", req->low );
+    fprintf( stderr, " high=%d", req->high );
     return (int)sizeof(*req);
 }
 
 static int dump_truncate_file_request( struct truncate_file_request *req, int len )
 {
-    printf( " handle=%d", req->handle );
+    fprintf( stderr, " handle=%d", req->handle );
     return (int)sizeof(*req);
 }
 
 static int dump_flush_file_request( struct flush_file_request *req, int len )
 {
-    printf( " handle=%d", req->handle );
+    fprintf( stderr, " handle=%d", req->handle );
     return (int)sizeof(*req);
 }
 
 static int dump_get_file_info_request( struct get_file_info_request *req, int len )
 {
-    printf( " handle=%d", req->handle );
+    fprintf( stderr, " handle=%d", req->handle );
     return (int)sizeof(*req);
 }
 
 static int dump_get_file_info_reply( struct get_file_info_reply *req, int len )
 {
-    printf( " attr=%d,", req->attr );
-    printf( " access_time=%ld,", req->access_time );
-    printf( " write_time=%ld,", req->write_time );
-    printf( " size_high=%d,", req->size_high );
-    printf( " size_low=%d,", req->size_low );
-    printf( " links=%d,", req->links );
-    printf( " index_high=%d,", req->index_high );
-    printf( " index_low=%d,", req->index_low );
-    printf( " serial=%08x", req->serial );
+    fprintf( stderr, " attr=%d,", req->attr );
+    fprintf( stderr, " access_time=%ld,", req->access_time );
+    fprintf( stderr, " write_time=%ld,", req->write_time );
+    fprintf( stderr, " size_high=%d,", req->size_high );
+    fprintf( stderr, " size_low=%d,", req->size_low );
+    fprintf( stderr, " links=%d,", req->links );
+    fprintf( stderr, " index_high=%d,", req->index_high );
+    fprintf( stderr, " index_low=%d,", req->index_low );
+    fprintf( stderr, " serial=%08x", req->serial );
     return (int)sizeof(*req);
 }
 
 static int dump_create_pipe_request( struct create_pipe_request *req, int len )
 {
-    printf( " inherit=%d", req->inherit );
+    fprintf( stderr, " inherit=%d", req->inherit );
     return (int)sizeof(*req);
 }
 
 static int dump_create_pipe_reply( struct create_pipe_reply *req, int len )
 {
-    printf( " handle_read=%d,", req->handle_read );
-    printf( " handle_write=%d", req->handle_write );
+    fprintf( stderr, " handle_read=%d,", req->handle_read );
+    fprintf( stderr, " handle_write=%d", req->handle_write );
     return (int)sizeof(*req);
 }
 
 static int dump_create_console_request( struct create_console_request *req, int len )
 {
-    printf( " inherit=%d", req->inherit );
+    fprintf( stderr, " inherit=%d", req->inherit );
     return (int)sizeof(*req);
 }
 
 static int dump_create_console_reply( struct create_console_reply *req, int len )
 {
-    printf( " handle_read=%d,", req->handle_read );
-    printf( " handle_write=%d", req->handle_write );
+    fprintf( stderr, " handle_read=%d,", req->handle_read );
+    fprintf( stderr, " handle_write=%d", req->handle_write );
     return (int)sizeof(*req);
 }
 
 static int dump_set_console_fd_request( struct set_console_fd_request *req, int len )
 {
-    printf( " handle=%d", req->handle );
+    fprintf( stderr, " handle=%d", req->handle );
     return (int)sizeof(*req);
 }
 
 static int dump_create_change_notification_request( struct create_change_notification_request *req, int len )
 {
-    printf( " subtree=%d,", req->subtree );
-    printf( " filter=%d", req->filter );
+    fprintf( stderr, " subtree=%d,", req->subtree );
+    fprintf( stderr, " filter=%d", req->filter );
     return (int)sizeof(*req);
 }
 
 static int dump_create_change_notification_reply( struct create_change_notification_reply *req, int len )
 {
-    printf( " handle=%d", req->handle );
+    fprintf( stderr, " handle=%d", req->handle );
+    return (int)sizeof(*req);
+}
+
+static int dump_create_mapping_request( struct create_mapping_request *req, int len )
+{
+    fprintf( stderr, " size_high=%d,", req->size_high );
+    fprintf( stderr, " size_low=%d,", req->size_low );
+    fprintf( stderr, " protect=%d,", req->protect );
+    fprintf( stderr, " handle=%d,", req->handle );
+    fprintf( stderr, " name=\"%.*s\"", len - (int)sizeof(*req), (char *)(req+1) );
+    return len;
+}
+
+static int dump_create_mapping_reply( struct create_mapping_reply *req, int len )
+{
+    fprintf( stderr, " handle=%d", req->handle );
+    return (int)sizeof(*req);
+}
+
+static int dump_get_mapping_info_request( struct get_mapping_info_request *req, int len )
+{
+    fprintf( stderr, " handle=%d", req->handle );
+    return (int)sizeof(*req);
+}
+
+static int dump_get_mapping_info_reply( struct get_mapping_info_reply *req, int len )
+{
+    fprintf( stderr, " size_high=%d,", req->size_high );
+    fprintf( stderr, " size_low=%d,", req->size_low );
+    fprintf( stderr, " protect=%d", req->protect );
     return (int)sizeof(*req);
 }
 
@@ -382,8 +405,6 @@
       (void(*)())dump_open_named_obj_reply },
     { (int(*)(void *,int))dump_create_file_request,
       (void(*)())dump_create_file_reply },
-    { (int(*)(void *,int))dump_get_unix_handle_request,
-      (void(*)())0 },
     { (int(*)(void *,int))dump_get_read_fd_request,
       (void(*)())0 },
     { (int(*)(void *,int))dump_get_write_fd_request,
@@ -404,6 +425,10 @@
       (void(*)())0 },
     { (int(*)(void *,int))dump_create_change_notification_request,
       (void(*)())dump_create_change_notification_reply },
+    { (int(*)(void *,int))dump_create_mapping_request,
+      (void(*)())dump_create_mapping_reply },
+    { (int(*)(void *,int))dump_get_mapping_info_request,
+      (void(*)())dump_get_mapping_info_reply },
 };
 
 static const char * const req_names[REQ_NB_REQUESTS] =
@@ -427,7 +452,6 @@
     "release_semaphore",
     "open_named_obj",
     "create_file",
-    "get_unix_handle",
     "get_read_fd",
     "get_write_fd",
     "set_file_pointer",
@@ -438,43 +462,45 @@
     "create_console",
     "set_console_fd",
     "create_change_notification",
+    "create_mapping",
+    "get_mapping_info",
 };
 
 void trace_request( enum request req, void *data, int len, int fd )
 {
     int size;
     current->last_req = req;
-    printf( "%08x: %s(", (unsigned int)current, req_names[req] );
+    fprintf( stderr, "%08x: %s(", (unsigned int)current, req_names[req] );
     size = dumpers[req].dump_req( data, len );
     if ((len -= size) > 0)
     {
         unsigned char *ptr = (unsigned char *)data + size;
-        while (len--) printf( ", %02x", *ptr++ );
+        while (len--) fprintf( stderr, ", %02x", *ptr++ );
     }
-    if (fd != -1) printf( " ) fd=%d\n", fd );
-    else printf( " )\n" );
+    if (fd != -1) fprintf( stderr, " ) fd=%d\n", fd );
+    else fprintf( stderr, " )\n" );
 }
 
 void trace_timeout(void)
 {
-    printf( "%08x: *timeout*\n", (unsigned int)current );
+    fprintf( stderr, "%08x: *timeout*\n", (unsigned int)current );
 }
 
 void trace_kill( int exit_code )
 {
-    printf( "%08x: *killed* exit_code=%d\n",
-            (unsigned int)current, exit_code );
+    fprintf( stderr,"%08x: *killed* exit_code=%d\n",
+             (unsigned int)current, exit_code );
 }
 
 void trace_reply( struct thread *thread, int type, int pass_fd,
                   struct iovec *vec, int veclen )
 {
     if (!thread) return;
-    printf( "%08x: %s() = %d",
-            (unsigned int)thread, req_names[thread->last_req], type );
+    fprintf( stderr, "%08x: %s() = %d",
+             (unsigned int)thread, req_names[thread->last_req], type );
     if (veclen)
     {
-	printf( " {" );
+	fprintf( stderr, " {" );
 	if (dumpers[thread->last_req].dump_reply)
 	{
 	    dumpers[thread->last_req].dump_reply( vec->iov_base );
@@ -485,10 +511,10 @@
 	{
 	    unsigned char *ptr = vec->iov_base;
 	    int len = vec->iov_len;
-	    while (len--) printf( ", %02x", *ptr++ );
+	    while (len--) fprintf( stderr, ", %02x", *ptr++ );
 	}
-	printf( " }" );
+	fprintf( stderr, " }" );
     }
-    if (pass_fd != -1) printf( " fd=%d\n", pass_fd );
-    else printf( "\n" );
+    if (pass_fd != -1) fprintf( stderr, " fd=%d\n", pass_fd );
+    else fprintf( stderr, "\n" );
 }