Further server optimizations:
- merged request and reply structures
- build requests directly into the buffer to avoid a copy

diff --git a/server/change.c b/server/change.c
index fb1f0cb..50f193e 100644
--- a/server/change.c
+++ b/server/change.c
@@ -41,13 +41,15 @@
 };
 
 
-static struct object *create_change_notification( int subtree, int filter )
+static struct change *create_change_notification( int subtree, int filter )
 {
     struct change *change;
-    if (!(change = alloc_object( &change_ops ))) return NULL;
-    change->subtree = subtree;
-    change->filter  = filter;
-    return &change->obj;
+    if ((change = alloc_object( &change_ops )))
+    {
+        change->subtree = subtree;
+        change->filter  = filter;
+    }
+    return change;
 }
 
 static void change_dump( struct object *obj, int verbose )
@@ -68,13 +70,13 @@
 /* create a change notification */
 DECL_HANDLER(create_change_notification)
 {
-    struct object *obj;
-    struct create_change_notification_reply *reply = push_reply_data( current, sizeof(*reply) );
+    struct change *change;
 
-    if ((obj = create_change_notification( req->subtree, req->filter )))
+    req->handle = -1;
+    if ((change = create_change_notification( req->subtree, req->filter )))
     {
-        reply->handle = alloc_handle( current->process, obj,
-                                      STANDARD_RIGHTS_REQUIRED|SYNCHRONIZE, 0 );
-        release_object( obj );
+        req->handle = alloc_handle( current->process, change,
+                                    STANDARD_RIGHTS_REQUIRED|SYNCHRONIZE, 0 );
+        release_object( change );
     }
 }
diff --git a/server/console.c b/server/console.c
index a4792b8..4790f90 100644
--- a/server/console.c
+++ b/server/console.c
@@ -69,7 +69,7 @@
 static void screen_buffer_destroy( struct object *obj );
 
 /* common routine */
-static int console_get_info( struct object *obj, struct get_file_info_reply *reply );
+static int console_get_info( struct object *obj, struct get_file_info_request *req );
 
 static const struct object_ops console_input_ops =
 {
@@ -183,12 +183,11 @@
     return 1;
 }
 
-static int set_console_fd( int handle, int fd, int pid )
+static int set_console_fd( int handle, int fd_in, int fd_out, int pid )
 {
     struct console_input *input;
     struct screen_buffer *output;
     struct object *obj;
-    int fd_in, fd_out;
 
     if (!(obj = get_handle_obj( current->process, handle, 0, NULL )))
         return 0;
@@ -215,21 +214,6 @@
     assert( !input->obj.head );
     assert( !output->obj.head );
 
-    if ((fd_in = dup(fd)) == -1)
-    {
-        file_set_error();
-        release_object( input );
-        release_object( output );
-        return 0;
-    }
-    if ((fd_out = dup(fd)) == -1)
-    {
-        file_set_error();
-        close( fd_in );
-        release_object( input );
-        release_object( output );
-        return 0;
-    }
     unregister_select_user( &input->select );
     unregister_select_user( &output->select );
     close( input->select.fd );
@@ -244,25 +228,21 @@
     return 1;
 }
 
-static int get_console_mode( int handle, int *mode )
+static int get_console_mode( int handle )
 {
     struct object *obj;
     int ret = 0;
 
-    if (!(obj = get_handle_obj( current->process, handle, GENERIC_READ, NULL )))
-        return 0;
-    if (obj->ops == &console_input_ops)
+    if ((obj = get_handle_obj( current->process, handle, GENERIC_READ, NULL )))
     {
-        *mode = ((struct console_input *)obj)->mode;
-        ret = 1;
+        if (obj->ops == &console_input_ops)
+            ret = ((struct console_input *)obj)->mode;
+        else if (obj->ops == &screen_buffer_ops)
+            ret = ((struct screen_buffer *)obj)->mode;
+        else
+            set_error( ERROR_INVALID_HANDLE );
+        release_object( obj );
     }
-    else if (obj->ops == &screen_buffer_ops)
-    {
-        *mode = ((struct screen_buffer *)obj)->mode;
-        ret = 1;
-    }
-    else set_error( ERROR_INVALID_HANDLE );
-    release_object( obj );
     return ret;
 }
 
@@ -316,21 +296,6 @@
     return 1;
 }
 
-/* get misc console information (output handle only) */
-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,
-                                                            GENERIC_READ, &screen_buffer_ops )))
-        return 0;
-    reply->cursor_size    = console->cursor_size;
-    reply->cursor_visible = console->cursor_visible;
-    reply->pid            = console->pid;
-    *title                = console->title;
-    release_object( console );
-    return 1;
-}
-
 /* add input events to a console input queue */
 static int write_console_input( int handle, int count, INPUT_RECORD *records )
 {
@@ -355,16 +320,16 @@
 }
 
 /* retrieve a pointer to the console input records */
-static int read_console_input( int handle, int count, int flush )
+static int read_console_input( int handle, int count, INPUT_RECORD *rec, int max, int flush )
 {
     struct console_input *console;
-    struct read_console_input_reply *reply = push_reply_data( current, sizeof(*reply) );
 
     if (!(console = (struct console_input *)get_handle_obj( current->process, handle,
                                                             GENERIC_READ, &console_input_ops )))
         return -1;
     if ((count < 0) || (count > console->recnum)) count = console->recnum;
-    add_reply_data( current, console->records, count * sizeof(INPUT_RECORD) );
+    if (count > max) count = max;
+    memcpy( rec, console->records, count * sizeof(INPUT_RECORD) );
     if (flush)
     {
         int i;
@@ -440,10 +405,18 @@
     return dup( console->select.fd );
 }
 
-static int console_get_info( struct object *obj, struct get_file_info_reply *reply )
+static int console_get_info( struct object *obj, struct get_file_info_request *req )
 {
-    memset( reply, 0, sizeof(*reply) );
-    reply->type = FILE_TYPE_CHAR;
+    req->type        = FILE_TYPE_CHAR;
+    req->attr        = 0;
+    req->access_time = 0;
+    req->write_time  = 0;
+    req->size_high   = 0;
+    req->size_low    = 0;
+    req->links       = 0;
+    req->index_high  = 0;
+    req->index_low   = 0;
+    req->serial      = 0;
     return 1;
 }
 
@@ -517,14 +490,12 @@
     unregister_select_user( &console->select );
     close( console->select.fd );
     if (console->input) console->input->output = NULL;
-    if (console->pid) kill( console->pid, SIGTERM );
     if (console->title) free( console->title );
 }
 
 /* allocate a console for the current process */
 DECL_HANDLER(alloc_console)
 {
-    struct alloc_console_reply *reply = push_reply_data( current, sizeof(*reply) );
     int in = -1, out = -1;
 
     if (!alloc_console( current->process )) goto done;
@@ -541,8 +512,8 @@
     free_console( current->process );
 
  done:
-    reply->handle_in  = in;
-    reply->handle_out = out;
+    req->handle_in  = in;
+    req->handle_out = out;
 }
 
 /* free the console of the current process */
@@ -554,40 +525,61 @@
 /* open a handle to the process console */
 DECL_HANDLER(open_console)
 {
-    struct open_console_reply *reply = push_reply_data( current, sizeof(*reply) );
     struct object *obj= req->output ? current->process->console_out : current->process->console_in;
 
-    if (obj) reply->handle = alloc_handle( current->process, obj, req->access, req->inherit );
+    if (obj) req->handle = alloc_handle( current->process, obj, req->access, req->inherit );
     else set_error( ERROR_ACCESS_DENIED );
 }
 
 /* set info about a console (output only) */
 DECL_HANDLER(set_console_info)
 {
-    size_t len = get_req_strlen();
-    set_console_info( req->handle, req, get_req_data( len + 1 ), len );
+    size_t len = get_req_strlen( req->title );
+    set_console_info( req->handle, req, req->title, len );
 }
 
 /* get info about a console (output only) */
 DECL_HANDLER(get_console_info)
 {
-    struct get_console_info_reply *reply = push_reply_data( current, sizeof(*reply) );
-    const char *title;
-    get_console_info( req->handle, reply, &title );
-    if (title) add_reply_data( current, title, strlen(title) + 1 );
+    struct screen_buffer *console;
+    if ((console = (struct screen_buffer *)get_handle_obj( current->process, req->handle,
+                                                           GENERIC_READ, &screen_buffer_ops )))
+    {
+        req->cursor_size    = console->cursor_size;
+        req->cursor_visible = console->cursor_visible;
+        req->pid            = console->pid;
+        strcpy( req->title, console->title ? console->title : "" );
+        release_object( console );
+    }
 }
 
 /* set a console fd */
 DECL_HANDLER(set_console_fd)
 {
-    set_console_fd( req->handle, fd, req->pid );
+    struct object *obj;
+    int fd_in, fd_out;
+
+    if (!(obj = get_handle_obj( current->process, req->file_handle,
+                                GENERIC_READ | GENERIC_WRITE, NULL ))) return;
+    if ((fd_in = obj->ops->get_read_fd( obj )) == -1)
+    {
+        release_object( obj );
+        return;
+    }
+    fd_out = obj->ops->get_write_fd( obj );
+    release_object( obj );
+    if (fd_out != -1)
+    {
+        if (set_console_fd( req->handle, fd_in, fd_out, req->pid )) return;
+        close( fd_out );
+    }
+    close( fd_in );
 }
 
 /* get a console mode (input or output) */
 DECL_HANDLER(get_console_mode)
 {
-    struct get_console_mode_reply *reply = push_reply_data( current, sizeof(*reply) );
-    get_console_mode( req->handle, &reply->mode );
+    req->mode = get_console_mode( req->handle );
 }
 
 /* set a console mode (input or output) */
@@ -599,18 +591,17 @@
 /* add input records to a console input queue */
 DECL_HANDLER(write_console_input)
 {
-    struct write_console_input_reply *reply = push_reply_data( current, sizeof(*reply) );
+    int max = get_req_size( req + 1, sizeof(INPUT_RECORD) );
+    int count = req->count;
 
-    if (check_req_data( req->count * sizeof(INPUT_RECORD)))
-    {
-        INPUT_RECORD *records = get_req_data( req->count * sizeof(INPUT_RECORD) );
-        reply->written = write_console_input( req->handle, req->count, records );
-    }
-    else fatal_protocol_error( "write_console_input: bad length" );
+    if (count > max) count = max;
+    req->written = write_console_input( req->handle, count, (INPUT_RECORD *)(req + 1) );
 }
 
 /* fetch input records from a console input queue */
 DECL_HANDLER(read_console_input)
 {
-    read_console_input( req->handle, req->count, req->flush );
+    int max = get_req_size( req + 1, sizeof(INPUT_RECORD) );
+    req->read = read_console_input( req->handle, req->count, (INPUT_RECORD *)(req + 1),
+                                    max, req->flush );
 }
diff --git a/server/debugger.c b/server/debugger.c
index 0181d71..404206e 100644
--- a/server/debugger.c
+++ b/server/debugger.c
@@ -146,16 +146,16 @@
 {
     struct debug_event *event = debug_ctx->event_head;
     struct thread *thread = event->thread;
-    struct wait_debug_event_reply *reply = push_reply_data( debug_ctx->owner, sizeof(*reply) );
+    struct wait_debug_event_request *req = get_req_ptr( debug_ctx->owner );
 
     assert( event );
     assert( debug_ctx->waiting );
 
     unlink_event( debug_ctx, event );
     event->sent = 1;
-    reply->code = event->code;
-    reply->pid  = thread->process;
-    reply->tid  = thread;
+    req->code = event->code;
+    req->pid  = thread->process;
+    req->tid  = thread;
     debug_ctx->waiting = 0;
     if (debug_ctx->timeout)
     {
@@ -163,20 +163,20 @@
         debug_ctx->timeout = NULL;
     }
     debug_ctx->owner->error = 0;
-    add_reply_data( debug_ctx->owner, &event->data, event_sizes[event->code] );
+    memcpy( req + 1, &event->data, event_sizes[event->code] );
 }
 
 /* timeout callback while waiting for a debug event */
 static void wait_event_timeout( void *ctx )
 {
     struct debug_ctx *debug_ctx = (struct debug_ctx *)ctx;
-    struct wait_debug_event_reply *reply = push_reply_data( debug_ctx->owner, sizeof(*reply) );
+    struct wait_debug_event_request *req = get_req_ptr( debug_ctx->owner );
 
     assert( debug_ctx->waiting );
 
-    reply->code = 0;
-    reply->pid  = 0;
-    reply->tid  = 0;
+    req->code = 0;
+    req->pid  = 0;
+    req->tid  = 0;
     debug_ctx->waiting = 0;
     debug_ctx->timeout = NULL;
     debug_ctx->owner->error = WAIT_TIMEOUT;
@@ -232,8 +232,8 @@
     {
         /* only send a reply if the thread is still there */
         /* (we can get a continue on an exit thread/process event) */
-        struct send_debug_event_reply *reply = push_reply_data( thread, sizeof(*reply) );
-        reply->status = status;
+        struct send_debug_event_request *req = get_req_ptr( thread );
+        req->status = status;
         send_reply( thread );
     }
     free_event( event );
@@ -380,10 +380,9 @@
 {
     if (!wait_for_debug_event( req->timeout ))
     {
-        struct wait_debug_event_reply *reply = push_reply_data( current, sizeof(*reply) );
-        reply->code = 0;
-        reply->pid  = NULL;
-        reply->tid  = NULL;
+        req->code = 0;
+        req->pid  = NULL;
+        req->tid  = NULL;
     }
 }
 
@@ -423,23 +422,13 @@
     assert( !current->debug_event );
     if ((req->code <= 0) || (req->code > RIP_EVENT))
     {
-        fatal_protocol_error( "send_debug_event: bad event code" );
+        fatal_protocol_error( current, "send_debug_event: bad code %d\n", req->code );
         return;
     }
-    if (!check_req_data( event_sizes[req->code] ))
-    {
-        fatal_protocol_error( "send_debug_event: bad length" );
-        return;
-    }
-    if (debugger && queue_debug_event( debugger, current, req->code,
-                                       get_req_data( event_sizes[req->code] )))
+    req->status = 0;
+    if (debugger && queue_debug_event( debugger, current, req->code, req + 1 ))
     {
         /* wait for continue_debug_event */
         current->state = SLEEPING;
     }
-    else
-    {
-        struct send_debug_event_reply *reply = push_reply_data( current, sizeof(*reply) );
-        reply->status = 0;
-    }
 }
