Server reorganization:
- moved request handlers to the specific C files
- moved handle management to handle.c
- moved server private includes to server/ instead of include/server/

diff --git a/include/server.h b/include/server.h
index 228c4bb..f0601ad 100644
--- a/include/server.h
+++ b/include/server.h
@@ -30,6 +30,9 @@
     int fd;    /* fd to pass */
 };
 
+/* request handler definition */
+#define DECL_HANDLER(name) \
+    void req_##name( struct name##_request *req, void *data, int len, int fd )
 
 /* Request structures */
 
@@ -314,6 +317,19 @@
 enum event_op { PULSE_EVENT, SET_EVENT, RESET_EVENT };
 
 
+/* Open an event */
+struct open_event_request
+{
+    unsigned int access;        /* wanted access rights */
+    int          inherit;       /* inherit flag */
+    char         name[0];       /* object name */
+};
+struct open_event_reply
+{
+    int          handle;        /* handle to the event */
+};
+
+
 /* Create a mutex */
 struct create_mutex_request
 {
@@ -334,6 +350,19 @@
 };
 
 
+/* Open a mutex */
+struct open_mutex_request
+{
+    unsigned int access;        /* wanted access rights */
+    int          inherit;       /* inherit flag */
+    char         name[0];       /* object name */
+};
+struct open_mutex_reply
+{
+    int          handle;        /* handle to the mutex */
+};
+
+
 /* Create a semaphore */
 struct create_semaphore_request
 {
@@ -360,19 +389,16 @@
 };
 
 
-/* Open a named object (event, mutex, semaphore) */
-struct open_named_obj_request
+/* Open a semaphore */
+struct open_semaphore_request
 {
-    int          type;          /* object type (see below) */
     unsigned int access;        /* wanted access rights */
     int          inherit;       /* inherit flag */
     char         name[0];       /* object name */
 };
-enum open_named_obj { OPEN_EVENT, OPEN_MUTEX, OPEN_SEMAPHORE, OPEN_MAPPING };
-
-struct open_named_obj_reply
+struct open_semaphore_reply
 {
-    int          handle;        /* handle to the object */
+    int          handle;        /* handle to the semaphore */
 };
 
 
@@ -640,6 +666,19 @@
 #define VPROT_COMMITTED  0x40
 
 
+/* Open a mapping */
+struct open_mapping_request
+{
+    unsigned int access;        /* wanted access rights */
+    int          inherit;       /* inherit flag */
+    char         name[0];       /* object name */
+};
+struct open_mapping_reply
+{
+    int          handle;        /* handle to the mapping */
+};
+
+
 /* Get information about a file mapping */
 struct get_mapping_info_request
 {
@@ -692,12 +731,13 @@
 };
 
 
+/* requests definitions */
+#include "server/request.h"
+
 /* client-side functions */
 
 #ifndef __WINE_SERVER__
 
-#include "server/request.h"
-
 /* client communication functions */
 extern void CLIENT_SendRequest( enum request req, int pass_fd,
                                 int n, ... /* arg_1, len_1, etc. */ );
diff --git a/include/server/process.h b/include/server/process.h
deleted file mode 100644
index cfd0d88..0000000
--- a/include/server/process.h
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Wine server processes
- *
- * Copyright (C) 1999 Alexandre Julliard
- */
-
-#ifndef __WINE_SERVER_PROCESS_H
-#define __WINE_SERVER_PROCESS_H
-
-#ifndef __WINE_SERVER__
-#error This file can only be used in the Wine server
-#endif
-
-#include "server/object.h"
-
-/* process structures */
-
-struct process;
-
-struct process_snapshot
-{
-    struct process *process;  /* process ptr */
-    struct process *parent;   /* process parent */
-    int             threads;  /* number of threads */
-    int             priority; /* priority class */
-};
-
-/* process functions */
-
-extern struct process *create_initial_process(void);
-extern struct process *create_process( struct new_process_request *req );
-extern struct process *get_process_from_id( void *id );
-extern struct process *get_process_from_handle( int handle, unsigned int access );
-extern int get_process_init_info( struct process *process, struct init_process_reply *reply );
-extern void add_process_thread( struct process *process,
-                                struct thread *thread );
-extern void remove_process_thread( struct process *process,
-                                   struct thread *thread );
-extern void kill_process( struct process *process, int exit_code );
-extern void get_process_info( struct process *process,
-                              struct get_process_info_reply *reply );
-extern void set_process_info( struct process *process,
-                              struct set_process_info_request *req );
-extern int alloc_console( struct process *process );
-extern int free_console( struct process *process );
-extern struct object *get_console( struct process *process, int output );
-extern struct process_snapshot *process_snap( int *count );
-
-/* handle functions */
-
-/* alloc_handle takes a void *obj for convenience, but you better make sure */
-/* 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 set_handle_info( struct process *process, int handle,
-                            int mask, int flags );
-extern struct object *get_handle_obj( struct process *process, int handle,
-                                      unsigned int access, const struct object_ops *ops );
-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 char *name, const struct object_ops *ops,
-                        unsigned int access, int inherit );
-
-#endif  /* __WINE_SERVER_PROCESS_H */
diff --git a/include/server/request.h b/include/server/request.h
index 6167edd..ae44fa2 100644
--- a/include/server/request.h
+++ b/include/server/request.h
@@ -28,11 +28,13 @@
     REQ_SELECT,
     REQ_CREATE_EVENT,
     REQ_EVENT_OP,
+    REQ_OPEN_EVENT,
     REQ_CREATE_MUTEX,
     REQ_RELEASE_MUTEX,
+    REQ_OPEN_MUTEX,
     REQ_CREATE_SEMAPHORE,
     REQ_RELEASE_SEMAPHORE,
-    REQ_OPEN_NAMED_OBJ,
+    REQ_OPEN_SEMAPHORE,
     REQ_CREATE_FILE,
     REQ_GET_READ_FD,
     REQ_GET_WRITE_FD,
@@ -56,6 +58,7 @@
     REQ_READ_CONSOLE_INPUT,
     REQ_CREATE_CHANGE_NOTIFICATION,
     REQ_CREATE_MAPPING,
+    REQ_OPEN_MAPPING,
     REQ_GET_MAPPING_INFO,
     REQ_CREATE_DEVICE,
     REQ_CREATE_SNAPSHOT,
@@ -65,9 +68,6 @@
 
 #ifdef WANT_REQUEST_HANDLERS
 
-#define DECL_HANDLER(name) \
-    static void req_##name( struct name##_request *req, void *data, int len, int fd )
-
 DECL_HANDLER(new_process);
 DECL_HANDLER(new_thread);
 DECL_HANDLER(set_debug);
@@ -91,11 +91,13 @@
 DECL_HANDLER(select);
 DECL_HANDLER(create_event);
 DECL_HANDLER(event_op);
+DECL_HANDLER(open_event);
 DECL_HANDLER(create_mutex);
 DECL_HANDLER(release_mutex);
+DECL_HANDLER(open_mutex);
 DECL_HANDLER(create_semaphore);
 DECL_HANDLER(release_semaphore);
-DECL_HANDLER(open_named_obj);
+DECL_HANDLER(open_semaphore);
 DECL_HANDLER(create_file);
 DECL_HANDLER(get_read_fd);
 DECL_HANDLER(get_write_fd);
@@ -119,6 +121,7 @@
 DECL_HANDLER(read_console_input);
 DECL_HANDLER(create_change_notification);
 DECL_HANDLER(create_mapping);
+DECL_HANDLER(open_mapping);
 DECL_HANDLER(get_mapping_info);
 DECL_HANDLER(create_device);
 DECL_HANDLER(create_snapshot);
@@ -151,11 +154,13 @@
     { (void(*)())req_select, sizeof(struct select_request) },
     { (void(*)())req_create_event, sizeof(struct create_event_request) },
     { (void(*)())req_event_op, sizeof(struct event_op_request) },
+    { (void(*)())req_open_event, sizeof(struct open_event_request) },
     { (void(*)())req_create_mutex, sizeof(struct create_mutex_request) },
     { (void(*)())req_release_mutex, sizeof(struct release_mutex_request) },
+    { (void(*)())req_open_mutex, sizeof(struct open_mutex_request) },
     { (void(*)())req_create_semaphore, sizeof(struct create_semaphore_request) },
     { (void(*)())req_release_semaphore, sizeof(struct release_semaphore_request) },
-    { (void(*)())req_open_named_obj, sizeof(struct open_named_obj_request) },
+    { (void(*)())req_open_semaphore, sizeof(struct open_semaphore_request) },
     { (void(*)())req_create_file, sizeof(struct create_file_request) },
     { (void(*)())req_get_read_fd, sizeof(struct get_read_fd_request) },
     { (void(*)())req_get_write_fd, sizeof(struct get_write_fd_request) },
@@ -179,6 +184,7 @@
     { (void(*)())req_read_console_input, sizeof(struct read_console_input_request) },
     { (void(*)())req_create_change_notification, sizeof(struct create_change_notification_request) },
     { (void(*)())req_create_mapping, sizeof(struct create_mapping_request) },
+    { (void(*)())req_open_mapping, sizeof(struct open_mapping_request) },
     { (void(*)())req_get_mapping_info, sizeof(struct get_mapping_info_request) },
     { (void(*)())req_create_device, sizeof(struct create_device_request) },
     { (void(*)())req_create_snapshot, sizeof(struct create_snapshot_request) },