diff --git a/server/device.c b/server/device.c
index d167c67..b9f488e 100644
--- a/server/device.c
+++ b/server/device.c
@@ -30,7 +30,7 @@
 };
 
 static void device_dump( struct object *obj, int verbose );
-static int device_get_info( struct object *obj, struct get_file_info_reply *reply );
+static int device_get_info( struct object *obj, struct get_file_info_request *req );
 
 static const struct object_ops device_ops =
 {
@@ -64,13 +64,20 @@
     fprintf( stderr, "Device id=%08x\n", dev->id );
 }
 
-static int device_get_info( struct object *obj, struct get_file_info_reply *reply )
+static int device_get_info( struct object *obj, struct get_file_info_request *req )
 {
     struct device *dev = (struct device *)obj;
     assert( obj->ops == &device_ops );
-    memset( reply, 0, sizeof(*reply) );
-    reply->type = FILE_TYPE_UNKNOWN;
-    reply->attr = dev->id;  /* hack! */
+    req->type        = FILE_TYPE_UNKNOWN;
+    req->attr        = dev->id;  /* hack! */
+    req->access_time = 0;
+    req->write_time  = 0;
+    req->size_high   = 0;
+    req->size_low    = 0;
+    req->links       = 0;
+    req->index_high  = 0;
+    req->index_low   = 0;
+    req->serial      = 0;
     return 1;
 }
 
@@ -78,12 +85,11 @@
 DECL_HANDLER(create_device)
 {
     struct device *dev;
-    struct create_device_reply *reply = push_reply_data( current, sizeof(*reply) );
 
+    req->handle = -1;
     if ((dev = create_device( req->id )))
     {
-        reply->handle = alloc_handle( current->process, dev, req->access, req->inherit );
+        req->handle = alloc_handle( current->process, dev, req->access, req->inherit );
         release_object( dev );
     }
-    else reply->handle = -1;
 }
diff --git a/server/event.c b/server/event.c
index 4d3ee7e..81d4ba7 100644
--- a/server/event.c
+++ b/server/event.c
@@ -128,25 +128,22 @@
 /* create an event */
 DECL_HANDLER(create_event)
 {
-    size_t len = get_req_strlen();
-    struct create_event_reply *reply = push_reply_data( current, sizeof(*reply) );
+    size_t len = get_req_strlen( req->name );
     struct event *event;
 
-    if ((event = create_event( get_req_data(len+1), len, req->manual_reset, req->initial_state )))
+    req->handle = -1;
+    if ((event = create_event( req->name, len, req->manual_reset, req->initial_state )))
     {
-        reply->handle = alloc_handle( current->process, event, EVENT_ALL_ACCESS, req->inherit );
+        req->handle = alloc_handle( current->process, event, EVENT_ALL_ACCESS, req->inherit );
         release_object( event );
     }
-    else reply->handle = -1;
 }
 
 /* open a handle to an event */
 DECL_HANDLER(open_event)
 {
-    size_t len = get_req_strlen();
-    struct open_event_reply *reply = push_reply_data( current, sizeof(*reply) );
-    reply->handle = open_object( get_req_data( len + 1 ), len, &event_ops,
-                                 req->access, req->inherit );
+    size_t len = get_req_strlen( req->name );
+    req->handle = open_object( req->name, len, &event_ops, req->access, req->inherit );
 }
 
 /* do an event operation */
@@ -164,6 +161,6 @@
         reset_event( req->handle );
         break;
     default:
-        fatal_protocol_error( "event_op: invalid operation" );
+        fatal_protocol_error( current, "event_op: invalid operation %d\n", req->op );
     }
 }
diff --git a/server/file.c b/server/file.c
index 8e9fd80..4b0feae 100644
--- a/server/file.c
+++ b/server/file.c
@@ -47,7 +47,7 @@
 static int file_get_read_fd( struct object *obj );
 static int file_get_write_fd( struct object *obj );
 static int file_flush( struct object *obj );
-static int file_get_info( struct object *obj, struct get_file_info_reply *reply );
+static int file_get_info( struct object *obj, struct get_file_info_request *req );
 static void file_destroy( struct object *obj );
 
 static const struct object_ops file_ops =
@@ -208,7 +208,7 @@
     struct file *file;
     int fd;
 
-    if ((fd = create_anonymous_file()) != -1) return NULL;
+    if ((fd = create_anonymous_file()) == -1) return NULL;
     if (!(file = create_file_for_fd( fd, access, 0, 0 ))) close( fd );
     return file;
 }
@@ -295,7 +295,7 @@
     return ret;
 }
 
-static int file_get_info( struct object *obj, struct get_file_info_reply *reply )
+static int file_get_info( struct object *obj, struct get_file_info_request *req )
 {
     struct stat st;
     struct file *file = (struct file *)obj;
@@ -307,19 +307,19 @@
         return 0;
     }
     if (S_ISCHR(st.st_mode) || S_ISFIFO(st.st_mode) ||
-        S_ISSOCK(st.st_mode) || isatty(file->select.fd)) reply->type = FILE_TYPE_CHAR;
-    else reply->type = FILE_TYPE_DISK;
-    if (S_ISDIR(st.st_mode)) reply->attr = FILE_ATTRIBUTE_DIRECTORY;
-    else reply->attr = FILE_ATTRIBUTE_ARCHIVE;
-    if (!(st.st_mode & S_IWUSR)) reply->attr |= FILE_ATTRIBUTE_READONLY;
-    reply->access_time = st.st_atime;
-    reply->write_time  = st.st_mtime;
-    reply->size_high   = 0;
-    reply->size_low    = S_ISDIR(st.st_mode) ? 0 : st.st_size;
-    reply->links       = st.st_nlink;
-    reply->index_high  = st.st_dev;
-    reply->index_low   = st.st_ino;
-    reply->serial      = 0; /* FIXME */
+        S_ISSOCK(st.st_mode) || isatty(file->select.fd)) req->type = FILE_TYPE_CHAR;
+    else req->type = FILE_TYPE_DISK;
+    if (S_ISDIR(st.st_mode)) req->attr = FILE_ATTRIBUTE_DIRECTORY;
+    else req->attr = FILE_ATTRIBUTE_ARCHIVE;
+    if (!(st.st_mode & S_IWUSR)) req->attr |= FILE_ATTRIBUTE_READONLY;
+    req->access_time = st.st_atime;
+    req->write_time  = st.st_mtime;
+    req->size_high   = 0;
+    req->size_low    = S_ISDIR(st.st_mode) ? 0 : st.st_size;
+    req->links       = st.st_nlink;
+    req->index_high  = st.st_dev;
+    req->index_low   = st.st_ino;
+    req->serial      = 0; /* FIXME */
     return 1;
 }
 
@@ -485,71 +485,72 @@
     /* FIXME: implement this */
     return 1;
 }
+
 /* create a file */
 DECL_HANDLER(create_file)
 {
-    struct create_file_reply *reply = push_reply_data( current, sizeof(*reply) );
-    struct file *file = NULL;
+    size_t len = get_req_strlen( req->name );
+    struct file *file;
 
-    if (fd == -1)
+    req->handle = -1;
+    if ((file = create_file( req->name, len, req->access,
+                             req->sharing, req->create, req->attrs )))
     {
-        size_t len = get_req_strlen();
-        file = create_file( get_req_data( len + 1), len, req->access,
-                            req->sharing, req->create, req->attrs );
-    }
-    else
-    {
-        if ((fd = dup(fd)) == -1)
-            file_set_error();
-        else
-            file = create_file_for_fd( fd, req->access, req->sharing, req->attrs );
-    }
-    if (file)
-    {
-        reply->handle = alloc_handle( current->process, file, req->access, req->inherit );
+        req->handle = alloc_handle( current->process, file, req->access, req->inherit );
         release_object( file );
     }
-    else reply->handle = -1;
+}
+
+/* allocate a file handle for a Unix fd */
+DECL_HANDLER(alloc_file_handle)
+{
+    struct file *file;
+
+    req->handle = -1;
+    if ((fd = dup(fd)) != -1)
+    {
+        if ((file = create_file_for_fd( fd, req->access, FILE_SHARE_READ | FILE_SHARE_WRITE, 0 )))
+        {
+            req->handle = alloc_handle( current->process, file, req->access, 0 );
+            release_object( file );
+        }
+        else close( fd );
+    }
+    else file_set_error();
 }
 
 /* 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 );
+        set_reply_fd( current, obj->ops->get_read_fd( obj ) );
         release_object( obj );
     }
-    else read_fd = -1;
-    set_reply_fd( current, read_fd );
 }
 
 /* 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 );
+        set_reply_fd( current, obj->ops->get_write_fd( obj ) );
         release_object( obj );
     }
-    else write_fd = -1;
-    set_reply_fd( current, write_fd );
 }
 
 /* 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 );
-    add_reply_data( current, &reply, sizeof(reply) );
+    int high = req->high;
+    int low  = req->low;
+    set_file_pointer( req->handle, &low, &high, req->whence );
+    req->new_low  = low;
+    req->new_high = high;
 }
 
 /* truncate (or extend) a file */
@@ -580,11 +581,10 @@
 DECL_HANDLER(get_file_info)
 {
     struct object *obj;
-    struct get_file_info_reply *reply = push_reply_data( current, sizeof(*reply) );
 
     if ((obj = get_handle_obj( current->process, req->handle, 0, NULL )))
     {
-        obj->ops->get_file_info( obj, reply );
+        obj->ops->get_file_info( obj, req );
         release_object( obj );
     }
 }
diff --git a/server/handle.c b/server/handle.c
index 4b5c303..8619e8b 100644
--- a/server/handle.c
+++ b/server/handle.c
@@ -403,8 +403,7 @@
 /* get information about a handle */
 DECL_HANDLER(get_handle_info)
 {
-    struct get_handle_info_reply *reply = push_reply_data( current, sizeof(*reply) );
-    reply->flags = set_handle_info( current->process, req->handle, 0, 0 );
+    req->flags = set_handle_info( current->process, req->handle, 0, 0 );
 }
 
 /* set a handle information */
@@ -416,20 +415,20 @@
 /* duplicate a handle */
 DECL_HANDLER(dup_handle)
 {
-    struct dup_handle_reply reply = { -1 };
     struct process *src, *dst;
 
+    req->handle = -1;
     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 );
+            req->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 );
+            req->handle = duplicate_handle( src, req->src_handle, dst,
+                                            req->access, req->inherit, req->options );
             release_object( dst );
         }
         /* close the handle no matter what happened */
@@ -437,5 +436,4 @@
             close_handle( src, req->src_handle );
         release_object( src );
     }
-    add_reply_data( current, &reply, sizeof(reply) );
 }
diff --git a/server/mapping.c b/server/mapping.c
index b336749..dc0690c 100644
--- a/server/mapping.c
+++ b/server/mapping.c
@@ -104,11 +104,11 @@
         if (!(mapping->file = get_file_obj( current->process, handle, access ))) goto error;
         if (!size_high && !size_low)
         {
-            struct get_file_info_reply reply;
+            struct get_file_info_request req;
             struct object *obj = (struct object *)mapping->file;
-            obj->ops->get_file_info( obj, &reply );
-            size_high = reply.size_high;
-            size_low  = ROUND_SIZE( 0, reply.size_low );
+            obj->ops->get_file_info( obj, &req );
+            size_high = req.size_high;
+            size_low  = ROUND_SIZE( 0, req.size_low );
         }
         else if (!grow_file( mapping->file, size_high, size_low )) goto error;
     }
@@ -133,23 +133,6 @@
     return NULL;
 }
 
-static int get_mapping_info( int handle, struct get_mapping_info_reply *reply )
-{
-    struct mapping *mapping;
-    int fd;
-
-    if (!(mapping = (struct mapping *)get_handle_obj( current->process, handle,
-                                                      0, &mapping_ops )))
-        return -1;
-    reply->size_high = mapping->size_high;
-    reply->size_low  = mapping->size_low;
-    reply->protect   = mapping->protect;
-    if (mapping->file) fd = file_get_mmap_fd( mapping->file );
-    else fd = -1;
-    release_object( mapping );
-    return fd;
-}
-
 static void mapping_dump( struct object *obj, int verbose )
 {
     struct mapping *mapping = (struct mapping *)obj;
@@ -169,34 +152,40 @@
 /* create a file mapping */
 DECL_HANDLER(create_mapping)
 {
-    size_t len = get_req_strlen();
-    struct create_mapping_reply *reply = push_reply_data( current, sizeof(*reply) );
+    size_t len = get_req_strlen( req->name );
     struct object *obj;
 
+    req->handle = -1;
     if ((obj = create_mapping( req->size_high, req->size_low,
-                               req->protect, req->handle, get_req_data( len + 1 ), len )))
+                               req->protect, req->file_handle, req->name, len )))
     {
         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 );
+        req->handle = alloc_handle( current->process, obj, access, req->inherit );
         release_object( obj );
     }
-    else reply->handle = -1;
 }
 
 /* open a handle to a mapping */
 DECL_HANDLER(open_mapping)
 {
-    size_t len = get_req_strlen();
-    struct open_mapping_reply *reply = push_reply_data( current, sizeof(*reply) );
-    reply->handle = open_object( get_req_data( len + 1 ), len, &mapping_ops,
-                                 req->access, req->inherit );
+    size_t len = get_req_strlen( req->name );
+    req->handle = open_object( req->name, len, &mapping_ops, req->access, req->inherit );
 }
 
 /* get a mapping information */
 DECL_HANDLER(get_mapping_info)
 {
-    struct get_mapping_info_reply *reply = push_reply_data( current, sizeof(*reply) );
-    int map_fd = get_mapping_info( req->handle, reply );
-    set_reply_fd( current, map_fd );
+    struct mapping *mapping;
+
+    if ((mapping = (struct mapping *)get_handle_obj( current->process, req->handle,
+                                                     0, &mapping_ops )))
+    {
+        req->size_high = mapping->size_high;
+        req->size_low  = mapping->size_low;
+        req->protect   = mapping->protect;
+        if (mapping->file) set_reply_fd( current, file_get_mmap_fd( mapping->file ) );
+        release_object( mapping );
+    }
 }