diff --git a/memory/virtual.c b/memory/virtual.c
index ef5d69d..5e810e0 100644
--- a/memory/virtual.c
+++ b/memory/virtual.c
@@ -1118,14 +1118,13 @@
                 BOOL inherit, /* [in] Inherit flag */
                 LPCSTR name )   /* [in] Name of file-mapping object */
 {
-    struct open_named_obj_request req;
-    struct open_named_obj_reply reply;
+    struct open_mapping_request req;
+    struct open_mapping_reply reply;
     int len = name ? strlen(name) + 1 : 0;
 
-    req.type    = OPEN_MAPPING;
     req.access  = access;
     req.inherit = inherit;
-    CLIENT_SendRequest( REQ_OPEN_NAMED_OBJ, -1, 2, &req, sizeof(req), name, len );
+    CLIENT_SendRequest( REQ_OPEN_MAPPING, -1, 2, &req, sizeof(req), name, len );
     CLIENT_WaitSimpleReply( &reply, sizeof(reply), NULL );
     if (reply.handle == -1) return 0; /* must return 0 on failure, not -1 */
     return reply.handle;
diff --git a/scheduler/event.c b/scheduler/event.c
index 04f5778..8ab0107 100644
--- a/scheduler/event.c
+++ b/scheduler/event.c
@@ -60,14 +60,13 @@
  */
 HANDLE WINAPI OpenEventA( DWORD access, BOOL inherit, LPCSTR name )
 {
-    struct open_named_obj_request req;
-    struct open_named_obj_reply reply;
+    struct open_event_request req;
+    struct open_event_reply reply;
     int len = name ? strlen(name) + 1 : 0;
 
-    req.type    = OPEN_EVENT;
     req.access  = access;
     req.inherit = inherit;
-    CLIENT_SendRequest( REQ_OPEN_NAMED_OBJ, -1, 2, &req, sizeof(req), name, len );
+    CLIENT_SendRequest( REQ_OPEN_EVENT, -1, 2, &req, sizeof(req), name, len );
     CLIENT_WaitSimpleReply( &reply, sizeof(reply), NULL );
     if (reply.handle == -1) return 0; /* must return 0 on failure, not -1 */
     return (HANDLE)reply.handle;
diff --git a/scheduler/mutex.c b/scheduler/mutex.c
index 7bbe6a8..185dea8 100644
--- a/scheduler/mutex.c
+++ b/scheduler/mutex.c
@@ -49,14 +49,13 @@
  */
 HANDLE WINAPI OpenMutexA( DWORD access, BOOL inherit, LPCSTR name )
 {
-    struct open_named_obj_request req;
-    struct open_named_obj_reply reply;
+    struct open_mutex_request req;
+    struct open_mutex_reply reply;
     int len = name ? strlen(name) + 1 : 0;
 
-    req.type    = OPEN_MUTEX;
     req.access  = access;
     req.inherit = inherit;
-    CLIENT_SendRequest( REQ_OPEN_NAMED_OBJ, -1, 2, &req, sizeof(req), name, len );
+    CLIENT_SendRequest( REQ_OPEN_MUTEX, -1, 2, &req, sizeof(req), name, len );
     CLIENT_WaitSimpleReply( &reply, sizeof(reply), NULL );
     if (reply.handle == -1) return 0; /* must return 0 on failure, not -1 */
     return reply.handle;
diff --git a/scheduler/semaphore.c b/scheduler/semaphore.c
index 298df02..dbe2eec 100644
--- a/scheduler/semaphore.c
+++ b/scheduler/semaphore.c
@@ -60,14 +60,13 @@
  */
 HANDLE WINAPI OpenSemaphoreA( DWORD access, BOOL inherit, LPCSTR name )
 {
-    struct open_named_obj_request req;
-    struct open_named_obj_reply reply;
+    struct open_semaphore_request req;
+    struct open_semaphore_reply reply;
     int len = name ? strlen(name) + 1 : 0;
 
-    req.type    = OPEN_SEMAPHORE;
     req.access  = access;
     req.inherit = inherit;
-    CLIENT_SendRequest( REQ_OPEN_NAMED_OBJ, -1, 2, &req, sizeof(req), name, len );
+    CLIENT_SendRequest( REQ_OPEN_SEMAPHORE, -1, 2, &req, sizeof(req), name, len );
     CLIENT_WaitSimpleReply( &reply, sizeof(reply), NULL );
     if (reply.handle == -1) return 0; /* must return 0 on failure, not -1 */
     return reply.handle;
diff --git a/server/Makefile.in b/server/Makefile.in
index f062a95..3aaa6da 100644
--- a/server/Makefile.in
+++ b/server/Makefile.in
@@ -11,6 +11,7 @@
 	device.c \
 	event.c \
 	file.c \
+	handle.c \
 	mapping.c \
 	mutex.c \
 	object.c \
diff --git a/server/change.c b/server/change.c
index bae2f23..679df12 100644
--- a/server/change.c
+++ b/server/change.c
@@ -10,7 +10,9 @@
 
 #include "winerror.h"
 #include "winnt.h"
-#include "server/thread.h"
+
+#include "handle.h"
+#include "thread.h"
 
 struct change
 {
@@ -38,7 +40,7 @@
 };
 
 
-struct object *create_change_notification( int subtree, int filter )
+static struct object *create_change_notification( int subtree, int filter )
 {
     struct change *change;
     if (!(change = mem_alloc( sizeof(*change) ))) return NULL;
@@ -69,3 +71,18 @@
     assert( obj->ops == &change_ops );
     free( change );
 }
+
+/* create a change notification */
+DECL_HANDLER(create_change_notification)
+{
+    struct object *obj;
+    struct create_change_notification_reply reply = { -1 };
+
+    if ((obj = create_change_notification( req->subtree, req->filter )))
+    {
+        reply.handle = alloc_handle( current->process, obj,
+                                     STANDARD_RIGHTS_REQUIRED|SYNCHRONIZE, 0 );
+        release_object( obj );
+    }
+    send_reply( current, -1, 1, &reply, sizeof(reply) );
+}
diff --git a/server/console.c b/server/console.c
index 0d095b4..d067c21 100644
--- a/server/console.c
+++ b/server/console.c
@@ -23,8 +23,10 @@
 #include "winerror.h"
 #include "winnt.h"
 #include "wincon.h"
-#include "server/process.h"
-#include "server/thread.h"
+
+#include "handle.h"
+#include "process.h"
+#include "thread.h"
 
 struct screen_buffer;
 
@@ -153,7 +155,7 @@
     return 1;
 }
 
-int set_console_fd( int handle, int fd, int pid )
+static int set_console_fd( int handle, int fd, int pid )
 {
     struct console_input *input;
     struct screen_buffer *output;
@@ -206,7 +208,7 @@
     return 1;
 }
 
-int get_console_mode( int handle, int *mode )
+static int get_console_mode( int handle, int *mode )
 {
     struct object *obj;
     int ret = 0;
@@ -228,7 +230,7 @@
     return ret;
 }
 
-int set_console_mode( int handle, int mode )
+static int set_console_mode( int handle, int mode )
 {
     struct object *obj;
     int ret = 0;
@@ -251,7 +253,7 @@
 }
 
 /* set misc console information (output handle only) */
-int set_console_info( int handle, struct set_console_info_request *req, const char *title )
+static int set_console_info( int handle, struct set_console_info_request *req, const char *title )
 {
     struct screen_buffer *console;
     if (!(console = (struct screen_buffer *)get_handle_obj( current->process, handle,
@@ -272,7 +274,7 @@
 }
 
 /* get misc console information (output handle only) */
-int get_console_info( int handle, struct get_console_info_reply *reply, const char **title )
+static int get_console_info( int handle, struct get_console_info_reply *reply, const char **title )
 {
     struct screen_buffer *console;
     if (!(console = (struct screen_buffer *)get_handle_obj( current->process, handle,
@@ -287,7 +289,7 @@
 }
 
 /* add input events to a console input queue */
-int write_console_input( int handle, int count, INPUT_RECORD *records )
+static int write_console_input( int handle, int count, INPUT_RECORD *records )
 {
     INPUT_RECORD *new_rec;
     struct console_input *console;
@@ -310,7 +312,7 @@
 }
 
 /* retrieve a pointer to the console input records */
-int read_console_input( int handle, int count, int flush )
+static int read_console_input( int handle, int count, int flush )
 {
     struct console_input *console;
 
@@ -472,3 +474,91 @@
     if (console->title) free( console->title );
     free( console );
 }
+
+/* allocate a console for the current process */
+DECL_HANDLER(alloc_console)
+{
+    alloc_console( current->process );
+    send_reply( current, -1, 0 );
+}
+
+/* free the console of the current process */
+DECL_HANDLER(free_console)
+{
+    free_console( current->process );
+    send_reply( current, -1, 0 );
+}
+
+/* open a handle to the process console */
+DECL_HANDLER(open_console)
+{
+    struct object *obj;
+    struct open_console_reply reply = { -1 };
+    if ((obj = get_console( current->process, req->output )))
+    {
+        reply.handle = alloc_handle( current->process, obj, req->access, req->inherit );
+        release_object( obj );
+    }
+    send_reply( current, -1, 1, &reply, sizeof(reply) );
+}
+
+/* set info about a console (output only) */
+DECL_HANDLER(set_console_info)
+{
+    char *name = (char *)data;
+    if (!len) name = NULL;
+    else CHECK_STRING( "set_console_info", name, len );
+    set_console_info( req->handle, req, name );
+    send_reply( current, -1, 0 );
+}
+
+/* get info about a console (output only) */
+DECL_HANDLER(get_console_info)
+{
+    struct get_console_info_reply reply;
+    const char *title;
+    get_console_info( req->handle, &reply, &title );
+    send_reply( current, -1, 2, &reply, sizeof(reply),
+                title, title ? strlen(title)+1 : 0 );
+}
+
+/* set a console fd */
+DECL_HANDLER(set_console_fd)
+{
+    set_console_fd( req->handle, fd, req->pid );
+    send_reply( current, -1, 0 );
+}
+
+/* get a console mode (input or output) */
+DECL_HANDLER(get_console_mode)
+{
+    struct get_console_mode_reply reply;
+    get_console_mode( req->handle, &reply.mode );
+    send_reply( current, -1, 1, &reply, sizeof(reply) );
+}
+
+/* set a console mode (input or output) */
+DECL_HANDLER(set_console_mode)
+{
+    set_console_mode( req->handle, req->mode );
+    send_reply( current, -1, 0 );
+}
+
+/* add input records to a console input queue */
+DECL_HANDLER(write_console_input)
+{
+    struct write_console_input_reply reply;
+    INPUT_RECORD *records = (INPUT_RECORD *)data;
+
+    if (len != req->count * sizeof(INPUT_RECORD))
+        fatal_protocol_error( "write_console_input: bad length %d for %d records\n",
+                              len, req->count );
+    reply.written = write_console_input( req->handle, req->count, records );
+    send_reply( current, -1, 1, &reply, sizeof(reply) );
+}
+
+/* fetch input records from a console input queue */
+DECL_HANDLER(read_console_input)
+{
+    read_console_input( req->handle, req->count, req->flush );
+}
diff --git a/server/device.c b/server/device.c
index 83446f4..5822293 100644
--- a/server/device.c
+++ b/server/device.c
@@ -18,7 +18,9 @@
 
 #include "winerror.h"
 #include "winbase.h"
-#include "server/thread.h"
+
+#include "handle.h"
+#include "thread.h"
 
 struct device
 {
@@ -44,7 +46,7 @@
     device_destroy
 };
 
-struct object *create_device( int id )
+static struct object *create_device( int id )
 {
     struct device *dev;
 
@@ -77,3 +79,18 @@
     assert( obj->ops == &device_ops );
     free( dev );
 }
+
+/* create a device */
+DECL_HANDLER(create_device)
+{
+    struct object *obj;
+    struct create_device_reply reply = { -1 };
+
+    if ((obj = create_device( req->id )))
+    {
+        reply.handle = alloc_handle( current->process, obj,
+                                     req->access, req->inherit );
+        release_object( obj );
+    }
+    send_reply( current, -1, 1, &reply, sizeof(reply) );
+}
diff --git a/server/event.c b/server/event.c
index 04f51603..5546d6e 100644
--- a/server/event.c
+++ b/server/event.c
@@ -10,8 +10,9 @@
 
 #include "winerror.h"
 #include "winnt.h"
-#include "server/process.h"
-#include "server/thread.h"
+
+#include "handle.h"
+#include "thread.h"
 
 struct event
 {
@@ -40,7 +41,7 @@
 };
 
 
-struct object *create_event( const char *name, int manual_reset, int initial_state )
+static struct object *create_event( const char *name, int manual_reset, int initial_state )
 {
     struct event *event;
 
@@ -55,12 +56,7 @@
     return &event->obj;
 }
 
-int open_event( unsigned int access, int inherit, const char *name )
-{
-    return open_object( name, &event_ops, access, inherit );
-}
-
-int pulse_event( int handle )
+static int pulse_event( int handle )
 {
     struct event *event;
 
@@ -75,7 +71,7 @@
     return 1;
 }
 
-int set_event( int handle )
+static int set_event( int handle )
 {
     struct event *event;
 
@@ -89,7 +85,7 @@
     return 1;
 }
 
-int reset_event( int handle )
+static int reset_event( int handle )
 {
     struct event *event;
 
@@ -132,3 +128,53 @@
     assert( obj->ops == &event_ops );
     free( event );
 }
+
+/* create an event */
+DECL_HANDLER(create_event)
+{
+    struct create_event_reply reply = { -1 };
+    struct object *obj;
+    char *name = (char *)data;
+    if (!len) name = NULL;
+    else CHECK_STRING( "create_event", name, len );
+
+    obj = create_event( name, req->manual_reset, req->initial_state );
+    if (obj)
+    {
+        reply.handle = alloc_handle( current->process, obj, EVENT_ALL_ACCESS, req->inherit );
+        release_object( obj );
+    }
+    send_reply( current, -1, 1, &reply, sizeof(reply) );
+}
+
+/* open a handle to an event */
+DECL_HANDLER(open_event)
+{
+    struct open_event_reply reply;
+    char *name = (char *)data;
+    if (!len) name = NULL;
+    else CHECK_STRING( "open_event", name, len );
+
+    reply.handle = open_object( name, &event_ops, req->access, req->inherit );
+    send_reply( current, -1, 1, &reply, sizeof(reply) );
+}
+
+/* do an event operation */
+DECL_HANDLER(event_op)
+{
+    switch(req->op)
+    {
+    case PULSE_EVENT:
+        pulse_event( req->handle );
+        break;
+    case SET_EVENT:
+        set_event( req->handle );
+        break;
+    case RESET_EVENT:
+        reset_event( req->handle );
+        break;
+    default:
+        fatal_protocol_error( "event_op: invalid operation %d\n", req->op );
+    }
+    send_reply( current, -1, 0 );
+}
diff --git a/server/file.c b/server/file.c
index 6d992bd..00f1c60 100644
--- a/server/file.c
+++ b/server/file.c
@@ -20,8 +20,9 @@
 
 #include "winerror.h"
 #include "winbase.h"
-#include "server/process.h"
-#include "server/thread.h"
+
+#include "handle.h"
+#include "thread.h"
 
 struct file
 {
@@ -98,8 +99,8 @@
     return 1;
 }
 
-struct object *create_file( int fd, const char *name, unsigned int access,
-                            unsigned int sharing, int create, unsigned int attrs )
+static struct object *create_file( int fd, const char *name, unsigned int access,
+                                   unsigned int sharing, int create, unsigned int attrs )
 {
     struct file *file;
     int hash = 0;
@@ -399,7 +400,7 @@
     return dup( file->fd );
 }
 
-int set_file_pointer( int handle, int *low, int *high, int whence )
+static int set_file_pointer( int handle, int *low, int *high, int whence )
 {
     struct file *file;
     int result;
@@ -428,7 +429,7 @@
     return 1;
 }
 
-int truncate_file( int handle )
+static int truncate_file( int handle )
 {
     struct file *file;
     int result;
@@ -468,7 +469,7 @@
     return 0;
 }
 
-int set_file_time( int handle, time_t access_time, time_t write_time )
+static int set_file_time( int handle, time_t access_time, time_t write_time )
 {
     struct file *file;
     struct utimbuf utimbuf;
@@ -493,16 +494,142 @@
     return 0;
 }
 
-int file_lock( struct file *file, int offset_high, int offset_low,
-               int count_high, int count_low )
+static int file_lock( struct file *file, int offset_high, int offset_low,
+                      int count_high, int count_low )
 {
     /* FIXME: implement this */
     return 1;
 }
 
-int file_unlock( struct file *file, int offset_high, int offset_low,
-                 int count_high, int count_low )
+static int file_unlock( struct file *file, int offset_high, int offset_low,
+                        int count_high, int count_low )
 {
     /* FIXME: implement this */
     return 1;
 }
+/* create a file */
+DECL_HANDLER(create_file)
+{
+    struct create_file_reply reply = { -1 };
+    struct object *obj;
+    char *name = (char *)data;
+    if (!len) name = NULL;
+    else CHECK_STRING( "create_file", name, len );
+
+    if ((obj = create_file( fd, name, req->access,
+                            req->sharing, req->create, req->attrs )) != NULL)
+    {
+        reply.handle = alloc_handle( current->process, obj, req->access, req->inherit );
+        release_object( obj );
+    }
+    send_reply( current, -1, 1, &reply, sizeof(reply) );
+}
+
+/* get a Unix fd to read from a file */
+DECL_HANDLER(get_read_fd)
+{
+    struct object *obj;
+    int read_fd;
+
+    if ((obj = get_handle_obj( current->process, req->handle, GENERIC_READ, NULL )))
+    {
+        read_fd = obj->ops->get_read_fd( obj );
+        release_object( obj );
+    }
+    else read_fd = -1;
+    send_reply( current, read_fd, 0 );
+}
+
+/* get a Unix fd to write to a file */
+DECL_HANDLER(get_write_fd)
+{
+    struct object *obj;
+    int write_fd;
+
+    if ((obj = get_handle_obj( current->process, req->handle, GENERIC_WRITE, NULL )))
+    {
+        write_fd = obj->ops->get_write_fd( obj );
+        release_object( obj );
+    }
+    else write_fd = -1;
+    send_reply( current, write_fd, 0 );
+}
+
+/* set a file current position */
+DECL_HANDLER(set_file_pointer)
+{
+    struct set_file_pointer_reply reply;
+    reply.low = req->low;
+    reply.high = req->high;
+    set_file_pointer( req->handle, &reply.low, &reply.high, req->whence );
+    send_reply( current, -1, 1, &reply, sizeof(reply) );
+}
+
+/* truncate (or extend) a file */
+DECL_HANDLER(truncate_file)
+{
+    truncate_file( req->handle );
+    send_reply( current, -1, 0 );
+}
+
+/* flush a file buffers */
+DECL_HANDLER(flush_file)
+{
+    struct object *obj;
+
+    if ((obj = get_handle_obj( current->process, req->handle, GENERIC_WRITE, NULL )))
+    {
+        obj->ops->flush( obj );
+        release_object( obj );
+    }
+    send_reply( current, -1, 0 );
+}
+
+/* set a file access and modification times */
+DECL_HANDLER(set_file_time)
+{
+    set_file_time( req->handle, req->access_time, req->write_time );
+    send_reply( current, -1, 0 );
+}
+
+/* get a file information */
+DECL_HANDLER(get_file_info)
+{
+    struct object *obj;
+    struct get_file_info_reply reply;
+
+    if ((obj = get_handle_obj( current->process, req->handle, 0, NULL )))
+    {
+        obj->ops->get_file_info( obj, &reply );
+        release_object( obj );
+    }
+    send_reply( current, -1, 1, &reply, sizeof(reply) );
+}
+
+/* lock a region of a file */
+DECL_HANDLER(lock_file)
+{
+    struct file *file;
+
+    if ((file = get_file_obj( current->process, req->handle, 0 )))
+    {
+        file_lock( file, req->offset_high, req->offset_low,
+                   req->count_high, req->count_low );
+        release_object( file );
+    }
+    send_reply( current, -1, 0 );
+}
+
+/* unlock a region of a file */
+DECL_HANDLER(unlock_file)
+{
+    struct file *file;
+
+    if ((file = get_file_obj( current->process, req->handle, 0 )))
+    {
+        file_unlock( file, req->offset_high, req->offset_low,
+                     req->count_high, req->count_low );
+        release_object( file );
+    }
+    send_reply( current, -1, 0 );
+}
diff --git a/server/handle.c b/server/handle.c
new file mode 100644
index 0000000..a99583b
--- /dev/null
+++ b/server/handle.c
@@ -0,0 +1,372 @@
+/*
+ * Server-side handle management
+ *
+ * Copyright (C) 1998 Alexandre Julliard
+ */
+
+#include <assert.h>
+#include <limits.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "winerror.h"
+#include "winbase.h"
+
+#include "handle.h"
+#include "process.h"
+#include "thread.h"
+
+struct handle_entry
+{
+    struct object *ptr;
+    unsigned int   access;
+};
+
+static struct process *initial_process;
+
+/* reserved handle access rights */
+#define RESERVED_SHIFT         25
+#define RESERVED_INHERIT       (HANDLE_FLAG_INHERIT << RESERVED_SHIFT)
+#define RESERVED_CLOSE_PROTECT (HANDLE_FLAG_PROTECT_FROM_CLOSE << RESERVED_SHIFT)
+#define RESERVED_ALL           (RESERVED_INHERIT | RESERVED_CLOSE_PROTECT)
+
+/* global handle macros */
+#define HANDLE_OBFUSCATOR         0x544a4def
+#define HANDLE_IS_GLOBAL(h)       (((h) ^ HANDLE_OBFUSCATOR) < 0x10000)
+#define HANDLE_LOCAL_TO_GLOBAL(h) ((h) ^ HANDLE_OBFUSCATOR)
+#define HANDLE_GLOBAL_TO_LOCAL(h) ((h) ^ HANDLE_OBFUSCATOR)
+
+#define MIN_HANDLE_ENTRIES  32
+
+/* grow a handle table */
+/* return 1 if OK, 0 on error */
+static int grow_handle_table( struct handle_table *table )
+{
+    struct handle_entry *new_entries;
+    int count = table->count;
+
+    if (count >= INT_MAX / 2) return 0;
+    count *= 2;
+    if (!(new_entries = realloc( table->entries, count * sizeof(struct handle_entry) )))
+    {
+        SET_ERROR( ERROR_OUTOFMEMORY );
+        return 0;
+    }
+    table->count   = count;
+    table->entries = new_entries;
+    return 1;
+}
+
+/* allocate a handle for an object, incrementing its refcount */
+/* return the handle, or -1 on error */
+int alloc_handle( struct process *process, void *obj, unsigned int access,
+                  int inherit )
+{
+    struct handle_table *table = get_process_handles( process );
+    struct handle_entry *entry;
+    int handle;
+
+    assert( !(access & RESERVED_ALL) );
+    if (inherit) access |= RESERVED_INHERIT;
+
+    /* find the first free entry */
+
+    if (!(entry = table->entries)) return -1;
+    for (handle = 0; handle <= table->last; handle++, entry++)
+        if (!entry->ptr) goto found;
+
+    if (handle >= table->count)
+    {
+        if (!grow_handle_table( table )) return -1;
+        entry = table->entries + handle;  /* the table may have moved */
+    }
+    table->last = handle;
+
+ found:
+    entry->ptr    = grab_object( obj );
+    entry->access = access;
+    return handle + 1;  /* avoid handle 0 */
+}
+
+/* return an handle entry, or NULL if the handle is invalid */
+static struct handle_entry *get_handle( struct process *process, int handle )
+{
+    struct handle_table *table;
+    struct handle_entry *entry;
+
+    if (HANDLE_IS_GLOBAL(handle))
+    {
+        handle = HANDLE_GLOBAL_TO_LOCAL(handle);
+        process = initial_process;
+    }
+    table = get_process_handles( process );
+    handle--;  /* handles start at 1 */
+    if ((handle < 0) || (handle > table->last)) goto error;
+    entry = table->entries + handle;
+    if (!entry->ptr) goto error;
+    return entry;
+
+ error:
+    SET_ERROR( ERROR_INVALID_HANDLE );
+    return NULL;
+}
+
+/* attempt to shrink a table */
+/* return 1 if OK, 0 on error */
+static int shrink_handle_table( struct handle_table *table )
+{
+    struct handle_entry *new_entries;
+    struct handle_entry *entry = table->entries + table->last;
+    int count = table->count;
+
+    while (table->last >= 0)
+    {
+        if (entry->ptr) break;
+        table->last--;
+        entry--;
+    }
+    if (table->last >= count / 4) return 1;  /* no need to shrink */
+    if (count < MIN_HANDLE_ENTRIES * 2) return 1;  /* too small to shrink */
+    count /= 2;
+    if (!(new_entries = realloc( table->entries,
+                                 count * sizeof(struct handle_entry) )))
+        return 0;
+    table->count   = count;
+    table->entries = new_entries;
+    return 1;
+}
+
+/* copy the handle table of the parent process */
+/* return 1 if OK, 0 on error */
+int copy_handle_table( struct process *process, struct process *parent )
+{
+    struct handle_table *parent_table;
+    struct handle_table *table = get_process_handles( process );
+    struct handle_entry *ptr;
+    int i, count, last;
+
+    if (!parent)  /* first process */
+    {
+        if (!initial_process) initial_process = process;
+        parent_table = NULL;
+        count = MIN_HANDLE_ENTRIES;
+        last  = -1;
+    }
+    else
+    {
+        parent_table = get_process_handles( parent );
+        assert( parent_table->entries );
+        count = parent_table->count;
+        last  = parent_table->last;
+    }
+
+    if (!(ptr = mem_alloc( count * sizeof(struct handle_entry)))) return 0;
+    table->entries = ptr;
+    table->count   = count;
+    table->last    = last;
+
+    if (last >= 0)
+    {
+        memcpy( ptr, parent_table->entries, (last + 1) * sizeof(struct handle_entry) );
+        for (i = 0; i <= last; i++, ptr++)
+        {
+            if (!ptr->ptr) continue;
+            if (ptr->access & RESERVED_INHERIT) grab_object( ptr->ptr );
+            else ptr->ptr = NULL; /* don't inherit this entry */
+        }
+    }
+    /* attempt to shrink the table */
+    shrink_handle_table( table );
+    return 1;
+}
+
+/* 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 )
+{
+    struct handle_table *table;
+    struct handle_entry *entry;
+    struct object *obj;
+
+    if (HANDLE_IS_GLOBAL(handle))
+    {
+        handle = HANDLE_GLOBAL_TO_LOCAL(handle);
+        process = initial_process;
+    }
+    table = get_process_handles( process );
+    if (!(entry = get_handle( process, handle ))) return 0;
+    if (entry->access & RESERVED_CLOSE_PROTECT) return 0;  /* FIXME: error code */
+    obj = entry->ptr;
+    entry->ptr = NULL;
+    if (handle-1 == table->last) shrink_handle_table( table );
+    release_object( obj );
+    return 1;
+}
+
+/* retrieve the object corresponding to a handle, incrementing its refcount */
+struct object *get_handle_obj( struct process *process, int handle,
+                               unsigned int access, const struct object_ops *ops )
+{
+    struct handle_entry *entry;
+    struct object *obj;
+
+    switch( handle )
+    {
+    case 0xfffffffe:  /* current thread pseudo-handle */
+        obj = &current->obj;
+        break;
+    case 0x7fffffff:  /* current process pseudo-handle */
+        obj = (struct object *)current->process;
+        break;
+    default:
+        if (!(entry = get_handle( process, handle ))) return NULL;
+        if ((entry->access & access) != access)
+        {
+            SET_ERROR( ERROR_ACCESS_DENIED );
+            return NULL;
+        }
+        obj = entry->ptr;
+        break;
+    }
+    if (ops && (obj->ops != ops))
+    {
+        SET_ERROR( ERROR_INVALID_HANDLE );  /* not the right type */
+        return NULL;
+    }
+    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 )
+{
+    struct handle_entry *entry;
+
+    if (!(entry = get_handle( process, handle ))) return -1;
+    mask  = (mask << RESERVED_SHIFT) & RESERVED_ALL;
+    flags = (flags << RESERVED_SHIFT) & mask;
+    entry->access = (entry->access & ~mask) | flags;
+    return (entry->access & RESERVED_ALL) >> RESERVED_SHIFT;
+}
+
+/* duplicate a handle */
+int duplicate_handle( struct process *src, int src_handle, struct process *dst,
+                      unsigned int access, int inherit, int options )
+{
+    int res;
+    struct handle_entry *entry = get_handle( src, src_handle );
+    if (!entry) return -1;
+
+    if (options & DUP_HANDLE_SAME_ACCESS) access = entry->access;
+    if (options & DUP_HANDLE_MAKE_GLOBAL) dst = initial_process;
+    access &= ~RESERVED_ALL;
+    res = alloc_handle( dst, entry->ptr, access, inherit );
+    if (options & DUP_HANDLE_MAKE_GLOBAL) res = HANDLE_LOCAL_TO_GLOBAL(res);
+    return res;
+}
+
+/* free the process handle entries */
+void free_handles( struct process *process )
+{
+    struct handle_table *table = get_process_handles( process );
+    struct handle_entry *entry;
+    int handle;
+
+    if (!(entry = table->entries)) return;
+    for (handle = 0; handle <= table->last; handle++, entry++)
+    {
+        struct object *obj = entry->ptr;
+        entry->ptr = NULL;
+        if (obj) release_object( obj );
+    }
+    free( table->entries );
+    table->count   = 0;
+    table->last    = -1;
+    table->entries = NULL;
+}
+
+/* open a new handle to an existing object */
+int open_object( const char *name, const struct object_ops *ops,
+                 unsigned int access, int inherit )
+{
+    struct object *obj = find_object( name );
+    if (!obj) 
+    {
+        SET_ERROR( ERROR_FILE_NOT_FOUND );
+        return -1;
+    }
+    if (ops && obj->ops != ops)
+    {
+        release_object( obj );
+        SET_ERROR( ERROR_INVALID_HANDLE );  /* FIXME: not the right type */ 
+        return -1;
+    }
+    return alloc_handle( current->process, obj, access, inherit );
+}
+
+/* dump a handle table on stdout */
+void dump_handles( struct process *process )
+{
+    struct handle_table *table = get_process_handles( process );
+    struct handle_entry *entry;
+    int i;
+
+    if (!table->entries) return;
+    entry = table->entries;
+    for (i = 0; i <= table->last; i++, entry++)
+    {
+        if (!entry->ptr) continue;
+        printf( "%5d: %p %08x ", i + 1, entry->ptr, entry->access );
+        entry->ptr->ops->dump( entry->ptr, 0 );
+    }
+}
+
+/* close a handle */
+DECL_HANDLER(close_handle)
+{
+    close_handle( current->process, req->handle );
+    send_reply( current, -1, 0 );
+}
+
+/* get information about a handle */
+DECL_HANDLER(get_handle_info)
+{
+    struct get_handle_info_reply reply;
+    reply.flags = set_handle_info( current->process, req->handle, 0, 0 );
+    send_reply( current, -1, 1, &reply, sizeof(reply) );
+}
+
+/* set a handle information */
+DECL_HANDLER(set_handle_info)
+{
+    set_handle_info( current->process, req->handle, req->mask, req->flags );
+    send_reply( current, -1, 0 );
+}
+
+/* duplicate a handle */
+DECL_HANDLER(dup_handle)
+{
+    struct dup_handle_reply reply = { -1 };
+    struct process *src, *dst;
+
+    if ((src = get_process_from_handle( req->src_process, PROCESS_DUP_HANDLE )))
+    {
+        if (req->options & DUP_HANDLE_MAKE_GLOBAL)
+        {
+            reply.handle = duplicate_handle( src, req->src_handle, NULL,
+                                             req->access, req->inherit, req->options );
+        }
+        else if ((dst = get_process_from_handle( req->dst_process, PROCESS_DUP_HANDLE )))
+        {
+            reply.handle = duplicate_handle( src, req->src_handle, dst,
+                                             req->access, req->inherit, req->options );
+            release_object( dst );
+        }
+        /* close the handle no matter what happened */
+        if (req->options & DUP_HANDLE_CLOSE_SOURCE)
+            close_handle( src, req->src_handle );
+        release_object( src );
+    }
+    send_reply( current, -1, 1, &reply, sizeof(reply) );
+}
diff --git a/server/handle.h b/server/handle.h
new file mode 100644
index 0000000..cb991e8
--- /dev/null
+++ b/server/handle.h
@@ -0,0 +1,43 @@
+/*
+ * Server-side handle definitions
+ *
+ * Copyright (C) 1999 Alexandre Julliard
+ */
+
+#ifndef __WINE_SERVER_HANDLE_H
+#define __WINE_SERVER_HANDLE_H
+
+#ifndef __WINE_SERVER__
+#error This file can only be used in the Wine server
+#endif
+
+struct process;
+struct object_ops;
+struct handle_entry;
+
+/* handle structures */
+
+struct handle_table
+{
+    int count;
+    int last;
+    struct handle_entry *entries;
+};
+
+/* handle functions */
+
+/* alloc_handle takes a void *obj for convenience, but you better make sure */
+/* 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 struct object *get_handle_obj( struct process *process, int handle,
+                                      unsigned int access, const struct object_ops *ops );
+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 char *name, const struct object_ops *ops,
+                        unsigned int access, int inherit );
+extern int copy_handle_table( struct process *process, struct process *parent );
+extern void free_handles( struct process *process );
+
+#endif  /* __WINE_SERVER_HANDLE_H */
diff --git a/server/main.c b/server/main.c
index e7190c9..31cb488 100644
--- a/server/main.c
+++ b/server/main.c
@@ -11,8 +11,8 @@
 #include <unistd.h>
 
 #include "server.h"
-#include "server/object.h"
-#include "server/thread.h"
+#include "object.h"
+#include "thread.h"
 
 int main( int argc, char *argv[] )
 {
diff --git a/server/mapping.c b/server/mapping.c
index acacbb6..0609118 100644
--- a/server/mapping.c
+++ b/server/mapping.c
@@ -12,8 +12,10 @@
 #include "config.h"
 #include "winerror.h"
 #include "winnt.h"
-#include "server/process.h"
-#include "server/thread.h"
+#include "winbase.h"
+
+#include "handle.h"
+#include "thread.h"
 
 struct mapping
 {
@@ -79,8 +81,8 @@
    (((int)(size) + ((int)(addr) & page_mask) + page_mask) & ~page_mask)
 
 
-struct object *create_mapping( int size_high, int size_low, int protect,
-                               int handle, const char *name )
+static struct object *create_mapping( int size_high, int size_low, int protect,
+                                      int handle, const char *name )
 {
     struct mapping *mapping;
     int access = 0;
@@ -131,12 +133,7 @@
     return NULL;
 }
 
-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 )
+static int get_mapping_info( int handle, struct get_mapping_info_reply *reply )
 {
     struct mapping *mapping;
     int fd;
@@ -169,3 +166,43 @@
     if (mapping->file) release_object( mapping->file );
     free( mapping );
 }
+
+/* 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, req->inherit );
+        release_object( obj );
+    }
+    send_reply( current, -1, 1, &reply, sizeof(reply) );
+}
+
+/* open a handle to a mapping */
+DECL_HANDLER(open_mapping)
+{
+    struct open_mapping_reply reply;
+    char *name = (char *)data;
+    if (!len) name = NULL;
+    else CHECK_STRING( "open_mapping", name, len );
+
+    reply.handle = open_object( name, &mapping_ops, req->access, req->inherit );
+    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/mutex.c b/server/mutex.c
index 1127de2..2adaacb 100644
--- a/server/mutex.c
+++ b/server/mutex.c
@@ -10,8 +10,9 @@
 
 #include "winerror.h"
 #include "winnt.h"
-#include "server/process.h"
-#include "server/thread.h"
+
+#include "handle.h"
+#include "thread.h"
 
 struct mutex
 {
@@ -43,7 +44,7 @@
 };
 
 
-struct object *create_mutex( const char *name, int owned )
+static struct object *create_mutex( const char *name, int owned )
 {
     struct mutex *mutex;
 
@@ -61,11 +62,6 @@
     return &mutex->obj;
 }
 
-int open_mutex( unsigned int access, int inherit, const char *name )
-{
-    return open_object( name, &mutex_ops, access, inherit );
-}
-
 /* release a mutex once the recursion count is 0 */
 static void do_release( struct mutex *mutex, struct thread *thread )
 {
@@ -79,7 +75,7 @@
     wake_up( &mutex->obj, 0 );
 }
 
-int release_mutex( int handle )
+static int release_mutex( int handle )
 {
     struct mutex *mutex;
 
@@ -148,3 +144,40 @@
     assert( obj->ops == &mutex_ops );
     free( mutex );
 }
+
+/* create a mutex */
+DECL_HANDLER(create_mutex)
+{
+    struct create_mutex_reply reply = { -1 };
+    struct object *obj;
+    char *name = (char *)data;
+    if (!len) name = NULL;
+    else CHECK_STRING( "create_mutex", name, len );
+
+    obj = create_mutex( name, req->owned );
+    if (obj)
+    {
+        reply.handle = alloc_handle( current->process, obj, MUTEX_ALL_ACCESS, req->inherit );
+        release_object( obj );
+    }
+    send_reply( current, -1, 1, &reply, sizeof(reply) );
+}
+
+/* open a handle to a mutex */
+DECL_HANDLER(open_mutex)
+{
+    struct open_mutex_reply reply;
+    char *name = (char *)data;
+    if (!len) name = NULL;
+    else CHECK_STRING( "open_mutex", name, len );
+
+    reply.handle = open_object( name, &mutex_ops, req->access, req->inherit );
+    send_reply( current, -1, 1, &reply, sizeof(reply) );
+}
+
+/* release a mutex */
+DECL_HANDLER(release_mutex)
+{
+    if (release_mutex( req->handle )) CLEAR_ERROR();
+    send_reply( current, -1, 0 );
+}
diff --git a/server/object.c b/server/object.c
index 4a40ac5..b907af3 100644
--- a/server/object.c
+++ b/server/object.c
@@ -11,8 +11,7 @@
 #include <string.h>
 
 #include "winerror.h"
-#include "server.h"
-#include "server/thread.h"
+#include "thread.h"
 
 int debug_level = 0;
 
diff --git a/include/server/object.h b/server/object.h
similarity index 63%
rename from include/server/object.h
rename to server/object.h
index 933afe7..48c2799 100644
--- a/include/server/object.h
+++ b/server/object.h
@@ -81,6 +81,7 @@
 struct iovec;
 struct thread;
 
+extern void fatal_protocol_error( const char *err, ... );
 extern void call_req_handler( struct thread *thread, enum request req,
                               void *data, int len, int fd );
 extern void call_timeout_handler( struct thread *thread );
@@ -91,6 +92,11 @@
 extern void trace_kill( int exit_code );
 extern void trace_reply( struct thread *thread, int type, int pass_fd,
                          struct iovec *vec, int veclen );
+/* check that the string is NULL-terminated and that the len is correct */
+#define CHECK_STRING(func,str,len) \
+  do { if (((str)[(len)-1] || strlen(str) != (len)-1)) \
+         fatal_protocol_error( "%s: invalid string '%.*s'\n", (func), (len), (str) ); \
+     } while(0)
 
 /* select functions */
 
@@ -118,88 +124,22 @@
 extern int send_reply_v( int client_fd, int type, int pass_fd,
                          struct iovec *vec, int veclen );
 
-/* event functions */
-
-extern struct object *create_event( const char *name, int manual_reset, int initial_state );
-extern int open_event( unsigned int access, int inherit, const char *name );
-extern int pulse_event( int handle );
-extern int set_event( int handle );
-extern int reset_event( int handle );
-
-
 /* mutex functions */
 
-extern struct object *create_mutex( const char *name, int owned );
-extern int open_mutex( unsigned int access, int inherit, const char *name );
-extern int release_mutex( int handle );
 extern void abandon_mutexes( struct thread *thread );
 
-
-/* semaphore functions */
-
-extern struct object *create_semaphore( const char *name, unsigned int initial, unsigned int max );
-extern int open_semaphore( unsigned int access, int inherit, const char *name );
-extern int release_semaphore( int handle, unsigned int count, unsigned int *prev_count );
-
-
 /* file functions */
 
-extern struct object *create_file( int fd, const char *name, unsigned int access,
-                                   unsigned int sharing, int create, unsigned int attrs );
 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 grow_file( struct file *file, int size_high, int size_low );
 extern struct file *create_temp_file( int access );
-extern int set_file_time( int handle, time_t access_time, time_t write_time );
-extern int file_lock( struct file *file, int offset_high, int offset_low,
-                      int count_high, int count_low );
-extern int file_unlock( struct file *file, int offset_high, int offset_low,
-                        int count_high, int count_low );
 extern void file_set_error(void);
 
-
-/* pipe functions */
-
-extern int create_pipe( struct object *obj[2] );
-
-
 /* console functions */
 
-struct tagINPUT_RECORD;
 extern int create_console( int fd, struct object *obj[2] );
-extern int set_console_fd( int handle, int fd, int pid );
-extern int get_console_mode( int handle, int *mode );
-extern int set_console_mode( int handle, int mode );
-extern int set_console_info( int handle, struct set_console_info_request *req,
-                             const char *title );
-extern int get_console_info( int handle, struct get_console_info_reply *reply,
-                             const char **title );
-extern int write_console_input( int handle, int count, struct tagINPUT_RECORD *records );
-extern int read_console_input( int handle, int count, int flush );
-
-
-/* change notification functions */
-
-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 );
-
-
-/* device functions */
-extern struct object *create_device( int id );
-
-
-/* snapshot functions */
-extern struct object *create_snapshot( int flags );
-extern int snapshot_next_process( int handle, int reset, struct next_process_reply *reply );
 
 extern int debug_level;
 
diff --git a/server/pipe.c b/server/pipe.c
index 06260f9..575f6f2 100644
--- a/server/pipe.c
+++ b/server/pipe.c
@@ -18,7 +18,9 @@
 
 #include "winerror.h"
 #include "winbase.h"
-#include "server/thread.h"
+
+#include "handle.h"
+#include "thread.h"
 
 enum side { READ_SIDE, WRITE_SIDE };
 
@@ -59,7 +61,7 @@
     NULL   /* we never set a timeout on a pipe */
 };
 
-int create_pipe( struct object *obj[2] )
+static int create_pipe( struct object *obj[2] )
 {
     struct pipe *newpipe[2];
     int fd[2];
@@ -200,3 +202,27 @@
     close( pipe->fd );
     free( pipe );
 }
+
+/* create an anonymous pipe */
+DECL_HANDLER(create_pipe)
+{
+    struct create_pipe_reply reply = { -1, -1 };
+    struct object *obj[2];
+    if (create_pipe( obj ))
+    {
+        reply.handle_read = alloc_handle( current->process, obj[0],
+                                          STANDARD_RIGHTS_REQUIRED|SYNCHRONIZE|GENERIC_READ,
+                                          req->inherit );
+        if (reply.handle_read != -1)
+        {
+            reply.handle_write = alloc_handle( current->process, obj[1],
+                                               STANDARD_RIGHTS_REQUIRED|SYNCHRONIZE|GENERIC_WRITE,
+                                               req->inherit );
+            if (reply.handle_write == -1)
+                close_handle( current->process, reply.handle_read );
+        }
+        release_object( obj[0] );
+        release_object( obj[1] );
+    }
+    send_reply( current, -1, 1, &reply, sizeof(reply) );
+}
diff --git a/server/process.c b/server/process.c
index 61273f0..6d435aa 100644
--- a/server/process.c
+++ b/server/process.c
@@ -17,37 +17,19 @@
 #include "winnt.h"
 
 #include "server.h"
-#include "server/process.h"
-#include "server/thread.h"
-
-/* reserved handle access rights */
-#define RESERVED_SHIFT         25
-#define RESERVED_INHERIT       (HANDLE_FLAG_INHERIT << RESERVED_SHIFT)
-#define RESERVED_CLOSE_PROTECT (HANDLE_FLAG_PROTECT_FROM_CLOSE << RESERVED_SHIFT)
-#define RESERVED_ALL           (RESERVED_INHERIT | RESERVED_CLOSE_PROTECT)
-
-/* global handle macros */
-#define HANDLE_OBFUSCATOR         0x544a4def
-#define HANDLE_IS_GLOBAL(h)       (((h) ^ HANDLE_OBFUSCATOR) < 0x10000)
-#define HANDLE_LOCAL_TO_GLOBAL(h) ((h) ^ HANDLE_OBFUSCATOR)
-#define HANDLE_GLOBAL_TO_LOCAL(h) ((h) ^ HANDLE_OBFUSCATOR)
-
-struct handle_entry
-{
-    struct object *ptr;
-    unsigned int   access;
-};
+#include "handle.h"
+#include "process.h"
+#include "thread.h"
 
 /* process structure */
+
 struct process
 {
     struct object        obj;             /* object header */
     struct process      *next;            /* system-wide process list */
     struct process      *prev;
     struct thread       *thread_list;     /* head of the thread list */
-    struct handle_entry *entries;         /* handle entry table */
-    int                  handle_count;    /* nb of allocated handle entries */
-    int                  handle_last;     /* last used handle entry */
+    struct handle_table  handles;         /* handle table */
     int                  exit_code;       /* process exit code */
     int                  running_threads; /* number of threads running in this process */
     struct timeval       start_time;      /* absolute time at process start */
@@ -59,20 +41,15 @@
     struct new_process_request *info;     /* startup info (freed after startup) */
 };
 
-
 static struct process initial_process;
 static struct process *first_process = &initial_process;
 static int running_processes;
 
-#define MIN_HANDLE_ENTRIES  32
-
 /* process operations */
 
 static void process_dump( struct object *obj, int verbose );
 static int process_signaled( struct object *obj, struct thread *thread );
 static void process_destroy( struct object *obj );
-static void free_handles( struct process *process );
-static int copy_handle_table( struct process *process, struct process *parent );
 
 static const struct object_ops process_ops =
 {
@@ -133,7 +110,7 @@
 }
 
 /* create a new process */
-struct process *create_process( struct new_process_request *req )
+static struct process *create_process( struct new_process_request *req )
 {
     struct process *process = NULL;
     struct process *parent = current->process;
@@ -223,8 +200,14 @@
                                              access, &process_ops );
 }
 
+/* get a pointer to the process handle table */
+struct handle_table *get_process_handles( struct process *process )
+{
+    return &process->handles;
+}
+
 /* retrieve the initialization info for a new process */
-int get_process_init_info( struct process *process, struct init_process_reply *reply )
+static int get_process_init_info( struct process *process, struct init_process_reply *reply )
 {
     struct new_process_request *info;
     if (!(info = process->info)) return 0;
@@ -248,25 +231,6 @@
     free_handles( process );
 }
 
-/* free the process handle entries */
-static void free_handles( struct process *process )
-{
-    struct handle_entry *entry;
-    int handle;
-
-    if (!(entry = process->entries)) return;
-    for (handle = 0; handle <= process->handle_last; handle++, entry++)
-    {
-        struct object *obj = entry->ptr;
-        entry->ptr = NULL;
-        if (obj) release_object( obj );
-    }
-    free( process->entries );
-    process->handle_count = 0;
-    process->handle_last  = -1;
-    process->entries = NULL;
-}
-
 /* add a thread to a process running threads list */
 void add_process_thread( struct process *process, struct thread *thread )
 {
@@ -297,268 +261,16 @@
     release_object( thread );
 }
 
-/* grow a handle table */
-/* return 1 if OK, 0 on error */
-static int grow_handle_table( struct process *process )
-{
-    struct handle_entry *new_entries;
-    int count = process->handle_count;
-
-    if (count >= INT_MAX / 2) return 0;
-    count *= 2;
-    if (!(new_entries = realloc( process->entries, count * sizeof(struct handle_entry) )))
-    {
-        SET_ERROR( ERROR_OUTOFMEMORY );
-        return 0;
-    }
-    process->handle_count = count;
-    process->entries      = new_entries;
-    return 1;
-}
-
-/* allocate a handle for an object, incrementing its refcount */
-/* return the handle, or -1 on error */
-int alloc_handle( struct process *process, void *obj, unsigned int access,
-                  int inherit )
-{
-    struct handle_entry *entry;
-    int handle;
-
-    assert( !(access & RESERVED_ALL) );
-    if (inherit) access |= RESERVED_INHERIT;
-
-    /* find the first free entry */
-
-    if (!(entry = process->entries)) return -1;
-    for (handle = 0; handle <= process->handle_last; handle++, entry++)
-        if (!entry->ptr) goto found;
-
-    if (handle >= process->handle_count)
-    {
-        if (!grow_handle_table( process )) return -1;
-        entry = process->entries + handle;  /* the table may have moved */
-    }
-    process->handle_last = handle;
-
- found:
-    entry->ptr    = grab_object( obj );
-    entry->access = access;
-    return handle + 1;  /* avoid handle 0 */
-}
-
-/* return an handle entry, or NULL if the handle is invalid */
-static struct handle_entry *get_handle( struct process *process, int handle )
-{
-    struct handle_entry *entry;
-
-    if (HANDLE_IS_GLOBAL(handle))
-    {
-        handle = HANDLE_GLOBAL_TO_LOCAL(handle);
-        process = &initial_process;
-    }
-    handle--;  /* handles start at 1 */
-    if ((handle < 0) || (handle > process->handle_last)) goto error;
-    entry = process->entries + handle;
-    if (!entry->ptr) goto error;
-    return entry;
-
- error:
-    SET_ERROR( ERROR_INVALID_HANDLE );
-    return NULL;
-}
-
-/* attempt to shrink a table */
-/* return 1 if OK, 0 on error */
-static int shrink_handle_table( struct process *process )
-{
-    struct handle_entry *new_entries;
-    struct handle_entry *entry = process->entries + process->handle_last;
-    int count = process->handle_count;
-
-    while (process->handle_last >= 0)
-    {
-        if (entry->ptr) break;
-        process->handle_last--;
-        entry--;
-    }
-    if (process->handle_last >= count / 4) return 1;  /* no need to shrink */
-    if (count < MIN_HANDLE_ENTRIES * 2) return 1;  /* too small to shrink */
-    count /= 2;
-    if (!(new_entries = realloc( process->entries,
-                                 count * sizeof(struct handle_entry) )))
-        return 0;
-    process->handle_count = count;
-    process->entries      = new_entries;
-    return 1;
-}
-
-/* copy the handle table of the parent process */
-/* return 1 if OK, 0 on error */
-static int copy_handle_table( struct process *process, struct process *parent )
-{
-    struct handle_entry *ptr;
-    int i, count, last;
-
-    if (!parent)  /* first process */
-    {
-        count = MIN_HANDLE_ENTRIES;
-        last  = -1;
-    }
-    else
-    {
-        assert( parent->entries );
-        count = parent->handle_count;
-        last  = parent->handle_last;
-    }
-
-    if (!(ptr = mem_alloc( count * sizeof(struct handle_entry)))) return 0;
-    process->entries      = ptr;
-    process->handle_count = count;
-    process->handle_last  = last;
-
-    if (last >= 0)
-    {
-        memcpy( ptr, parent->entries, (last + 1) * sizeof(struct handle_entry) );
-        for (i = 0; i <= last; i++, ptr++)
-        {
-            if (!ptr->ptr) continue;
-            if (ptr->access & RESERVED_INHERIT) grab_object( ptr->ptr );
-            else ptr->ptr = NULL; /* don't inherit this entry */
-        }
-    }
-    /* attempt to shrink the table */
-    shrink_handle_table( process );
-    return 1;
-}
-
-/* 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 )
-{
-    struct handle_entry *entry;
-    struct object *obj;
-
-    if (HANDLE_IS_GLOBAL(handle))
-    {
-        handle = HANDLE_GLOBAL_TO_LOCAL(handle);
-        process = &initial_process;
-    }
-    if (!(entry = get_handle( process, handle ))) return 0;
-    if (entry->access & RESERVED_CLOSE_PROTECT) return 0;  /* FIXME: error code */
-    obj = entry->ptr;
-    entry->ptr = NULL;
-    if (handle-1 == process->handle_last) shrink_handle_table( process );
-    release_object( obj );
-    return 1;
-}
-
-/* retrieve the object corresponding to a handle, incrementing its refcount */
-struct object *get_handle_obj( struct process *process, int handle,
-                               unsigned int access, const struct object_ops *ops )
-{
-    struct handle_entry *entry;
-    struct object *obj;
-
-    switch( handle )
-    {
-    case 0xfffffffe:  /* current thread pseudo-handle */
-        obj = &current->obj;
-        break;
-    case 0x7fffffff:  /* current process pseudo-handle */
-        obj = (struct object *)current->process;
-        break;
-    default:
-        if (!(entry = get_handle( process, handle ))) return NULL;
-        if ((entry->access & access) != access)
-        {
-            SET_ERROR( ERROR_ACCESS_DENIED );
-            return NULL;
-        }
-        obj = entry->ptr;
-        break;
-    }
-    if (ops && (obj->ops != ops))
-    {
-        SET_ERROR( ERROR_INVALID_HANDLE );  /* not the right type */
-        return NULL;
-    }
-    return grab_object( obj );
-}
-
-/* get/set the handle reserved flags */
-/* return the new flags (or -1 on error) */
-int set_handle_info( struct process *process, int handle, int mask, int flags )
-{
-    struct handle_entry *entry;
-
-    if (!(entry = get_handle( process, handle ))) return -1;
-    mask  = (mask << RESERVED_SHIFT) & RESERVED_ALL;
-    flags = (flags << RESERVED_SHIFT) & mask;
-    entry->access = (entry->access & ~mask) | flags;
-    return (entry->access & RESERVED_ALL) >> RESERVED_SHIFT;
-}
-
-/* duplicate a handle */
-int duplicate_handle( struct process *src, int src_handle, struct process *dst,
-                      unsigned int access, int inherit, int options )
-{
-    int res;
-    struct handle_entry *entry = get_handle( src, src_handle );
-    if (!entry) return -1;
-
-    if (options & DUP_HANDLE_SAME_ACCESS) access = entry->access;
-    if (options & DUP_HANDLE_MAKE_GLOBAL) dst = &initial_process;
-    access &= ~RESERVED_ALL;
-    res = alloc_handle( dst, entry->ptr, access, inherit );
-    if (options & DUP_HANDLE_MAKE_GLOBAL) res = HANDLE_LOCAL_TO_GLOBAL(res);
-    return res;
-}
-
-/* open a new handle to an existing object */
-int open_object( const char *name, const struct object_ops *ops,
-                 unsigned int access, int inherit )
-{
-    struct object *obj = find_object( name );
-    if (!obj) 
-    {
-        SET_ERROR( ERROR_FILE_NOT_FOUND );
-        return -1;
-    }
-    if (ops && obj->ops != ops)
-    {
-        release_object( obj );
-        SET_ERROR( ERROR_INVALID_HANDLE );  /* FIXME: not the right type */ 
-        return -1;
-    }
-    return alloc_handle( current->process, obj, access, inherit );
-}
-
-/* dump a handle table on stdout */
-void dump_handles( struct process *process )
-{
-    struct handle_entry *entry;
-    int i;
-
-    if (!process->entries) return;
-    entry = process->entries;
-    for (i = 0; i <= process->handle_last; i++, entry++)
-    {
-        if (!entry->ptr) continue;
-        printf( "%5d: %p %08x ", i + 1, entry->ptr, entry->access );
-        entry->ptr->ops->dump( entry->ptr, 0 );
-    }
-}
-
 /* kill a process on the spot */
-void kill_process( struct process *process, int exit_code )
+static void kill_process( struct process *process, int exit_code )
 {
     while (process->thread_list)
         kill_thread( process->thread_list, exit_code );
 }
 
 /* get all information about a process */
-void get_process_info( struct process *process,
-                       struct get_process_info_reply *reply )
+static void get_process_info( struct process *process,
+                              struct get_process_info_reply *reply )
 {
     reply->pid              = process;
     reply->exit_code        = process->exit_code;
@@ -568,8 +280,8 @@
 }
 
 /* set all information about a process */
-void set_process_info( struct process *process,
-                       struct set_process_info_request *req )
+static void set_process_info( struct process *process,
+                              struct set_process_info_request *req )
 {
     if (req->mask & SET_PROCESS_INFO_PRIORITY)
         process->priority = req->priority;
@@ -634,3 +346,95 @@
     *count = running_processes;
     return snapshot;
 }
+
+/* create a new process */
+DECL_HANDLER(new_process)
+{
+    struct new_process_reply reply;
+    struct process *process;
+
+    if ((process = create_process( req )))
+    {
+        reply.pid    = process;
+        reply.handle = alloc_handle( current->process, process,
+                                     PROCESS_ALL_ACCESS, req->inherit );
+        release_object( process );
+    }
+    else
+    {
+        reply.handle = -1;
+        reply.pid    = NULL;
+    }
+    send_reply( current, -1, 1, &reply, sizeof(reply) );
+}
+
+/* initialize a new process */
+DECL_HANDLER(init_process)
+{
+    struct init_process_reply reply;
+    if (current->state != RUNNING)
+    {
+        fatal_protocol_error( "init_process: init_thread not called yet\n" );
+        return;
+    }
+    if (!get_process_init_info( current->process, &reply ))
+    {
+        fatal_protocol_error( "init_process: called twice\n" );
+        return;
+    }
+    send_reply( current, -1, 1, &reply, sizeof(reply) );
+}
+
+/* open a handle to a process */
+DECL_HANDLER(open_process)
+{
+    struct open_process_reply reply = { -1 };
+    struct process *process = get_process_from_id( req->pid );
+    if (process)
+    {
+        reply.handle = alloc_handle( current->process, process,
+                                     req->access, req->inherit );
+        release_object( process );
+    }
+    send_reply( current, -1, 1, &reply, sizeof(reply) );
+}
+
+/* terminate a process */
+DECL_HANDLER(terminate_process)
+{
+    struct process *process;
+
+    if ((process = get_process_from_handle( req->handle, PROCESS_TERMINATE )))
+    {
+        kill_process( process, req->exit_code );
+        release_object( process );
+    }
+    if (current) send_reply( current, -1, 0 );
+}
+
+/* fetch information about a process */
+DECL_HANDLER(get_process_info)
+{
+    struct process *process;
+    struct get_process_info_reply reply = { 0, 0, 0 };
+
+    if ((process = get_process_from_handle( req->handle, PROCESS_QUERY_INFORMATION )))
+    {
+        get_process_info( process, &reply );
+        release_object( process );
+    }
+    send_reply( current, -1, 1, &reply, sizeof(reply) );
+}
+
+/* set information about a process */
+DECL_HANDLER(set_process_info)
+{
+    struct process *process;
+
+    if ((process = get_process_from_handle( req->handle, PROCESS_SET_INFORMATION )))
+    {
+        set_process_info( process, req );
+        release_object( process );
+    }
+    send_reply( current, -1, 0 );
+}
diff --git a/server/process.h b/server/process.h
new file mode 100644
index 0000000..3414443
--- /dev/null
+++ b/server/process.h
@@ -0,0 +1,44 @@
+/*
+ * Wine server processes
+ *
+ * Copyright (C) 1999 Alexandre Julliard
+ */
+
+#ifndef __WINE_SERVER_PROCESS_H
+#define __WINE_SERVER_PROCESS_H
+
+#ifndef __WINE_SERVER__
+#error This file can only be used in the Wine server
+#endif
+
+#include "object.h"
+
+/* process structures */
+
+struct process;
+struct handle_table;
+
+struct process_snapshot
+{
+    struct process *process;  /* process ptr */
+    struct process *parent;   /* process parent */
+    int             threads;  /* number of threads */
+    int             priority; /* priority class */
+};
+
+/* process functions */
+
+extern struct process *create_initial_process(void);
+extern struct process *get_process_from_id( void *id );
+extern struct process *get_process_from_handle( int handle, unsigned int access );
+extern struct handle_table *get_process_handles( struct process *process );
+extern void add_process_thread( struct process *process,
+                                struct thread *thread );
+extern void remove_process_thread( struct process *process,
+                                   struct thread *thread );
+extern int alloc_console( struct process *process );
+extern int free_console( struct process *process );
+extern struct object *get_console( struct process *process, int output );
+extern struct process_snapshot *process_snap( int *count );
+
+#endif  /* __WINE_SERVER_PROCESS_H */
diff --git a/server/request.c b/server/request.c
index 49b9f5a..cb99777 100644
--- a/server/request.c
+++ b/server/request.c
@@ -20,20 +20,12 @@
 #include "wincon.h"
 #define WANT_REQUEST_HANDLERS
 #include "server.h"
-#include "server/request.h"
-#include "server/process.h"
-#include "server/thread.h"
-
-/* check that the string is NULL-terminated and that the len is correct */
-#define CHECK_STRING(func,str,len) \
-  do { if (((str)[(len)-1] || strlen(str) != (len)-1)) \
-         fatal_protocol_error( "%s: invalid string '%.*s'\n", (func), (len), (str) ); \
-     } while(0)
+#include "thread.h"
  
 struct thread *current = NULL;  /* thread handling the current request */
 
 /* complain about a protocol error and terminate the client connection */
-static void fatal_protocol_error( const char *err, ... )
+void fatal_protocol_error( const char *err, ... )
 {
     va_list args;
 
@@ -60,7 +52,7 @@
 
     if (len < handler->min_size)
     {
-        fatal_protocol_error( "req %d bad length %d < %d)\n", req, len, handler->min_size );
+        fatal_protocol_error( "req %d bad length %d < %d\n", req, len, handler->min_size );
         return;
     }
 
@@ -100,82 +92,6 @@
     current = (old_current != thread) ? old_current : NULL;
 }
 
-
-/* create a new process */
-DECL_HANDLER(new_process)
-{
-    struct new_process_reply reply;
-    struct process *process;
-
-    if ((process = create_process( req )))
-    {
-        reply.pid    = process;
-        reply.handle = alloc_handle( current->process, process,
-                                     PROCESS_ALL_ACCESS, req->inherit );
-        release_object( process );
-    }
-    else
-    {
-        reply.handle = -1;
-        reply.pid    = NULL;
-    }
-    send_reply( current, -1, 1, &reply, sizeof(reply) );
-}
-
-/* create a new thread */
-DECL_HANDLER(new_thread)
-{
-    struct new_thread_reply reply;
-    int new_fd;
-
-    if ((new_fd = dup(fd)) != -1)
-    {
-        reply.tid = create_thread( new_fd, req->pid, req->suspend,
-                                   req->inherit, &reply.handle );
-        if (!reply.tid) close( new_fd );
-    }
-    else
-        SET_ERROR( ERROR_TOO_MANY_OPEN_FILES );
-
-    send_reply( current, -1, 1, &reply, sizeof(reply) );
-}
-
-/* initialize a new process */
-DECL_HANDLER(init_process)
-{
-    struct init_process_reply reply;
-    if (current->state != RUNNING)
-    {
-        fatal_protocol_error( "init_process: init_thread not called yet\n" );
-        return;
-    }
-    if (!get_process_init_info( current->process, &reply ))
-    {
-        fatal_protocol_error( "init_process: called twice\n" );
-        return;
-    }
-    send_reply( current, -1, 1, &reply, sizeof(reply) );
-}
-
-/* initialize a new thread */
-DECL_HANDLER(init_thread)
-{
-    struct init_thread_reply reply;
-
-    if (current->state != STARTING)
-    {
-        fatal_protocol_error( "init_thread: already running\n" );
-        return;
-    }
-    current->state    = RUNNING;
-    current->unix_pid = req->unix_pid;
-    if (current->suspend > 0)
-        kill( current->unix_pid, SIGSTOP );
-    reply.pid = current->process;
-    reply.tid = current;
-    send_reply( current, -1, 1, &reply, sizeof(reply) );
-}
-
 /* set the debug level */
 DECL_HANDLER(set_debug)
 {
@@ -186,135 +102,6 @@
     send_reply( current, -1, 0 );
 }
 
-/* terminate a process */
-DECL_HANDLER(terminate_process)
-{
-    struct process *process;
-
-    if ((process = get_process_from_handle( req->handle, PROCESS_TERMINATE )))
-    {
-        kill_process( process, req->exit_code );
-        release_object( process );
-    }
-    if (current) send_reply( current, -1, 0 );
-}
-
-/* terminate a thread */
-DECL_HANDLER(terminate_thread)
-{
-    struct thread *thread;
-
-    if ((thread = get_thread_from_handle( req->handle, THREAD_TERMINATE )))
-    {
-        kill_thread( thread, req->exit_code );
-        release_object( thread );
-    }
-    if (current) send_reply( current, -1, 0 );
-}
-
-/* close a handle */
-DECL_HANDLER(close_handle)
-{
-    close_handle( current->process, req->handle );
-    send_reply( current, -1, 0 );
-}
-
-/* get information about a handle */
-DECL_HANDLER(get_handle_info)
-{
-    struct get_handle_info_reply reply;
-    reply.flags = set_handle_info( current->process, req->handle, 0, 0 );
-    send_reply( current, -1, 1, &reply, sizeof(reply) );
-}
-
-/* set a handle information */
-DECL_HANDLER(set_handle_info)
-{
-    set_handle_info( current->process, req->handle, req->mask, req->flags );
-    send_reply( current, -1, 0 );
-}
-
-/* duplicate a handle */
-DECL_HANDLER(dup_handle)
-{
-    struct dup_handle_reply reply = { -1 };
-    struct process *src, *dst;
-
-    if ((src = get_process_from_handle( req->src_process, PROCESS_DUP_HANDLE )))
-    {
-        if (req->options & DUP_HANDLE_MAKE_GLOBAL)
-        {
-            reply.handle = duplicate_handle( src, req->src_handle, NULL,
-                                             req->access, req->inherit, req->options );
-        }
-        else if ((dst = get_process_from_handle( req->dst_process, PROCESS_DUP_HANDLE )))
-        {
-            reply.handle = duplicate_handle( src, req->src_handle, dst,
-                                             req->access, req->inherit, req->options );
-            release_object( dst );
-        }
-        /* close the handle no matter what happened */
-        if (req->options & DUP_HANDLE_CLOSE_SOURCE)
-            close_handle( src, req->src_handle );
-        release_object( src );
-    }
-    send_reply( current, -1, 1, &reply, sizeof(reply) );
-}
-
-/* fetch information about a process */
-DECL_HANDLER(get_process_info)
-{
-    struct process *process;
-    struct get_process_info_reply reply = { 0, 0, 0 };
-
-    if ((process = get_process_from_handle( req->handle, PROCESS_QUERY_INFORMATION )))
-    {
-        get_process_info( process, &reply );
-        release_object( process );
-    }
-    send_reply( current, -1, 1, &reply, sizeof(reply) );
-}
-
-/* set information about a process */
-DECL_HANDLER(set_process_info)
-{
-    struct process *process;
-
-    if ((process = get_process_from_handle( req->handle, PROCESS_SET_INFORMATION )))
-    {
-        set_process_info( process, req );
-        release_object( process );
-    }
-    send_reply( current, -1, 0 );
-}
-
-/* fetch information about a thread */
-DECL_HANDLER(get_thread_info)
-{
-    struct thread *thread;
-    struct get_thread_info_reply reply = { 0, 0 };
-
-    if ((thread = get_thread_from_handle( req->handle, THREAD_QUERY_INFORMATION )))
-    {
-        get_thread_info( thread, &reply );
-        release_object( thread );
-    }
-    send_reply( current, -1, 1, &reply, sizeof(reply) );
-}
-
-/* set information about a thread */
-DECL_HANDLER(set_thread_info)
-{
-    struct thread *thread;
-
-    if ((thread = get_thread_from_handle( req->handle, THREAD_SET_INFORMATION )))
-    {
-        set_thread_info( thread, req );
-        release_object( thread );
-    }
-    send_reply( current, -1, 0 );
-}
-
 /* debugger support operations */
 DECL_HANDLER(debugger)
 {
@@ -331,505 +118,3 @@
 
     send_reply( current, -1, 0 );
 }
-
-/* suspend a thread */
-DECL_HANDLER(suspend_thread)
-{
-    struct thread *thread;
-    struct suspend_thread_reply reply = { -1 };
-    if ((thread = get_thread_from_handle( req->handle, THREAD_SUSPEND_RESUME )))
-    {
-        reply.count = suspend_thread( thread );
-        release_object( thread );
-    }
-    send_reply( current, -1, 1, &reply, sizeof(reply) );
-    
-}
-
-/* resume a thread */
-DECL_HANDLER(resume_thread)
-{
-    struct thread *thread;
-    struct resume_thread_reply reply = { -1 };
-    if ((thread = get_thread_from_handle( req->handle, THREAD_SUSPEND_RESUME )))
-    {
-        reply.count = resume_thread( thread );
-        release_object( thread );
-    }
-    send_reply( current, -1, 1, &reply, sizeof(reply) );
-    
-}
-
-/* queue an APC for a thread */
-DECL_HANDLER(queue_apc)
-{
-    struct thread *thread;
-    if ((thread = get_thread_from_handle( req->handle, THREAD_SET_CONTEXT )))
-    {
-        thread_queue_apc( thread, req->func, req->param );
-        release_object( thread );
-    }
-    send_reply( current, -1, 0 );
-}
-
-/* open a handle to a process */
-DECL_HANDLER(open_process)
-{
-    struct open_process_reply reply = { -1 };
-    struct process *process = get_process_from_id( req->pid );
-    if (process)
-    {
-        reply.handle = alloc_handle( current->process, process,
-                                     req->access, req->inherit );
-        release_object( process );
-    }
-    send_reply( current, -1, 1, &reply, sizeof(reply) );
-}
-
-/* select on a handle list */
-DECL_HANDLER(select)
-{
-    if (len != req->count * sizeof(int))
-        fatal_protocol_error( "select: bad length %d for %d handles\n",
-                              len, req->count );
-    sleep_on( current, req->count, (int *)data, req->flags, req->timeout );
-}
-
-/* create an event */
-DECL_HANDLER(create_event)
-{
-    struct create_event_reply reply = { -1 };
-    struct object *obj;
-    char *name = (char *)data;
-    if (!len) name = NULL;
-    else CHECK_STRING( "create_event", name, len );
-
-    obj = create_event( name, req->manual_reset, req->initial_state );
-    if (obj)
-    {
-        reply.handle = alloc_handle( current->process, obj, EVENT_ALL_ACCESS, req->inherit );
-        release_object( obj );
-    }
-    send_reply( current, -1, 1, &reply, sizeof(reply) );
-}
-
-/* do an event operation */
-DECL_HANDLER(event_op)
-{
-    switch(req->op)
-    {
-    case PULSE_EVENT:
-        pulse_event( req->handle );
-        break;
-    case SET_EVENT:
-        set_event( req->handle );
-        break;
-    case RESET_EVENT:
-        reset_event( req->handle );
-        break;
-    default:
-        fatal_protocol_error( "event_op: invalid operation %d\n", req->op );
-    }
-    send_reply( current, -1, 0 );
-}
-
-/* create a mutex */
-DECL_HANDLER(create_mutex)
-{
-    struct create_mutex_reply reply = { -1 };
-    struct object *obj;
-    char *name = (char *)data;
-    if (!len) name = NULL;
-    else CHECK_STRING( "create_mutex", name, len );
-
-    obj = create_mutex( name, req->owned );
-    if (obj)
-    {
-        reply.handle = alloc_handle( current->process, obj, MUTEX_ALL_ACCESS, req->inherit );
-        release_object( obj );
-    }
-    send_reply( current, -1, 1, &reply, sizeof(reply) );
-}
-
-/* release a mutex */
-DECL_HANDLER(release_mutex)
-{
-    if (release_mutex( req->handle )) CLEAR_ERROR();
-    send_reply( current, -1, 0 );
-}
-
-/* create a semaphore */
-DECL_HANDLER(create_semaphore)
-{
-    struct create_semaphore_reply reply = { -1 };
-    struct object *obj;
-    char *name = (char *)data;
-    if (!len) name = NULL;
-    else CHECK_STRING( "create_semaphore", name, len );
-
-    obj = create_semaphore( name, req->initial, req->max );
-    if (obj)
-    {
-        reply.handle = alloc_handle( current->process, obj, SEMAPHORE_ALL_ACCESS, req->inherit );
-        release_object( obj );
-    }
-    send_reply( current, -1, 1, &reply, sizeof(reply) );
-}
-
-/* release a semaphore */
-DECL_HANDLER(release_semaphore)
-{
-    struct release_semaphore_reply reply;
-    if (release_semaphore( req->handle, req->count, &reply.prev_count )) CLEAR_ERROR();
-    send_reply( current, -1, 1, &reply, sizeof(reply) );
-}
-
-/* open a handle to a named object (event, mutex, semaphore) */
-DECL_HANDLER(open_named_obj)
-{
-    struct open_named_obj_reply reply;
-    char *name = (char *)data;
-    if (!len) name = NULL;
-    else CHECK_STRING( "open_named_obj", name, len );
-
-    switch(req->type)
-    {
-    case OPEN_EVENT:
-        reply.handle = open_event( req->access, req->inherit, name );
-        break;
-    case OPEN_MUTEX:
-        reply.handle = open_mutex( req->access, req->inherit, name );
-        break;
-    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 );
-    }
-    send_reply( current, -1, 1, &reply, sizeof(reply) );
-}
-
-/* create a file */
-DECL_HANDLER(create_file)
-{
-    struct create_file_reply reply = { -1 };
-    struct object *obj;
-    char *name = (char *)data;
-    if (!len) name = NULL;
-    else CHECK_STRING( "create_file", name, len );
-
-    if ((obj = create_file( fd, name, req->access,
-                            req->sharing, req->create, req->attrs )) != NULL)
-    {
-        reply.handle = alloc_handle( current->process, obj, req->access, req->inherit );
-        release_object( obj );
-    }
-    send_reply( current, -1, 1, &reply, sizeof(reply) );
-}
-
-/* get a Unix fd to read from a file */
-DECL_HANDLER(get_read_fd)
-{
-    struct object *obj;
-    int read_fd;
-
-    if ((obj = get_handle_obj( current->process, req->handle, GENERIC_READ, NULL )))
-    {
-        read_fd = obj->ops->get_read_fd( obj );
-        release_object( obj );
-    }
-    else read_fd = -1;
-    send_reply( current, read_fd, 0 );
-}
-
-/* get a Unix fd to write to a file */
-DECL_HANDLER(get_write_fd)
-{
-    struct object *obj;
-    int write_fd;
-
-    if ((obj = get_handle_obj( current->process, req->handle, GENERIC_WRITE, NULL )))
-    {
-        write_fd = obj->ops->get_write_fd( obj );
-        release_object( obj );
-    }
-    else write_fd = -1;
-    send_reply( current, write_fd, 0 );
-}
-
-/* set a file current position */
-DECL_HANDLER(set_file_pointer)
-{
-    struct set_file_pointer_reply reply;
-    reply.low = req->low;
-    reply.high = req->high;
-    set_file_pointer( req->handle, &reply.low, &reply.high, req->whence );
-    send_reply( current, -1, 1, &reply, sizeof(reply) );
-}
-
-/* truncate (or extend) a file */
-DECL_HANDLER(truncate_file)
-{
-    truncate_file( req->handle );
-    send_reply( current, -1, 0 );
-}
-
-/* flush a file buffers */
-DECL_HANDLER(flush_file)
-{
-    struct object *obj;
-
-    if ((obj = get_handle_obj( current->process, req->handle, GENERIC_WRITE, NULL )))
-    {
-        obj->ops->flush( obj );
-        release_object( obj );
-    }
-    send_reply( current, -1, 0 );
-}
-
-/* set a file access and modification times */
-DECL_HANDLER(set_file_time)
-{
-    set_file_time( req->handle, req->access_time, req->write_time );
-    send_reply( current, -1, 0 );
-}
-
-/* get a file information */
-DECL_HANDLER(get_file_info)
-{
-    struct object *obj;
-    struct get_file_info_reply reply;
-
-    if ((obj = get_handle_obj( current->process, req->handle, 0, NULL )))
-    {
-        obj->ops->get_file_info( obj, &reply );
-        release_object( obj );
-    }
-    send_reply( current, -1, 1, &reply, sizeof(reply) );
-}
-
-/* lock a region of a file */
-DECL_HANDLER(lock_file)
-{
-    struct file *file;
-
-    if ((file = get_file_obj( current->process, req->handle, 0 )))
-    {
-        file_lock( file, req->offset_high, req->offset_low,
-                   req->count_high, req->count_low );
-        release_object( file );
-    }
-    send_reply( current, -1, 0 );
-}
-
-
-/* unlock a region of a file */
-DECL_HANDLER(unlock_file)
-{
-    struct file *file;
-
-    if ((file = get_file_obj( current->process, req->handle, 0 )))
-    {
-        file_unlock( file, req->offset_high, req->offset_low,
-                     req->count_high, req->count_low );
-        release_object( file );
-    }
-    send_reply( current, -1, 0 );
-}
-
-
-/* create an anonymous pipe */
-DECL_HANDLER(create_pipe)
-{
-    struct create_pipe_reply reply = { -1, -1 };
-    struct object *obj[2];
-    if (create_pipe( obj ))
-    {
-        reply.handle_read = alloc_handle( current->process, obj[0],
-                                          STANDARD_RIGHTS_REQUIRED|SYNCHRONIZE|GENERIC_READ,
-                                          req->inherit );
-        if (reply.handle_read != -1)
-        {
-            reply.handle_write = alloc_handle( current->process, obj[1],
-                                               STANDARD_RIGHTS_REQUIRED|SYNCHRONIZE|GENERIC_WRITE,
-                                               req->inherit );
-            if (reply.handle_write == -1)
-                close_handle( current->process, reply.handle_read );
-        }
-        release_object( obj[0] );
-        release_object( obj[1] );
-    }
-    send_reply( current, -1, 1, &reply, sizeof(reply) );
-}
-
-/* allocate a console for the current process */
-DECL_HANDLER(alloc_console)
-{
-    alloc_console( current->process );
-    send_reply( current, -1, 0 );
-}
-
-/* free the console of the current process */
-DECL_HANDLER(free_console)
-{
-    free_console( current->process );
-    send_reply( current, -1, 0 );
-}
-
-/* open a handle to the process console */
-DECL_HANDLER(open_console)
-{
-    struct object *obj;
-    struct open_console_reply reply = { -1 };
-    if ((obj = get_console( current->process, req->output )))
-    {
-        reply.handle = alloc_handle( current->process, obj, req->access, req->inherit );
-        release_object( obj );
-    }
-    send_reply( current, -1, 1, &reply, sizeof(reply) );
-}
-
-/* set info about a console (output only) */
-DECL_HANDLER(set_console_info)
-{
-    char *name = (char *)data;
-    if (!len) name = NULL;
-    else CHECK_STRING( "set_console_info", name, len );
-    set_console_info( req->handle, req, name );
-    send_reply( current, -1, 0 );
-}
-
-/* get info about a console (output only) */
-DECL_HANDLER(get_console_info)
-{
-    struct get_console_info_reply reply;
-    const char *title;
-    get_console_info( req->handle, &reply, &title );
-    send_reply( current, -1, 2, &reply, sizeof(reply),
-                title, title ? strlen(title)+1 : 0 );
-}
-
-/* set a console fd */
-DECL_HANDLER(set_console_fd)
-{
-    set_console_fd( req->handle, fd, req->pid );
-    send_reply( current, -1, 0 );
-}
-
-/* get a console mode (input or output) */
-DECL_HANDLER(get_console_mode)
-{
-    struct get_console_mode_reply reply;
-    get_console_mode( req->handle, &reply.mode );
-    send_reply( current, -1, 1, &reply, sizeof(reply) );
-}
-
-/* set a console mode (input or output) */
-DECL_HANDLER(set_console_mode)
-{
-    set_console_mode( req->handle, req->mode );
-    send_reply( current, -1, 0 );
-}
-
-/* add input records to a console input queue */
-DECL_HANDLER(write_console_input)
-{
-    struct write_console_input_reply reply;
-    INPUT_RECORD *records = (INPUT_RECORD *)data;
-
-    if (len != req->count * sizeof(INPUT_RECORD))
-        fatal_protocol_error( "write_console_input: bad length %d for %d records\n",
-                              len, req->count );
-    reply.written = write_console_input( req->handle, req->count, records );
-    send_reply( current, -1, 1, &reply, sizeof(reply) );
-}
-
-/* fetch input records from a console input queue */
-DECL_HANDLER(read_console_input)
-{
-    read_console_input( req->handle, req->count, req->flush );
-}
-
-/* create a change notification */
-DECL_HANDLER(create_change_notification)
-{
-    struct object *obj;
-    struct create_change_notification_reply reply = { -1 };
-
-    if ((obj = create_change_notification( req->subtree, req->filter )))
-    {
-        reply.handle = alloc_handle( current->process, obj,
-                                     STANDARD_RIGHTS_REQUIRED|SYNCHRONIZE, 0 );
-        release_object( obj );
-    }
-    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, req->inherit );
-        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) );
-}
-
-/* create a device */
-DECL_HANDLER(create_device)
-{
-    struct object *obj;
-    struct create_device_reply reply = { -1 };
-
-    if ((obj = create_device( req->id )))
-    {
-        reply.handle = alloc_handle( current->process, obj,
-                                     req->access, req->inherit );
-        release_object( obj );
-    }
-    send_reply( current, -1, 1, &reply, sizeof(reply) );
-}
-
-/* create a snapshot */
-DECL_HANDLER(create_snapshot)
-{
-    struct object *obj;
-    struct create_snapshot_reply reply = { -1 };
-
-    if ((obj = create_snapshot( req->flags )))
-    {
-        reply.handle = alloc_handle( current->process, obj, 0, req->inherit );
-        release_object( obj );
-    }
-    send_reply( current, -1, 1, &reply, sizeof(reply) );
-}
-
-/* get the next process from a snapshot */
-DECL_HANDLER(next_process)
-{
-    struct next_process_reply reply;
-    snapshot_next_process( req->handle, req->reset, &reply );
-    send_reply( current, -1, 1, &reply, sizeof(reply) );
-}
-
diff --git a/server/select.c b/server/select.c
index 4121eac..013ba71 100644
--- a/server/select.c
+++ b/server/select.c
@@ -15,7 +15,7 @@
 #include <sys/types.h>
 #include <unistd.h>
 
-#include "server/object.h"
+#include "object.h"
 
 /* select user fd */
 struct user
diff --git a/server/semaphore.c b/server/semaphore.c
index ad92a69..5d297e4 100644
--- a/server/semaphore.c
+++ b/server/semaphore.c
@@ -10,8 +10,9 @@
 
 #include "winerror.h"
 #include "winnt.h"
-#include "server/process.h"
-#include "server/thread.h"
+
+#include "handle.h"
+#include "thread.h"
 
 struct semaphore
 {
@@ -40,7 +41,7 @@
 };
 
 
-struct object *create_semaphore( const char *name, unsigned int initial, unsigned int max )
+static struct object *create_semaphore( const char *name, unsigned int initial, unsigned int max )
 {
     struct semaphore *sem;
 
@@ -60,12 +61,7 @@
     return &sem->obj;
 }
 
-int open_semaphore( unsigned int access, int inherit, const char *name )
-{
-    return open_object( name, &semaphore_ops, access, inherit );
-}
-
-int release_semaphore( int handle, unsigned int count, unsigned int *prev_count )
+static int release_semaphore( int handle, unsigned int count, unsigned int *prev_count )
 {
     struct semaphore *sem;
 
@@ -124,3 +120,41 @@
     assert( obj->ops == &semaphore_ops );
     free( sem );
 }
+
+/* create a semaphore */
+DECL_HANDLER(create_semaphore)
+{
+    struct create_semaphore_reply reply = { -1 };
+    struct object *obj;
+    char *name = (char *)data;
+    if (!len) name = NULL;
+    else CHECK_STRING( "create_semaphore", name, len );
+
+    obj = create_semaphore( name, req->initial, req->max );
+    if (obj)
+    {
+        reply.handle = alloc_handle( current->process, obj, SEMAPHORE_ALL_ACCESS, req->inherit );
+        release_object( obj );
+    }
+    send_reply( current, -1, 1, &reply, sizeof(reply) );
+}
+
+/* open a handle to a semaphore */
+DECL_HANDLER(open_semaphore)
+{
+    struct open_semaphore_reply reply;
+    char *name = (char *)data;
+    if (!len) name = NULL;
+    else CHECK_STRING( "open_semaphore", name, len );
+
+    reply.handle = open_object( name, &semaphore_ops, req->access, req->inherit );
+    send_reply( current, -1, 1, &reply, sizeof(reply) );
+}
+
+/* release a semaphore */
+DECL_HANDLER(release_semaphore)
+{
+    struct release_semaphore_reply reply;
+    if (release_semaphore( req->handle, req->count, &reply.prev_count )) CLEAR_ERROR();
+    send_reply( current, -1, 1, &reply, sizeof(reply) );
+}
diff --git a/server/snapshot.c b/server/snapshot.c
index ee18993..c9e678a 100644
--- a/server/snapshot.c
+++ b/server/snapshot.c
@@ -13,8 +13,10 @@
 #include "winerror.h"
 #include "winnt.h"
 #include "tlhelp32.h"
-#include "server/process.h"
-#include "server/thread.h"
+
+#include "handle.h"
+#include "process.h"
+#include "thread.h"
 
 
 struct snapshot
@@ -44,7 +46,7 @@
 
 
 /* create a new snapshot */
-struct object *create_snapshot( int flags )
+static struct object *create_snapshot( int flags )
 {
     struct snapshot *snapshot;
     if (!(snapshot = mem_alloc( sizeof(*snapshot) ))) return NULL;
@@ -59,7 +61,7 @@
 }
 
 /* get the next process in the snapshot */
-int snapshot_next_process( int handle, int reset, struct next_process_reply *reply )
+static int snapshot_next_process( int handle, int reset, struct next_process_reply *reply )
 {
     struct snapshot *snapshot;
     struct process_snapshot *ptr;
@@ -108,3 +110,25 @@
     }
     free( snapshot );
 }
+
+/* create a snapshot */
+DECL_HANDLER(create_snapshot)
+{
+    struct object *obj;
+    struct create_snapshot_reply reply = { -1 };
+
+    if ((obj = create_snapshot( req->flags )))
+    {
+        reply.handle = alloc_handle( current->process, obj, 0, req->inherit );
+        release_object( obj );
+    }
+    send_reply( current, -1, 1, &reply, sizeof(reply) );
+}
+
+/* get the next process from a snapshot */
+DECL_HANDLER(next_process)
+{
+    struct next_process_reply reply;
+    snapshot_next_process( req->handle, req->reset, &reply );
+    send_reply( current, -1, 1, &reply, sizeof(reply) );
+}
diff --git a/server/socket.c b/server/socket.c
index 371b10b..7b2033d 100644
--- a/server/socket.c
+++ b/server/socket.c
@@ -18,8 +18,7 @@
 
 #include "config.h"
 #include "server.h"
-
-#include "server/object.h"
+#include "object.h"
 
 /* Some versions of glibc don't define this */
 #ifndef SCM_RIGHTS
diff --git a/server/thread.c b/server/thread.c
index d184f04..eff2b08 100644
--- a/server/thread.c
+++ b/server/thread.c
@@ -18,9 +18,11 @@
 
 #include "winbase.h"
 #include "winerror.h"
+
+#include "handle.h"
 #include "server.h"
-#include "server/thread.h"
-#include "server/process.h"
+#include "process.h"
+#include "thread.h"
 
 
 /* thread queues */
@@ -81,6 +83,7 @@
     thread->client_fd = fd;
     thread->unix_pid  = 0;  /* not known yet */
     thread->mutex     = NULL;
+    thread->debugger  = NULL;
     thread->wait      = NULL;
     thread->apc       = NULL;
     thread->apc_count = 0;
@@ -107,7 +110,7 @@
 }
 
 /* create a new thread */
-struct thread *create_thread( int fd, void *pid, int suspend, int inherit, int *handle )
+static struct thread *create_thread( int fd, void *pid, int suspend, int inherit, int *handle )
 {
     struct thread *thread;
     struct process *process;
@@ -192,19 +195,9 @@
                                             access, &thread_ops );
 }
 
-/* get all information about a thread */
-void get_thread_info( struct thread *thread,
-                      struct get_thread_info_reply *reply )
-{
-    reply->tid       = thread;
-    reply->exit_code = thread->exit_code;
-    reply->priority  = thread->priority;
-}
-
-
 /* set all information about a thread */
-void set_thread_info( struct thread *thread,
-                      struct set_thread_info_request *req )
+static void set_thread_info( struct thread *thread,
+                             struct set_thread_info_request *req )
 {
     if (req->mask & SET_THREAD_INFO_PRIORITY)
         thread->priority = req->priority;
@@ -216,7 +209,7 @@
 }
 
 /* suspend a thread */
-int suspend_thread( struct thread *thread )
+static int suspend_thread( struct thread *thread )
 {
     int old_count = thread->suspend;
     if (thread->suspend < MAXIMUM_SUSPEND_COUNT)
@@ -230,7 +223,7 @@
 }
 
 /* resume a thread */
-int resume_thread( struct thread *thread )
+static int resume_thread( struct thread *thread )
 {
     int old_count = thread->suspend;
     if (thread->suspend > 0)
@@ -456,7 +449,7 @@
 }
 
 /* sleep on a list of objects */