+
diff --git a/server/mutex.c b/server/mutex.c
index f171d95..32b7407 100644
--- a/server/mutex.c
+++ b/server/mutex.c
@@ -126,25 +126,22 @@
 /* create a mutex */
 DECL_HANDLER(create_mutex)
 {
-    size_t len = get_req_strlen();
-    struct create_mutex_reply *reply = push_reply_data( current, sizeof(*reply) );
+    size_t len = get_req_strlen( req->name );
     struct mutex *mutex;
 
-    if ((mutex = create_mutex( get_req_data( len + 1 ), len, req->owned )))
+    req->handle = -1;
+    if ((mutex = create_mutex( req->name, len, req->owned )))
     {
-        reply->handle = alloc_handle( current->process, mutex, MUTEX_ALL_ACCESS, req->inherit );
+        req->handle = alloc_handle( current->process, mutex, MUTEX_ALL_ACCESS, req->inherit );
         release_object( mutex );
     }
-    else reply->handle = -1;
 }
 
 /* open a handle to a mutex */
 DECL_HANDLER(open_mutex)
 {
-    size_t len = get_req_strlen();
-    struct open_mutex_reply *reply = push_reply_data( current, sizeof(*reply) );
-    reply->handle = open_object( get_req_data( len + 1 ), len, &mutex_ops,
-                                 req->access, req->inherit );
+    size_t len = get_req_strlen( req->name );
+    req->handle = open_object( req->name, len, &mutex_ops, req->access, req->inherit );
 }
 
 /* release a mutex */
diff --git a/server/object.c b/server/object.c
index 7054e41..d50fd7d 100644
--- a/server/object.c
+++ b/server/object.c
@@ -240,7 +240,7 @@
     return 0;
 }
 
-int no_get_file_info( struct object *obj, struct get_file_info_reply *info )
+int no_get_file_info( struct object *obj, struct get_file_info_request *info )
 {
     set_error( ERROR_INVALID_HANDLE );
     return 0;
diff --git a/server/object.h b/server/object.h
index 8da0c81..0e23b18 100644
--- a/server/object.h
+++ b/server/object.h
@@ -47,7 +47,7 @@
     /* flush the object buffers */
     int  (*flush)(struct object *);
     /* get file information */
-    int  (*get_file_info)(struct object *,struct get_file_info_reply *);
+    int  (*get_file_info)(struct object *,struct get_file_info_request *);
     /* destroy on refcount == 0 */
     void (*destroy)(struct object *);
 };
@@ -80,7 +80,7 @@
 extern int no_read_fd( struct object *obj );
 extern int no_write_fd( struct object *obj );
 extern int no_flush( struct object *obj );
-extern int no_get_file_info( struct object *obj, struct get_file_info_reply *info );
+extern int no_get_file_info( struct object *obj, struct get_file_info_request *info );
 extern void no_destroy( struct object *obj );
 extern void default_select_event( int event, void *private );
 #ifdef DEBUG_OBJECTS
@@ -123,7 +123,7 @@
 extern struct client *add_client( int client_fd, struct thread *self );
 extern void remove_client( struct client *client, int exit_code );
 extern void client_pass_fd( struct client *client, int pass_fd );
-extern void client_reply( struct client *client );
+extern void client_reply( struct client *client, unsigned int res );
 
 /* mutex functions */
 
diff --git a/server/pipe.c b/server/pipe.c
index 9eaf93d..00c2863 100644
--- a/server/pipe.c
+++ b/server/pipe.c
@@ -39,7 +39,7 @@
 static int pipe_signaled( struct object *obj, struct thread *thread );
 static int pipe_get_read_fd( struct object *obj );
 static int pipe_get_write_fd( struct object *obj );
-static int pipe_get_info( struct object *obj, struct get_file_info_reply *reply );
+static int pipe_get_info( struct object *obj, struct get_file_info_request *req );
 static void pipe_destroy( struct object *obj );
 
 static const struct object_ops pipe_ops =
@@ -189,10 +189,18 @@
     return dup( pipe->select.fd );
 }
 
-static int pipe_get_info( struct object *obj, struct get_file_info_reply *reply )
+static int pipe_get_info( struct object *obj, struct get_file_info_request *req )
 {
-    memset( reply, 0, sizeof(*reply) );
-    reply->type = FILE_TYPE_PIPE;
+    req->type        = FILE_TYPE_PIPE;
+    req->attr        = 0;
+    req->access_time = 0;
+    req->write_time  = 0;
+    req->size_high   = 0;
+    req->size_low    = 0;
+    req->links       = 0;
+    req->index_high  = 0;
+    req->index_low   = 0;
+    req->serial      = 0;
     return 1;
 }
 
@@ -209,23 +217,25 @@
 /* create an anonymous pipe */
 DECL_HANDLER(create_pipe)
 {
-    struct create_pipe_reply reply = { -1, -1 };
     struct object *obj[2];
+    int hread = -1, hwrite = -1;
+
     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)
+        hread = alloc_handle( current->process, obj[0],
+                              STANDARD_RIGHTS_REQUIRED|SYNCHRONIZE|GENERIC_READ,
+                              req->inherit );
+        if (hread != -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 );
+            hwrite = alloc_handle( current->process, obj[1],
+                                   STANDARD_RIGHTS_REQUIRED|SYNCHRONIZE|GENERIC_WRITE,
+                                   req->inherit );
+            if (hwrite == -1)
+                close_handle( current->process, hread );
         }
         release_object( obj[0] );
         release_object( obj[1] );
     }
-    add_reply_data( current, &reply, sizeof(reply) );
+    req->handle_read  = hread;
+    req->handle_write = hwrite;
 }
diff --git a/server/process.c b/server/process.c
index b1e4df7..9f68c2e 100644
--- a/server/process.c
+++ b/server/process.c
@@ -82,10 +82,10 @@
     /* alloc a handle for the process itself */
     alloc_handle( process, process, PROCESS_ALL_ACCESS, 0 );
 
-    if (!(process->info = mem_alloc( sizeof(*process->info) + len + 1 ))) goto error;
+    if (!(process->info = mem_alloc( sizeof(*process->info) + len ))) goto error;
     memcpy( process->info, req, sizeof(*req) );
-    memcpy( process->info->cmd_line, cmd_line, len );
-    process->info->cmd_line[len] = 0;
+    memcpy( process->info->cmdline, cmd_line, len );
+    process->info->cmdline[len] = 0;
 
     /* set the process console */
     if (req->create_flags & CREATE_NEW_CONSOLE)
@@ -285,14 +285,13 @@
 }
 
 /* get all information about a process */
-static 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_request *req )
 {
-    reply->pid              = process;
-    reply->exit_code        = process->exit_code;
-    reply->priority         = process->priority;
-    reply->process_affinity = process->affinity;
-    reply->system_affinity  = 1;
+    req->pid              = process;
+    req->exit_code        = process->exit_code;
+    req->priority         = process->priority;
+    req->process_affinity = process->affinity;
+    req->system_affinity  = 1;
 }
 
 /* set all information about a process */
@@ -333,62 +332,55 @@
 /* create a new process */
 DECL_HANDLER(new_process)
 {
-    struct new_process_reply *reply = push_reply_data( current, sizeof(*reply) );
-    size_t len = get_req_strlen();
+    size_t len = get_req_strlen( req->cmdline );
     struct process *process;
 
-    if ((process = create_process( current->process, req, get_req_data( len + 1 ), len )))
+    req->handle = -1;
+    req->pid    = NULL;
+    if ((process = create_process( current->process, req, req->cmdline, len )))
     {
-        reply->handle = alloc_handle( current->process, process,
-                                      PROCESS_ALL_ACCESS, req->inherit );
-        reply->pid    = process;
+        req->handle = alloc_handle( current->process, process, PROCESS_ALL_ACCESS, req->inherit );
+        req->pid    = process;
         release_object( process );
     }
-    else
-    {
-        reply->handle = -1;
-        reply->pid    = NULL;
-    }
 }
 
 /* initialize a new process */
 DECL_HANDLER(init_process)
 {
-    struct init_process_reply *reply = push_reply_data( current, sizeof(*reply) );
     struct new_process_request *info;
 
     if (current->state == STARTING)
     {
-        fatal_protocol_error( "init_process: init_thread not called yet\n" );
+        fatal_protocol_error( current, "init_process: init_thread not called yet\n" );
         return;
     }
     if (!(info = current->process->info))
     {
-        fatal_protocol_error( "init_process: called twice\n" );
+        fatal_protocol_error( current, "init_process: called twice\n" );
         return;
     }
     current->process->info = NULL;
-    reply->start_flags = info->start_flags;
-    reply->hstdin      = info->hstdin;
-    reply->hstdout     = info->hstdout;
-    reply->hstderr     = info->hstderr;
-    reply->cmd_show    = info->cmd_show;
-    reply->env_ptr     = info->env_ptr;
-    add_reply_data( current, info->cmd_line, strlen(info->cmd_line) + 1 );
+    req->start_flags = info->start_flags;
+    req->hstdin      = info->hstdin;
+    req->hstdout     = info->hstdout;
+    req->hstderr     = info->hstderr;
+    req->cmd_show    = info->cmd_show;
+    req->env_ptr     = info->env_ptr;
+    strcpy( req->cmdline, info->cmdline );
     free( info );
 }
 
 /* open a handle to a process */
 DECL_HANDLER(open_process)
 {
-    struct open_process_reply *reply = push_reply_data( current, sizeof(*reply) );
     struct process *process = get_process_from_id( req->pid );
+    req->handle = -1;
     if (process)
     {
-        reply->handle = alloc_handle( current->process, process, req->access, req->inherit );
+        req->handle = alloc_handle( current->process, process, req->access, req->inherit );
         release_object( process );
     }
-    else reply->handle = -1;
 }
 
 /* terminate a process */
@@ -407,11 +399,10 @@
 DECL_HANDLER(get_process_info)
 {
     struct process *process;
-    struct get_process_info_reply *reply = push_reply_data( current, sizeof(*reply) );
 
     if ((process = get_process_from_handle( req->handle, PROCESS_QUERY_INFORMATION )))
     {
-        get_process_info( process, reply );
+        get_process_info( process, req );
         release_object( process );
     }
 }
diff --git a/server/request.c b/server/request.c
index a8cab9c..56b394d 100644
--- a/server/request.c
+++ b/server/request.c
@@ -26,55 +26,33 @@
 struct thread *current = NULL;  /* thread handling the current request */
 
 /* complain about a protocol error and terminate the client connection */
-void fatal_protocol_error( const char *err )
+void fatal_protocol_error( struct thread *thread, const char *err, ... )
 {
-    unsigned char *p;
+    va_list args;
 
-    fprintf( stderr, "Protocol error:%p: %s\n    request:", current, err );
-    for (p = (unsigned char *)current->buffer; p < (unsigned char *)current->req_end; p++)
-        fprintf( stderr, " %02x", *p );
-    fprintf( stderr, "\n" );
-    remove_client( current->client, -2 );
+    va_start( args, err );
+    fprintf( stderr, "Protocol error:%p: ", thread );
+    vfprintf( stderr, err, args );
+    va_end( args );
+    remove_client( thread->client, PROTOCOL_ERROR );
 }
 
 /* call a request handler */
-void call_req_handler( struct thread *thread, int fd )
+void call_req_handler( struct thread *thread, enum request req, int fd )
 {
-    const struct handler *handler;
-    struct header *head;
-    unsigned int req, len;
-
     current = thread;
-    assert (current);
-
-    head = (struct header *)current->buffer;
-
-    req = head->type;
-    len = head->len;
-
-    /* set the buffer pointers */
-    current->req_pos = current->reply_pos = (char *)current->buffer + sizeof(struct header);
-    current->req_end = (char *)current->buffer + len;
     clear_error();
 
-    if ((len < sizeof(struct header)) || (len > MAX_MSG_LENGTH)) goto bad_header;
-    if (req >= REQ_NB_REQUESTS) goto bad_header;
-
     if (debug_level) trace_request( req, fd );
 
-    /* now call the handler */
-    handler = &req_handlers[req];
-    if (!check_req_data( handler->min_size )) goto bad_request;
-    handler->handler( get_req_data( handler->min_size ), fd );
-    if (current && current->state != SLEEPING) send_reply( current );
-    current = NULL;
-    return;
-
- bad_header:
-    /* dump only the header */
-    current->req_end = (char *)current->buffer + sizeof(struct header);
- bad_request:
-    fatal_protocol_error( "bad request" );
+    if (req < REQ_NB_REQUESTS)
+    {
+        req_handlers[req].handler( current->buffer, fd );
+        if (current && current->state != SLEEPING) send_reply( current );
+        current = NULL;
+        return;
+    }
+    fatal_protocol_error( current, "bad request %d\n", req );
 }
 
 /* handle a client timeout */
@@ -110,15 +88,8 @@
 /* send a reply to a thread */
 void send_reply( struct thread *thread )
 {
-    struct header *head = thread->buffer;
-    int len = (char *)thread->reply_pos - (char *)thread->buffer;
-
-    assert( len < MAX_MSG_LENGTH );
-
-    head->len  = len;
-    head->type = thread->error;
     if (thread->state == SLEEPING) thread->state = RUNNING;
-    client_reply( thread->client );
+    client_reply( thread->client, thread->error );
 }
 
 /* set the debug level */
diff --git a/server/request.h b/server/request.h
index b161a55..f9e0c95 100644
--- a/server/request.h
+++ b/server/request.h
@@ -13,14 +13,21 @@
 
 #include "thread.h"
 
-/* request handler definition */
+/* max request length */
+#define MAX_REQUEST_LENGTH  8192
 
+/* exit code passed to remove_client on communication error */
+#define OUT_OF_MEMORY  -1
+#define BROKEN_PIPE    -2
+#define PROTOCOL_ERROR -3
+
+/* request handler definition */
 #define DECL_HANDLER(name) void req_##name( struct name##_request *req, int fd )
 
 /* request functions */
 