-void sleep_on( struct thread *thread, int count, int *handles, int flags, int timeout )
+static void sleep_on( struct thread *thread, int count, int *handles, int flags, int timeout )
 {
     assert( !thread->wait );
     if (!wait_on( thread, count, handles, flags, timeout ))
@@ -498,7 +491,7 @@
 }
 
 /* queue an async procedure call */
-int thread_queue_apc( struct thread *thread, void *func, void *param )
+static int thread_queue_apc( struct thread *thread, void *func, void *param )
 {
     struct thread_apc *apc;
     if (!thread->apc)
@@ -534,3 +527,130 @@
     wake_up( &thread->obj, 0 );
     release_object( thread );
 }
+
+/* create a new thread */
+DECL_HANDLER(new_thread)
+{
+    struct new_thread_reply reply;
+    int new_fd;
+
+    if ((new_fd = dup(fd)) != -1)
+    {
+        reply.tid = create_thread( new_fd, req->pid, req->suspend,
+                                   req->inherit, &reply.handle );
+        if (!reply.tid) close( new_fd );
+    }
+    else
+        SET_ERROR( ERROR_TOO_MANY_OPEN_FILES );
+
+    send_reply( current, -1, 1, &reply, sizeof(reply) );
+}
+
+/* initialize a new thread */
+DECL_HANDLER(init_thread)
+{
+    struct init_thread_reply reply;
+
+    if (current->state != STARTING)
+    {
+        fatal_protocol_error( "init_thread: already running\n" );
+        return;
+    }
+    current->state    = RUNNING;
+    current->unix_pid = req->unix_pid;
+    if (current->suspend > 0) kill( current->unix_pid, SIGSTOP );
+    reply.pid = current->process;
+    reply.tid = current;
+    send_reply( current, -1, 1, &reply, sizeof(reply) );
+}
+
+/* terminate a thread */
+DECL_HANDLER(terminate_thread)
+{
+    struct thread *thread;
+
+    if ((thread = get_thread_from_handle( req->handle, THREAD_TERMINATE )))
+    {
+        kill_thread( thread, req->exit_code );
+        release_object( thread );
+    }
+    if (current) send_reply( current, -1, 0 );
+}
+
+/* fetch information about a thread */
+DECL_HANDLER(get_thread_info)
+{
+    struct thread *thread;
+    struct get_thread_info_reply reply = { 0, 0, 0 };
+
+    if ((thread = get_thread_from_handle( req->handle, THREAD_QUERY_INFORMATION )))
+    {
+        reply.tid       = thread;
+        reply.exit_code = thread->exit_code;
+        reply.priority  = thread->priority;
+        release_object( thread );
+    }
+    send_reply( current, -1, 1, &reply, sizeof(reply) );
+}
+
+/* set information about a thread */
+DECL_HANDLER(set_thread_info)
+{
+    struct thread *thread;
+
+    if ((thread = get_thread_from_handle( req->handle, THREAD_SET_INFORMATION )))
+    {
+        set_thread_info( thread, req );
+        release_object( thread );
+    }
+    send_reply( current, -1, 0 );
+}
+
+/* suspend a thread */
+DECL_HANDLER(suspend_thread)
+{
+    struct thread *thread;
+    struct suspend_thread_reply reply = { -1 };
+    if ((thread = get_thread_from_handle( req->handle, THREAD_SUSPEND_RESUME )))
+    {
+        reply.count = suspend_thread( thread );
+        release_object( thread );
+    }
+    send_reply( current, -1, 1, &reply, sizeof(reply) );
+    
+}
+
+/* resume a thread */
+DECL_HANDLER(resume_thread)
+{
+    struct thread *thread;
+    struct resume_thread_reply reply = { -1 };
+    if ((thread = get_thread_from_handle( req->handle, THREAD_SUSPEND_RESUME )))
+    {
+        reply.count = resume_thread( thread );
+        release_object( thread );
+    }
+    send_reply( current, -1, 1, &reply, sizeof(reply) );
+    
+}
+
+/* select on a handle list */
+DECL_HANDLER(select)
+{
+    if (len != req->count * sizeof(int))
+        fatal_protocol_error( "select: bad length %d for %d handles\n",
+                              len, req->count );
+    sleep_on( current, req->count, (int *)data, req->flags, req->timeout );
+}
+
+/* queue an APC for a thread */
+DECL_HANDLER(queue_apc)
+{
+    struct thread *thread;
+    if ((thread = get_thread_from_handle( req->handle, THREAD_SET_CONTEXT )))
+    {
+        thread_queue_apc( thread, req->func, req->param );
+        release_object( thread );
+    }
+    send_reply( current, -1, 0 );
+}
diff --git a/include/server/thread.h b/server/thread.h
similarity index 78%
rename from include/server/thread.h
rename to server/thread.h
index bc77a37..fed1d18 100644
--- a/include/server/thread.h
+++ b/server/thread.h
@@ -11,7 +11,7 @@
 #error This file can only be used in the Wine server
 #endif
 
-#include "server/object.h"
+#include "object.h"
 
 /* thread structure */
 
@@ -19,6 +19,7 @@
 struct thread_wait;
 struct thread_apc;
 struct mutex;
+struct debugger;
 
 enum run_state { STARTING, RUNNING, TERMINATED };
 
@@ -31,6 +32,7 @@
     struct thread      *proc_prev;
     struct process     *process;
     struct mutex       *mutex;     /* list of currently owned mutexes */
+    struct debugger    *debugger;  /* debugger info if this thread is a debugger */
     struct thread_wait *wait;      /* current wait condition if sleeping */
     struct thread_apc  *apc;       /* list of async procedure calls */
     int                 apc_count; /* number of outstanding APCs */
@@ -50,27 +52,17 @@
 /* thread functions */
 
 extern void create_initial_thread( int fd );
-extern struct thread *create_thread( int fd, void *pid, int suspend, int inherit, int *handle );
 extern struct thread *get_thread_from_id( void *id );
 extern struct thread *get_thread_from_handle( int handle, unsigned int access );
-extern void get_thread_info( struct thread *thread,
-                             struct get_thread_info_reply *reply );
-extern void set_thread_info( struct thread *thread,
-                             struct set_thread_info_request *req );
-extern int suspend_thread( struct thread *thread );
-extern int resume_thread( struct thread *thread );
 extern void suspend_all_threads( void );
 extern void resume_all_threads( void );
 extern int send_reply( struct thread *thread, int pass_fd,
                        int n, ... /* arg_1, len_1, ..., arg_n, len_n */ );
 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 int thread_queue_apc( struct thread *thread, void *func, void *param );
 extern void kill_thread( struct thread *thread, int exit_code );
 extern void thread_killed( struct thread *thread, int exit_code );
 extern void thread_timeout(void);