-extern void fatal_protocol_error( const char *err );
-extern void call_req_handler( struct thread *thread, int fd );
+extern void fatal_protocol_error( struct thread *thread, const char *err, ... );
+extern void call_req_handler( struct thread *thread, enum request req, int fd );
 extern void call_timeout_handler( void *thread );
 extern void call_kill_handler( struct thread *thread, int exit_code );
 extern void set_reply_fd( struct thread *thread, int pass_fd );
@@ -29,48 +36,26 @@
 extern void trace_request( enum request req, int fd );
 extern void trace_timeout(void);
 extern void trace_kill( int exit_code );
-extern void trace_reply( struct thread *thread, int pass_fd );
+extern void trace_reply( struct thread *thread, unsigned int res, int pass_fd );
 
-
-/* Warning: the buffer is shared between request and reply,
- * so make sure you are finished using the request before starting
- * to add data for the reply.
- */
-
-/* remove some data from the current request */
-static inline void *get_req_data( size_t len )
+/* get the request buffer */
+static inline void *get_req_ptr( struct thread *thread )
 {
-    void *old = current->req_pos;
-    current->req_pos = (char *)old + len;
-    return old;
+    return thread->buffer;
 }
 
-/* check that there is enough data available in the current request */
-static inline int check_req_data( size_t len )
+/* get the remaining size in the request buffer for object of a given size */
+static inline int get_req_size( const void *ptr, size_t typesize )
 {
-    return (char *)current->req_pos + len <= (char *)current->req_end;
+    return ((char *)current->buffer + MAX_REQUEST_LENGTH - (char *)ptr) / typesize;
 }
 
 /* get the length of a request string, without going past the end of the request */
-static inline size_t get_req_strlen(void)
+static inline size_t get_req_strlen( const char *str )
 {
-    char *p = current->req_pos;
-    while (*p && (p < (char *)current->req_end - 1)) p++;
-    return p - (char *)current->req_pos;
-}
-
-/* make space for some data in the current reply */
-static inline void *push_reply_data( struct thread *thread, size_t len )
-{
-    void *old = thread->reply_pos;
-    thread->reply_pos = (char *)old + len;
-    return old;
-}
-
-/* add some data to the current reply */
-static inline void add_reply_data( struct thread *thread, const void *data, size_t len )
-{
-    memcpy( push_reply_data( thread, len ), data, len );
+    const char *p = str;
+    while (*p && (p < (char *)current->buffer + MAX_REQUEST_LENGTH - 1)) p++;
+    return p - str;
 }
 
 /* Everything below this line is generated automatically by tools/make_requests */
@@ -81,6 +66,7 @@
 DECL_HANDLER(set_debug);
 DECL_HANDLER(init_process);
 DECL_HANDLER(init_thread);
+DECL_HANDLER(get_thread_buffer);
 DECL_HANDLER(terminate_process);
 DECL_HANDLER(terminate_thread);
 DECL_HANDLER(get_process_info);
@@ -91,6 +77,7 @@
 DECL_HANDLER(resume_thread);
 DECL_HANDLER(debugger);
 DECL_HANDLER(queue_apc);
+DECL_HANDLER(get_apcs);
 DECL_HANDLER(close_handle);
 DECL_HANDLER(get_handle_info);
 DECL_HANDLER(set_handle_info);
@@ -107,6 +94,7 @@
 DECL_HANDLER(release_semaphore);
 DECL_HANDLER(open_semaphore);
 DECL_HANDLER(create_file);
+DECL_HANDLER(alloc_file_handle);
 DECL_HANDLER(get_read_fd);
 DECL_HANDLER(get_write_fd);
 DECL_HANDLER(set_file_pointer);
@@ -150,6 +138,7 @@
     { (void(*)())req_set_debug, sizeof(struct set_debug_request) },
     { (void(*)())req_init_process, sizeof(struct init_process_request) },
     { (void(*)())req_init_thread, sizeof(struct init_thread_request) },
+    { (void(*)())req_get_thread_buffer, sizeof(struct get_thread_buffer_request) },
     { (void(*)())req_terminate_process, sizeof(struct terminate_process_request) },
     { (void(*)())req_terminate_thread, sizeof(struct terminate_thread_request) },
     { (void(*)())req_get_process_info, sizeof(struct get_process_info_request) },
@@ -160,6 +149,7 @@
     { (void(*)())req_resume_thread, sizeof(struct resume_thread_request) },
     { (void(*)())req_debugger, sizeof(struct debugger_request) },
     { (void(*)())req_queue_apc, sizeof(struct queue_apc_request) },
+    { (void(*)())req_get_apcs, sizeof(struct get_apcs_request) },
     { (void(*)())req_close_handle, sizeof(struct close_handle_request) },
     { (void(*)())req_get_handle_info, sizeof(struct get_handle_info_request) },
     { (void(*)())req_set_handle_info, sizeof(struct set_handle_info_request) },
@@ -176,6 +166,7 @@
     { (void(*)())req_release_semaphore, sizeof(struct release_semaphore_request) },
     { (void(*)())req_open_semaphore, sizeof(struct open_semaphore_request) },
     { (void(*)())req_create_file, sizeof(struct create_file_request) },
+    { (void(*)())req_alloc_file_handle, sizeof(struct alloc_file_handle_request) },
     { (void(*)())req_get_read_fd, sizeof(struct get_read_fd_request) },
     { (void(*)())req_get_write_fd, sizeof(struct get_write_fd_request) },
     { (void(*)())req_set_file_pointer, sizeof(struct set_file_pointer_request) },
diff --git a/server/semaphore.c b/server/semaphore.c
index 6b2caec..f9fb671 100644
--- a/server/semaphore.c
+++ b/server/semaphore.c
@@ -64,31 +64,33 @@
     return sem;
 }
 
-static void release_semaphore( int handle, unsigned int count, unsigned int *prev_count )
+static unsigned int release_semaphore( int handle, unsigned int count )
 {
     struct semaphore *sem;
+    unsigned int prev = 0;
 
-    if (!(sem = (struct semaphore *)get_handle_obj( current->process, handle,
-                                                    SEMAPHORE_MODIFY_STATE, &semaphore_ops )))
-        return;
-
-    *prev_count = sem->count;
-    if (sem->count + count < sem->count || sem->count + count > sem->max)
+    if ((sem = (struct semaphore *)get_handle_obj( current->process, handle,
+                                                   SEMAPHORE_MODIFY_STATE, &semaphore_ops )))
     {
-        set_error( ERROR_TOO_MANY_POSTS );
+        prev = sem->count;
+        if (sem->count + count < sem->count || sem->count + count > sem->max)
+        {
+            set_error( ERROR_TOO_MANY_POSTS );
+        }
+        else if (sem->count)
+        {
+            /* there cannot be any thread waiting if the count is != 0 */
+            assert( !sem->obj.head );
+            sem->count += count;
+        }
+        else
+        {
+            sem->count = count;
+            wake_up( &sem->obj, count );
+        }
+        release_object( sem );
     }
-    else if (sem->count)
-    {
-        /* there cannot be any thread waiting if the count is != 0 */
-        assert( !sem->obj.head );
-        sem->count += count;
-    }
-    else
-    {
-        sem->count = count;
-        wake_up( &sem->obj, count );
-    }
-    release_object( sem );
+    return prev;
 }
 
 static void semaphore_dump( struct object *obj, int verbose )
@@ -118,30 +120,26 @@
 /* create a semaphore */
 DECL_HANDLER(create_semaphore)
 {
-    size_t len = get_req_strlen();
-    struct create_semaphore_reply *reply = push_reply_data( current, sizeof(*reply) );
+    size_t len = get_req_strlen( req->name );
     struct semaphore *sem;
 
-    if ((sem = create_semaphore( get_req_data( len + 1 ), len, req->initial, req->max )))
+    req->handle = -1;
+    if ((sem = create_semaphore( req->name, len, req->initial, req->max )))
     {
-        reply->handle = alloc_handle( current->process, sem, SEMAPHORE_ALL_ACCESS, req->inherit );
+        req->handle = alloc_handle( current->process, sem, SEMAPHORE_ALL_ACCESS, req->inherit );
         release_object( sem );
     }
-    else reply->handle = -1;
 }
 
 /* open a handle to a semaphore */
 DECL_HANDLER(open_semaphore)
 {
-    size_t len = get_req_strlen();
-    struct open_semaphore_reply *reply = push_reply_data( current, sizeof(*reply) );
-    reply->handle = open_object( get_req_data( len + 1 ), len, &semaphore_ops,
-                                 req->access, req->inherit );
+    size_t len = get_req_strlen( req->name );
+    req->handle = open_object( req->name, len, &semaphore_ops, req->access, req->inherit );
 }
 
 /* release a semaphore */
 DECL_HANDLER(release_semaphore)
 {
-    struct release_semaphore_reply *reply = push_reply_data( current, sizeof(*reply) );
-    release_semaphore( req->handle, req->count, &reply->prev_count );
+    req->prev_count = release_semaphore( req->handle, req->count );
 }
diff --git a/server/snapshot.c b/server/snapshot.c
index 6aebf1b..5ac30cc 100644
--- a/server/snapshot.c
+++ b/server/snapshot.c
@@ -64,31 +64,25 @@
 }
 
 /* get the next process in the snapshot */
-static int snapshot_next_process( int handle, int reset, struct next_process_reply *reply )
+static int snapshot_next_process( struct snapshot *snapshot, struct next_process_request *req )
 {
-    struct snapshot *snapshot;
     struct process_snapshot *ptr;
-    if (!(snapshot = (struct snapshot *)get_handle_obj( current->process, handle,
-                                                        0, &snapshot_ops )))
-        return 0;
+
     if (!snapshot->process_count)
     {
         set_error( ERROR_INVALID_PARAMETER );  /* FIXME */
-        release_object( snapshot );
         return 0;
     }
-    if (reset) snapshot->process_pos = 0;
+    if (req->reset) snapshot->process_pos = 0;
     else if (snapshot->process_pos >= snapshot->process_count)
     {
         set_error( ERROR_NO_MORE_FILES );
-        release_object( snapshot );
         return 0;
     }
     ptr = &snapshot->process[snapshot->process_pos++];
-    reply->pid      = ptr->process;
-    reply->threads  = ptr->threads;
-    reply->priority = ptr->priority;
-    release_object( snapshot );
+    req->pid      = ptr->process;
+    req->threads  = ptr->threads;
+    req->priority = ptr->priority;
     return 1;
 }
 
@@ -117,19 +111,24 @@
 DECL_HANDLER(create_snapshot)
 {
     struct snapshot *snapshot;
-    struct create_snapshot_reply *reply = push_reply_data( current, sizeof(*reply) );
 
+    req->handle = -1;
     if ((snapshot = create_snapshot( req->flags )))
     {
-        reply->handle = alloc_handle( current->process, snapshot, 0, req->inherit );
+        req->handle = alloc_handle( current->process, snapshot, 0, req->inherit );
         release_object( snapshot );
     }
-    else reply->handle = -1;
 }
 
 /* get the next process from a snapshot */
 DECL_HANDLER(next_process)
 {
-    struct next_process_reply *reply = push_reply_data( current, sizeof(*reply) );
-    snapshot_next_process( req->handle, req->reset, reply );
+    struct snapshot *snapshot;
+
+    if ((snapshot = (struct snapshot *)get_handle_obj( current->process, req->handle,
+                                                       0, &snapshot_ops )))
+    {
+        snapshot_next_process( snapshot, req );
+        release_object( snapshot );
+    }
 }
diff --git a/server/socket.c b/server/socket.c
index 9b78e07..5628c1e 100644
--- a/server/socket.c
+++ b/server/socket.c
@@ -30,139 +30,102 @@
 struct client
 {
     struct select_user   select;     /* select user */
-    unsigned int         seq;        /* current sequence number */
+    unsigned int         res;        /* current result to send */
     int                  pass_fd;    /* fd to pass to and from the client */
     struct thread       *self;       /* client thread (opaque pointer) */
     struct timeout_user *timeout;    /* current timeout (opaque pointer) */
 };
 
 
-/* exit code passed to remove_client */
-#define OUT_OF_MEMORY  -1
-#define BROKEN_PIPE    -2
-#define PROTOCOL_ERROR -3
-
-
-/* signal a client protocol error */
-static void protocol_error( struct client *client, const char *err, ... )
+/* socket communication static structures */
+static struct iovec iovec;
+static struct msghdr msghdr = { NULL, 0, &iovec, 1, };
+#ifndef HAVE_MSGHDR_ACCRIGHTS
+struct cmsg_fd
 {
-    va_list args;
+    int len;   /* sizeof structure */
+    int level; /* SOL_SOCKET */
+    int type;  /* SCM_RIGHTS */
+    int fd;    /* fd to pass */
+};
+static struct cmsg_fd cmsg = { sizeof(cmsg), SOL_SOCKET, SCM_RIGHTS, -1 };
+#endif  /* HAVE_MSGHDR_ACCRIGHTS */
 
-    va_start( args, err );
-    fprintf( stderr, "Protocol error:%p: ", client->self );
-    vfprintf( stderr, err, args );
-    va_end( args );
-    remove_client( client, PROTOCOL_ERROR );
-}
 
 /* send a message to a client that is ready to receive something */
-static void do_write( struct client *client )
+static int do_write( struct client *client )
 {
     int ret;
 
     if (client->pass_fd == -1)
     {
-        ret = write( client->select.fd, &client->seq, sizeof(client->seq) );
+        ret = write( client->select.fd, &client->res, sizeof(client->res) );
+        if (ret == sizeof(client->res)) goto ok;
     }
     else  /* we have an fd to send */
     {
-        struct iovec vec;
-        struct msghdr msghdr;
-
 #ifdef HAVE_MSGHDR_ACCRIGHTS
+        msghdr.msg_accrightslen = sizeof(int);
         msghdr.msg_accrights = (void *)&client->pass_fd;
-        msghdr.msg_accrightslen = sizeof(client->pass_fd);
 #else  /* HAVE_MSGHDR_ACCRIGHTS */
-        struct cmsg_fd cmsg;
-
-        cmsg.len   = sizeof(cmsg);
-        cmsg.level = SOL_SOCKET;
-        cmsg.type  = SCM_RIGHTS;
-        cmsg.fd    = client->pass_fd;
         msghdr.msg_control    = &cmsg;
         msghdr.msg_controllen = sizeof(cmsg);
-        msghdr.msg_flags      = 0;
+        cmsg.fd = client->pass_fd;
 #endif  /* HAVE_MSGHDR_ACCRIGHTS */
 
-        msghdr.msg_name    = NULL;
-        msghdr.msg_namelen = 0;
-        msghdr.msg_iov     = &vec;
-        msghdr.msg_iovlen  = 1;
-        vec.iov_base = (char *)&client->seq;
-        vec.iov_len  = sizeof(client->seq);
+        iovec.iov_base = (char *)&client->res;
+        iovec.iov_len  = sizeof(client->res);
 
         ret = sendmsg( client->select.fd, &msghdr, 0 );
         close( client->pass_fd );
         client->pass_fd = -1;
-    }
-    if (ret == sizeof(client->seq))
-    {
-        /* everything OK */
-        client->seq++;
-        set_select_events( &client->select, READ_EVENT );
-        return;
+        if (ret == sizeof(client->res)) goto ok;
     }
     if (ret == -1)
     {
+        if (errno == EWOULDBLOCK) return 0;  /* not a fatal error */
         if (errno != EPIPE) perror("sendmsg");
-        remove_client( client, BROKEN_PIPE );
-        return;
     }
-    fprintf( stderr, "Partial sequence sent (%d)\n", ret );
+    else fprintf( stderr, "Partial message sent %d/%d\n", ret, sizeof(client->res) );
     remove_client( client, BROKEN_PIPE );
+    return 0;
+
+ ok:
+    set_select_events( &client->select, READ_EVENT );
+    return 1;
 }
 
 
 /* read a message from a client that has something to say */
 static void do_read( struct client *client )
 {
-    struct iovec vec;
-    int ret, seq;
+    int ret;
+    enum request req;
 
 #ifdef HAVE_MSGHDR_ACCRIGHTS
-    struct msghdr msghdr;
-
-    msghdr.msg_accrights    = (void *)&client->pass_fd;
-    msghdr.msg_accrightslen = sizeof(client->pass_fd);
+    msghdr.msg_accrightslen = sizeof(int);
+    msghdr.msg_accrights = (void *)&client->pass_fd;
 #else  /* HAVE_MSGHDR_ACCRIGHTS */
-    struct msghdr msghdr;
-    struct cmsg_fd cmsg;
-
-    cmsg.len   = sizeof(cmsg);
-    cmsg.level = SOL_SOCKET;
-    cmsg.type  = SCM_RIGHTS;
-    cmsg.fd    = -1;
     msghdr.msg_control    = &cmsg;
     msghdr.msg_controllen = sizeof(cmsg);
-    msghdr.msg_flags      = 0;
+    cmsg.fd = -1;
 #endif  /* HAVE_MSGHDR_ACCRIGHTS */
 
     assert( client->pass_fd == -1 );
 
-    msghdr.msg_name    = NULL;
-    msghdr.msg_namelen = 0;
-    msghdr.msg_iov     = &vec;
-    msghdr.msg_iovlen  = 1;
-
-    vec.iov_base = &seq;
-    vec.iov_len  = sizeof(seq);
+    iovec.iov_base = &req;
+    iovec.iov_len  = sizeof(req);
 
     ret = recvmsg( client->select.fd, &msghdr, 0 );
 #ifndef HAVE_MSGHDR_ACCRIGHTS
     client->pass_fd = cmsg.fd;
 #endif
 
-    if (ret == sizeof(seq))
+    if (ret == sizeof(req))
     {
         int pass_fd = client->pass_fd;
-        if (seq != client->seq++)
-        {
-            protocol_error( client, "bad sequence %08x instead of %08x\n",
-                            seq, client->seq - 1 );
-            return;
-        }
         client->pass_fd = -1;
-        call_req_handler( client->self, pass_fd );
+        call_req_handler( client->self, req, pass_fd );
         if (pass_fd != -1) close( pass_fd );
         return;
     }
@@ -177,7 +140,7 @@
         remove_client( client, BROKEN_PIPE );
         return;
     }
-    protocol_error( client, "partial sequence received %d/%d\n", ret, sizeof(seq) );
+    fatal_protocol_error( client->self, "partial message received %d/%d\n", ret, sizeof(req) );
 }
 
 /* handle a client event */
@@ -204,7 +167,6 @@
     client->select.fd            = fd;
     client->select.func          = client_event;
     client->select.private       = client;
-    client->seq                  = 0;
     client->self                 = self;
     client->timeout              = NULL;
     client->pass_fd              = -1;
@@ -237,8 +199,9 @@
 }
 
 /* send a reply to a client */
-void client_reply( struct client *client )
+void client_reply( struct client *client, unsigned int res )
 {
-    if (debug_level) trace_reply( client->self, client->pass_fd );
-    set_select_events( &client->select, WRITE_EVENT );
+    if (debug_level) trace_reply( client->self, res, client->pass_fd );
+    client->res = res;
+    if (!do_write( client )) set_select_events( &client->select, WRITE_EVENT );
 }
diff --git a/server/thread.c b/server/thread.c
index aa9febc..d85a149 100644
--- a/server/thread.c
+++ b/server/thread.c
@@ -84,10 +84,9 @@
     int fd;
 
     if ((fd = create_anonymous_file()) == -1) return -1;
-    if (ftruncate( fd, MAX_MSG_LENGTH ) == -1) goto error;
-    if ((thread->buffer = mmap( 0, MAX_MSG_LENGTH, PROT_READ | PROT_WRITE,
+    if (ftruncate( fd, MAX_REQUEST_LENGTH ) == -1) goto error;
+    if ((thread->buffer = mmap( 0, MAX_REQUEST_LENGTH, PROT_READ | PROT_WRITE,
                                 MAP_SHARED, fd, 0 )) == (void*)-1) goto error;
-    thread->req_pos = thread->reply_pos = thread->buffer;
     return fd;
 
  error:
@@ -123,7 +122,7 @@
     thread->affinity    = 1;
     thread->suspend     = (suspend != 0);
     thread->buffer      = (void *)-1;
-    thread->last_req    = 0;
+    thread->last_req    = REQ_GET_THREAD_BUFFER;
 
     if (!first_thread)  /* creating the first thread */
     {
@@ -143,7 +142,6 @@
         close( buf_fd );
         goto error;
     }
-    push_reply_data( thread, sizeof(struct header) );
     set_reply_fd( thread, buf_fd );  /* send the fd to the client */
     send_reply( thread );
     return thread;
@@ -173,7 +171,7 @@
     if (thread->prev) thread->prev->next = thread->next;
     else first_thread = thread->next;
     if (thread->apc) free( thread->apc );
-    if (thread->buffer != (void *)-1) munmap( thread->buffer, MAX_MSG_LENGTH );
+    if (thread->buffer != (void *)-1) munmap( thread->buffer, MAX_REQUEST_LENGTH );
 }
 
 /* dump a thread on stdout for debugging purposes */
@@ -378,7 +376,7 @@
             /* Wait satisfied: tell it to the object */
             *signaled = i;
             if (entry->obj->ops->satisfied( entry->obj, thread ))
-                *signaled += STATUS_ABANDONED_WAIT_0;
+                *signaled = i + STATUS_ABANDONED_WAIT_0;
             return 1;
         }
     }
@@ -404,62 +402,48 @@
     return 0;
 }
 
-/* build a select reply to wake up the client */
-static void build_select_reply( struct thread *thread, int signaled )
-{
-    struct select_reply *reply = push_reply_data( thread, sizeof(*reply) );
-    reply->signaled = signaled;
-    if ((signaled == STATUS_USER_APC) && thread->apc)
-    {
-        add_reply_data( thread, thread->apc, thread->apc_count * sizeof(*thread->apc) );
-        free( thread->apc );
-        thread->apc = NULL;
-        thread->apc_count = 0;
-    }
-}
-
 /* attempt to wake up a thread */
 /* return 1 if OK, 0 if the wait condition is still not satisfied */
 static int wake_thread( struct thread *thread )
 {
-    int signaled;
+    struct select_request *req = get_req_ptr( thread );
 
-    if (!check_wait( thread, &signaled )) return 0;
+    if (!check_wait( thread, &req->signaled )) return 0;
     end_wait( thread );
-    build_select_reply( thread, signaled );
     return 1;
 }
 
 /* sleep on a list of objects */
 static void sleep_on( struct thread *thread, int count, int *handles, int flags, int timeout )
 {
+    struct select_request *req;
     assert( !thread->wait );
-    if (!wait_on( thread, count, handles, flags, timeout ))
-    {
-        build_select_reply( thread, -1 );
-        return;
-    }
+    if (!wait_on( thread, count, handles, flags, timeout )) goto error;
     if (wake_thread( thread )) return;
     /* now we need to wait */
     if (flags & SELECT_TIMEOUT)
     {
         if (!(thread->wait->user = add_timeout_user( &thread->wait->timeout,
                                                      call_timeout_handler, thread )))
-        {
-            build_select_reply( thread, -1 );
-            return;
-        }
+            goto error;
     }
     thread->state = SLEEPING;
+    return;
+
+ error:
+    req = get_req_ptr( thread );
+    req->signaled = -1;
 }
 
 /* timeout for the current thread */
 void thread_timeout(void)
 {
+    struct select_request *req = get_req_ptr( current );
+
     assert( current->wait );
     current->wait->user = NULL;
     end_wait( current );
-    build_select_reply( current, STATUS_TIMEOUT );
+    req->signaled = STATUS_TIMEOUT;
     send_reply( current );
 }
 
@@ -525,39 +509,40 @@
 /* create a new thread */
 DECL_HANDLER(new_thread)
 {
-    struct new_thread_reply reply;
     struct thread *thread;
     struct process *process;
-    int new_fd;
 
     if ((process = get_process_from_id( req->pid )))
     {
-        if ((new_fd = dup(fd)) != -1)
+        if ((fd = dup(fd)) != -1)
         {
-            if ((thread = create_thread( new_fd, process, req->suspend )))
+            if ((thread = create_thread( fd, process, req->suspend )))
             {
-                reply.tid = thread;
-                reply.handle = alloc_handle( current->process, thread,
-                                             THREAD_ALL_ACCESS, req->inherit );
-                if (reply.handle == -1) release_object( thread );
+                req->tid = thread;
+                if ((req->handle = alloc_handle( current->process, thread,
+                                                 THREAD_ALL_ACCESS, req->inherit )) == -1)
+                    release_object( thread );
                 /* else will be released when the thread gets killed */
             }
-            else close( new_fd );
+            else close( fd );
         }
-        else set_error( ERROR_TOO_MANY_OPEN_FILES );
+        else file_set_error();
         release_object( process );
     }
-    add_reply_data( current, &reply, sizeof(reply) );
+}
+
+/* retrieve the thread buffer file descriptor */
+DECL_HANDLER(get_thread_buffer)
+{
+    fatal_protocol_error( current, "get_thread_buffer: should never get called directly\n" );
 }
 
 /* initialize a new thread */
 DECL_HANDLER(init_thread)
 {
-    struct init_thread_reply *reply = push_reply_data( current, sizeof(*reply) );
-
     if (current->state != STARTING)
     {
-        fatal_protocol_error( "init_thread: already running\n" );
+        fatal_protocol_error( current, "init_thread: already running\n" );
         return;
     }
     current->state    = RUNNING;
@@ -565,8 +550,8 @@
     current->teb      = req->teb;
     if (current->suspend + current->process->suspend > 0)
         kill( current->unix_pid, SIGSTOP );
-    reply->pid = current->process;
-    reply->tid = current;
+    req->pid = current->process;
+    req->tid = current;
 }
 
 /* terminate a thread */
@@ -585,13 +570,12 @@
 DECL_HANDLER(get_thread_info)
 {
     struct thread *thread;
-    struct get_thread_info_reply *reply = push_reply_data( current, sizeof(*reply) );
 
     if ((thread = get_thread_from_handle( req->handle, THREAD_QUERY_INFORMATION )))
     {
-        reply->tid       = thread;
-        reply->exit_code = thread->exit_code;
-        reply->priority  = thread->priority;
+        req->tid       = thread;
+        req->exit_code = thread->exit_code;
+        req->priority  = thread->priority;
         release_object( thread );
     }
 }
@@ -612,10 +596,10 @@
 DECL_HANDLER(suspend_thread)
 {
     struct thread *thread;
-    struct suspend_thread_reply *reply = push_reply_data( current, sizeof(*reply) );
+
     if ((thread = get_thread_from_handle( req->handle, THREAD_SUSPEND_RESUME )))
     {
-        reply->count = suspend_thread( thread );
+        req->count = suspend_thread( thread );
         release_object( thread );
     }
 }
@@ -624,10 +608,10 @@
 DECL_HANDLER(resume_thread)
 {
     struct thread *thread;
-    struct resume_thread_reply *reply = push_reply_data( current, sizeof(*reply) );
+
     if ((thread = get_thread_from_handle( req->handle, THREAD_SUSPEND_RESUME )))
     {
-        reply->count = resume_thread( thread );
+        req->count = resume_thread( thread );
         release_object( thread );
     }
 }
@@ -635,12 +619,7 @@
 /* select on a handle list */
 DECL_HANDLER(select)
 {
-    if (check_req_data( req->count * sizeof(int) ))
-    {
-        sleep_on( current, req->count, get_req_data( req->count * sizeof(int) ),
-                  req->flags, req->timeout );
-    }
-    else fatal_protocol_error( "select: bad length" );
+    sleep_on( current, req->count, req->handles, req->flags, req->timeout );
 }
 
 /* queue an APC for a thread */
@@ -653,3 +632,15 @@
         release_object( thread );
     }
 }
+
+/* get list of APC to call */
+DECL_HANDLER(get_apcs)
+{
+    if ((req->count = current->apc_count))
+    {
+        memcpy( req->apcs, current->apc, current->apc_count * sizeof(*current->apc) );
+        free( current->apc );
+        current->apc = NULL;
+        current->apc_count = 0;
+    }
+}
diff --git a/server/thread.h b/server/thread.h
index cb8c248..006dd2e 100644
--- a/server/thread.h
+++ b/server/thread.h
@@ -49,9 +49,6 @@
     int                 affinity;  /* affinity mask */
     int                 suspend;   /* suspend count */
     void               *buffer;    /* buffer for communication with the client */