-extern void sleep_on( struct thread *thread, int count, int *handles,
-                      int flags, int timeout );
 extern void wake_up( struct object *obj, int max );
 
 #define GET_ERROR()     (current->error)
diff --git a/server/trace.c b/server/trace.c
index a0a5e49..dcd5aa2 100644
--- a/server/trace.c
+++ b/server/trace.c
@@ -4,7 +4,7 @@
 #include <sys/types.h>
 #include <sys/uio.h>
 #include "server.h"
-#include "server/thread.h"
+#include "thread.h"
 
 static int dump_new_process_request( struct new_process_request *req, int len )
 {
@@ -269,6 +269,20 @@
     return (int)sizeof(*req);
 }
 
+static int dump_open_event_request( struct open_event_request *req, int len )
+{
+    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_event_reply( struct open_event_reply *req, int len )
+{
+    fprintf( stderr, " handle=%d", req->handle );
+    return (int)sizeof(*req);
+}
+
 static int dump_create_mutex_request( struct create_mutex_request *req, int len )
 {
     fprintf( stderr, " owned=%d,", req->owned );
@@ -289,6 +303,20 @@
     return (int)sizeof(*req);
 }
 
+static int dump_open_mutex_request( struct open_mutex_request *req, int len )
+{
+    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_mutex_reply( struct open_mutex_reply *req, int len )
+{
+    fprintf( stderr, " handle=%d", req->handle );
+    return (int)sizeof(*req);
+}
+
 static int dump_create_semaphore_request( struct create_semaphore_request *req, int len )
 {
     fprintf( stderr, " initial=%08x,", req->initial );
@@ -317,16 +345,15 @@
     return (int)sizeof(*req);
 }
 
-static int dump_open_named_obj_request( struct open_named_obj_request *req, int len )
+static int dump_open_semaphore_request( struct open_semaphore_request *req, int len )
 {
-    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 )
+static int dump_open_semaphore_reply( struct open_semaphore_reply *req, int len )
 {
     fprintf( stderr, " handle=%d", req->handle );
     return (int)sizeof(*req);
@@ -584,6 +611,20 @@
     return (int)sizeof(*req);
 }
 
+static int dump_open_mapping_request( struct open_mapping_request *req, int len )
+{
+    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_mapping_reply( struct open_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 );
@@ -694,16 +735,20 @@
       (void(*)())dump_create_event_reply },
     { (int(*)(void *,int))dump_event_op_request,
       (void(*)())0 },
+    { (int(*)(void *,int))dump_open_event_request,
+      (void(*)())dump_open_event_reply },
     { (int(*)(void *,int))dump_create_mutex_request,
       (void(*)())dump_create_mutex_reply },
     { (int(*)(void *,int))dump_release_mutex_request,
       (void(*)())0 },
+    { (int(*)(void *,int))dump_open_mutex_request,
+      (void(*)())dump_open_mutex_reply },
     { (int(*)(void *,int))dump_create_semaphore_request,
       (void(*)())dump_create_semaphore_reply },
     { (int(*)(void *,int))dump_release_semaphore_request,
       (void(*)())dump_release_semaphore_reply },
-    { (int(*)(void *,int))dump_open_named_obj_request,
-      (void(*)())dump_open_named_obj_reply },
+    { (int(*)(void *,int))dump_open_semaphore_request,
+      (void(*)())dump_open_semaphore_reply },
     { (int(*)(void *,int))dump_create_file_request,
       (void(*)())dump_create_file_reply },
     { (int(*)(void *,int))dump_get_read_fd_request,
@@ -750,6 +795,8 @@
       (void(*)())dump_create_change_notification_reply },
     { (int(*)(void *,int))dump_create_mapping_request,
       (void(*)())dump_create_mapping_reply },
+    { (int(*)(void *,int))dump_open_mapping_request,
+      (void(*)())dump_open_mapping_reply },
     { (int(*)(void *,int))dump_get_mapping_info_request,
       (void(*)())dump_get_mapping_info_reply },
     { (int(*)(void *,int))dump_create_device_request,
@@ -785,11 +832,13 @@
     "select",
     "create_event",
     "event_op",
+    "open_event",
     "create_mutex",
     "release_mutex",
+    "open_mutex",
     "create_semaphore",
     "release_semaphore",
-    "open_named_obj",
+    "open_semaphore",
     "create_file",
     "get_read_fd",
     "get_write_fd",
@@ -813,6 +862,7 @@
     "read_console_input",
     "create_change_notification",
     "create_mapping",
+    "open_mapping",
     "get_mapping_info",
     "create_device",
     "create_snapshot",
diff --git a/tools/make_requests b/tools/make_requests
index b587a91..0b0f69f 100755
--- a/tools/make_requests
+++ b/tools/make_requests
@@ -33,7 +33,7 @@
 #include <sys/types.h>
 #include <sys/uio.h>
 #include "server.h"
-#include "server/thread.h"
+#include "thread.h"
 EOF
 
 ### Parse server.h to find request/reply structure definitions
@@ -159,9 +159,6 @@
 
 #ifdef WANT_REQUEST_HANDLERS
 
-#define DECL_HANDLER(name) \\
-    static void req_##name( struct name##_request *req, void *data, int len, int fd )
-
 EOF
 
 foreach $req (@requests) { print REQUESTS "DECL_HANDLER($req);\n"; }