-    void               *req_pos;   /* current request position in buffer */
-    void               *req_end;   /* ptr to end of current request */
-    void               *reply_pos; /* current reply position in buffer */
     enum request        last_req;  /* last request received (for debugging) */
 };
 
diff --git a/server/trace.c b/server/trace.c
index 10ca05d..b7110aa 100644
--- a/server/trace.c
+++ b/server/trace.c
@@ -9,46 +9,32 @@
 #include <sys/uio.h>
 #include "request.h"
 
-static int dump_chars( void *ptr, int len )
-{
-    fprintf( stderr, "\"%.*s\"", len, (char *)ptr );
-    return len;
-}
 
-static int dump_ints( void *ptr, int len )
+/* dumping for functions for requests that have a variable part */
+
+static void dump_varargs_select( struct select_request *req )
 {
     int i;
-    if (!(len /= sizeof(int)))
-    {
-        fprintf( stderr, "{}" );
-        return 0;
-    }
-    for (i = 0; i < len; i++)
-        fprintf( stderr, "%c%d", i ? ',' : '{', *((int *)ptr + i) );
+    for (i = 0; i < req->count; i++)
+        fprintf( stderr, "%c%d", i ? ',' : '{', req->handles[i] );
     fprintf( stderr, "}" );
-    return len * sizeof(int);
 }
 
-static int dump_ptrs( void *ptr, int len )
+static void dump_varargs_get_apcs( struct get_apcs_request *req )
 {
     int i;
-    if (!(len /= sizeof(void*)))
-    {
-        fprintf( stderr, "{}" );
-        return 0;
-    }
-    for (i = 0; i < len; i++)
-        fprintf( stderr, "%c%p", i ? ',' : '{', *((void **)ptr + i) );
+    for (i = 0; i < 2 * req->count; i++)
+        fprintf( stderr, "%c%p", i ? ',' : '{', req->apcs[i] );
     fprintf( stderr, "}" );
-    return len * sizeof(void*);
 }
 
-typedef int (*dump_func)( const void *req, int len );
+
+typedef void (*dump_func)( const void *req );
 
 /* Everything below this line is generated automatically by tools/make_requests */
 /* ### make_requests begin ### */
 
-static int dump_new_process_request( struct new_process_request *req, int len )
+static void dump_new_process_request( struct new_process_request *req )
 {
     fprintf( stderr, " inherit=%d,", req->inherit );
     fprintf( stderr, " inherit_all=%d,", req->inherit_all );
@@ -59,45 +45,38 @@
     fprintf( stderr, " hstderr=%d,", req->hstderr );
     fprintf( stderr, " cmd_show=%d,", req->cmd_show );
     fprintf( stderr, " env_ptr=%p,", req->env_ptr );
-    fprintf( stderr, " cmd_line=" );
-    return dump_chars( req+1, len - (int)sizeof(*req) ) + sizeof(*req);
+    fprintf( stderr, " cmdline=\"%s\"", req->cmdline );
 }
 
-static int dump_new_process_reply( struct new_process_reply *req, int len )
+static void dump_new_process_reply( struct new_process_request *req )
 {
     fprintf( stderr, " pid=%p,", req->pid );
     fprintf( stderr, " handle=%d", req->handle );
-    return (int)sizeof(*req);
 }
 
-static int dump_new_thread_request( struct new_thread_request *req, int len )
+static void dump_new_thread_request( struct new_thread_request *req )
 {
     fprintf( stderr, " pid=%p,", req->pid );
     fprintf( stderr, " suspend=%d,", req->suspend );
     fprintf( stderr, " inherit=%d", req->inherit );
-    return (int)sizeof(*req);
 }
 
-static int dump_new_thread_reply( struct new_thread_reply *req, int len )
+static void dump_new_thread_reply( struct new_thread_request *req )
 {
     fprintf( stderr, " tid=%p,", req->tid );
     fprintf( stderr, " handle=%d", req->handle );
-    return (int)sizeof(*req);
 }
 
-static int dump_set_debug_request( struct set_debug_request *req, int len )
+static void dump_set_debug_request( struct set_debug_request *req )
 {
     fprintf( stderr, " level=%d", req->level );
-    return (int)sizeof(*req);
 }
 
-static int dump_init_process_request( struct init_process_request *req, int len )
+static void dump_init_process_request( struct init_process_request *req )
 {
-    fprintf( stderr, " dummy=%d", req->dummy );
-    return (int)sizeof(*req);
 }
 
-static int dump_init_process_reply( struct init_process_reply *req, int len )
+static void dump_init_process_reply( struct init_process_request *req )
 {
     fprintf( stderr, " start_flags=%d,", req->start_flags );
     fprintf( stderr, " hstdin=%d,", req->hstdin );
@@ -105,151 +84,146 @@
     fprintf( stderr, " hstderr=%d,", req->hstderr );
     fprintf( stderr, " cmd_show=%d,", req->cmd_show );
     fprintf( stderr, " env_ptr=%p,", req->env_ptr );
-    fprintf( stderr, " cmdline=" );
-    return dump_chars( req+1, len - (int)sizeof(*req) ) + sizeof(*req);
+    fprintf( stderr, " cmdline=\"%s\"", req->cmdline );
 }
 
-static int dump_init_thread_request( struct init_thread_request *req, int len )
+static void dump_init_thread_request( struct init_thread_request *req )
 {
     fprintf( stderr, " unix_pid=%d,", req->unix_pid );
     fprintf( stderr, " teb=%p", req->teb );
-    return (int)sizeof(*req);
 }
 
-static int dump_init_thread_reply( struct init_thread_reply *req, int len )
+static void dump_init_thread_reply( struct init_thread_request *req )
 {
     fprintf( stderr, " pid=%p,", req->pid );
     fprintf( stderr, " tid=%p", req->tid );
-    return (int)sizeof(*req);
 }
 
-static int dump_terminate_process_request( struct terminate_process_request *req, int len )
+static void dump_get_thread_buffer_request( struct get_thread_buffer_request *req )
+{
+    fprintf( stderr, " dummy=%d", req->dummy );
+}
+
+static void dump_terminate_process_request( struct terminate_process_request *req )
 {
     fprintf( stderr, " handle=%d,", req->handle );
     fprintf( stderr, " exit_code=%d", req->exit_code );
-    return (int)sizeof(*req);
 }
 
-static int dump_terminate_thread_request( struct terminate_thread_request *req, int len )
+static void dump_terminate_thread_request( struct terminate_thread_request *req )
 {
     fprintf( stderr, " handle=%d,", req->handle );
     fprintf( stderr, " exit_code=%d", req->exit_code );
-    return (int)sizeof(*req);
 }
 
-static int dump_get_process_info_request( struct get_process_info_request *req, int len )
+static void dump_get_process_info_request( struct get_process_info_request *req )
 {
     fprintf( stderr, " handle=%d", req->handle );
-    return (int)sizeof(*req);
 }
 
-static int dump_get_process_info_reply( struct get_process_info_reply *req, int len )
+static void dump_get_process_info_reply( struct get_process_info_request *req )
 {
     fprintf( stderr, " pid=%p,", req->pid );
     fprintf( stderr, " exit_code=%d,", req->exit_code );
     fprintf( stderr, " priority=%d,", req->priority );
     fprintf( stderr, " process_affinity=%d,", req->process_affinity );
     fprintf( stderr, " system_affinity=%d", req->system_affinity );
-    return (int)sizeof(*req);
 }
 
-static int dump_set_process_info_request( struct set_process_info_request *req, int len )
+static void dump_set_process_info_request( struct set_process_info_request *req )
 {
     fprintf( stderr, " handle=%d,", req->handle );
     fprintf( stderr, " mask=%d,", req->mask );
     fprintf( stderr, " priority=%d,", req->priority );
     fprintf( stderr, " affinity=%d", req->affinity );
-    return (int)sizeof(*req);
 }
 
-static int dump_get_thread_info_request( struct get_thread_info_request *req, int len )
+static void dump_get_thread_info_request( struct get_thread_info_request *req )
 {
     fprintf( stderr, " handle=%d", req->handle );
-    return (int)sizeof(*req);
 }
 
-static int dump_get_thread_info_reply( struct get_thread_info_reply *req, int len )
+static void dump_get_thread_info_reply( struct get_thread_info_request *req )
 {
     fprintf( stderr, " tid=%p,", req->tid );
     fprintf( stderr, " exit_code=%d,", req->exit_code );
     fprintf( stderr, " priority=%d", req->priority );
-    return (int)sizeof(*req);
 }
 
-static int dump_set_thread_info_request( struct set_thread_info_request *req, int len )
+static void dump_set_thread_info_request( struct set_thread_info_request *req )
 {
     fprintf( stderr, " handle=%d,", req->handle );
     fprintf( stderr, " mask=%d,", req->mask );
     fprintf( stderr, " priority=%d,", req->priority );
     fprintf( stderr, " affinity=%d", req->affinity );
-    return (int)sizeof(*req);
 }
 
-static int dump_suspend_thread_request( struct suspend_thread_request *req, int len )
+static void dump_suspend_thread_request( struct suspend_thread_request *req )
 {
     fprintf( stderr, " handle=%d", req->handle );
-    return (int)sizeof(*req);
 }
 
-static int dump_suspend_thread_reply( struct suspend_thread_reply *req, int len )
+static void dump_suspend_thread_reply( struct suspend_thread_request *req )
 {
     fprintf( stderr, " count=%d", req->count );
-    return (int)sizeof(*req);
 }
 
-static int dump_resume_thread_request( struct resume_thread_request *req, int len )
+static void dump_resume_thread_request( struct resume_thread_request *req )
 {
     fprintf( stderr, " handle=%d", req->handle );
-    return (int)sizeof(*req);
 }
 
-static int dump_resume_thread_reply( struct resume_thread_reply *req, int len )
+static void dump_resume_thread_reply( struct resume_thread_request *req )
 {
     fprintf( stderr, " count=%d", req->count );
-    return (int)sizeof(*req);
 }
 
-static int dump_debugger_request( struct debugger_request *req, int len )
+static void dump_debugger_request( struct debugger_request *req )
 {
     fprintf( stderr, " op=%d", req->op );
-    return (int)sizeof(*req);
 }
 
-static int dump_queue_apc_request( struct queue_apc_request *req, int len )
+static void dump_queue_apc_request( struct queue_apc_request *req )
 {
     fprintf( stderr, " handle=%d,", req->handle );
     fprintf( stderr, " func=%p,", req->func );
     fprintf( stderr, " param=%p", req->param );
-    return (int)sizeof(*req);
 }
 
-static int dump_close_handle_request( struct close_handle_request *req, int len )
+static void dump_get_apcs_request( struct get_apcs_request *req )
+{
+}
+
+static void dump_get_apcs_reply( struct get_apcs_request *req )
+{
+    fprintf( stderr, " count=%d,", req->count );
+    fprintf( stderr, " apcs=" );
+    dump_varargs_get_apcs( req );
+}
+
+static void dump_close_handle_request( struct close_handle_request *req )
 {
     fprintf( stderr, " handle=%d", req->handle );
-    return (int)sizeof(*req);
 }
 
-static int dump_get_handle_info_request( struct get_handle_info_request *req, int len )
+static void dump_get_handle_info_request( struct get_handle_info_request *req )
 {
     fprintf( stderr, " handle=%d", req->handle );
-    return (int)sizeof(*req);
 }
 
-static int dump_get_handle_info_reply( struct get_handle_info_reply *req, int len )
+static void dump_get_handle_info_reply( struct get_handle_info_request *req )
 {
     fprintf( stderr, " flags=%d", req->flags );
-    return (int)sizeof(*req);
 }
 
-static int dump_set_handle_info_request( struct set_handle_info_request *req, int len )
+static void dump_set_handle_info_request( struct set_handle_info_request *req )
 {
     fprintf( stderr, " handle=%d,", req->handle );
     fprintf( stderr, " flags=%d,", req->flags );
     fprintf( stderr, " mask=%d", req->mask );
-    return (int)sizeof(*req);
 }
 
-static int dump_dup_handle_request( struct dup_handle_request *req, int len )
+static void dump_dup_handle_request( struct dup_handle_request *req )
 {
     fprintf( stderr, " src_process=%d,", req->src_process );
     fprintf( stderr, " src_handle=%d,", req->src_handle );
@@ -257,229 +231,207 @@
     fprintf( stderr, " access=%08x,", req->access );
     fprintf( stderr, " inherit=%d,", req->inherit );
     fprintf( stderr, " options=%d", req->options );
-    return (int)sizeof(*req);
 }
 
-static int dump_dup_handle_reply( struct dup_handle_reply *req, int len )
+static void dump_dup_handle_reply( struct dup_handle_request *req )
 {
     fprintf( stderr, " handle=%d", req->handle );
-    return (int)sizeof(*req);
 }
 
-static int dump_open_process_request( struct open_process_request *req, int len )
+static void dump_open_process_request( struct open_process_request *req )
 {
     fprintf( stderr, " pid=%p,", req->pid );
     fprintf( stderr, " access=%08x,", req->access );
     fprintf( stderr, " inherit=%d", req->inherit );
-    return (int)sizeof(*req);
 }
 
-static int dump_open_process_reply( struct open_process_reply *req, int len )
+static void dump_open_process_reply( struct open_process_request *req )
 {
     fprintf( stderr, " handle=%d", req->handle );
-    return (int)sizeof(*req);
 }
 
-static int dump_select_request( struct select_request *req, int len )
+static void dump_select_request( struct select_request *req )
 {
     fprintf( stderr, " count=%d,", req->count );
     fprintf( stderr, " flags=%d,", req->flags );
     fprintf( stderr, " timeout=%d,", req->timeout );
     fprintf( stderr, " handles=" );
-    return dump_ints( req+1, len - (int)sizeof(*req) ) + sizeof(*req);
+    dump_varargs_select( req );
 }
 
-static int dump_select_reply( struct select_reply *req, int len )
+static void dump_select_reply( struct select_request *req )
 {
-    fprintf( stderr, " signaled=%d,", req->signaled );
-    fprintf( stderr, " apcs=" );
-    return dump_ptrs( req+1, len - (int)sizeof(*req) ) + sizeof(*req);
+    fprintf( stderr, " signaled=%d", req->signaled );
 }
 
-static int dump_create_event_request( struct create_event_request *req, int len )
+static void dump_create_event_request( struct create_event_request *req )
 {
     fprintf( stderr, " manual_reset=%d,", req->manual_reset );
     fprintf( stderr, " initial_state=%d,", req->initial_state );
     fprintf( stderr, " inherit=%d,", req->inherit );
-    fprintf( stderr, " name=" );
-    return dump_chars( req+1, len - (int)sizeof(*req) ) + sizeof(*req);
+    fprintf( stderr, " name=\"%s\"", req->name );
 }
 
-static int dump_create_event_reply( struct create_event_reply *req, int len )
+static void dump_create_event_reply( struct create_event_request *req )
 {
     fprintf( stderr, " handle=%d", req->handle );
-    return (int)sizeof(*req);
 }
 
-static int dump_event_op_request( struct event_op_request *req, int len )
+static void dump_event_op_request( struct event_op_request *req )
 {
     fprintf( stderr, " handle=%d,", req->handle );
     fprintf( stderr, " op=%d", req->op );
-    return (int)sizeof(*req);
 }
 
-static int dump_open_event_request( struct open_event_request *req, int len )
+static void dump_open_event_request( struct open_event_request *req )
 {
     fprintf( stderr, " access=%08x,", req->access );
     fprintf( stderr, " inherit=%d,", req->inherit );
-    fprintf( stderr, " name=" );
-    return dump_chars( req+1, len - (int)sizeof(*req) ) + sizeof(*req);
+    fprintf( stderr, " name=\"%s\"", req->name );
 }
 
-static int dump_open_event_reply( struct open_event_reply *req, int len )
+static void dump_open_event_reply( struct open_event_request *req )
 {
     fprintf( stderr, " handle=%d", req->handle );
-    return (int)sizeof(*req);
 }
 
-static int dump_create_mutex_request( struct create_mutex_request *req, int len )
+static void dump_create_mutex_request( struct create_mutex_request *req )
 {
     fprintf( stderr, " owned=%d,", req->owned );
     fprintf( stderr, " inherit=%d,", req->inherit );
-    fprintf( stderr, " name=" );
-    return dump_chars( req+1, len - (int)sizeof(*req) ) + sizeof(*req);
+    fprintf( stderr, " name=\"%s\"", req->name );
 }
 
-static int dump_create_mutex_reply( struct create_mutex_reply *req, int len )
+static void dump_create_mutex_reply( struct create_mutex_request *req )
 {
     fprintf( stderr, " handle=%d", req->handle );
-    return (int)sizeof(*req);
 }
 
-static int dump_release_mutex_request( struct release_mutex_request *req, int len )
+static void dump_release_mutex_request( struct release_mutex_request *req )
 {
     fprintf( stderr, " handle=%d", req->handle );
-    return (int)sizeof(*req);
 }
 
-static int dump_open_mutex_request( struct open_mutex_request *req, int len )
+static void dump_open_mutex_request( struct open_mutex_request *req )
 {
     fprintf( stderr, " access=%08x,", req->access );
     fprintf( stderr, " inherit=%d,", req->inherit );
-    fprintf( stderr, " name=" );
-    return dump_chars( req+1, len - (int)sizeof(*req) ) + sizeof(*req);
+    fprintf( stderr, " name=\"%s\"", req->name );
 }
 
-static int dump_open_mutex_reply( struct open_mutex_reply *req, int len )
+static void dump_open_mutex_reply( struct open_mutex_request *req )
 {
     fprintf( stderr, " handle=%d", req->handle );
-    return (int)sizeof(*req);
 }
 
-static int dump_create_semaphore_request( struct create_semaphore_request *req, int len )
+static void dump_create_semaphore_request( struct create_semaphore_request *req )
 {
     fprintf( stderr, " initial=%08x,", req->initial );
     fprintf( stderr, " max=%08x,", req->max );
     fprintf( stderr, " inherit=%d,", req->inherit );
-    fprintf( stderr, " name=" );
-    return dump_chars( req+1, len - (int)sizeof(*req) ) + sizeof(*req);
+    fprintf( stderr, " name=\"%s\"", req->name );
 }
 
-static int dump_create_semaphore_reply( struct create_semaphore_reply *req, int len )
+static void dump_create_semaphore_reply( struct create_semaphore_request *req )
 {
     fprintf( stderr, " handle=%d", req->handle );
-    return (int)sizeof(*req);
 }
 
-static int dump_release_semaphore_request( struct release_semaphore_request *req, int len )
+static void dump_release_semaphore_request( struct release_semaphore_request *req )
 {
     fprintf( stderr, " handle=%d,", req->handle );
     fprintf( stderr, " count=%08x", req->count );
-    return (int)sizeof(*req);
 }
 
-static int dump_release_semaphore_reply( struct release_semaphore_reply *req, int len )
+static void dump_release_semaphore_reply( struct release_semaphore_request *req )
 {
     fprintf( stderr, " prev_count=%08x", req->prev_count );
-    return (int)sizeof(*req);
 }
 
-static int dump_open_semaphore_request( struct open_semaphore_request *req, int len )
+static void dump_open_semaphore_request( struct open_semaphore_request *req )
 {
     fprintf( stderr, " access=%08x,", req->access );
     fprintf( stderr, " inherit=%d,", req->inherit );
-    fprintf( stderr, " name=" );
-    return dump_chars( req+1, len - (int)sizeof(*req) ) + sizeof(*req);
+    fprintf( stderr, " name=\"%s\"", req->name );
 }
 
-static int dump_open_semaphore_reply( struct open_semaphore_reply *req, int len )
+static void dump_open_semaphore_reply( struct open_semaphore_request *req )
 {
     fprintf( stderr, " handle=%d", req->handle );
-    return (int)sizeof(*req);
 }
 
-static int dump_create_file_request( struct create_file_request *req, int len )
+static void dump_create_file_request( struct create_file_request *req )
 {
     fprintf( stderr, " access=%08x,", req->access );
     fprintf( stderr, " inherit=%d,", req->inherit );
     fprintf( stderr, " sharing=%08x,", req->sharing );
     fprintf( stderr, " create=%d,", req->create );
     fprintf( stderr, " attrs=%08x,", req->attrs );
-    fprintf( stderr, " name=" );
-    return dump_chars( req+1, len - (int)sizeof(*req) ) + sizeof(*req);
+    fprintf( stderr, " name=\"%s\"", req->name );
 }
 
-static int dump_create_file_reply( struct create_file_reply *req, int len )
+static void dump_create_file_reply( struct create_file_request *req )
 {
     fprintf( stderr, " handle=%d", req->handle );
-    return (int)sizeof(*req);
 }
 
-static int dump_get_read_fd_request( struct get_read_fd_request *req, int len )
+static void dump_alloc_file_handle_request( struct alloc_file_handle_request *req )
+{
+    fprintf( stderr, " access=%08x", req->access );
+}
+
+static void dump_alloc_file_handle_reply( struct alloc_file_handle_request *req )
 {
     fprintf( stderr, " handle=%d", req->handle );
-    return (int)sizeof(*req);
 }
 
-static int dump_get_write_fd_request( struct get_write_fd_request *req, int len )
+static void dump_get_read_fd_request( struct get_read_fd_request *req )
 {
     fprintf( stderr, " handle=%d", req->handle );
-    return (int)sizeof(*req);
 }
 
-static int dump_set_file_pointer_request( struct set_file_pointer_request *req, int len )
+static void dump_get_write_fd_request( struct get_write_fd_request *req )
+{
+    fprintf( stderr, " handle=%d", req->handle );
+}
+
+static void dump_set_file_pointer_request( struct set_file_pointer_request *req )
 {
     fprintf( stderr, " handle=%d,", req->handle );
     fprintf( stderr, " low=%d,", req->low );
     fprintf( stderr, " high=%d,", req->high );
     fprintf( stderr, " whence=%d", req->whence );
-    return (int)sizeof(*req);
 }
 
-static int dump_set_file_pointer_reply( struct set_file_pointer_reply *req, int len )
+static void dump_set_file_pointer_reply( struct set_file_pointer_request *req )
 {
-    fprintf( stderr, " low=%d,", req->low );
-    fprintf( stderr, " high=%d", req->high );
-    return (int)sizeof(*req);
+    fprintf( stderr, " new_low=%d,", req->new_low );
+    fprintf( stderr, " new_high=%d", req->new_high );
 }
 
-static int dump_truncate_file_request( struct truncate_file_request *req, int len )
+static void dump_truncate_file_request( struct truncate_file_request *req )
 {
     fprintf( stderr, " handle=%d", req->handle );
-    return (int)sizeof(*req);
 }
 
-static int dump_set_file_time_request( struct set_file_time_request *req, int len )
+static void dump_set_file_time_request( struct set_file_time_request *req )
 {
     fprintf( stderr, " handle=%d,", req->handle );
     fprintf( stderr, " access_time=%ld,", req->access_time );
     fprintf( stderr, " write_time=%ld", req->write_time );
-    return (int)sizeof(*req);
 }
 
-static int dump_flush_file_request( struct flush_file_request *req, int len )
+static void dump_flush_file_request( struct flush_file_request *req )
 {
     fprintf( stderr, " handle=%d", req->handle );
-    return (int)sizeof(*req);
 }
 
-static int dump_get_file_info_request( struct get_file_info_request *req, int len )
+static void dump_get_file_info_request( struct get_file_info_request *req )
 {
     fprintf( stderr, " handle=%d", req->handle );
-    return (int)sizeof(*req);
 }
 
-static int dump_get_file_info_reply( struct get_file_info_reply *req, int len )
+static void dump_get_file_info_reply( struct get_file_info_request *req )
 {
     fprintf( stderr, " type=%d,", req->type );
     fprintf( stderr, " attr=%d,", req->attr );
@@ -491,292 +443,252 @@
     fprintf( stderr, " index_high=%d,", req->index_high );
     fprintf( stderr, " index_low=%d,", req->index_low );
     fprintf( stderr, " serial=%08x", req->serial );
-    return (int)sizeof(*req);
 }
 
-static int dump_lock_file_request( struct lock_file_request *req, int len )
+static void dump_lock_file_request( struct lock_file_request *req )
 {
     fprintf( stderr, " handle=%d,", req->handle );
     fprintf( stderr, " offset_low=%08x,", req->offset_low );
     fprintf( stderr, " offset_high=%08x,", req->offset_high );
     fprintf( stderr, " count_low=%08x,", req->count_low );
     fprintf( stderr, " count_high=%08x", req->count_high );
-    return (int)sizeof(*req);
 }
 
-static int dump_unlock_file_request( struct unlock_file_request *req, int len )
+static void dump_unlock_file_request( struct unlock_file_request *req )
 {
     fprintf( stderr, " handle=%d,", req->handle );
     fprintf( stderr, " offset_low=%08x,", req->offset_low );
     fprintf( stderr, " offset_high=%08x,", req->offset_high );
     fprintf( stderr, " count_low=%08x,", req->count_low );
     fprintf( stderr, " count_high=%08x", req->count_high );
-    return (int)sizeof(*req);
 }
 
-static int dump_create_pipe_request( struct create_pipe_request *req, int len )
+static void dump_create_pipe_request( struct create_pipe_request *req )
 {
     fprintf( stderr, " inherit=%d", req->inherit );
-    return (int)sizeof(*req);
 }
 
-static int dump_create_pipe_reply( struct create_pipe_reply *req, int len )
+static void dump_create_pipe_reply( struct create_pipe_request *req )
 {
     fprintf( stderr, " handle_read=%d,", req->handle_read );
     fprintf( stderr, " handle_write=%d", req->handle_write );
-    return (int)sizeof(*req);
 }
 
-static int dump_alloc_console_request( struct alloc_console_request *req, int len )
+static void dump_alloc_console_request( struct alloc_console_request *req )
 {
     fprintf( stderr, " access=%08x,", req->access );
     fprintf( stderr, " inherit=%d", req->inherit );
-    return (int)sizeof(*req);
 }
 
-static int dump_alloc_console_reply( struct alloc_console_reply *req, int len )
+static void dump_alloc_console_reply( struct alloc_console_request *req )
 {
     fprintf( stderr, " handle_in=%d,", req->handle_in );
     fprintf( stderr, " handle_out=%d", req->handle_out );
-    return (int)sizeof(*req);
 }
 
-static int dump_free_console_request( struct free_console_request *req, int len )
+static void dump_free_console_request( struct free_console_request *req )
 {
     fprintf( stderr, " dummy=%d", req->dummy );
-    return (int)sizeof(*req);
 }
 
-static int dump_open_console_request( struct open_console_request *req, int len )
+static void dump_open_console_request( struct open_console_request *req )
 {
     fprintf( stderr, " output=%d,", req->output );
     fprintf( stderr, " access=%08x,", req->access );
     fprintf( stderr, " inherit=%d", req->inherit );
-    return (int)sizeof(*req);
 }
 
-static int dump_open_console_reply( struct open_console_reply *req, int len )
+static void dump_open_console_reply( struct open_console_request *req )
 {
     fprintf( stderr, " handle=%d", req->handle );
-    return (int)sizeof(*req);
 }
 
-static int dump_set_console_fd_request( struct set_console_fd_request *req, int len )
+static void dump_set_console_fd_request( struct set_console_fd_request *req )
 {
     fprintf( stderr, " handle=%d,", req->handle );
+    fprintf( stderr, " file_handle=%d,", req->file_handle );
     fprintf( stderr, " pid=%d", req->pid );
-    return (int)sizeof(*req);
 }
 
-static int dump_get_console_mode_request( struct get_console_mode_request *req, int len )
+static void dump_get_console_mode_request( struct get_console_mode_request *req )
 {
     fprintf( stderr, " handle=%d", req->handle );
-    return (int)sizeof(*req);
 }
 
-static int dump_get_console_mode_reply( struct get_console_mode_reply *req, int len )
+static void dump_get_console_mode_reply( struct get_console_mode_request *req )
 {
     fprintf( stderr, " mode=%d", req->mode );
-    return (int)sizeof(*req);
 }
 
-static int dump_set_console_mode_request( struct set_console_mode_request *req, int len )
+static void dump_set_console_mode_request( struct set_console_mode_request *req )
 {
     fprintf( stderr, " handle=%d,", req->handle );
     fprintf( stderr, " mode=%d", req->mode );
-    return (int)sizeof(*req);
 }
 
-static int dump_set_console_info_request( struct set_console_info_request *req, int len )
+static void dump_set_console_info_request( struct set_console_info_request *req )
 {
     fprintf( stderr, " handle=%d,", req->handle );
     fprintf( stderr, " mask=%d,", req->mask );
     fprintf( stderr, " cursor_size=%d,", req->cursor_size );
     fprintf( stderr, " cursor_visible=%d,", req->cursor_visible );
-    fprintf( stderr, " title=" );
-    return dump_chars( req+1, len - (int)sizeof(*req) ) + sizeof(*req);
+    fprintf( stderr, " title=\"%s\"", req->title );
 }
 
-static int dump_get_console_info_request( struct get_console_info_request *req, int len )
+static void dump_get_console_info_request( struct get_console_info_request *req )
 {
     fprintf( stderr, " handle=%d", req->handle );
-    return (int)sizeof(*req);
 }
 
-static int dump_get_console_info_reply( struct get_console_info_reply *req, int len )
+static void dump_get_console_info_reply( struct get_console_info_request *req )
 {
     fprintf( stderr, " cursor_size=%d,", req->cursor_size );
     fprintf( stderr, " cursor_visible=%d,", req->cursor_visible );
     fprintf( stderr, " pid=%d,", req->pid );
-    fprintf( stderr, " title=" );
-    return dump_chars( req+1, len - (int)sizeof(*req) ) + sizeof(*req);
+    fprintf( stderr, " title=\"%s\"", req->title );
 }
 
-static int dump_write_console_input_request( struct write_console_input_request *req, int len )
+static void dump_write_console_input_request( struct write_console_input_request *req )
 {
     fprintf( stderr, " handle=%d,", req->handle );
     fprintf( stderr, " count=%d", req->count );
-    return (int)sizeof(*req);
 }
 
-static int dump_write_console_input_reply( struct write_console_input_reply *req, int len )
+static void dump_write_console_input_reply( struct write_console_input_request *req )
 {
     fprintf( stderr, " written=%d", req->written );
-    return (int)sizeof(*req);
 }
 
-static int dump_read_console_input_request( struct read_console_input_request *req, int len )
+static void dump_read_console_input_request( struct read_console_input_request *req )
 {
     fprintf( stderr, " handle=%d,", req->handle );
     fprintf( stderr, " count=%d,", req->count );
     fprintf( stderr, " flush=%d", req->flush );
-    return (int)sizeof(*req);
 }
 
-static int dump_read_console_input_reply( struct read_console_input_reply *req, int len )
+static void dump_read_console_input_reply( struct read_console_input_request *req )
 {
-    fprintf( stderr, " dummy=%d", req->dummy );
-    return (int)sizeof(*req);
+    fprintf( stderr, " read=%d", req->read );
 }
 
-static int dump_create_change_notification_request( struct create_change_notification_request *req, int len )
+static void dump_create_change_notification_request( struct create_change_notification_request *req )
 {
     fprintf( stderr, " subtree=%d,", req->subtree );
     fprintf( stderr, " filter=%d", req->filter );
-    return (int)sizeof(*req);
 }
 
-static int dump_create_change_notification_reply( struct create_change_notification_reply *req, int len )
+static void dump_create_change_notification_reply( struct create_change_notification_request *req )
 {
     fprintf( stderr, " handle=%d", req->handle );
-    return (int)sizeof(*req);
 }
 
-static int dump_create_mapping_request( struct create_mapping_request *req, int len )
+static void dump_create_mapping_request( struct create_mapping_request *req )
 {
     fprintf( stderr, " size_high=%d,", req->size_high );
     fprintf( stderr, " size_low=%d,", req->size_low );
     fprintf( stderr, " protect=%d,", req->protect );
     fprintf( stderr, " inherit=%d,", req->inherit );
-    fprintf( stderr, " handle=%d,", req->handle );
-    fprintf( stderr, " name=" );
-    return dump_chars( req+1, len - (int)sizeof(*req) ) + sizeof(*req);
+    fprintf( stderr, " file_handle=%d,", req->file_handle );
+    fprintf( stderr, " name=\"%s\"", req->name );
 }
 
-static int dump_create_mapping_reply( struct create_mapping_reply *req, int len )
+static void dump_create_mapping_reply( struct create_mapping_request *req )
 {
     fprintf( stderr, " handle=%d", req->handle );
-    return (int)sizeof(*req);
 }
 
-static int dump_open_mapping_request( struct open_mapping_request *req, int len )
+static void dump_open_mapping_request( struct open_mapping_request *req )
 {
     fprintf( stderr, " access=%08x,", req->access );
     fprintf( stderr, " inherit=%d,", req->inherit );
-    fprintf( stderr, " name=" );
-    return dump_chars( req+1, len - (int)sizeof(*req) ) + sizeof(*req);
+    fprintf( stderr, " name=\"%s\"", req->name );
 }
 
-static int dump_open_mapping_reply( struct open_mapping_reply *req, int len )
+static void dump_open_mapping_reply( struct open_mapping_request *req )
 {
     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 )
+static void dump_get_mapping_info_request( struct get_mapping_info_request *req )
 {
     fprintf( stderr, " handle=%d", req->handle );
-    return (int)sizeof(*req);
 }
 
-static int dump_get_mapping_info_reply( struct get_mapping_info_reply *req, int len )
+static void dump_get_mapping_info_reply( struct get_mapping_info_request *req )
 {
     fprintf( stderr, " size_high=%d,", req->size_high );
     fprintf( stderr, " size_low=%d,", req->size_low );
     fprintf( stderr, " protect=%d", req->protect );
-    return (int)sizeof(*req);
 }
 
-static int dump_create_device_request( struct create_device_request *req, int len )
+static void dump_create_device_request( struct create_device_request *req )
 {
     fprintf( stderr, " access=%08x,", req->access );
     fprintf( stderr, " inherit=%d,", req->inherit );
     fprintf( stderr, " id=%d", req->id );
-    return (int)sizeof(*req);
 }
 
-static int dump_create_device_reply( struct create_device_reply *req, int len )
+static void dump_create_device_reply( struct create_device_request *req )
 {
     fprintf( stderr, " handle=%d", req->handle );
-    return (int)sizeof(*req);
 }
 
-static int dump_create_snapshot_request( struct create_snapshot_request *req, int len )
+static void dump_create_snapshot_request( struct create_snapshot_request *req )
 {
     fprintf( stderr, " inherit=%d,", req->inherit );
     fprintf( stderr, " flags=%d", req->flags );
-    return (int)sizeof(*req);
 }
 
-static int dump_create_snapshot_reply( struct create_snapshot_reply *req, int len )
+static void dump_create_snapshot_reply( struct create_snapshot_request *req )
 {
     fprintf( stderr, " handle=%d", req->handle );
-    return (int)sizeof(*req);
 }
 
-static int dump_next_process_request( struct next_process_request *req, int len )
+static void dump_next_process_request( struct next_process_request *req )
 {
     fprintf( stderr, " handle=%d,", req->handle );
     fprintf( stderr, " reset=%d", req->reset );
-    return (int)sizeof(*req);
 }
 
-static int dump_next_process_reply( struct next_process_reply *req, int len )
+static void dump_next_process_reply( struct next_process_request *req )
 {
     fprintf( stderr, " pid=%p,", req->pid );
     fprintf( stderr, " threads=%d,", req->threads );
     fprintf( stderr, " priority=%d", req->priority );
-    return (int)sizeof(*req);
 }
 
-static int dump_wait_debug_event_request( struct wait_debug_event_request *req, int len )
+static void dump_wait_debug_event_request( struct wait_debug_event_request *req )
 {
     fprintf( stderr, " timeout=%d", req->timeout );
-    return (int)sizeof(*req);
 }
 
-static int dump_wait_debug_event_reply( struct wait_debug_event_reply *req, int len )
+static void dump_wait_debug_event_reply( struct wait_debug_event_request *req )
 {
     fprintf( stderr, " code=%d,", req->code );
     fprintf( stderr, " pid=%p,", req->pid );
     fprintf( stderr, " tid=%p", req->tid );
-    return (int)sizeof(*req);
 }
 
-static int dump_send_debug_event_request( struct send_debug_event_request *req, int len )
+static void dump_send_debug_event_request( struct send_debug_event_request *req )
 {
     fprintf( stderr, " code=%d", req->code );
-    return (int)sizeof(*req);
 }
 
-static int dump_send_debug_event_reply( struct send_debug_event_reply *req, int len )
+static void dump_send_debug_event_reply( struct send_debug_event_request *req )
 {
     fprintf( stderr, " status=%d", req->status );
-    return (int)sizeof(*req);
 }
 
-static int dump_continue_debug_event_request( struct continue_debug_event_request *req, int len )
+static void dump_continue_debug_event_request( struct continue_debug_event_request *req )
 {
     fprintf( stderr, " pid=%p,", req->pid );
     fprintf( stderr, " tid=%p,", req->tid );
     fprintf( stderr, " status=%d", req->status );
-    return (int)sizeof(*req);
 }
 
-static int dump_debug_process_request( struct debug_process_request *req, int len )
+static void dump_debug_process_request( struct debug_process_request *req )
 {
     fprintf( stderr, " pid=%p", req->pid );
-    return (int)sizeof(*req);
 }
 
 static const dump_func req_dumpers[REQ_NB_REQUESTS] = {
@@ -785,6 +697,7 @@
     (dump_func)dump_set_debug_request,
     (dump_func)dump_init_process_request,
     (dump_func)dump_init_thread_request,
+    (dump_func)dump_get_thread_buffer_request,
     (dump_func)dump_terminate_process_request,
     (dump_func)dump_terminate_thread_request,
     (dump_func)dump_get_process_info_request,
@@ -795,6 +708,7 @@
     (dump_func)dump_resume_thread_request,
     (dump_func)dump_debugger_request,
     (dump_func)dump_queue_apc_request,
+    (dump_func)dump_get_apcs_request,
     (dump_func)dump_close_handle_request,
     (dump_func)dump_get_handle_info_request,
     (dump_func)dump_set_handle_info_request,
@@ -811,6 +725,7 @@
     (dump_func)dump_release_semaphore_request,
     (dump_func)dump_open_semaphore_request,
     (dump_func)dump_create_file_request,
+    (dump_func)dump_alloc_file_handle_request,
     (dump_func)dump_get_read_fd_request,
     (dump_func)dump_get_write_fd_request,
     (dump_func)dump_set_file_pointer_request,
@@ -852,6 +767,7 @@
     (dump_func)dump_init_thread_reply,
     (dump_func)0,
     (dump_func)0,
+    (dump_func)0,
     (dump_func)dump_get_process_info_reply,
     (dump_func)0,
     (dump_func)dump_get_thread_info_reply,
@@ -860,6 +776,7 @@
     (dump_func)dump_resume_thread_reply,
     (dump_func)0,
     (dump_func)0,
+    (dump_func)dump_get_apcs_reply,
     (dump_func)0,
     (dump_func)dump_get_handle_info_reply,
     (dump_func)0,
@@ -876,6 +793,7 @@
     (dump_func)dump_release_semaphore_reply,
     (dump_func)dump_open_semaphore_reply,
     (dump_func)dump_create_file_reply,
+    (dump_func)dump_alloc_file_handle_reply,
     (dump_func)0,
     (dump_func)0,
     (dump_func)dump_set_file_pointer_reply,
@@ -915,6 +833,7 @@
     "set_debug",
     "init_process",
     "init_thread",
+    "get_thread_buffer",
     "terminate_process",
     "terminate_thread",
     "get_process_info",
@@ -925,6 +844,7 @@
     "resume_thread",
     "debugger",
     "queue_apc",
+    "get_apcs",
     "close_handle",
     "get_handle_info",
     "set_handle_info",
@@ -941,6 +861,7 @@
     "release_semaphore",
     "open_semaphore",
     "create_file",
+    "alloc_file_handle",
     "get_read_fd",
     "get_write_fd",
     "set_file_pointer",
@@ -979,16 +900,14 @@
 
 void trace_request( enum request req, int fd )
 {
-    int size, len;
     current->last_req = req;
-    fprintf( stderr, "%08x: %s(", (unsigned int)current, req_names[req] );
-    len = (char *)current->req_end - (char *)current->req_pos;
-    size = req_dumpers[req]( current->req_pos, len );
-    if ((len -= size) > 0)
+    if (req < REQ_NB_REQUESTS)
     {
-        unsigned char *ptr = (unsigned char *)current->req_pos + size;
-        while (len--) fprintf( stderr, ", %02x", *ptr++ );
+        fprintf( stderr, "%08x: %s(", (unsigned int)current, req_names[req] );
+        req_dumpers[req]( current->buffer );
     }
+    else
+        fprintf( stderr, "%08x: %d(", (unsigned int)current, req );
     if (fd != -1) fprintf( stderr, " ) fd=%d\n", fd );
     else fprintf( stderr, " )\n" );
 }
@@ -1004,22 +923,14 @@
              (unsigned int)current, exit_code );
 }
 
-void trace_reply( struct thread *thread, int pass_fd )
+void trace_reply( struct thread *thread, unsigned int res, int pass_fd )
 {
-    struct header *head = thread->buffer;
-    int len = head->len - sizeof(*head);
     fprintf( stderr, "%08x: %s() = %d",
-             (unsigned int)thread, req_names[thread->last_req], head->type );
-    if (len)
+             (unsigned int)thread, req_names[thread->last_req], res );
+    if (reply_dumpers[thread->last_req])
     {
-        const unsigned char *data = (unsigned char *)(head + 1);
-        int res = 0;
-	fprintf( stderr, " {" );
-	if (reply_dumpers[thread->last_req])
-	    res = reply_dumpers[thread->last_req]( data, len );
-        len -= res;
-        data += res;
-        while (len--) fprintf( stderr, ", %02x", *data++ );
+        fprintf( stderr, " {" );
+        reply_dumpers[thread->last_req]( thread->buffer );
 	fprintf( stderr, " }" );
     }
     if (pass_fd != -1) fprintf( stderr, " fd=%d\n", pass_fd );