diff --git a/files/change.c b/files/change.c
index 4142d39b0eec544a2d4e3c46e8d622acda64eb46..c5f63109c247331e5fcbc8171d9a29adbcd91d8d 100644
--- a/files/change.c
+++ b/files/change.c
@@ -19,20 +19,17 @@
 
 
 /****************************************************************************
- *		FindFirstChangeNotification32A (KERNEL32.248)
+ *		FindFirstChangeNotificationA (KERNEL32.248)
  */
-HANDLE WINAPI FindFirstChangeNotificationA( LPCSTR lpPathName,
-                                                BOOL bWatchSubtree,
-                                                DWORD dwNotifyFilter ) 
+HANDLE WINAPI FindFirstChangeNotificationA( LPCSTR lpPathName, BOOL bWatchSubtree,
+                                            DWORD dwNotifyFilter ) 
 {
-    struct create_change_notification_request req;
-    struct create_change_notification_reply reply;
+    struct create_change_notification_request *req = get_req_buffer();
 
-    req.subtree = bWatchSubtree;
-    req.filter  = dwNotifyFilter;
-    CLIENT_SendRequest( REQ_CREATE_CHANGE_NOTIFICATION, -1, 1, &req, sizeof(req) );
-    CLIENT_WaitSimpleReply( &reply, sizeof(reply), NULL );
-    return reply.handle;
+    req->subtree = bWatchSubtree;
+    req->filter  = dwNotifyFilter;
+    server_call( REQ_CREATE_CHANGE_NOTIFICATION );
+    return req->handle;
 }
 
 /****************************************************************************
diff --git a/files/dos_fs.c b/files/dos_fs.c
index c708b540f9e98d5bc0193b28cc3ff8c2f36e0a2a..fdcb3544dd1f44f2751cd655fa6ee1152f2b8c9d 100644
--- a/files/dos_fs.c
+++ b/files/dos_fs.c
@@ -613,17 +613,14 @@ const DOS_DEVICE *DOSFS_GetDevice( const char *name )
  */
 const DOS_DEVICE *DOSFS_GetDeviceByHandle( HFILE hFile )
 {
-    struct get_file_info_request req;
-    struct get_file_info_reply reply;
+    struct get_file_info_request *req = get_req_buffer();
 
-    req.handle = hFile;
-    CLIENT_SendRequest( REQ_GET_FILE_INFO, -1, 1, &req, sizeof(req) );
-    if (!CLIENT_WaitSimpleReply( &reply, sizeof(reply), NULL ) &&
-        (reply.type == FILE_TYPE_UNKNOWN))
+    req->handle = hFile;
+    if (!server_call( REQ_GET_FILE_INFO ) && (req->type == FILE_TYPE_UNKNOWN))
     {
-        if ((reply.attr >= 0) &&
-            (reply.attr < sizeof(DOSFS_Devices)/sizeof(DOSFS_Devices[0])))
-            return &DOSFS_Devices[reply.attr];
+        if ((req->attr >= 0) &&
+            (req->attr < sizeof(DOSFS_Devices)/sizeof(DOSFS_Devices[0])))
+            return &DOSFS_Devices[req->attr];
     }
     return NULL;
 }
diff --git a/files/file.c b/files/file.c
index d7e8558250bd3dabcd7dc4e495cec5e024b8e12c..edce50779d0868f41a2e96a0d7251fe2cc8bb54d 100644
--- a/files/file.c
+++ b/files/file.c
@@ -304,24 +304,16 @@ void FILE_SetDosError(void)
 HFILE FILE_DupUnixHandle( int fd, DWORD access )
 {
     int unix_handle;
-    struct create_file_request req;
-    struct create_file_reply reply;
+    struct alloc_file_handle_request *req = get_req_buffer();
 
     if ((unix_handle = dup(fd)) == -1)
     {
         FILE_SetDosError();
         return INVALID_HANDLE_VALUE;
     }
-    req.access  = access;
-    req.inherit = 1;
-    req.sharing = FILE_SHARE_READ | FILE_SHARE_WRITE;
-    req.create  = 0;
-    req.attrs   = 0;
-    
-    CLIENT_SendRequest( REQ_CREATE_FILE, unix_handle, 1,
-                        &req, sizeof(req) );
-    CLIENT_WaitSimpleReply( &reply, sizeof(reply), NULL );
-    return reply.handle;
+    req->access  = access;
+    server_call_fd( REQ_ALLOC_FILE_HANDLE, unix_handle, NULL );
+    return req->handle;
 }
 
 
@@ -334,38 +326,28 @@ HFILE FILE_CreateFile( LPCSTR filename, DWORD access, DWORD sharing,
                          LPSECURITY_ATTRIBUTES sa, DWORD creation,
                          DWORD attributes, HANDLE template )
 {
-    struct create_file_request req;
-    struct create_file_reply reply;
-
-    req.access  = access;
-    req.inherit = (sa && (sa->nLength>=sizeof(*sa)) && sa->bInheritHandle);
-    req.sharing = sharing;
-    req.create  = creation;
-    req.attrs   = attributes;
-    CLIENT_SendRequest( REQ_CREATE_FILE, -1, 2,
-                        &req, sizeof(req),
-                        filename, strlen(filename) + 1 );
+    struct create_file_request *req = get_req_buffer();
+
+    req->access  = access;
+    req->inherit = (sa && (sa->nLength>=sizeof(*sa)) && sa->bInheritHandle);
+    req->sharing = sharing;
+    req->create  = creation;
+    req->attrs   = attributes;
+    lstrcpynA( req->name, filename, server_remaining(req->name) );
     SetLastError(0);
-    CLIENT_WaitSimpleReply( &reply, sizeof(reply), NULL );
+    server_call( REQ_CREATE_FILE );
 
     /* If write access failed, retry without GENERIC_WRITE */
 
-    if ((reply.handle == -1) && !Options.failReadOnly &&
+    if ((req->handle == -1) && !Options.failReadOnly &&
         (access & GENERIC_WRITE)) 
     {
     	DWORD lasterror = GetLastError();
-	if ((lasterror == ERROR_ACCESS_DENIED) || 
-	    (lasterror == ERROR_WRITE_PROTECT))
-        {
-	    req.access &= ~GENERIC_WRITE;
-	    CLIENT_SendRequest( REQ_CREATE_FILE, -1, 2,
-				&req, sizeof(req),
-				filename, strlen(filename) + 1 );
-            SetLastError(0);
-	    CLIENT_WaitSimpleReply( &reply, sizeof(reply), NULL );
-	}
+	if ((lasterror == ERROR_ACCESS_DENIED) || (lasterror == ERROR_WRITE_PROTECT))
+            return FILE_CreateFile( filename, access & ~GENERIC_WRITE, sharing,
+                                    sa, creation, attributes, template );
     }
-    return reply.handle;
+    return req->handle;
 }
 
 
@@ -376,16 +358,14 @@ HFILE FILE_CreateFile( LPCSTR filename, DWORD access, DWORD sharing,
  */
 HFILE FILE_CreateDevice( int client_id, DWORD access, LPSECURITY_ATTRIBUTES sa )
 {
-    struct create_device_request req;
-    struct create_device_reply reply;
+    struct create_device_request *req = get_req_buffer();
 
-    req.access  = access;
-    req.inherit = (sa && (sa->nLength>=sizeof(*sa)) && sa->bInheritHandle);
-    req.id      = client_id;
-    CLIENT_SendRequest( REQ_CREATE_DEVICE, -1, 1, &req, sizeof(req) );
+    req->access  = access;
+    req->inherit = (sa && (sa->nLength>=sizeof(*sa)) && sa->bInheritHandle);
+    req->id      = client_id;
     SetLastError(0);
-    CLIENT_WaitSimpleReply( &reply, sizeof(reply), NULL );
-    return reply.handle;
+    server_call( REQ_CREATE_DEVICE );
+    return req->handle;
 }
 
 
@@ -562,24 +542,21 @@ BOOL FILE_Stat( LPCSTR unixName, BY_HANDLE_FILE_INFORMATION *info )
 DWORD WINAPI GetFileInformationByHandle( HFILE hFile,
                                          BY_HANDLE_FILE_INFORMATION *info )
 {
-    struct get_file_info_request req;
-    struct get_file_info_reply reply;
+    struct get_file_info_request *req = get_req_buffer();
 
     if (!info) return 0;
-    req.handle = hFile;
-    CLIENT_SendRequest( REQ_GET_FILE_INFO, -1, 1, &req, sizeof(req) );
-    if (CLIENT_WaitSimpleReply( &reply, sizeof(reply), NULL ))
-        return 0;
-    DOSFS_UnixTimeToFileTime( reply.write_time, &info->ftCreationTime, 0 );
-    DOSFS_UnixTimeToFileTime( reply.write_time, &info->ftLastWriteTime, 0 );
-    DOSFS_UnixTimeToFileTime( reply.access_time, &info->ftLastAccessTime, 0 );
-    info->dwFileAttributes     = reply.attr;
-    info->dwVolumeSerialNumber = reply.serial;
-    info->nFileSizeHigh        = reply.size_high;
-    info->nFileSizeLow         = reply.size_low;
-    info->nNumberOfLinks       = reply.links;
-    info->nFileIndexHigh       = reply.index_high;
-    info->nFileIndexLow        = reply.index_low;
+    req->handle = hFile;
+    if (server_call( REQ_GET_FILE_INFO )) return 0;
+    DOSFS_UnixTimeToFileTime( req->write_time, &info->ftCreationTime, 0 );
+    DOSFS_UnixTimeToFileTime( req->write_time, &info->ftLastWriteTime, 0 );
+    DOSFS_UnixTimeToFileTime( req->access_time, &info->ftLastAccessTime, 0 );
+    info->dwFileAttributes     = req->attr;
+    info->dwVolumeSerialNumber = req->serial;
+    info->nFileSizeHigh        = req->size_high;
+    info->nFileSizeLow         = req->size_low;
+    info->nNumberOfLinks       = req->links;
+    info->nFileIndexHigh       = req->index_high;
+    info->nFileIndexLow        = req->index_low;
     return 1;
 }
 
@@ -1121,7 +1098,7 @@ HFILE WINAPI _lclose( HFILE hFile )
 BOOL WINAPI ReadFile( HANDLE hFile, LPVOID buffer, DWORD bytesToRead,
                         LPDWORD bytesRead, LPOVERLAPPED overlapped )
 {
-    struct get_read_fd_request req;
+    struct get_read_fd_request *req = get_req_buffer();
     int unix_handle, result;
 
     TRACE(file, "%d %p %ld\n", hFile, buffer, bytesToRead );
@@ -1129,9 +1106,8 @@ BOOL WINAPI ReadFile( HANDLE hFile, LPVOID buffer, DWORD bytesToRead,
     if (bytesRead) *bytesRead = 0;  /* Do this before anything else */
     if (!bytesToRead) return TRUE;
 
-    req.handle = hFile;
-    CLIENT_SendRequest( REQ_GET_READ_FD, -1, 1, &req, sizeof(req) );
-    CLIENT_WaitReply( NULL, &unix_handle, 0 );
+    req->handle = hFile;
+    server_call_fd( REQ_GET_READ_FD, -1, &unix_handle );
     if (unix_handle == -1) return FALSE;
     while ((result = read( unix_handle, buffer, bytesToRead )) == -1)
     {
@@ -1153,7 +1129,7 @@ BOOL WINAPI ReadFile( HANDLE hFile, LPVOID buffer, DWORD bytesToRead,
 BOOL WINAPI WriteFile( HANDLE hFile, LPCVOID buffer, DWORD bytesToWrite,
                          LPDWORD bytesWritten, LPOVERLAPPED overlapped )
 {
-    struct get_write_fd_request req;
+    struct get_write_fd_request *req = get_req_buffer();
     int unix_handle, result;
 
     TRACE(file, "%d %p %ld\n", hFile, buffer, bytesToWrite );
@@ -1161,9 +1137,8 @@ BOOL WINAPI WriteFile( HANDLE hFile, LPCVOID buffer, DWORD bytesToWrite,
     if (bytesWritten) *bytesWritten = 0;  /* Do this before anything else */
     if (!bytesToWrite) return TRUE;
 
-    req.handle = hFile;
-    CLIENT_SendRequest( REQ_GET_WRITE_FD, -1, 1, &req, sizeof(req) );
-    CLIENT_WaitReply( NULL, &unix_handle, 0 );
+    req->handle = hFile;
+    server_call_fd( REQ_GET_WRITE_FD, -1, &unix_handle );
     if (unix_handle == -1) return FALSE;
     while ((result = write( unix_handle, buffer, bytesToWrite )) == -1)
     {
@@ -1254,8 +1229,7 @@ HFILE WINAPI _lcreat( LPCSTR path, INT attr )
 DWORD WINAPI SetFilePointer( HFILE hFile, LONG distance, LONG *highword,
                              DWORD method )
 {
-    struct set_file_pointer_request req;
-    struct set_file_pointer_reply reply;
+    struct set_file_pointer_request *req = get_req_buffer();
 
     if (highword && *highword)
     {
@@ -1266,16 +1240,15 @@ DWORD WINAPI SetFilePointer( HFILE hFile, LONG distance, LONG *highword,
     TRACE(file, "handle %d offset %ld origin %ld\n",
           hFile, distance, method );
 
-    req.handle = hFile;
-    req.low = distance;
-    req.high = highword ? *highword : 0;
+    req->handle = hFile;
+    req->low = distance;
+    req->high = highword ? *highword : 0;
     /* FIXME: assumes 1:1 mapping between Windows and Unix seek constants */
-    req.whence = method;
-    CLIENT_SendRequest( REQ_SET_FILE_POINTER, -1, 1, &req, sizeof(req) );
-    if (CLIENT_WaitSimpleReply( &reply, sizeof(reply), NULL )) return 0xffffffff;
+    req->whence = method;
     SetLastError( 0 );
-    if (highword) *highword = reply.high;
-    return reply.low;
+    if (server_call( REQ_SET_FILE_POINTER )) return 0xffffffff;
+    if (highword) *highword = req->new_high;
+    return req->new_low;
 }
 
 
@@ -1462,11 +1435,9 @@ UINT WINAPI SetHandleCount( UINT count )
  */
 BOOL WINAPI FlushFileBuffers( HFILE hFile )
 {
-    struct flush_file_request req;
-
-    req.handle = hFile;
-    CLIENT_SendRequest( REQ_FLUSH_FILE, -1, 1, &req, sizeof(req) );
-    return !CLIENT_WaitReply( NULL, NULL, 0 );
+    struct flush_file_request *req = get_req_buffer();
+    req->handle = hFile;
+    return !server_call( REQ_FLUSH_FILE );
 }
 
 
@@ -1475,11 +1446,9 @@ BOOL WINAPI FlushFileBuffers( HFILE hFile )
  */
 BOOL WINAPI SetEndOfFile( HFILE hFile )
 {
-    struct truncate_file_request req;
-
-    req.handle = hFile;
-    CLIENT_SendRequest( REQ_TRUNCATE_FILE, -1, 1, &req, sizeof(req) );
-    return !CLIENT_WaitReply( NULL, NULL, 0 );
+    struct truncate_file_request *req = get_req_buffer();
+    req->handle = hFile;
+    return !server_call( REQ_TRUNCATE_FILE );
 }
 
 
@@ -1631,14 +1600,10 @@ int FILE_munmap( LPVOID start, DWORD size_high, DWORD size_low )
  */
 DWORD WINAPI GetFileType( HFILE hFile )
 {
-    struct get_file_info_request req;
-    struct get_file_info_reply reply;
-
-    req.handle = hFile;
-    CLIENT_SendRequest( REQ_GET_FILE_INFO, -1, 1, &req, sizeof(req) );
-    if (CLIENT_WaitSimpleReply( &reply, sizeof(reply), NULL ))
-        return FILE_TYPE_UNKNOWN;
-    return reply.type;
+    struct get_file_info_request *req = get_req_buffer();
+    req->handle = hFile;
+    if (server_call( REQ_GET_FILE_INFO )) return FILE_TYPE_UNKNOWN;
+    return req->type;
 }
 
 
@@ -1913,20 +1878,18 @@ BOOL WINAPI SetFileTime( HFILE hFile,
                            const FILETIME *lpLastAccessTime,
                            const FILETIME *lpLastWriteTime )
 {
-    struct set_file_time_request req;
+    struct set_file_time_request *req = get_req_buffer();
 
-    req.handle = hFile;
+    req->handle = hFile;
     if (lpLastAccessTime)
-	req.access_time = DOSFS_FileTimeToUnixTime(lpLastAccessTime, NULL);
+	req->access_time = DOSFS_FileTimeToUnixTime(lpLastAccessTime, NULL);
     else
-	req.access_time = 0; /* FIXME */
+	req->access_time = 0; /* FIXME */
     if (lpLastWriteTime)
-	req.write_time = DOSFS_FileTimeToUnixTime(lpLastWriteTime, NULL);
+	req->write_time = DOSFS_FileTimeToUnixTime(lpLastWriteTime, NULL);
     else
-	req.write_time = 0; /* FIXME */
-
-    CLIENT_SendRequest( REQ_SET_FILE_TIME, -1, 1, &req, sizeof(req) );
-    return !CLIENT_WaitReply( NULL, NULL, 0 );
+	req->write_time = 0; /* FIXME */
+    return !server_call( REQ_SET_FILE_TIME );
 }
 
 
@@ -1936,15 +1899,14 @@ BOOL WINAPI SetFileTime( HFILE hFile,
 BOOL WINAPI LockFile( HFILE hFile, DWORD dwFileOffsetLow, DWORD dwFileOffsetHigh,
                         DWORD nNumberOfBytesToLockLow, DWORD nNumberOfBytesToLockHigh )
 {
-    struct lock_file_request req;
+    struct lock_file_request *req = get_req_buffer();
 
-    req.handle      = hFile;
-    req.offset_low  = dwFileOffsetLow;
-    req.offset_high = dwFileOffsetHigh;
-    req.count_low   = nNumberOfBytesToLockLow;
-    req.count_high  = nNumberOfBytesToLockHigh;
-    CLIENT_SendRequest( REQ_LOCK_FILE, -1, 1, &req, sizeof(req) );
-    return !CLIENT_WaitReply( NULL, NULL, 0 );
+    req->handle      = hFile;
+    req->offset_low  = dwFileOffsetLow;
+    req->offset_high = dwFileOffsetHigh;
+    req->count_low   = nNumberOfBytesToLockLow;
+    req->count_high  = nNumberOfBytesToLockHigh;
+    return !server_call( REQ_LOCK_FILE );
 }
 
 /**************************************************************************
@@ -1984,15 +1946,14 @@ BOOL WINAPI LockFileEx( HANDLE hFile, DWORD flags, DWORD reserved,
 BOOL WINAPI UnlockFile( HFILE hFile, DWORD dwFileOffsetLow, DWORD dwFileOffsetHigh,
                           DWORD nNumberOfBytesToUnlockLow, DWORD nNumberOfBytesToUnlockHigh )
 {
-    struct unlock_file_request req;
+    struct unlock_file_request *req = get_req_buffer();
 
-    req.handle      = hFile;
-    req.offset_low  = dwFileOffsetLow;
-    req.offset_high = dwFileOffsetHigh;
-    req.count_low   = nNumberOfBytesToUnlockLow;
-    req.count_high  = nNumberOfBytesToUnlockHigh;
-    CLIENT_SendRequest( REQ_UNLOCK_FILE, -1, 1, &req, sizeof(req) );
-    return !CLIENT_WaitReply( NULL, NULL, 0 );
+    req->handle      = hFile;
+    req->offset_low  = dwFileOffsetLow;
+    req->offset_high = dwFileOffsetHigh;
+    req->count_low   = nNumberOfBytesToUnlockLow;
+    req->count_high  = nNumberOfBytesToUnlockHigh;
+    return !server_call( REQ_UNLOCK_FILE );
 }
 
 
diff --git a/include/server.h b/include/server.h
index b2f5426cc51caeab767707877740b2e5ededbdc9..f70847681881072af0437ea4b808df9a215f9e77 100644
--- a/include/server.h
+++ b/include/server.h
@@ -10,144 +10,122 @@
 #include <stdlib.h>
 #include <time.h>
 
-/* message header as sent on the wire */
-struct header
-{
-    unsigned int  len;     /* total msg length (including this header) */
-    unsigned int  type;    /* msg type */
-};
-
-/* max msg length (including the header) */
-#define MAX_MSG_LENGTH  16384
+/* Request structures */
 
-/* data structure used to pass an fd with sendmsg/recvmsg */
-struct cmsg_fd
-{
-    int len;   /* sizeof structure */
-    int level; /* SOL_SOCKET */
-    int type;  /* SCM_RIGHTS */
-    int fd;    /* fd to pass */
-};
+/* Following are the definitions of all the client<->server   */
+/* communication format; if you make any change in this file, */
+/* you must run tools/make_requests again. */
 
-/* Request structures */
 
-/* following are the definitions of all the client<->server  */
-/* communication format; requests are from client to server, */
-/* replies are from server to client. All requests must have */
-/* a corresponding structure; the replies can be empty in    */
-/* which case it isn't necessary to define a structure.      */
+/* These empty macros are used by tools/make_requests */
+/* to generate the request/reply tracing functions */
+#define IN  /*nothing*/
+#define OUT /*nothing*/
 
 
 /* Create a new process from the context of the parent */
 struct new_process_request
 {
-    int          inherit;      /* inherit flag */
-    int          inherit_all;  /* inherit all handles from parent */
-    int          create_flags; /* creation flags */
-    int          start_flags;  /* flags from startup info */
-    int          hstdin;       /* handle for stdin */
-    int          hstdout;      /* handle for stdout */
-    int          hstderr;      /* handle for stderr */
-    int          cmd_show;     /* main window show mode */
-    void*        env_ptr;      /* pointer to environment (FIXME: hack) */
-    char         cmd_line[0];  /* command line */
-};
-struct new_process_reply
-{
-    void*        pid;          /* process id */
-    int          handle;       /* process handle (in the current process) */
+    IN  int          inherit;      /* inherit flag */
+    IN  int          inherit_all;  /* inherit all handles from parent */
+    IN  int          create_flags; /* creation flags */
+    IN  int          start_flags;  /* flags from startup info */
+    IN  int          hstdin;       /* handle for stdin */
+    IN  int          hstdout;      /* handle for stdout */
+    IN  int          hstderr;      /* handle for stderr */
+    IN  int          cmd_show;     /* main window show mode */
+    IN  void*        env_ptr;      /* pointer to environment (FIXME: hack) */
+    OUT void*        pid;          /* process id */
+    OUT int          handle;       /* process handle (in the current process) */
+    IN  char         cmdline[1];   /* command line */
 };
 
 
 /* Create a new thread from the context of the parent */
 struct new_thread_request
 {
-    void*        pid;          /* process id for the new thread */
-    int          suspend;      /* new thread should be suspended on creation */ 
-    int          inherit;      /* inherit flag */
-};
-struct new_thread_reply
-{
-    void*        tid;          /* thread id */
-    int          handle;       /* thread handle (in the current process) */
+    IN  void*        pid;          /* process id for the new thread */
+    IN  int          suspend;      /* new thread should be suspended on creation */ 
+    IN  int          inherit;      /* inherit flag */
+    OUT void*        tid;          /* thread id */
+    OUT int          handle;       /* thread handle (in the current process) */
 };
 
 
 /* Set the server debug level */
 struct set_debug_request
 {
-    int          level;        /* New debug level */
+    IN  int          level;        /* New debug level */
 };
 
 
 /* Initialize a process; called from the new process context */
 struct init_process_request
 {
-    int          dummy;
-};
-struct init_process_reply
-{
-    int          start_flags;  /* flags from startup info */
-    int          hstdin;       /* handle for stdin */
-    int          hstdout;      /* handle for stdout */
-    int          hstderr;      /* handle for stderr */
-    int          cmd_show;     /* main window show mode */
-    void*        env_ptr;      /* pointer to environment (FIXME: hack) */
-    char         cmdline[0];   /* command line */
+    OUT int          start_flags;  /* flags from startup info */
+    OUT int          hstdin;       /* handle for stdin */
+    OUT int          hstdout;      /* handle for stdout */
+    OUT int          hstderr;      /* handle for stderr */
+    OUT int          cmd_show;     /* main window show mode */
+    OUT void*        env_ptr;      /* pointer to environment (FIXME: hack) */
+    OUT char         cmdline[1];   /* command line */
 };
 
 
 /* Initialize a thread; called from the child after fork()/clone() */
 struct init_thread_request
 {
-    int          unix_pid;     /* Unix pid of new thread */
-    void*        teb;          /* TEB of new thread (in thread address space) */
+    IN  int          unix_pid;     /* Unix pid of new thread */
+    IN  void*        teb;          /* TEB of new thread (in thread address space) */
+    OUT void*        pid;          /* process id of the new thread's process */
+    OUT void*        tid;          /* thread id of the new thread */
 };
-struct init_thread_reply
+
+
+/* Retrieve the thread buffer file descriptor */
+/* The reply to this request is the first thing a newly */
+/* created thread gets (without having to request it) */
+struct get_thread_buffer_request
 {
-    void*        pid;          /* process id of the new thread's process */
-    void*        tid;          /* thread id of the new thread */
+    IN  int          dummy;
 };
 
 
 /* Terminate a process */
 struct terminate_process_request
 {
-    int          handle;       /* process handle to terminate */
-    int          exit_code;    /* process exit code */
+    IN  int          handle;       /* process handle to terminate */
+    IN  int          exit_code;    /* process exit code */
 };
 
 
 /* Terminate a thread */
 struct terminate_thread_request
 {
-    int          handle;       /* thread handle to terminate */
-    int          exit_code;    /* thread exit code */
+    IN  int          handle;       /* thread handle to terminate */
+    IN  int          exit_code;    /* thread exit code */
 };
 
 
 /* Retrieve information about a process */
 struct get_process_info_request
 {
-    int          handle;       /* process handle */
-};
-struct get_process_info_reply
-{
-    void*        pid;              /* server process id */
-    int          exit_code;        /* process exit code */
-    int          priority;         /* priority class */
-    int          process_affinity; /* process affinity mask */
-    int          system_affinity;  /* system affinity mask */
+    IN  int          handle;       /* process handle */
+    OUT void*        pid;              /* server process id */
+    OUT int          exit_code;        /* process exit code */
+    OUT int          priority;         /* priority class */
+    OUT int          process_affinity; /* process affinity mask */
+    OUT int          system_affinity;  /* system affinity mask */
 };
 
 
 /* Set a process informations */
 struct set_process_info_request
 {
-    int          handle;       /* process handle */
-    int          mask;         /* setting mask (see below) */
-    int          priority;     /* priority class */
-    int          affinity;     /* affinity mask */
+    IN  int          handle;       /* process handle */
+    IN  int          mask;         /* setting mask (see below) */
+    IN  int          priority;     /* priority class */
+    IN  int          affinity;     /* affinity mask */
 };
 #define SET_PROCESS_INFO_PRIORITY 0x01
 #define SET_PROCESS_INFO_AFFINITY 0x02
@@ -156,23 +134,20 @@ struct set_process_info_request
 /* Retrieve information about a thread */
 struct get_thread_info_request
 {
-    int          handle;       /* thread handle */
-};
-struct get_thread_info_reply
-{
-    void*        tid;          /* server thread id */
-    int          exit_code;    /* thread exit code */
-    int          priority;     /* thread priority level */
+    IN  int          handle;       /* thread handle */
+    OUT void*        tid;          /* server thread id */
+    OUT int          exit_code;    /* thread exit code */
+    OUT int          priority;     /* thread priority level */
 };
 
 
 /* Set a thread informations */
 struct set_thread_info_request
 {
-    int          handle;       /* thread handle */
-    int          mask;         /* setting mask (see below) */
-    int          priority;     /* priority class */
-    int          affinity;     /* affinity mask */
+    IN  int          handle;       /* thread handle */
+    IN  int          mask;         /* setting mask (see below) */
+    IN  int          priority;     /* priority class */
+    IN  int          affinity;     /* affinity mask */
 };
 #define SET_THREAD_INFO_PRIORITY 0x01
 #define SET_THREAD_INFO_AFFINITY 0x02
@@ -181,29 +156,23 @@ struct set_thread_info_request
 /* Suspend a thread */
 struct suspend_thread_request
 {
-    int          handle;       /* thread handle */
-};
-struct suspend_thread_reply
-{
-    int          count;        /* new suspend count */
+    IN  int          handle;       /* thread handle */
+    OUT int          count;        /* new suspend count */
 };
 
 
 /* Resume a thread */
 struct resume_thread_request
 {
-    int          handle;       /* thread handle */
-};
-struct resume_thread_reply
-{
-    int          count;        /* new suspend count */
+    IN  int          handle;       /* thread handle */
+    OUT int          count;        /* new suspend count */
 };
 
 
 /* Debugger support: freeze / unfreeze */
 struct debugger_request
 {
-    int          op;           /* operation type */
+    IN  int          op;           /* operation type */
 };
 
 enum debugger_op { DEBUGGER_FREEZE_ALL, DEBUGGER_UNFREEZE_ALL };
@@ -212,83 +181,78 @@ enum debugger_op { DEBUGGER_FREEZE_ALL, DEBUGGER_UNFREEZE_ALL };
 /* Queue an APC for a thread */
 struct queue_apc_request
 {
-    int          handle;       /* thread handle */
-    void*        func;         /* function to call */
-    void*        param;        /* param for function to call */
+    IN  int          handle;       /* thread handle */
+    IN  void*        func;         /* function to call */
+    IN  void*        param;        /* param for function to call */
+};
+
+
+/* Get list of APC to call */
+struct get_apcs_request
+{
+    OUT int          count;        /* number of apcs */
+    OUT void*        apcs[1];      /* async procedures to call */
 };
 
 
 /* Close a handle for the current process */
 struct close_handle_request
 {
-    int          handle;       /* handle to close */
+    IN  int          handle;       /* handle to close */
 };
 
 
 /* Get information about a handle */
 struct get_handle_info_request
 {
-    int          handle;       /* handle we are interested in */
-};
-struct get_handle_info_reply
-{
-    int          flags;        /* handle flags */
+    IN  int          handle;       /* handle we are interested in */
+    OUT int          flags;        /* handle flags */
 };
 
 
 /* Set a handle information */
 struct set_handle_info_request
 {
-    int          handle;       /* handle we are interested in */
-    int          flags;        /* new handle flags */
-    int          mask;         /* mask for flags to set */
+    IN  int          handle;       /* handle we are interested in */
+    IN  int          flags;        /* new handle flags */
+    IN  int          mask;         /* mask for flags to set */
 };
 
 
 /* Duplicate a handle */
 struct dup_handle_request
 {
-    int          src_process;  /* src process handle */
-    int          src_handle;   /* src handle to duplicate */
-    int          dst_process;  /* dst process handle */
-    unsigned int access;       /* wanted access rights */
-    int          inherit;      /* inherit flag */
-    int          options;      /* duplicate options (see below) */
+    IN  int          src_process;  /* src process handle */
+    IN  int          src_handle;   /* src handle to duplicate */
+    IN  int          dst_process;  /* dst process handle */
+    IN  unsigned int access;       /* wanted access rights */
+    IN  int          inherit;      /* inherit flag */
+    IN  int          options;      /* duplicate options (see below) */
+    OUT int          handle;       /* duplicated handle in dst process */
 };
 #define DUP_HANDLE_CLOSE_SOURCE  DUPLICATE_CLOSE_SOURCE
 #define DUP_HANDLE_SAME_ACCESS   DUPLICATE_SAME_ACCESS
 #define DUP_HANDLE_MAKE_GLOBAL   0x80000000  /* Not a Windows flag */
-struct dup_handle_reply
-{
-    int          handle;       /* duplicated handle in dst process */
-};
 
 
 /* Open a handle to a process */
 struct open_process_request
 {
-    void*        pid;          /* process id to open */
-    unsigned int access;       /* wanted access rights */
-    int          inherit;      /* inherit flag */
-};
-struct open_process_reply
-{
-    int          handle;       /* handle to the process */
+    IN  void*        pid;          /* process id to open */
+    IN  unsigned int access;       /* wanted access rights */
+    IN  int          inherit;      /* inherit flag */
+    OUT int          handle;       /* handle to the process */
 };
 
 
 /* Wait for handles */
 struct select_request
 {
-    int          count;        /* handles count */
-    int          flags;        /* wait flags (see below) */
-    int          timeout;      /* timeout in ms */
-    int          handles[0];   /* handles to select on */
-};
-struct select_reply
-{
-    int          signaled;     /* signaled handle */
-    void*        apcs[0];      /* async procedures to call */
+    IN  int          count;        /* handles count */
+    IN  int          flags;        /* wait flags (see below) */
+    IN  int          timeout;      /* timeout in ms */
+    OUT int          signaled;     /* signaled handle */
+    IN  int          handles[1];   /* handles to select on */
 };
 #define SELECT_ALL       1
 #define SELECT_ALERTABLE 2
@@ -298,21 +262,18 @@ struct select_reply
 /* Create an event */
 struct create_event_request
 {
-    int          manual_reset;  /* manual reset event */
-    int          initial_state; /* initial state of the event */
-    int          inherit;       /* inherit flag */
-    char         name[0];       /* event name */
-};
-struct create_event_reply
-{
-    int          handle;        /* handle to the event */
+    IN  int          manual_reset;  /* manual reset event */
+    IN  int          initial_state; /* initial state of the event */
+    IN  int          inherit;       /* inherit flag */
+    OUT int          handle;        /* handle to the event */
+    IN  char         name[1];       /* event name */
 };
 
 /* Event operation */
 struct event_op_request
 {
-    int           handle;       /* handle to event */
-    int           op;           /* event operation (see below) */
+    IN  int           handle;       /* handle to event */
+    IN  int           op;           /* event operation (see below) */
 };
 enum event_op { PULSE_EVENT, SET_EVENT, RESET_EVENT };
 
@@ -320,278 +281,248 @@ enum event_op { PULSE_EVENT, SET_EVENT, RESET_EVENT };
 /* Open an event */
 struct open_event_request
 {
-    unsigned int access;        /* wanted access rights */
-    int          inherit;       /* inherit flag */
-    char         name[0];       /* object name */
-};
-struct open_event_reply
-{
-    int          handle;        /* handle to the event */
+    IN  unsigned int access;        /* wanted access rights */
+    IN  int          inherit;       /* inherit flag */
+    OUT int          handle;        /* handle to the event */
+    IN  char         name[1];       /* object name */
 };
 
 
 /* Create a mutex */
 struct create_mutex_request
 {
-    int          owned;         /* initially owned? */
-    int          inherit;       /* inherit flag */
-    char         name[0];       /* mutex name */
-};
-struct create_mutex_reply
-{
-    int          handle;        /* handle to the mutex */
+    IN  int          owned;         /* initially owned? */
+    IN  int          inherit;       /* inherit flag */
+    OUT int          handle;        /* handle to the mutex */
+    IN  char         name[1];       /* mutex name */
 };
 
 
 /* Release a mutex */
 struct release_mutex_request
 {
-    int          handle;        /* handle to the mutex */
+    IN  int          handle;        /* handle to the mutex */
 };
 
 
 /* Open a mutex */
 struct open_mutex_request
 {
-    unsigned int access;        /* wanted access rights */
-    int          inherit;       /* inherit flag */
-    char         name[0];       /* object name */
-};
-struct open_mutex_reply
-{
-    int          handle;        /* handle to the mutex */
+    IN  unsigned int access;        /* wanted access rights */
+    IN  int          inherit;       /* inherit flag */
+    OUT int          handle;        /* handle to the mutex */
+    IN  char         name[1];       /* object name */
 };
 
 
 /* Create a semaphore */
 struct create_semaphore_request
 {
-    unsigned int initial;       /* initial count */
-    unsigned int max;           /* maximum count */
-    int          inherit;       /* inherit flag */
-    char         name[0];       /* semaphore name */
-};
-struct create_semaphore_reply
-{
-    int          handle;        /* handle to the semaphore */
+    IN  unsigned int initial;       /* initial count */
+    IN  unsigned int max;           /* maximum count */
+    IN  int          inherit;       /* inherit flag */
+    OUT int          handle;        /* handle to the semaphore */
+    IN  char         name[1];       /* semaphore name */
 };
 
 
 /* Release a semaphore */
 struct release_semaphore_request
 {
-    int          handle;        /* handle to the semaphore */
-    unsigned int count;         /* count to add to semaphore */
-};
-struct release_semaphore_reply
-{
-    unsigned int prev_count;    /* previous semaphore count */
+    IN  int          handle;        /* handle to the semaphore */
+    IN  unsigned int count;         /* count to add to semaphore */
+    OUT unsigned int prev_count;    /* previous semaphore count */
 };
 
 
 /* Open a semaphore */
 struct open_semaphore_request
 {
-    unsigned int access;        /* wanted access rights */
-    int          inherit;       /* inherit flag */
-    char         name[0];       /* object name */
-};
-struct open_semaphore_reply
-{
-    int          handle;        /* handle to the semaphore */
+    IN  unsigned int access;        /* wanted access rights */
+    IN  int          inherit;       /* inherit flag */
+    OUT int          handle;        /* handle to the semaphore */
+    IN  char         name[1];       /* object name */
 };
 
 
 /* Create a file */
 struct create_file_request
 {
-    unsigned int access;        /* wanted access rights */
-    int          inherit;       /* inherit flag */
-    unsigned int sharing;       /* sharing flags */
-    int          create;        /* file create action */
-    unsigned int attrs;         /* file attributes for creation */
-    char         name[0];       /* file name */
+    IN  unsigned int access;        /* wanted access rights */
+    IN  int          inherit;       /* inherit flag */
+    IN  unsigned int sharing;       /* sharing flags */
+    IN  int          create;        /* file create action */
+    IN  unsigned int attrs;         /* file attributes for creation */
+    OUT int          handle;        /* handle to the file */
+    IN  char         name[1];       /* file name */
 };
-struct create_file_reply
+
+
+/* Allocate a file handle for a Unix fd */
+struct alloc_file_handle_request
 {
-    int          handle;        /* handle to the file */
+    IN  unsigned int access;        /* wanted access rights */
+    OUT int          handle;        /* handle to the file */
 };
 
 
 /* Get a Unix fd to read from a file */
 struct get_read_fd_request
 {
-    int          handle;        /* handle to the file */
+    IN  int          handle;        /* handle to the file */
 };
 
 
 /* Get a Unix fd to write to a file */
 struct get_write_fd_request
 {
-    int          handle;        /* handle to the file */
+    IN  int          handle;        /* handle to the file */
 };
 
 
 /* Set a file current position */
 struct set_file_pointer_request
 {
-    int          handle;        /* handle to the file */
-    int          low;           /* position low word */
-    int          high;          /* position high word */
-    int          whence;        /* whence to seek */
-};
-struct set_file_pointer_reply
-{
-    int          low;           /* new position low word */
-    int          high;          /* new position high word */
+    IN  int          handle;        /* handle to the file */
+    IN  int          low;           /* position low word */
+    IN  int          high;          /* position high word */
+    IN  int          whence;        /* whence to seek */
+    OUT int          new_low;       /* new position low word */
+    OUT int          new_high;      /* new position high word */
 };
 
 
 /* Truncate (or extend) a file */
 struct truncate_file_request
 {
-    int          handle;        /* handle to the file */
+    IN  int          handle;        /* handle to the file */
 };
 
 
 /* Set a file access and modification times */
 struct set_file_time_request
 {
-    int          handle;        /* handle to the file */
-    time_t       access_time;   /* last access time */
-    time_t       write_time;    /* last write time */
+    IN  int          handle;        /* handle to the file */
+    IN  time_t       access_time;   /* last access time */
+    IN  time_t       write_time;    /* last write time */
 };
 
 
 /* Flush a file buffers */
 struct flush_file_request
 {
-    int          handle;        /* handle to the file */
+    IN  int          handle;        /* handle to the file */
 };
 
 
 /* Get information about a file */
 struct get_file_info_request
 {
-    int          handle;        /* handle to the file */
-};
-struct get_file_info_reply
-{
-    int          type;          /* file type */
-    int          attr;          /* file attributes */
-    time_t       access_time;   /* last access time */
-    time_t       write_time;    /* last write time */
-    int          size_high;     /* file size */
-    int          size_low;      /* file size */
-    int          links;         /* number of links */
-    int          index_high;    /* unique index */
-    int          index_low;     /* unique index */
-    unsigned int serial;        /* volume serial number */
+    IN  int          handle;        /* handle to the file */
+    OUT int          type;          /* file type */
+    OUT int          attr;          /* file attributes */
+    OUT time_t       access_time;   /* last access time */
+    OUT time_t       write_time;    /* last write time */
+    OUT int          size_high;     /* file size */
+    OUT int          size_low;      /* file size */
+    OUT int          links;         /* number of links */
+    OUT int          index_high;    /* unique index */
+    OUT int          index_low;     /* unique index */
+    OUT unsigned int serial;        /* volume serial number */
 };
 
 
 /* Lock a region of a file */
 struct lock_file_request
 {
-    int          handle;        /* handle to the file */
-    unsigned int offset_low;    /* offset of start of lock */
-    unsigned int offset_high;   /* offset of start of lock */
-    unsigned int count_low;     /* count of bytes to lock */
-    unsigned int count_high;    /* count of bytes to lock */
+    IN  int          handle;        /* handle to the file */
+    IN  unsigned int offset_low;    /* offset of start of lock */
+    IN  unsigned int offset_high;   /* offset of start of lock */
+    IN  unsigned int count_low;     /* count of bytes to lock */
+    IN  unsigned int count_high;    /* count of bytes to lock */
 };
 
 
 /* Unlock a region of a file */
 struct unlock_file_request
 {
-    int          handle;        /* handle to the file */
-    unsigned int offset_low;    /* offset of start of unlock */
-    unsigned int offset_high;   /* offset of start of unlock */
-    unsigned int count_low;     /* count of bytes to unlock */
-    unsigned int count_high;    /* count of bytes to unlock */
+    IN  int          handle;        /* handle to the file */
+    IN  unsigned int offset_low;    /* offset of start of unlock */
+    IN  unsigned int offset_high;   /* offset of start of unlock */
+    IN  unsigned int count_low;     /* count of bytes to unlock */
+    IN  unsigned int count_high;    /* count of bytes to unlock */
 };
 
 
 /* Create an anonymous pipe */
 struct create_pipe_request
 {
-    int          inherit;       /* inherit flag */
-};
-struct create_pipe_reply
-{
-    int          handle_read;   /* handle to the read-side of the pipe */
-    int          handle_write;  /* handle to the write-side of the pipe */
+    IN  int          inherit;       /* inherit flag */
+    OUT int          handle_read;   /* handle to the read-side of the pipe */
+    OUT int          handle_write;  /* handle to the write-side of the pipe */
 };
 
 
 /* Allocate a console for the current process */
 struct alloc_console_request
 {
-    unsigned int access;        /* wanted access rights */
-    int          inherit;       /* inherit flag */
-};
-struct alloc_console_reply
-{
-    int          handle_in;     /* handle to console input */
-    int          handle_out;    /* handle to console output */
+    IN  unsigned int access;        /* wanted access rights */
+    IN  int          inherit;       /* inherit flag */
+    OUT int          handle_in;     /* handle to console input */
+    OUT int          handle_out;    /* handle to console output */
 };
 
 
 /* Free the console of the current process */
 struct free_console_request
 {
-    int dummy;
+    IN  int dummy;
 };
 
 
 /* Open a handle to the process console */
 struct open_console_request
 {
-    int          output;        /* input or output? */
-    unsigned int access;        /* wanted access rights */
-    int          inherit;       /* inherit flag */
-};
-struct open_console_reply
-{
-    int          handle;        /* handle to the console */
+    IN  int          output;        /* input or output? */
+    IN  unsigned int access;        /* wanted access rights */
+    IN  int          inherit;       /* inherit flag */
+    OUT int          handle;        /* handle to the console */
 };
 
 
 /* Set a console file descriptor */
 struct set_console_fd_request
 {
-    int          handle;        /* handle to the console */
-    int          pid;           /* pid of xterm (hack) */
+    IN  int          handle;        /* handle to the console */
+    IN  int          file_handle;   /* handle of file to use as file descriptor */
+    IN  int          pid;           /* pid of xterm (hack) */
 };
 
 
 /* Get a console mode (input or output) */
 struct get_console_mode_request
 {
-    int          handle;        /* handle to the console */
-};
-struct get_console_mode_reply
-{
-    int          mode;          /* console mode */
+    IN  int          handle;        /* handle to the console */
+    OUT int          mode;          /* console mode */
 };
 
 
 /* Set a console mode (input or output) */
 struct set_console_mode_request
 {
-    int          handle;        /* handle to the console */
-    int          mode;          /* console mode */
+    IN  int          handle;        /* handle to the console */
+    IN  int          mode;          /* console mode */
 };
 
 
 /* Set info about a console (output only) */
 struct set_console_info_request
 {
-    int          handle;        /* handle to the console */
-    int          mask;          /* setting mask (see below) */
-    int          cursor_size;   /* size of cursor (percentage filled) */
-    int          cursor_visible;/* cursor visibility flag */
-    char         title[0];      /* console title */
+    IN  int          handle;        /* handle to the console */
+    IN  int          mask;          /* setting mask (see below) */
+    IN  int          cursor_size;   /* size of cursor (percentage filled) */
+    IN  int          cursor_visible;/* cursor visibility flag */
+    IN  char         title[1];      /* console title */
 };
 #define SET_CONSOLE_INFO_CURSOR 0x01
 #define SET_CONSOLE_INFO_TITLE  0x02
@@ -599,68 +530,53 @@ struct set_console_info_request
 /* Get info about a console (output only) */
 struct get_console_info_request
 {
-    int          handle;        /* handle to the console */
-};
-struct get_console_info_reply
-{
-    int          cursor_size;   /* size of cursor (percentage filled) */
-    int          cursor_visible;/* cursor visibility flag */
-    int          pid;           /* pid of xterm (hack) */
-    char         title[0];      /* console title */
+    IN  int          handle;        /* handle to the console */
+    OUT int          cursor_size;   /* size of cursor (percentage filled) */
+    OUT int          cursor_visible;/* cursor visibility flag */
+    OUT int          pid;           /* pid of xterm (hack) */
+    OUT char         title[1];      /* console title */
 };
 
 
 /* Add input records to a console input queue */
 struct write_console_input_request
 {
-    int          handle;        /* handle to the console input */
-    int          count;         /* number of input records */
-/*  INPUT_RECORD records[0]; */ /* input records */
-};
-struct write_console_input_reply
-{
-    int          written;       /* number of records written */
+    IN  int          handle;        /* handle to the console input */
+    IN  int          count;         /* number of input records */
+    OUT int          written;       /* number of records written */
+ /* INPUT_RECORD records[0]; */     /* input records */
 };
 
 /* Fetch input records from a console input queue */
 struct read_console_input_request
 {
-    int          handle;        /* handle to the console input */
-    int          count;         /* max number of records to retrieve */
-    int          flush;         /* flush the retrieved records from the queue? */
-};
-struct read_console_input_reply
-{
-    int dummy;
-/*  INPUT_RECORD records[0]; */ /* input records */
+    IN  int          handle;        /* handle to the console input */
+    IN  int          count;         /* max number of records to retrieve */
+    IN  int          flush;         /* flush the retrieved records from the queue? */
+    OUT int          read;          /* number of records read */
+ /* INPUT_RECORD records[0]; */     /* input records */
 };
 
 
 /* Create a change notification */
 struct create_change_notification_request
 {
-    int          subtree;       /* watch all the subtree */
-    int          filter;        /* notification filter */
-};
-struct create_change_notification_reply
-{
-    int          handle;        /* handle to the change notification */
+    IN  int          subtree;       /* watch all the subtree */
+    IN  int          filter;        /* notification filter */
+    OUT int          handle;        /* handle to the change notification */
 };
 
 
 /* Create a file mapping */
 struct create_mapping_request
 {
-    int          size_high;     /* mapping size */
-    int          size_low;      /* mapping size */
-    int          protect;       /* protection flags (see below) */
-    int          inherit;       /* inherit flag */
-    int          handle;        /* file handle */
-    char         name[0];       /* object name */
-};
-struct create_mapping_reply
-{
-    int          handle;        /* handle to the mapping */
+    IN  int          size_high;     /* mapping size */
+    IN  int          size_low;      /* mapping size */
+    IN  int          protect;       /* protection flags (see below) */
+    IN  int          inherit;       /* inherit flag */
+    IN  int          file_handle;   /* file handle */
+    OUT int          handle;        /* handle to the mapping */
+    IN  char         name[1];       /* object name */
 };
 /* protection flags */
 #define VPROT_READ       0x01
@@ -675,91 +591,70 @@ struct create_mapping_reply
 /* Open a mapping */
 struct open_mapping_request
 {
-    unsigned int access;        /* wanted access rights */
-    int          inherit;       /* inherit flag */
-    char         name[0];       /* object name */
-};
-struct open_mapping_reply
-{
-    int          handle;        /* handle to the mapping */
+    IN  unsigned int access;        /* wanted access rights */
+    IN  int          inherit;       /* inherit flag */
+    OUT int          handle;        /* handle to the mapping */
+    IN  char         name[1];       /* object name */
 };
 
 
 /* Get information about a file mapping */
 struct get_mapping_info_request
 {
-    int          handle;        /* handle to the mapping */
-};
-struct get_mapping_info_reply
-{
-    int          size_high;     /* mapping size */
-    int          size_low;      /* mapping size */
-    int          protect;       /* protection flags */
+    IN  int          handle;        /* handle to the mapping */
+    OUT int          size_high;     /* mapping size */
+    OUT int          size_low;      /* mapping size */
+    OUT int          protect;       /* protection flags */
 };
 
 
 /* Create a device */
 struct create_device_request
 {
-    unsigned int access;        /* wanted access rights */
-    int          inherit;       /* inherit flag */
-    int          id;            /* client private id */
-};
-struct create_device_reply
-{
-    int          handle;        /* handle to the device */
+    IN  unsigned int access;        /* wanted access rights */
+    IN  int          inherit;       /* inherit flag */
+    IN  int          id;            /* client private id */
+    OUT int          handle;        /* handle to the device */
 };
 
 
 /* Create a snapshot */
 struct create_snapshot_request
 {
-    int          inherit;       /* inherit flag */
-    int          flags;         /* snapshot flags (TH32CS_*) */
-};
-struct create_snapshot_reply
-{
-    int          handle;        /* handle to the snapshot */
+    IN  int          inherit;       /* inherit flag */
+    IN  int          flags;         /* snapshot flags (TH32CS_*) */
+    OUT int          handle;        /* handle to the snapshot */
 };
 
 
 /* Get the next process from a snapshot */
 struct next_process_request
 {
-    int          handle;        /* handle to the snapshot */
-    int          reset;         /* reset snapshot position? */
-};
-struct next_process_reply
-{
-    void*        pid;          /* process id */
-    int          threads;      /* number of threads */
-    int          priority;     /* process priority */
+    IN  int          handle;        /* handle to the snapshot */
+    IN  int          reset;         /* reset snapshot position? */
+    OUT void*        pid;          /* process id */
+    OUT int          threads;      /* number of threads */
+    OUT int          priority;     /* process priority */
 };
 
 
 /* Wait for a debug event */
 struct wait_debug_event_request
 {
-    int          timeout;      /* timeout in ms */
-};
-struct wait_debug_event_reply
-{
-    int          code;         /* event code */
-    void*        pid;          /* process id */
-    void*        tid;          /* thread id */
-    /* followed by the event data (see below) */
+    IN  int          timeout;      /* timeout in ms */
+    OUT int          code;         /* event code */
+    OUT void*        pid;          /* process id */
+    OUT void*        tid;          /* thread id */
+/*  OUT union debug_event_data data; */
 };
 
 
 /* Send a debug event */
 struct send_debug_event_request
 {
-    int          code;         /* event code */
-    /* followed by the event data (see below) */
-};
-struct send_debug_event_reply
-{
-    int          status;       /* event continuation status */
+    IN  int          code;         /* event code */
+    OUT int          status;       /* event continuation status */
+/*  IN  union debug_event_data data; */
 };
 
 
@@ -837,16 +732,16 @@ union debug_event_data
 /* Continue a debug event */
 struct continue_debug_event_request
 {
-    void*        pid;          /* process id to continue */
-    void*        tid;          /* thread id to continue */
-    int          status;       /* continuation status */
+    IN  void*        pid;          /* process id to continue */
+    IN  void*        tid;          /* thread id to continue */
+    IN  int          status;       /* continuation status */
 };
 
 
 /* Start debugging an existing process */
 struct debug_process_request
 {
-    void*        pid;          /* id of the process to debug */
+    IN  void*        pid;          /* id of the process to debug */
 };
 
 
@@ -860,6 +755,7 @@ enum request
     REQ_SET_DEBUG,
     REQ_INIT_PROCESS,
     REQ_INIT_THREAD,
+    REQ_GET_THREAD_BUFFER,
     REQ_TERMINATE_PROCESS,
     REQ_TERMINATE_THREAD,
     REQ_GET_PROCESS_INFO,
@@ -870,6 +766,7 @@ enum request
     REQ_RESUME_THREAD,
     REQ_DEBUGGER,
     REQ_QUEUE_APC,
+    REQ_GET_APCS,
     REQ_CLOSE_HANDLE,
     REQ_GET_HANDLE_INFO,
     REQ_SET_HANDLE_INFO,
@@ -886,6 +783,7 @@ enum request
     REQ_RELEASE_SEMAPHORE,
     REQ_OPEN_SEMAPHORE,
     REQ_CREATE_FILE,
+    REQ_ALLOC_FILE_HANDLE,
     REQ_GET_READ_FD,
     REQ_GET_WRITE_FD,
     REQ_SET_FILE_POINTER,
@@ -930,31 +828,24 @@ enum request
 
 #include "thread.h"
 
-/* make space for some data in the server arguments buffer */
-static inline void *server_add_data( int len )
+/* client communication functions */
+
+/* get a pointer to the request buffer */
+static inline void *get_req_buffer(void)
 {
-    void *old = NtCurrentTeb()->buffer_args;
-    NtCurrentTeb()->buffer_args = (char *)old + len;
-    return old;
+    return NtCurrentTeb()->buffer;
 }
 
-/* maximum remaining size in the server arguments buffer */
-static inline int server_remaining(void)
+/* maximum remaining size in the server buffer */
+static inline int server_remaining( const void *ptr )
 {
-    TEB *teb = NtCurrentTeb();
-    return (char *)teb->buffer + teb->buffer_size - (char *)teb->buffer_args;
+    return (char *)NtCurrentTeb()->buffer + NtCurrentTeb()->buffer_size - (char *)ptr;
 }
 
 extern unsigned int server_call( enum request req );
-extern unsigned int server_call_fd( enum request req, int *fd );
+extern unsigned int server_call_fd( enum request req, int fd_out, int *fd_in );
+extern void server_protocol_error( const char *err, ... );
 
-/* client communication functions */
-extern void CLIENT_ProtocolError( const char *err, ... );
-extern void CLIENT_SendRequest( enum request req, int pass_fd,
-                                int n, ... /* arg_1, len_1, etc. */ );
-extern unsigned int CLIENT_WaitReply( int *len, int *passed_fd,
-                                      int n, ... /* arg_1, len_1, etc. */ );
-extern unsigned int CLIENT_WaitSimpleReply( void *reply, int len, int *passed_fd );
 extern int CLIENT_InitServer(void);
 extern int CLIENT_SetDebug( int level );
 extern int CLIENT_DebuggerRequest( int op );
diff --git a/include/thread.h b/include/thread.h
index 6db75502800490c6458ab788c1bf9ee9a9eedd69..36c8ad5ea4c2a7de078e8b3d0abe0f5bf3fccc85 100644
--- a/include/thread.h
+++ b/include/thread.h
@@ -39,8 +39,8 @@ typedef struct _TEB
     WORD         teb_sel;        /*  3c Selector to TEB */
     WORD         emu_sel;        /*  3e 80387 emulator selector */
     void        *buffer;         /*  40 Buffer shared with server */
-    void        *buffer_args;    /*  44 Current position of arguments in server buffer */
-    int          buffer_size;    /*  48 Size of server buffer */
+    int          buffer_size;    /*  44 Size of server buffer */
+    void       (*startup)(void); /*  48 Thread startup routine */
     int          thread_errno;   /*  4c Per-thread errno (was: ring0_thread) */
     int          thread_h_errno; /*  50 Per-thread h_errno (was: ptr to tdbx structure) */
     void        *stack_base;     /*  54 Base of the stack */
@@ -69,8 +69,6 @@ typedef struct _TEB
     SYSLEVEL    *sys_mutex[4];   /* 1d8 Syslevel mutex pointers */
     DWORD        unknown6[2];    /* 1e8 Unknown */
     /* The following are Wine-specific fields */
-    unsigned int seq;            /* Server sequence number */
-    void       (*startup)(void); /* Thread startup routine */
     struct _TEB *next;           /* Global thread list */
     DWORD        cleanup;        /* Cleanup service handle */
 } TEB;
diff --git a/loader/dos/module.c b/loader/dos/module.c
index 4a34576ffdb5b3753491c8a7537eacf4508f483e..56ebf9d63677b70d1f22b547ac579e5cf8064aa1 100644
--- a/loader/dos/module.c
+++ b/loader/dos/module.c
@@ -344,8 +344,8 @@ BOOL MZ_InitTask( LPDOSTASK lpDosTask )
   pid_t child;
   char *fname,*farg,arg[16],fproc[64],path[256],*fpath;
   SECURITY_ATTRIBUTES attr={sizeof(attr),NULL,TRUE};
-  struct get_read_fd_request r_req;
-  struct get_write_fd_request w_req;
+  struct get_read_fd_request *r_req = get_req_buffer();
+  struct get_write_fd_request *w_req = get_req_buffer();
 
   if (!lpDosTask) return FALSE;
   /* create pipes */
@@ -357,12 +357,10 @@ BOOL MZ_InitTask( LPDOSTASK lpDosTask )
     CloseHandle(lpDosTask->hXPipe);
     return FALSE;
   }
-  r_req.handle = lpDosTask->hReadPipe;
-  CLIENT_SendRequest( REQ_GET_READ_FD, -1, 1, &r_req, sizeof(r_req) );
-  CLIENT_WaitReply( NULL, &(lpDosTask->read_pipe), 0 );
-  w_req.handle = lpDosTask->hXPipe;
-  CLIENT_SendRequest( REQ_GET_WRITE_FD, -1, 1, &w_req, sizeof(w_req) );
-  CLIENT_WaitReply( NULL, &x_fd, 0 );
+  r_req->handle = lpDosTask->hReadPipe;
+  server_call_fd( REQ_GET_READ_FD, -1, &lpDosTask->read_pipe );
+  w_req->handle = lpDosTask->hXPipe;
+  server_call_fd( REQ_GET_WRITE_FD, -1, &x_fd );
 
   TRACE("win32 pipe: read=%d, write=%d, unix pipe: read=%d, write=%d\n",
 	       lpDosTask->hReadPipe,lpDosTask->hXPipe,lpDosTask->read_pipe,x_fd);
diff --git a/memory/virtual.c b/memory/virtual.c
index 71a0e60f4b26ed0d927b1b8dc431b65142ce8650..09b5d4934d1146a44c90189d6fd8a1a6739e022f 100644
--- a/memory/virtual.c
+++ b/memory/virtual.c
@@ -1051,8 +1051,7 @@ HANDLE WINAPI CreateFileMappingA(
                 DWORD size_low,  /* [in] Low-order 32 bits of object size */
                 LPCSTR name      /* [in] Name of file-mapping object */ )
 {
-    struct create_mapping_request req;
-    struct create_mapping_reply reply;
+    struct create_mapping_request *req = get_req_buffer();
     BYTE vprot;
 
     /* Check parameters */
@@ -1074,19 +1073,16 @@ HANDLE WINAPI CreateFileMappingA(
 
     /* Create the server object */
 
-    if (!name) name = "";
-    req.handle    = hFile;
-    req.size_high = size_high;
-    req.size_low  = size_low;
-    req.protect   = vprot;
-    req.inherit   = (sa && (sa->nLength>=sizeof(*sa)) && sa->bInheritHandle);
-    CLIENT_SendRequest( REQ_CREATE_MAPPING, -1, 2,
-                        &req, sizeof(req),
-                        name, strlen(name) + 1 );
+    req->file_handle = hFile;
+    req->size_high   = size_high;
+    req->size_low    = size_low;
+    req->protect     = vprot;
+    req->inherit     = (sa && (sa->nLength>=sizeof(*sa)) && sa->bInheritHandle);
+    lstrcpynA( req->name, name ? name : "", server_remaining(req->name) );
     SetLastError(0);
-    CLIENT_WaitSimpleReply( &reply, sizeof(reply), NULL );
-    if (reply.handle == -1) return 0;
-    return reply.handle;
+    server_call( REQ_CREATE_MAPPING );
+    if (req->handle == -1) return 0;
+    return req->handle;
 }
 
 
@@ -1119,16 +1115,14 @@ HANDLE WINAPI OpenFileMappingA(
                 BOOL inherit, /* [in] Inherit flag */
                 LPCSTR name )   /* [in] Name of file-mapping object */
 {
-    struct open_mapping_request req;
-    struct open_mapping_reply reply;
-    int len = name ? strlen(name) + 1 : 0;
-
-    req.access  = access;
-    req.inherit = inherit;
-    CLIENT_SendRequest( REQ_OPEN_MAPPING, -1, 2, &req, sizeof(req), name, len );
-    CLIENT_WaitSimpleReply( &reply, sizeof(reply), NULL );
-    if (reply.handle == -1) return 0; /* must return 0 on failure, not -1 */
-    return reply.handle;
+    struct open_mapping_request *req = get_req_buffer();
+
+    req->access  = access;
+    req->inherit = inherit;
+    lstrcpynA( req->name, name ? name : "", server_remaining(req->name) );
+    server_call( REQ_OPEN_MAPPING );
+    if (req->handle == -1) return 0; /* must return 0 on failure, not -1 */
+    return req->handle;
 }
 
 
@@ -1185,8 +1179,8 @@ LPVOID WINAPI MapViewOfFileEx(
     UINT ptr = (UINT)-1, size = 0;
     int flags = MAP_PRIVATE;
     int unix_handle = -1;
-    struct get_mapping_info_request req;
-    struct get_mapping_info_reply info;
+    int prot;
+    struct get_mapping_info_request *req = get_req_buffer();
 
     /* Check parameters */
 
@@ -1197,29 +1191,28 @@ LPVOID WINAPI MapViewOfFileEx(
         return NULL;
     }
 
-    req.handle = handle;
-    CLIENT_SendRequest( REQ_GET_MAPPING_INFO, -1, 1, &req, sizeof(req) );
-    if (CLIENT_WaitSimpleReply( &info, sizeof(info), &unix_handle ))
-        goto error;
+    req->handle = handle;
+    if (server_call_fd( REQ_GET_MAPPING_INFO, -1, &unix_handle )) goto error;
 
-    if (info.size_high || offset_high)
+    if (req->size_high || offset_high)
         ERR("Offsets larger than 4Gb not supported\n");
 
-    if ((offset_low >= info.size_low) ||
-        (count > info.size_low - offset_low))
+    if ((offset_low >= req->size_low) ||
+        (count > req->size_low - offset_low))
     {
         SetLastError( ERROR_INVALID_PARAMETER );
         goto error;
     }
     if (count) size = ROUND_SIZE( offset_low, count );
-    else size = info.size_low - offset_low;
+    else size = req->size_low - offset_low;
+    prot = req->protect;
 
     switch(access)
     {
     case FILE_MAP_ALL_ACCESS:
     case FILE_MAP_WRITE:
     case FILE_MAP_WRITE | FILE_MAP_READ:
-        if (!(info.protect & VPROT_WRITE))
+        if (!(prot & VPROT_WRITE))
         {
             SetLastError( ERROR_INVALID_PARAMETER );
             goto error;
@@ -1229,7 +1222,7 @@ LPVOID WINAPI MapViewOfFileEx(
     case FILE_MAP_READ:
     case FILE_MAP_COPY:
     case FILE_MAP_COPY | FILE_MAP_READ:
-        if (info.protect & VPROT_READ) break;
+        if (prot & VPROT_READ) break;
         /* fall through */
     default:
         SetLastError( ERROR_INVALID_PARAMETER );
@@ -1238,13 +1231,10 @@ LPVOID WINAPI MapViewOfFileEx(
 
     /* Map the file */
 
-    TRACE("handle=%x size=%x offset=%lx\n",
-                     handle, size, offset_low );
+    TRACE("handle=%x size=%x offset=%lx\n", handle, size, offset_low );
 
-    ptr = (UINT)FILE_dommap( unix_handle,
-                               addr, 0, size, 0, offset_low,
-                               VIRTUAL_GetUnixProt( info.protect ),
-                               flags );
+    ptr = (UINT)FILE_dommap( unix_handle, addr, 0, size, 0, offset_low,
+                             VIRTUAL_GetUnixProt( prot ), flags );
     if (ptr == (UINT)-1) {
         /* KB: Q125713, 25-SEP-1995, "Common File Mapping Problems and
 	 * Platform Differences": 
@@ -1259,8 +1249,7 @@ LPVOID WINAPI MapViewOfFileEx(
         goto error;
     }
 
-    if (!(view = VIRTUAL_CreateView( ptr, size, offset_low, 0,
-                                     info.protect, handle )))
+    if (!(view = VIRTUAL_CreateView( ptr, size, offset_low, 0, prot, handle )))
     {
         SetLastError( ERROR_OUTOFMEMORY );
         goto error;
diff --git a/misc/comm.c b/misc/comm.c
index f20a63f991400f3bebfdeb021e59bb694591c873..b8cee05d7f9cb6a27a09f62c66718bce8808a2d6 100644
--- a/misc/comm.c
+++ b/misc/comm.c
@@ -1476,31 +1476,30 @@ BOOL WINAPI BuildCommDCBW(LPCWSTR devid,LPDCB lpdcb)
 }
 
 /*****************************************************************************
- *      COMM_Handle2fd
- *  returns a file descriptor for reading from or writing to
- *  mode is GENERIC_READ or GENERIC_WRITE. Make sure to close
- *  the handle afterwards!
+ *      COMM_GetReadFd
+ *  Returns a file descriptor for reading.
+ *  Make sure to close the handle afterwards!
  */
-int COMM_Handle2fd(HANDLE handle, int mode) {
-    struct get_read_fd_request r_req;
-    struct get_write_fd_request w_req;
+static int COMM_GetReadFd( HANDLE handle)
+{
     int fd;
+    struct get_read_fd_request *req = get_req_buffer();
+    req->handle = handle;
+    server_call_fd( REQ_GET_READ_FD, -1, &fd );
+    return fd;
+}
 
-    w_req.handle = r_req.handle = handle;
-
-    switch(mode) {
-    case GENERIC_WRITE:
-        CLIENT_SendRequest( REQ_GET_WRITE_FD, -1, 1, &w_req, sizeof(w_req) );
-        break;
-    case GENERIC_READ:
-        CLIENT_SendRequest( REQ_GET_READ_FD, -1, 1, &r_req, sizeof(r_req) );
-        break;
-    default:
-        ERR(comm,"COMM_Handle2fd: Don't know what type of fd is required.\n");
-        return -1;
-    }
-    CLIENT_WaitReply( NULL, &fd, 0 );
-
+/*****************************************************************************
+ *      COMM_GetWriteFd
+ *  Returns a file descriptor for writing.
+ *  Make sure to close the handle afterwards!
+ */
+static int COMM_GetWriteFd( HANDLE handle)
+{
+    int fd;
+    struct get_write_fd_request *req = get_req_buffer();
+    req->handle = handle;
+    server_call_fd( REQ_GET_WRITE_FD, -1, &fd );
     return fd;
 }
 
@@ -1534,7 +1533,7 @@ BOOL WINAPI EscapeCommFunction(HANDLE handle,UINT nFunction)
 	struct termios	port;
 
     	TRACE(comm,"handle %d, function=%d\n", handle, nFunction);
-	fd = COMM_Handle2fd(handle, GENERIC_WRITE);
+	fd = COMM_GetWriteFd(handle);
 	if(fd<0)
 		return FALSE;
 
@@ -1611,7 +1610,7 @@ BOOL WINAPI PurgeComm( HANDLE handle, DWORD flags)
 
      TRACE(comm,"handle %d, flags %lx\n", handle, flags);
 
-     fd = COMM_Handle2fd(handle, GENERIC_WRITE);
+     fd = COMM_GetWriteFd(handle);
      if(fd<0)
          return FALSE;
 
@@ -1648,7 +1647,7 @@ BOOL WINAPI ClearCommError(INT handle,LPDWORD errors,LPCOMSTAT lpStat)
 {
     int fd;
 
-    fd=COMM_Handle2fd(handle,GENERIC_READ);
+    fd=COMM_GetReadFd(handle);
     if(0>fd) 
     {
         return FALSE;
@@ -1693,7 +1692,7 @@ BOOL WINAPI SetupComm( HANDLE handle, DWORD insize, DWORD outsize)
     int fd;
 
     FIXME(comm, "insize %ld outsize %ld unimplemented stub\n", insize, outsize);
-    fd=COMM_Handle2fd(handle,GENERIC_WRITE);
+    fd=COMM_GetWriteFd(handle);
     if(0>fd)
     {
         return FALSE;
@@ -1710,7 +1709,7 @@ BOOL WINAPI GetCommMask(HANDLE handle,LPDWORD evtmask)
     int fd;
 
     TRACE(comm, "handle %d, mask %p\n", handle, evtmask);
-    if(0>(fd=COMM_Handle2fd(handle,GENERIC_READ))) 
+    if(0>(fd=COMM_GetReadFd(handle))) 
     {
         return FALSE;
     }
@@ -1727,7 +1726,7 @@ BOOL WINAPI SetCommMask(INT handle,DWORD evtmask)
     int fd;
 
     TRACE(comm, "handle %d, mask %lx\n", handle, evtmask);
-    if(0>(fd=COMM_Handle2fd(handle,GENERIC_WRITE))) {
+    if(0>(fd=COMM_GetWriteFd(handle))) {
         return FALSE;
     }
     close(fd);
@@ -1742,19 +1741,14 @@ BOOL WINAPI SetCommState(INT handle,LPDCB lpdcb)
 {
      struct termios port;
      int fd;
-     struct get_write_fd_request req;
 
      TRACE(comm,"handle %d, ptr %p\n", handle, lpdcb);
 
-     req.handle = handle;
-     CLIENT_SendRequest( REQ_GET_WRITE_FD, -1, 1, &req, sizeof(req) );
-     CLIENT_WaitReply( NULL, &fd, 0 );
-
-     if(fd<0)
-         return FALSE;
+     if ((fd = COMM_GetWriteFd(handle)) < 0) return FALSE;
 
      if (tcgetattr(fd,&port) == -1) {
-         commerror = WinError();	
+         commerror = WinError();
+         close( fd );
          return FALSE;
      }
 
@@ -1821,6 +1815,7 @@ BOOL WINAPI SetCommState(INT handle,LPDCB lpdcb)
 			break;		
 		default:
 			commerror = IE_BAUDRATE;
+                        close( fd );
 			return FALSE;
 	}
 #elif !defined(__EMX__)
@@ -1863,6 +1858,7 @@ BOOL WINAPI SetCommState(INT handle,LPDCB lpdcb)
                         break;
                 default:
                         commerror = IE_BAUDRATE;
+                        close( fd );
                         return FALSE;
         }
         port.c_ispeed = port.c_ospeed;
@@ -1884,6 +1880,7 @@ BOOL WINAPI SetCommState(INT handle,LPDCB lpdcb)
 			break;
 		default:
 			commerror = IE_BYTESIZE;
+                        close( fd );
 			return FALSE;
 	}
 
@@ -1904,6 +1901,7 @@ BOOL WINAPI SetCommState(INT handle,LPDCB lpdcb)
                         break;
                 default:
                         commerror = IE_BYTESIZE;
+                        close( fd );
                         return FALSE;
         }
 	
@@ -1918,6 +1916,7 @@ BOOL WINAPI SetCommState(INT handle,LPDCB lpdcb)
 				break;
 		default:
 			commerror = IE_BYTESIZE;
+                        close( fd );
 			return FALSE;
 	}
 #ifdef CRTSCTS
@@ -1941,9 +1940,11 @@ BOOL WINAPI SetCommState(INT handle,LPDCB lpdcb)
 
 	if (tcsetattr(fd,TCSADRAIN,&port)==-1) {
 		commerror = WinError();	
+                close( fd );
 		return FALSE;
 	} else {
 		commerror = 0;
+                close( fd );
 		return TRUE;
 	}
 }
@@ -1956,21 +1957,18 @@ BOOL WINAPI GetCommState(INT handle, LPDCB lpdcb)
 {
      struct termios port;
      int fd;
-     struct get_read_fd_request req;
 
      TRACE(comm,"handle %d, ptr %p\n", handle, lpdcb);
-     req.handle = handle;
-     CLIENT_SendRequest( REQ_GET_READ_FD, -1, 1, &req, sizeof(req) );
-     CLIENT_WaitReply( NULL, &fd, 0 );
 
-     if(fd<0)
-         return FALSE;
+     if ((fd = COMM_GetReadFd(handle)) < 0) return FALSE;
 
      if (tcgetattr(fd, &port) == -1) {
         TRACE(comm,"tcgetattr(%d, ...) returned -1",fd);
 		commerror = WinError();	
+                close( fd );
 		return FALSE;
 	}
+     close( fd );
 #ifndef __EMX__
 #ifdef CBAUD
         switch (port.c_cflag & CBAUD) {
diff --git a/misc/toolhelp.c b/misc/toolhelp.c
index d437530bc06063464f30951b967fcaff8ea1377a..7abf041ad278ca3b235cd78c0ebdd95444ae0b2d 100644
--- a/misc/toolhelp.c
+++ b/misc/toolhelp.c
@@ -116,8 +116,7 @@ FARPROC16 tmp;
  */
 HANDLE WINAPI CreateToolhelp32Snapshot( DWORD flags, DWORD process ) 
 {
-    struct create_snapshot_request req;
-    struct create_snapshot_reply reply;
+    struct create_snapshot_request *req = get_req_buffer();
 
     TRACE( toolhelp, "%lx,%lx\n", flags, process );
     if (flags & (TH32CS_SNAPHEAPLIST|TH32CS_SNAPMODULE|TH32CS_SNAPTHREAD))
@@ -127,13 +126,12 @@ HANDLE WINAPI CreateToolhelp32Snapshot( DWORD flags, DWORD process )
         SetLastError( ERROR_CALL_NOT_IMPLEMENTED );
         return INVALID_HANDLE_VALUE;
     }
-
+    
     /* Now do the snapshot */
-    req.flags   = flags & ~TH32CS_INHERIT;
-    req.inherit = (flags & TH32CS_INHERIT) != 0;
-    CLIENT_SendRequest( REQ_CREATE_SNAPSHOT, -1, 1, &req, sizeof(req) );
-    CLIENT_WaitSimpleReply( &reply, sizeof(reply), NULL );
-    return reply.handle;
+    req->flags   = flags & ~TH32CS_INHERIT;
+    req->inherit = (flags & TH32CS_INHERIT) != 0;
+    server_call( REQ_CREATE_SNAPSHOT );
+    return req->handle;
 }
 
 
@@ -144,8 +142,7 @@ HANDLE WINAPI CreateToolhelp32Snapshot( DWORD flags, DWORD process )
  */
 static BOOL TOOLHELP_Process32Next( HANDLE handle, LPPROCESSENTRY lppe, BOOL first )
 {
-    struct next_process_request req;
-    struct next_process_reply reply;
+    struct next_process_request *req = get_req_buffer();
 
     if (lppe->dwSize < sizeof (PROCESSENTRY))
     {
@@ -153,17 +150,16 @@ static BOOL TOOLHELP_Process32Next( HANDLE handle, LPPROCESSENTRY lppe, BOOL fir
         ERR (toolhelp, "Result buffer too small\n");
         return FALSE;
     }
-    req.handle = handle;
-    req.reset = first;
-    CLIENT_SendRequest( REQ_NEXT_PROCESS, -1, 1, &req, sizeof(req) );
-    if (CLIENT_WaitSimpleReply( &reply, sizeof(reply), NULL )) return FALSE;
+    req->handle = handle;
+    req->reset = first;
+    if (server_call( REQ_NEXT_PROCESS )) return FALSE;
     lppe->cntUsage            = 1;
-    lppe->th32ProcessID       = (DWORD)reply.pid;
+    lppe->th32ProcessID       = (DWORD)req->pid;
     lppe->th32DefaultHeapID   = 0;  /* FIXME */ 
     lppe->th32ModuleID        = 0;  /* FIXME */
-    lppe->cntThreads          = reply.threads;
+    lppe->cntThreads          = req->threads;
     lppe->th32ParentProcessID = 0;  /* FIXME */
-    lppe->pcPriClassBase      = reply.priority;
+    lppe->pcPriClassBase      = req->priority;
     lppe->dwFlags             = -1; /* FIXME */
     lppe->szExeFile[0]        = 0;  /* FIXME */
     return TRUE;
diff --git a/scheduler/client.c b/scheduler/client.c
index 4f5dbdb80991899dd4f7edc6251cb1d4de97c501..bc62f539de19ef837bacb957879ebea6c8130eae 100644
--- a/scheduler/client.c
+++ b/scheduler/client.c
@@ -26,6 +26,14 @@
 #define SCM_RIGHTS 1
 #endif
 
+/* data structure used to pass an fd with sendmsg/recvmsg */
+struct cmsg_fd
+{
+    int len;   /* sizeof structure */
+    int level; /* SOL_SOCKET */
+    int type;  /* SCM_RIGHTS */
+    int fd;    /* fd to pass */
+};
 
 /***********************************************************************
  *           CLIENT_Die
@@ -39,9 +47,9 @@ static void CLIENT_Die(void)
 }
 
 /***********************************************************************
- *           CLIENT_ProtocolError
+ *           server_protocol_error
  */
-void CLIENT_ProtocolError( const char *err, ... )
+void server_protocol_error( const char *err, ... )
 {
     va_list args;
 
@@ -54,9 +62,9 @@ void CLIENT_ProtocolError( const char *err, ... )
 
 
 /***********************************************************************
- *           CLIENT_perror
+ *           server_perror
  */
-void CLIENT_perror( const char *err )
+static void server_perror( const char *err )
 {
     fprintf( stderr, "Client protocol error:%p: ", NtCurrentTeb()->tid );
     perror( err );
@@ -71,24 +79,15 @@ void CLIENT_perror( const char *err )
  */
 static void send_request( enum request req )
 {
-    struct header *head = NtCurrentTeb()->buffer;
-    int ret, seq = NtCurrentTeb()->seq++;
-
-    assert( server_remaining() >= 0 );
-
-    head->type = req;
-    head->len  = (char *)NtCurrentTeb()->buffer_args - (char *)NtCurrentTeb()->buffer;
-
-    NtCurrentTeb()->buffer_args = head + 1;  /* reset the args buffer */
-
-    if ((ret = write( NtCurrentTeb()->socket, &seq, sizeof(seq) )) == sizeof(seq))
+    int ret;
+    if ((ret = write( NtCurrentTeb()->socket, &req, sizeof(req) )) == sizeof(req))
         return;
     if (ret == -1)
     {
         if (errno == EPIPE) CLIENT_Die();
-        CLIENT_perror( "sendmsg" );
+        server_perror( "sendmsg" );
     }
-    CLIENT_ProtocolError( "partial seq sent %d/%d\n", ret, sizeof(seq) );
+    server_protocol_error( "partial msg sent %d/%d\n", ret, sizeof(req) );
 }
 
 /***********************************************************************
@@ -98,23 +97,15 @@ static void send_request( enum request req )
  */
 static void send_request_fd( enum request req, int fd )
 {
-    struct header *head = NtCurrentTeb()->buffer;
-    int ret, seq = NtCurrentTeb()->seq++;
+    int ret;
 #ifndef HAVE_MSGHDR_ACCRIGHTS
     struct cmsg_fd cmsg;
 #endif
     struct msghdr msghdr;
     struct iovec vec;
 
-    assert( server_remaining() >= 0 );
-
-    head->type = req;
-    head->len  = (char *)NtCurrentTeb()->buffer_args - (char *)NtCurrentTeb()->buffer;
-
-    NtCurrentTeb()->buffer_args = head + 1;  /* reset the args buffer */
-
-    vec.iov_base = &seq;
-    vec.iov_len  = sizeof(seq);
+    vec.iov_base = &req;
+    vec.iov_len  = sizeof(req);
 
     msghdr.msg_name    = NULL;
     msghdr.msg_namelen = 0;
@@ -134,13 +125,13 @@ static void send_request_fd( enum request req, int fd )
     msghdr.msg_flags      = 0;
 #endif  /* HAVE_MSGHDR_ACCRIGHTS */
 
-    if ((ret = sendmsg( NtCurrentTeb()->socket, &msghdr, 0 )) == sizeof(seq)) return;
+    if ((ret = sendmsg( NtCurrentTeb()->socket, &msghdr, 0 )) == sizeof(req)) return;
     if (ret == -1)
     {
         if (errno == EPIPE) CLIENT_Die();
-        CLIENT_perror( "sendmsg" );
+        server_perror( "sendmsg" );
     }
-    CLIENT_ProtocolError( "partial seq sent %d/%d\n", ret, sizeof(seq) );
+    server_protocol_error( "partial msg sent %d/%d\n", ret, sizeof(req) );
 }
 
 /***********************************************************************
@@ -148,26 +139,23 @@ static void send_request_fd( enum request req, int fd )
  *
  * Wait for a reply from the server.
  */
-static void wait_reply(void)
+static unsigned int wait_reply(void)
 {
-    int seq, ret;
+    int ret;
+    unsigned int res;
 
     for (;;)
     {
-        if ((ret = read( NtCurrentTeb()->socket, &seq, sizeof(seq) )) == sizeof(seq))
-        {
-            if (seq != NtCurrentTeb()->seq++)
-                CLIENT_ProtocolError( "sequence %08x instead of %08x\n", seq, NtCurrentTeb()->seq - 1 );
-            return;
-        }
+        if ((ret = read( NtCurrentTeb()->socket, &res, sizeof(res) )) == sizeof(res))
+            return res;
         if (ret == -1)
         {
             if (errno == EINTR) continue;
             if (errno == EPIPE) CLIENT_Die();
-            CLIENT_perror("read");
+            server_perror("read");
         }
         if (!ret) CLIENT_Die(); /* the server closed the connection; time to die... */
-        CLIENT_ProtocolError( "partial seq received %d/%d\n", ret, sizeof(seq) );
+        server_protocol_error( "partial msg received %d/%d\n", ret, sizeof(res) );
     }
 }
 
@@ -177,17 +165,18 @@ static void wait_reply(void)
  *
  * Wait for a reply from the server, when a file descriptor is passed.
  */
-static int wait_reply_fd(void)
+static unsigned int wait_reply_fd( int *fd )
 {
     struct iovec vec;
-    int seq, ret;
+    int ret;
+    unsigned int res;
 
 #ifdef HAVE_MSGHDR_ACCRIGHTS
     struct msghdr msghdr;
-    int fd = -1;
 
-    msghdr.msg_accrights    = (void *)&fd;
-    msghdr.msg_accrightslen = sizeof(int);
+    *fd = -1;
+    msghdr.msg_accrights    = (void *)fd;
+    msghdr.msg_accrightslen = sizeof(*fd);
 #else  /* HAVE_MSGHDR_ACCRIGHTS */
     struct msghdr msghdr;
     struct cmsg_fd cmsg;
@@ -205,29 +194,26 @@ static int wait_reply_fd(void)
     msghdr.msg_namelen = 0;
     msghdr.msg_iov     = &vec;
     msghdr.msg_iovlen  = 1;
-    vec.iov_base = &seq;
-    vec.iov_len  = sizeof(seq);
+    vec.iov_base = &res;
+    vec.iov_len  = sizeof(res);
 
     for (;;)
     {
-        if ((ret = recvmsg( NtCurrentTeb()->socket, &msghdr, 0 )) == sizeof(seq))
+        if ((ret = recvmsg( NtCurrentTeb()->socket, &msghdr, 0 )) == sizeof(res))
         {
-            if (seq != NtCurrentTeb()->seq++)
-                CLIENT_ProtocolError( "sequence %08x instead of %08x\n", seq, NtCurrentTeb()->seq - 1 );
-#ifdef HAVE_MSGHDR_ACCRIGHTS
-            return fd;
-#else
-            return cmsg.fd;
+#ifndef HAVE_MSGHDR_ACCRIGHTS
+            *fd = cmsg.fd;
 #endif
+            return res;
         }
         if (ret == -1)
         {
             if (errno == EINTR) continue;
             if (errno == EPIPE) CLIENT_Die();
-            CLIENT_perror("recvmsg");
+            server_perror("recvmsg");
         }
         if (!ret) CLIENT_Die(); /* the server closed the connection; time to die... */
-        CLIENT_ProtocolError( "partial seq received %d/%d\n", ret, sizeof(seq) );
+        server_protocol_error( "partial seq received %d/%d\n", ret, sizeof(res) );
     }
 }
 
@@ -239,18 +225,15 @@ static int wait_reply_fd(void)
  */
 unsigned int server_call( enum request req )
 {
-    struct header *head;
+    unsigned int res;
 
     send_request( req );
-    wait_reply();
-
-    head = (struct header *)NtCurrentTeb()->buffer;
-    if ((head->len < sizeof(*head)) || (head->len > NtCurrentTeb()->buffer_size))
-        CLIENT_ProtocolError( "header length %d\n", head->len );
-    if (head->type) SetLastError( head->type );
-    return head->type;  /* error code */
+    res = wait_reply();
+    if (res) SetLastError( res );
+    return res;  /* error code */
 }
 
+
 /***********************************************************************
  *           server_call_fd
  *
@@ -258,125 +241,17 @@ unsigned int server_call( enum request req )
  * If *fd is != -1, it will be passed to the server.
  * If the server passes an fd, it will be stored into *fd.
  */
-unsigned int server_call_fd( enum request req, int *fd )
-{
-    struct header *head;
-
-    if (*fd == -1) send_request( req );
-    else send_request_fd( req, *fd );
-    *fd = wait_reply_fd();
-
-    head = (struct header *)NtCurrentTeb()->buffer;
-    if ((head->len < sizeof(*head)) || (head->len > NtCurrentTeb()->buffer_size))
-        CLIENT_ProtocolError( "header length %d\n", head->len );
-    if (head->type) SetLastError( head->type );
-    return head->type;  /* error code */
-}
-
-/***********************************************************************
- *           CLIENT_SendRequest
- *
- * Send a request to the server.
- */
-void CLIENT_SendRequest( enum request req, int pass_fd,
-                         int n, ... /* arg_1, len_1, etc. */ )
-{
-    va_list args;
-
-    va_start( args, n );
-    while (n--)
-    {
-        void *ptr = va_arg( args, void * );
-        int len   = va_arg( args, int );
-        memcpy( server_add_data( len ), ptr, len );
-    }
-    va_end( args );
-
-    if (pass_fd == -1) send_request( req );
-    else
-    {
-        send_request_fd( req, pass_fd );
-        close( pass_fd ); /* we passed the fd now we can close it */
-    }
-}
-
-
-/***********************************************************************
- *           CLIENT_WaitReply_v
- *
- * Wait for a reply from the server.
- * Returns the error code (or 0 if OK).
- */
-static unsigned int CLIENT_WaitReply_v( int *len, int *passed_fd,
-                                        struct iovec *vec, int veclen )
-{
-    struct header *head;
-    char *ptr;
-    int i, remaining;
-
-    if (passed_fd) *passed_fd = wait_reply_fd();
-    else wait_reply();
-
-    head = (struct header *)NtCurrentTeb()->buffer;
-    if ((head->len < sizeof(*head)) || (head->len > NtCurrentTeb()->buffer_size))
-        CLIENT_ProtocolError( "header length %d\n", head->len );
-
-    remaining = head->len - sizeof(*head);
-    ptr = (char *)(head + 1);
-    for (i = 0; i < veclen; i++, vec++)
-    {
-        int len = MIN( remaining, vec->iov_len );
-        memcpy( vec->iov_base, ptr, len );
-        ptr += len;
-        if (!(remaining -= len)) break;
-    }
-    if (len) *len = head->len - sizeof(*head);
-    if (head->type) SetLastError( head->type );
-    return head->type;  /* error code */
-}
-
-
-/***********************************************************************
- *           CLIENT_WaitReply
- *
- * Wait for a reply from the server.
- */
-unsigned int CLIENT_WaitReply( int *len, int *passed_fd,
-                               int n, ... /* arg_1, len_1, etc. */ )
+unsigned int server_call_fd( enum request req, int fd_out, int *fd_in )
 {
-    struct iovec vec[16];
-    va_list args;
-    int i;
-
-    assert( n < 16 );
-    va_start( args, n );
-    for (i = 0; i < n; i++)
-    {
-        vec[i].iov_base = va_arg( args, void * );
-        vec[i].iov_len  = va_arg( args, int );
-    }
-    va_end( args );
-    return CLIENT_WaitReply_v( len, passed_fd, vec, n );
-}
+    unsigned int res;
 
+    if (fd_out == -1) send_request( req );
+    else send_request_fd( req, fd_out );
 
-/***********************************************************************
- *           CLIENT_WaitSimpleReply
- *
- * Wait for a simple fixed-length reply from the server.
- */
-unsigned int CLIENT_WaitSimpleReply( void *reply, int len, int *passed_fd )
-{
-    struct iovec vec;
-    unsigned int ret;
-    int got;
-
-    vec.iov_base = reply;
-    vec.iov_len  = len;
-    ret = CLIENT_WaitReply_v( &got, passed_fd, &vec, 1 );
-    if (got != len)
-        CLIENT_ProtocolError( "WaitSimpleReply: len %d != %d\n", len, got );
-    return ret;
+    if (fd_in) res = wait_reply_fd( fd_in );
+    else res = wait_reply();
+    if (res) SetLastError( res );
+    return res;  /* error code */
 }
 
 
@@ -427,24 +302,23 @@ int CLIENT_InitServer(void)
  */
 int CLIENT_InitThread(void)
 {
-    struct init_thread_request req;
-    struct init_thread_reply reply;
+    struct init_thread_request *req;
     TEB *teb = NtCurrentTeb();
+    int fd;
 
-    int fd = wait_reply_fd();
-    if (fd == -1) CLIENT_ProtocolError( "no fd passed on first request\n" );
-    if ((teb->buffer_size = lseek( fd, 0, SEEK_END )) == -1) CLIENT_perror( "lseek" );
+    if (wait_reply_fd( &fd ) || (fd == -1))
+        server_protocol_error( "no fd passed on first request\n" );
+    if ((teb->buffer_size = lseek( fd, 0, SEEK_END )) == -1) server_perror( "lseek" );
     teb->buffer = mmap( 0, teb->buffer_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0 );
     close( fd );
-    if (teb->buffer == (void*)-1) CLIENT_perror( "mmap" );
-    teb->buffer_args = (char *)teb->buffer + sizeof(struct header);
-
-    req.unix_pid = getpid();
-    req.teb      = teb;
-    CLIENT_SendRequest( REQ_INIT_THREAD, -1, 1, &req, sizeof(req) );
-    if (CLIENT_WaitSimpleReply( &reply, sizeof(reply), NULL )) return -1;
-    teb->process->server_pid = reply.pid;
-    teb->tid = reply.tid;
+    if (teb->buffer == (void*)-1) server_perror( "mmap" );
+
+    req = get_req_buffer();
+    req->unix_pid = getpid();
+    req->teb      = teb;
+    if (server_call( REQ_INIT_THREAD )) return -1;
+    teb->process->server_pid = req->pid;
+    teb->tid = req->tid;
     return 0;
 }
 
@@ -456,8 +330,9 @@ int CLIENT_InitThread(void)
  */
 int CLIENT_SetDebug( int level )
 {
-    CLIENT_SendRequest( REQ_SET_DEBUG, -1, 1, &level, sizeof(level) );
-    return CLIENT_WaitReply( NULL, NULL, 0 );
+    struct set_debug_request *req = get_req_buffer();
+    req->level = level;
+    return server_call( REQ_SET_DEBUG );
 }
 
 /***********************************************************************
@@ -467,9 +342,8 @@ int CLIENT_SetDebug( int level )
  */
 int CLIENT_DebuggerRequest( int op )
 {
-    struct debugger_request req;
-    req.op = op;
-    CLIENT_SendRequest( REQ_DEBUGGER, -1, 1, &req, sizeof(req) );
-    return CLIENT_WaitReply( NULL, NULL, 0 );
+    struct debugger_request *req = get_req_buffer();
+    req->op = op;
+    return server_call( REQ_DEBUGGER );
 }
 
diff --git a/scheduler/debugger.c b/scheduler/debugger.c
index fd969858e3b4ddf395d0d6a8978454cf792c6440..e5a4beae93cec9e12d8a71fb8ce0e72d81ebacfb 100644
--- a/scheduler/debugger.c
+++ b/scheduler/debugger.c
@@ -17,13 +17,12 @@
  */
 static DWORD DEBUG_SendEvent( int code, void *data, int size )
 {
-    struct send_debug_event_request req;
-    struct send_debug_event_reply reply;
-
-    req.code = code;
-    CLIENT_SendRequest( REQ_SEND_DEBUG_EVENT, -1, 2, &req, sizeof(req), data, size );
-    if (CLIENT_WaitSimpleReply( &reply, sizeof(reply), NULL )) return 0;
-    return reply.status;
+    DWORD ret = 0;
+    struct send_debug_event_request *req = get_req_buffer();
+    req->code = code;
+    memcpy( req + 1, data, size );
+    if (!server_call( REQ_SEND_DEBUG_EVENT )) ret = req->status;
+    return ret;
 }
 
 
@@ -135,94 +134,74 @@ DWORD DEBUG_SendUnloadDLLEvent( HMODULE module )
  */
 BOOL WINAPI WaitForDebugEvent( LPDEBUG_EVENT event, DWORD timeout )
 {
-    /* size of the event data */
-    static const int event_sizes[] =
-    {
-        0,
-        sizeof(struct debug_event_exception),       /* EXCEPTION_DEBUG_EVENT */
-        sizeof(struct debug_event_create_thread),   /* CREATE_THREAD_DEBUG_EVENT */
-        sizeof(struct debug_event_create_process),  /* CREATE_PROCESS_DEBUG_EVENT */
-        sizeof(struct debug_event_exit),            /* EXIT_THREAD_DEBUG_EVENT */
-        sizeof(struct debug_event_exit),            /* EXIT_PROCESS_DEBUG_EVENT */
-        sizeof(struct debug_event_load_dll),        /* LOAD_DLL_DEBUG_EVENT */
-        sizeof(struct debug_event_unload_dll),      /* UNLOAD_DLL_DEBUG_EVENT */
-        sizeof(struct debug_event_output_string),   /* OUTPUT_DEBUG_STRING_EVENT */
-        sizeof(struct debug_event_rip_info)         /* RIP_EVENT */
-    };
-
-    struct wait_debug_event_request req;
-    struct wait_debug_event_reply reply;
-    union debug_event_data data;
-    int i, len;
-
-    req.timeout = timeout;
-    CLIENT_SendRequest( REQ_WAIT_DEBUG_EVENT, -1, 1, &req, sizeof(req) );
-    if (CLIENT_WaitReply( &len, NULL, 2, &reply, sizeof(reply),
-                          &data, sizeof(data) )) return FALSE;
-    if ((reply.code < 0) || (reply.code > RIP_EVENT))
-        CLIENT_ProtocolError( "WaitForDebugEvent: bad code %d\n", reply.code );
-    if (len != sizeof(reply) + event_sizes[reply.code])
-        CLIENT_ProtocolError( "WaitForDebugEvent: bad len %d for code %d\n", len, reply.code );
-
-    event->dwDebugEventCode = reply.code;
-    event->dwProcessId      = (DWORD)reply.pid;
-    event->dwThreadId       = (DWORD)reply.tid;
-    switch(reply.code)
+    struct wait_debug_event_request *req = get_req_buffer();
+    union debug_event_data *data = (union debug_event_data *)(req + 1);
+    int i;
+
+    req->timeout = timeout;
+    if (server_call( REQ_WAIT_DEBUG_EVENT )) return FALSE;
+    if ((req->code < 0) || (req->code > RIP_EVENT))
+        server_protocol_error( "WaitForDebugEvent: bad code %d\n", req->code );
+
+    event->dwDebugEventCode = req->code;
+    event->dwProcessId      = (DWORD)req->pid;
+    event->dwThreadId       = (DWORD)req->tid;
+    switch(req->code)
     {
     case EXCEPTION_DEBUG_EVENT:
-        event->u.Exception.ExceptionRecord.ExceptionCode    = data.exception.code;
-        event->u.Exception.ExceptionRecord.ExceptionFlags   = data.exception.flags;
-        event->u.Exception.ExceptionRecord.ExceptionRecord  = data.exception.record;
-        event->u.Exception.ExceptionRecord.ExceptionAddress = data.exception.addr;
-        event->u.Exception.ExceptionRecord.NumberParameters = data.exception.nb_params;
-        for (i = 0; i < data.exception.nb_params; i++)
-            event->u.Exception.ExceptionRecord.ExceptionInformation[i] = data.exception.params[i];
-        event->u.Exception.dwFirstChance = data.exception.first_chance;
+        event->u.Exception.ExceptionRecord.ExceptionCode    = data->exception.code;
+        event->u.Exception.ExceptionRecord.ExceptionFlags   = data->exception.flags;
+        event->u.Exception.ExceptionRecord.ExceptionRecord  = data->exception.record;
+        event->u.Exception.ExceptionRecord.ExceptionAddress = data->exception.addr;
+        event->u.Exception.ExceptionRecord.NumberParameters = data->exception.nb_params;
+        for (i = 0; i < data->exception.nb_params; i++)
+            event->u.Exception.ExceptionRecord.ExceptionInformation[i] = data->exception.params[i];
+        event->u.Exception.dwFirstChance = data->exception.first_chance;
         break;
     case CREATE_THREAD_DEBUG_EVENT:
-        event->u.CreateThread.hThread           = data.create_thread.handle;
-        event->u.CreateThread.lpThreadLocalBase = data.create_thread.teb;
-        event->u.CreateThread.lpStartAddress    = data.create_thread.start;
+        event->u.CreateThread.hThread           = data->create_thread.handle;
+        event->u.CreateThread.lpThreadLocalBase = data->create_thread.teb;
+        event->u.CreateThread.lpStartAddress    = data->create_thread.start;
         break;
     case CREATE_PROCESS_DEBUG_EVENT:
-        event->u.CreateProcessInfo.hFile                 = data.create_process.file;
-        event->u.CreateProcessInfo.hProcess              = data.create_process.process;
-        event->u.CreateProcessInfo.hThread               = data.create_process.thread;
-        event->u.CreateProcessInfo.lpBaseOfImage         = data.create_process.base;
-        event->u.CreateProcessInfo.dwDebugInfoFileOffset = data.create_process.dbg_offset;
-        event->u.CreateProcessInfo.nDebugInfoSize        = data.create_process.dbg_size;
-        event->u.CreateProcessInfo.lpThreadLocalBase     = data.create_process.teb;
-        event->u.CreateProcessInfo.lpStartAddress        = data.create_process.start;
-        event->u.CreateProcessInfo.lpImageName           = data.create_process.name;
-        event->u.CreateProcessInfo.fUnicode              = data.create_process.unicode;
-        if (data.create_process.file == -1) event->u.CreateProcessInfo.hFile = 0;
+        event->u.CreateProcessInfo.hFile                 = data->create_process.file;
+        event->u.CreateProcessInfo.hProcess              = data->create_process.process;
+        event->u.CreateProcessInfo.hThread               = data->create_process.thread;
+        event->u.CreateProcessInfo.lpBaseOfImage         = data->create_process.base;
+        event->u.CreateProcessInfo.dwDebugInfoFileOffset = data->create_process.dbg_offset;
+        event->u.CreateProcessInfo.nDebugInfoSize        = data->create_process.dbg_size;
+        event->u.CreateProcessInfo.lpThreadLocalBase     = data->create_process.teb;
+        event->u.CreateProcessInfo.lpStartAddress        = data->create_process.start;
+        event->u.CreateProcessInfo.lpImageName           = data->create_process.name;
+        event->u.CreateProcessInfo.fUnicode              = data->create_process.unicode;
+        if (data->create_process.file == -1) event->u.CreateProcessInfo.hFile = 0;
         break;
     case EXIT_THREAD_DEBUG_EVENT:
-        event->u.ExitThread.dwExitCode = data.exit.exit_code;
+        event->u.ExitThread.dwExitCode = data->exit.exit_code;
         break;
     case EXIT_PROCESS_DEBUG_EVENT:
-        event->u.ExitProcess.dwExitCode = data.exit.exit_code;
+        event->u.ExitProcess.dwExitCode = data->exit.exit_code;
         break;
     case LOAD_DLL_DEBUG_EVENT:
-        event->u.LoadDll.hFile                 = data.load_dll.handle;
-        event->u.LoadDll.lpBaseOfDll           = data.load_dll.base;
-        event->u.LoadDll.dwDebugInfoFileOffset = data.load_dll.dbg_offset;
-        event->u.LoadDll.nDebugInfoSize        = data.load_dll.dbg_size;
-        event->u.LoadDll.lpImageName           = data.load_dll.name;
-        event->u.LoadDll.fUnicode              = data.load_dll.unicode;
-        if (data.load_dll.handle == -1) event->u.LoadDll.hFile = 0;
+        event->u.LoadDll.hFile                 = data->load_dll.handle;
+        event->u.LoadDll.lpBaseOfDll           = data->load_dll.base;
+        event->u.LoadDll.dwDebugInfoFileOffset = data->load_dll.dbg_offset;
+        event->u.LoadDll.nDebugInfoSize        = data->load_dll.dbg_size;
+        event->u.LoadDll.lpImageName           = data->load_dll.name;
+        event->u.LoadDll.fUnicode              = data->load_dll.unicode;
+        if (data->load_dll.handle == -1) event->u.LoadDll.hFile = 0;
         break;
     case UNLOAD_DLL_DEBUG_EVENT:
-        event->u.UnloadDll.lpBaseOfDll = data.unload_dll.base;
+        event->u.UnloadDll.lpBaseOfDll = data->unload_dll.base;
         break;
     case OUTPUT_DEBUG_STRING_EVENT:
-        event->u.DebugString.lpDebugStringData  = data.output_string.string;
-        event->u.DebugString.fUnicode           = data.output_string.unicode;
-        event->u.DebugString.nDebugStringLength = data.output_string.length;
+        event->u.DebugString.lpDebugStringData  = data->output_string.string;
+        event->u.DebugString.fUnicode           = data->output_string.unicode;
+        event->u.DebugString.nDebugStringLength = data->output_string.length;
         break;
     case RIP_EVENT:
-        event->u.RipInfo.dwError = data.rip_info.error;
-        event->u.RipInfo.dwType  = data.rip_info.type;
+        event->u.RipInfo.dwError = data->rip_info.error;
+        event->u.RipInfo.dwType  = data->rip_info.type;
         break;
     }
     return TRUE;
@@ -234,13 +213,11 @@ BOOL WINAPI WaitForDebugEvent( LPDEBUG_EVENT event, DWORD timeout )
  */
 BOOL WINAPI ContinueDebugEvent( DWORD pid, DWORD tid, DWORD status )
 {
-    struct continue_debug_event_request req;
-
-    req.pid    = (void *)pid;
-    req.tid    = (void *)tid;
-    req.status = status;
-    CLIENT_SendRequest( REQ_CONTINUE_DEBUG_EVENT, -1, 1, &req, sizeof(req) );
-    return !CLIENT_WaitReply( NULL, NULL, 0 );
+    struct continue_debug_event_request *req = get_req_buffer();
+    req->pid    = (void *)pid;
+    req->tid    = (void *)tid;
+    req->status = status;
+    return !server_call( REQ_CONTINUE_DEBUG_EVENT );
 }
 
 
@@ -249,10 +226,9 @@ BOOL WINAPI ContinueDebugEvent( DWORD pid, DWORD tid, DWORD status )
  */
 BOOL WINAPI DebugActiveProcess( DWORD pid )
 {
-    struct debug_process_request req;
-    req.pid = (void *)pid;
-    CLIENT_SendRequest( REQ_DEBUG_PROCESS, -1, 1, &req, sizeof(req) );
-    return !CLIENT_WaitReply( NULL, NULL, 0 );
+    struct debug_process_request *req = get_req_buffer();
+    req->pid = (void *)pid;
+    return !server_call( REQ_DEBUG_PROCESS );
 }
 
 
diff --git a/scheduler/event.c b/scheduler/event.c
index a145c766ac9cea17df8c61ea27b8c1b777a26c4a..9c37bc3449451d27c7dd6115838b1601935cf023 100644
--- a/scheduler/event.c
+++ b/scheduler/event.c
@@ -18,18 +18,16 @@
 HANDLE WINAPI CreateEventA( SECURITY_ATTRIBUTES *sa, BOOL manual_reset,
                                 BOOL initial_state, LPCSTR name )
 {
-    struct create_event_request req;
-    struct create_event_reply reply;
-
-    if (!name) name = "";
-    req.manual_reset = manual_reset;
-    req.initial_state = initial_state;
-    req.inherit = (sa && (sa->nLength>=sizeof(*sa)) && sa->bInheritHandle);
-    CLIENT_SendRequest( REQ_CREATE_EVENT, -1, 2, &req, sizeof(req), name, strlen(name)+1 );
+    struct create_event_request *req = get_req_buffer();
+
+    req->manual_reset = manual_reset;
+    req->initial_state = initial_state;
+    req->inherit = (sa && (sa->nLength>=sizeof(*sa)) && sa->bInheritHandle);
+    lstrcpynA( req->name, name ? name : "", server_remaining(req->name) );
     SetLastError(0);
-    CLIENT_WaitSimpleReply( &reply, sizeof(reply), NULL );
-    if (reply.handle == -1) return 0;
-    return reply.handle;
+    server_call( REQ_CREATE_EVENT );
+    if (req->handle == -1) return 0;
+    return req->handle;
 }
 
 
@@ -59,16 +57,14 @@ HANDLE WINAPI WIN16_CreateEvent( BOOL manual_reset, BOOL initial_state )
  */
 HANDLE WINAPI OpenEventA( DWORD access, BOOL inherit, LPCSTR name )
 {
-    struct open_event_request req;
-    struct open_event_reply reply;
-    int len = name ? strlen(name) + 1 : 0;
-
-    req.access  = access;
-    req.inherit = inherit;
-    CLIENT_SendRequest( REQ_OPEN_EVENT, -1, 2, &req, sizeof(req), name, len );
-    CLIENT_WaitSimpleReply( &reply, sizeof(reply), NULL );
-    if (reply.handle == -1) return 0; /* must return 0 on failure, not -1 */
-    return (HANDLE)reply.handle;
+    struct open_event_request *req = get_req_buffer();
+
+    req->access  = access;
+    req->inherit = inherit;
+    lstrcpynA( req->name, name ? name : "", server_remaining(req->name) );
+    server_call( REQ_OPEN_EVENT );
+    if (req->handle == -1) return 0; /* must return 0 on failure, not -1 */
+    return req->handle;
 }
 
 
@@ -91,12 +87,10 @@ HANDLE WINAPI OpenEventW( DWORD access, BOOL inherit, LPCWSTR name )
  */
 static BOOL EVENT_Operation( HANDLE handle, enum event_op op )
 {
-    struct event_op_request req;
-
-    req.handle = handle;
-    req.op     = op;
-    CLIENT_SendRequest( REQ_EVENT_OP, -1, 1, &req, sizeof(req) );
-    return !CLIENT_WaitReply( NULL, NULL, 0 );
+    struct event_op_request *req = get_req_buffer();
+    req->handle = handle;
+    req->op     = op;
+    return !server_call( REQ_EVENT_OP );
 }
 
 
diff --git a/scheduler/handle.c b/scheduler/handle.c
index 98d9c59d9c8c85d57ff15b1beb6f566bd22fb98a..8555a465fa15c26290dc9f4b8b58b54731430b2a 100644
--- a/scheduler/handle.c
+++ b/scheduler/handle.c
@@ -18,11 +18,9 @@ DEFAULT_DEBUG_CHANNEL(win32)
  */
 BOOL WINAPI CloseHandle( HANDLE handle )
 {
-    struct close_handle_request req;
-    
-    req.handle = handle;
-    CLIENT_SendRequest( REQ_CLOSE_HANDLE, -1, 1, &req, sizeof(req) );
-    return !CLIENT_WaitReply( NULL, NULL, 0 );
+    struct close_handle_request *req = get_req_buffer();
+    req->handle = handle;
+    return !server_call( REQ_CLOSE_HANDLE );
 }
 
 
@@ -31,13 +29,10 @@ BOOL WINAPI CloseHandle( HANDLE handle )
  */
 BOOL WINAPI GetHandleInformation( HANDLE handle, LPDWORD flags )
 {
-    struct get_handle_info_request req;
-    struct get_handle_info_reply reply;
-
-    req.handle = handle;
-    CLIENT_SendRequest( REQ_GET_HANDLE_INFO, -1, 1, &req, sizeof(req) );
-    if (CLIENT_WaitSimpleReply( &reply, sizeof(reply), NULL )) return FALSE;
-    if (flags) *flags = reply.flags;
+    struct get_handle_info_request *req = get_req_buffer();
+    req->handle = handle;
+    if (server_call( REQ_GET_HANDLE_INFO )) return FALSE;
+    if (flags) *flags = req->flags;
     return TRUE;
 }
 
@@ -47,13 +42,11 @@ BOOL WINAPI GetHandleInformation( HANDLE handle, LPDWORD flags )
  */
 BOOL WINAPI SetHandleInformation( HANDLE handle, DWORD mask, DWORD flags )
 {
-    struct set_handle_info_request req;
-
-    req.handle = handle;
-    req.flags  = flags;
-    req.mask   = mask;
-    CLIENT_SendRequest( REQ_SET_HANDLE_INFO, -1, 1, &req, sizeof(req) );
-    return !CLIENT_WaitReply( NULL, NULL, 0 );
+    struct set_handle_info_request *req = get_req_buffer();
+    req->handle = handle;
+    req->flags  = flags;
+    req->mask   = mask;
+    return !server_call( REQ_SET_HANDLE_INFO );
 }
 
 
@@ -64,19 +57,17 @@ BOOL WINAPI DuplicateHandle( HANDLE source_process, HANDLE source,
                                HANDLE dest_process, HANDLE *dest,
                                DWORD access, BOOL inherit, DWORD options )
 {
-    struct dup_handle_request req;
-    struct dup_handle_reply reply;
-
-    req.src_process = source_process;
-    req.src_handle  = source;
-    req.dst_process = dest_process;
-    req.access      = access;
-    req.inherit     = inherit;
-    req.options     = options;
-
-    CLIENT_SendRequest( REQ_DUP_HANDLE, -1, 1, &req, sizeof(req) );
-    if (CLIENT_WaitSimpleReply( &reply, sizeof(reply), NULL )) return FALSE;
-    if (dest) *dest = reply.handle;
+    struct dup_handle_request *req = get_req_buffer();
+
+    req->src_process = source_process;
+    req->src_handle  = source;
+    req->dst_process = dest_process;
+    req->access      = access;
+    req->inherit     = inherit;
+    req->options     = options;
+
+    if (server_call( REQ_DUP_HANDLE )) return FALSE;
+    if (dest) *dest = req->handle;
     return TRUE;
 }
 
@@ -86,19 +77,17 @@ BOOL WINAPI DuplicateHandle( HANDLE source_process, HANDLE source,
  */
 HANDLE WINAPI ConvertToGlobalHandle(HANDLE hSrc)
 {
-    struct dup_handle_request req;
-    struct dup_handle_reply reply;
-
-    req.src_process = GetCurrentProcess();
-    req.src_handle  = hSrc;
-    req.dst_process = -1;
-    req.access      = 0;
-    req.inherit     = FALSE;
-    req.options     = DUP_HANDLE_MAKE_GLOBAL | DUP_HANDLE_SAME_ACCESS;
-
-    CLIENT_SendRequest( REQ_DUP_HANDLE, -1, 1, &req, sizeof(req) );
-    CLIENT_WaitSimpleReply( &reply, sizeof(reply), NULL );
-    return reply.handle;
+    struct dup_handle_request *req = get_req_buffer();
+
+    req->src_process = GetCurrentProcess();
+    req->src_handle  = hSrc;
+    req->dst_process = -1;
+    req->access      = 0;
+    req->inherit     = FALSE;
+    req->options     = DUP_HANDLE_MAKE_GLOBAL | DUP_HANDLE_SAME_ACCESS;
+
+    server_call( REQ_DUP_HANDLE );
+    return req->handle;
 }
 
 /***********************************************************************
diff --git a/scheduler/mutex.c b/scheduler/mutex.c
index 956749532a5e8bc6857563e5e0754879bcfd7516..94110f1aaa65dd23ff09c86c5cb1df74a883f605 100644
--- a/scheduler/mutex.c
+++ b/scheduler/mutex.c
@@ -16,17 +16,15 @@
  */
 HANDLE WINAPI CreateMutexA( SECURITY_ATTRIBUTES *sa, BOOL owner, LPCSTR name )
 {
-    struct create_mutex_request req;
-    struct create_mutex_reply reply;
+    struct create_mutex_request *req = get_req_buffer();
 
-    if (!name) name = "";
-    req.owned   = owner;
-    req.inherit = (sa && (sa->nLength>=sizeof(*sa)) && sa->bInheritHandle);
-    CLIENT_SendRequest( REQ_CREATE_MUTEX, -1, 2, &req, sizeof(req), name, strlen(name)+1 );
+    req->owned   = owner;
+    req->inherit = (sa && (sa->nLength>=sizeof(*sa)) && sa->bInheritHandle);
+    lstrcpynA( req->name, name ? name : "", server_remaining(req->name) );
     SetLastError(0);
-    CLIENT_WaitSimpleReply( &reply, sizeof(reply), NULL );
-    if (reply.handle == -1) return 0;
-    return reply.handle;
+    server_call( REQ_CREATE_MUTEX );
+    if (req->handle == -1) return 0;
+    return req->handle;
 }
 
 
@@ -48,16 +46,14 @@ HANDLE WINAPI CreateMutexW( SECURITY_ATTRIBUTES *sa, BOOL owner,
  */
 HANDLE WINAPI OpenMutexA( DWORD access, BOOL inherit, LPCSTR name )
 {
-    struct open_mutex_request req;
-    struct open_mutex_reply reply;
-    int len = name ? strlen(name) + 1 : 0;
+    struct open_mutex_request *req = get_req_buffer();
 
-    req.access  = access;
-    req.inherit = inherit;
-    CLIENT_SendRequest( REQ_OPEN_MUTEX, -1, 2, &req, sizeof(req), name, len );
-    CLIENT_WaitSimpleReply( &reply, sizeof(reply), NULL );
-    if (reply.handle == -1) return 0; /* must return 0 on failure, not -1 */
-    return reply.handle;
+    req->access  = access;
+    req->inherit = inherit;
+    lstrcpynA( req->name, name ? name : "", server_remaining(req->name) );
+    server_call( REQ_OPEN_MUTEX );
+    if (req->handle == -1) return 0; /* must return 0 on failure, not -1 */
+    return req->handle;
 }
 
 
@@ -78,9 +74,7 @@ HANDLE WINAPI OpenMutexW( DWORD access, BOOL inherit, LPCWSTR name )
  */
 BOOL WINAPI ReleaseMutex( HANDLE handle )
 {
-    struct release_mutex_request req;
-
-    req.handle = handle;
-    CLIENT_SendRequest( REQ_RELEASE_MUTEX, -1, 1, &req, sizeof(req) );
-    return !CLIENT_WaitReply( NULL, NULL, 0 );
+    struct release_mutex_request *req = get_req_buffer();
+    req->handle = handle;
+    return !server_call( REQ_RELEASE_MUTEX );
 }
diff --git a/scheduler/pipe.c b/scheduler/pipe.c
index 74fff8c58be199632c9b5c6fc3edc31b324cc042..6b018c7a93ac47c7f97a417c4eb0a88d113af00b 100644
--- a/scheduler/pipe.c
+++ b/scheduler/pipe.c
@@ -16,15 +16,11 @@
 BOOL WINAPI CreatePipe( PHANDLE hReadPipe, PHANDLE hWritePipe,
                           LPSECURITY_ATTRIBUTES sa, DWORD size )
 {
-    struct create_pipe_request req;
-    struct create_pipe_reply reply;
-    int len;
+    struct create_pipe_request *req = get_req_buffer();
 
-    req.inherit = (sa && (sa->nLength>=sizeof(*sa)) && sa->bInheritHandle);
-    CLIENT_SendRequest( REQ_CREATE_PIPE, -1, 1, &req, sizeof(req) );
-    if (CLIENT_WaitReply( &len, NULL, 1, &reply, sizeof(reply) ) != ERROR_SUCCESS)
-        return FALSE;
-    *hReadPipe  = reply.handle_read;
-    *hWritePipe = reply.handle_write;
+    req->inherit = (sa && (sa->nLength>=sizeof(*sa)) && sa->bInheritHandle);
+    if (server_call( REQ_CREATE_PIPE )) return FALSE;
+    *hReadPipe  = req->handle_read;
+    *hWritePipe = req->handle_write;
     return TRUE;
 }
diff --git a/scheduler/process.c b/scheduler/process.c
index 20d2737de390946b9b26807d69986b6bc81fa2ee..70cc70921da7b8748d688de73ce3a96ad8a19e46 100644
--- a/scheduler/process.c
+++ b/scheduler/process.c
@@ -73,20 +73,6 @@ PDB *PROCESS_Initial(void)
     return &initial_pdb;
 }
 
-/***********************************************************************
- *           PROCESS_QueryInfo
- *
- * Retrieve information about a process
- */
-static BOOL PROCESS_QueryInfo( HANDLE handle,
-                                 struct get_process_info_reply *reply )
-{
-    struct get_process_info_request req;
-    req.handle = handle;
-    CLIENT_SendRequest( REQ_GET_PROCESS_INFO, -1, 1, &req, sizeof(req) );
-    return !CLIENT_WaitSimpleReply( reply, sizeof(*reply), NULL );
-}
-
 /***********************************************************************
  *           PROCESS_IsCurrent
  *
@@ -94,9 +80,10 @@ static BOOL PROCESS_QueryInfo( HANDLE handle,
  */
 BOOL PROCESS_IsCurrent( HANDLE handle )
 {
-    struct get_process_info_reply reply;
-    return (PROCESS_QueryInfo( handle, &reply ) &&
-            (reply.pid == PROCESS_Current()->server_pid));
+    struct get_process_info_request *req = get_req_buffer();
+    req->handle = handle;
+    return (!server_call( REQ_GET_PROCESS_INFO ) &&
+            (req->pid == PROCESS_Current()->server_pid));
 }
 
 
@@ -252,21 +239,12 @@ void PROCESS_CallUserSignalProc( UINT uCode, HMODULE hModule )
  */
 static BOOL PROCESS_CreateEnvDB(void)
 {
-    struct init_process_request req;
-    struct init_process_reply reply;
+    struct init_process_request *req = get_req_buffer();
     STARTUPINFOA *startup;
     ENVDB *env_db;
     char cmd_line[4096];
-    int len;
     PDB *pdb = PROCESS_Current();
 
-    /* Retrieve startup info from the server */
-
-    req.dummy = 0;
-    CLIENT_SendRequest( REQ_INIT_PROCESS, -1, 1, &req, sizeof(req) );
-    if (CLIENT_WaitReply( &len, NULL, 2, &reply, sizeof(reply), cmd_line, sizeof(cmd_line) ))
-        return FALSE;
-
     /* Allocate the env DB */
 
     if (!(env_db = HeapAlloc( pdb->heap, HEAP_ZERO_MEMORY, sizeof(ENVDB) )))
@@ -278,15 +256,20 @@ static BOOL PROCESS_CreateEnvDB(void)
     if (!(startup = HeapAlloc( pdb->heap, HEAP_ZERO_MEMORY, sizeof(STARTUPINFOA) )))
         return FALSE;
     env_db->startup_info = startup;
-    startup->dwFlags     = reply.start_flags;
-    startup->wShowWindow = reply.cmd_show;
-    env_db->hStdin  = startup->hStdInput  = reply.hstdin;
-    env_db->hStdout = startup->hStdOutput = reply.hstdout;
-    env_db->hStderr = startup->hStdError  = reply.hstderr;
+
+    /* Retrieve startup info from the server */
+
+    if (server_call( REQ_INIT_PROCESS )) return FALSE;
+    startup->dwFlags     = req->start_flags;
+    startup->wShowWindow = req->cmd_show;
+    env_db->hStdin  = startup->hStdInput  = req->hstdin;
+    env_db->hStdout = startup->hStdOutput = req->hstdout;
+    env_db->hStderr = startup->hStdError  = req->hstderr;
+    lstrcpynA( cmd_line, req->cmdline, sizeof(cmd_line) );
 
     /* Copy the parent environment */
 
-    if (!ENV_InheritEnvironment( pdb, reply.env_ptr )) return FALSE;
+    if (!ENV_InheritEnvironment( pdb, req->env_ptr )) return FALSE;
 
     /* Copy the command line */
 
@@ -527,8 +510,7 @@ PDB *PROCESS_Create( NE_MODULE *pModule, LPCSTR cmd_line, LPCSTR env,
     HANDLE handles[2], load_done_evt = INVALID_HANDLE_VALUE;
     DWORD exitcode, size;
     int server_thandle;
-    struct new_process_request req;
-    struct new_process_reply reply;
+    struct new_process_request *req = get_req_buffer();
     TEB *teb = NULL;
     PDB *parent = PROCESS_Current();
     PDB *pdb = PROCESS_CreatePDB( parent, inherit );
@@ -538,29 +520,28 @@ PDB *PROCESS_Create( NE_MODULE *pModule, LPCSTR cmd_line, LPCSTR env,
 
     /* Create the process on the server side */
 
-    req.inherit      = (psa && (psa->nLength >= sizeof(*psa)) && psa->bInheritHandle);
-    req.inherit_all  = inherit;
-    req.create_flags = flags;
-    req.start_flags  = startup->dwFlags;
+    req->inherit      = (psa && (psa->nLength >= sizeof(*psa)) && psa->bInheritHandle);
+    req->inherit_all  = inherit;
+    req->create_flags = flags;
+    req->start_flags  = startup->dwFlags;
     if (startup->dwFlags & STARTF_USESTDHANDLES)
     {
-        req.hstdin  = startup->hStdInput;
-        req.hstdout = startup->hStdOutput;
-        req.hstderr = startup->hStdError;
+        req->hstdin  = startup->hStdInput;
+        req->hstdout = startup->hStdOutput;
+        req->hstderr = startup->hStdError;
     }
     else
     {
-        req.hstdin  = GetStdHandle( STD_INPUT_HANDLE );
-        req.hstdout = GetStdHandle( STD_OUTPUT_HANDLE );
-        req.hstderr = GetStdHandle( STD_ERROR_HANDLE );
+        req->hstdin  = GetStdHandle( STD_INPUT_HANDLE );
+        req->hstdout = GetStdHandle( STD_OUTPUT_HANDLE );
+        req->hstderr = GetStdHandle( STD_ERROR_HANDLE );
     }
-    req.cmd_show = startup->wShowWindow;
-    req.env_ptr = (void*)env;  /* FIXME: hack */
-    CLIENT_SendRequest( REQ_NEW_PROCESS, -1, 2,
-                        &req, sizeof(req), cmd_line, strlen(cmd_line) + 1 );
-    if (CLIENT_WaitSimpleReply( &reply, sizeof(reply), NULL )) goto error;
-    pdb->server_pid   = reply.pid;
-    info->hProcess    = reply.handle;
+    req->cmd_show = startup->wShowWindow;
+    req->env_ptr = (void*)env;  /* FIXME: hack */
+    lstrcpynA( req->cmdline, cmd_line, server_remaining(req->cmdline) );
+    if (server_call( REQ_NEW_PROCESS )) goto error;
+    pdb->server_pid   = req->pid;
+    info->hProcess    = req->handle;
     info->dwProcessId = (DWORD)pdb->server_pid;
 
     if ((flags & DEBUG_PROCESS) ||
@@ -675,11 +656,10 @@ void WINAPI ExitProcess16( WORD status )
  */
 BOOL WINAPI TerminateProcess( HANDLE handle, DWORD exit_code )
 {
-    struct terminate_process_request req;
-    req.handle    = handle;
-    req.exit_code = exit_code;
-    CLIENT_SendRequest( REQ_TERMINATE_PROCESS, -1, 1, &req, sizeof(req) );
-    return !CLIENT_WaitReply( NULL, NULL, 0 );
+    struct terminate_process_request *req = get_req_buffer();
+    req->handle    = handle;
+    req->exit_code = exit_code;
+    return !server_call( REQ_TERMINATE_PROCESS );
 }
 
 
@@ -816,15 +796,14 @@ HANDLE WINAPI GetCurrentProcess(void)
  */
 HANDLE WINAPI OpenProcess( DWORD access, BOOL inherit, DWORD id )
 {
-    struct open_process_request req;
-    struct open_process_reply reply;
-
-    req.pid     = (void *)id;
-    req.access  = access;
-    req.inherit = inherit;
-    CLIENT_SendRequest( REQ_OPEN_PROCESS, -1, 1, &req, sizeof(req) );
-    if (CLIENT_WaitSimpleReply( &reply, sizeof(reply), NULL )) return 0;
-    return reply.handle;
+    HANDLE ret = 0;
+    struct open_process_request *req = get_req_buffer();
+
+    req->pid     = (void *)id;
+    req->access  = access;
+    req->inherit = inherit;
+    if (!server_call( REQ_OPEN_PROCESS )) ret = req->handle;
+    return ret;
 }			      
 
 /*********************************************************************
@@ -832,9 +811,11 @@ HANDLE WINAPI OpenProcess( DWORD access, BOOL inherit, DWORD id )
  */
 DWORD WINAPI MapProcessHandle( HANDLE handle )
 {
-    struct get_process_info_reply reply;
-    if ( !PROCESS_QueryInfo( handle, &reply ) ) return 0;
-    return (DWORD)reply.pid;
+    DWORD ret = 0;
+    struct get_process_info_request *req = get_req_buffer();
+    req->handle = handle;
+    if (!server_call( REQ_GET_PROCESS_INFO )) ret = (DWORD)req->pid;
+    return ret;
 }
 
 /***********************************************************************
@@ -870,12 +851,11 @@ LCID WINAPI GetThreadLocale(void)
  */
 BOOL WINAPI SetPriorityClass( HANDLE hprocess, DWORD priorityclass )
 {
-    struct set_process_info_request req;
-    req.handle   = hprocess;
-    req.priority = priorityclass;
-    req.mask     = SET_PROCESS_INFO_PRIORITY;
-    CLIENT_SendRequest( REQ_SET_PROCESS_INFO, -1, 1, &req, sizeof(req) );
-    return !CLIENT_WaitReply( NULL, NULL, 0 );
+    struct set_process_info_request *req = get_req_buffer();
+    req->handle   = hprocess;
+    req->priority = priorityclass;
+    req->mask     = SET_PROCESS_INFO_PRIORITY;
+    return !server_call( REQ_SET_PROCESS_INFO );
 }
 
 
@@ -884,9 +864,11 @@ BOOL WINAPI SetPriorityClass( HANDLE hprocess, DWORD priorityclass )
  */
 DWORD WINAPI GetPriorityClass(HANDLE hprocess)
 {
-    struct get_process_info_reply reply;
-    if (!PROCESS_QueryInfo( hprocess, &reply )) return 0;
-    return reply.priority;
+    DWORD ret = 0;
+    struct get_process_info_request *req = get_req_buffer();
+    req->handle = hprocess;
+    if (!server_call( REQ_GET_PROCESS_INFO )) ret = req->priority;
+    return ret;
 }
 
 
@@ -895,12 +877,11 @@ DWORD WINAPI GetPriorityClass(HANDLE hprocess)
  */
 BOOL WINAPI SetProcessAffinityMask( HANDLE hProcess, DWORD affmask )
 {
-    struct set_process_info_request req;
-    req.handle   = hProcess;
-    req.affinity = affmask;
-    req.mask     = SET_PROCESS_INFO_AFFINITY;
-    CLIENT_SendRequest( REQ_SET_PROCESS_INFO, -1, 1, &req, sizeof(req) );
-    return !CLIENT_WaitReply( NULL, NULL, 0 );
+    struct set_process_info_request *req = get_req_buffer();
+    req->handle   = hProcess;
+    req->affinity = affmask;
+    req->mask     = SET_PROCESS_INFO_AFFINITY;
+    return !server_call( REQ_SET_PROCESS_INFO );
 }
 
 /**********************************************************************
@@ -910,11 +891,16 @@ BOOL WINAPI GetProcessAffinityMask( HANDLE hProcess,
                                       LPDWORD lpProcessAffinityMask,
                                       LPDWORD lpSystemAffinityMask )
 {
-    struct get_process_info_reply reply;
-    if (!PROCESS_QueryInfo( hProcess, &reply )) return FALSE;
-    if (lpProcessAffinityMask) *lpProcessAffinityMask = reply.process_affinity;
-    if (lpSystemAffinityMask) *lpSystemAffinityMask = reply.system_affinity;
-    return TRUE;
+    BOOL ret = FALSE;
+    struct get_process_info_request *req = get_req_buffer();
+    req->handle = hProcess;
+    if (!server_call( REQ_GET_PROCESS_INFO ))
+    {
+        if (lpProcessAffinityMask) *lpProcessAffinityMask = req->process_affinity;
+        if (lpSystemAffinityMask) *lpSystemAffinityMask = req->system_affinity;
+        ret = TRUE;
+    }
+    return ret;
 }
 
 
@@ -1119,10 +1105,15 @@ BOOL WINAPI GetExitCodeProcess(
     HANDLE hProcess,  /* [I] handle to the process */
     LPDWORD lpExitCode) /* [O] address to receive termination status */
 {
-    struct get_process_info_reply reply;
-    if (!PROCESS_QueryInfo( hProcess, &reply )) return FALSE;
-    if (lpExitCode) *lpExitCode = reply.exit_code;
-    return TRUE;
+    BOOL ret = FALSE;
+    struct get_process_info_request *req = get_req_buffer();
+    req->handle = hProcess;
+    if (!server_call( REQ_GET_PROCESS_INFO ))
+    {
+        if (lpExitCode) *lpExitCode = req->exit_code;
+        ret = TRUE;
+    }
+    return ret;
 }
 
 
diff --git a/scheduler/semaphore.c b/scheduler/semaphore.c
index 018606be5037bb6e8bd9bb78c05e54c19fd28488..890efa8b1f138b040dcfb348288e2e2eea353f9d 100644
--- a/scheduler/semaphore.c
+++ b/scheduler/semaphore.c
@@ -16,8 +16,7 @@
  */
 HANDLE WINAPI CreateSemaphoreA( SECURITY_ATTRIBUTES *sa, LONG initial, LONG max, LPCSTR name )
 {
-    struct create_semaphore_request req;
-    struct create_semaphore_reply reply;
+    struct create_semaphore_request *req = get_req_buffer();
 
     /* Check parameters */
 
@@ -27,16 +26,14 @@ HANDLE WINAPI CreateSemaphoreA( SECURITY_ATTRIBUTES *sa, LONG initial, LONG max,
         return 0;
     }
 
-    if (!name) name = "";
-    req.initial = (unsigned int)initial;
-    req.max     = (unsigned int)max;
-    req.inherit = (sa && (sa->nLength>=sizeof(*sa)) && sa->bInheritHandle);
-
-    CLIENT_SendRequest( REQ_CREATE_SEMAPHORE, -1, 2, &req, sizeof(req), name, strlen(name)+1 );
+    req->initial = (unsigned int)initial;
+    req->max     = (unsigned int)max;
+    req->inherit = (sa && (sa->nLength>=sizeof(*sa)) && sa->bInheritHandle);
+    lstrcpynA( req->name, name ? name : "", server_remaining(req->name) );
     SetLastError(0);
-    CLIENT_WaitSimpleReply( &reply, sizeof(reply), NULL );
-    if (reply.handle == -1) return 0;
-    return reply.handle;
+    server_call( REQ_CREATE_SEMAPHORE );
+    if (req->handle == -1) return 0;
+    return req->handle;
 }
 
 
@@ -58,16 +55,14 @@ HANDLE WINAPI CreateSemaphoreW( SECURITY_ATTRIBUTES *sa, LONG initial,
  */
 HANDLE WINAPI OpenSemaphoreA( DWORD access, BOOL inherit, LPCSTR name )
 {
-    struct open_semaphore_request req;
-    struct open_semaphore_reply reply;
-    int len = name ? strlen(name) + 1 : 0;
-
-    req.access  = access;
-    req.inherit = inherit;
-    CLIENT_SendRequest( REQ_OPEN_SEMAPHORE, -1, 2, &req, sizeof(req), name, len );
-    CLIENT_WaitSimpleReply( &reply, sizeof(reply), NULL );
-    if (reply.handle == -1) return 0; /* must return 0 on failure, not -1 */
-    return reply.handle;
+    struct open_semaphore_request *req = get_req_buffer();
+
+    req->access  = access;
+    req->inherit = inherit;
+    lstrcpynA( req->name, name ? name : "", server_remaining(req->name) );
+    server_call( REQ_OPEN_SEMAPHORE );
+    if (req->handle == -1) return 0; /* must return 0 on failure, not -1 */
+    return req->handle;
 }
 
 
@@ -88,18 +83,16 @@ HANDLE WINAPI OpenSemaphoreW( DWORD access, BOOL inherit, LPCWSTR name )
  */
 BOOL WINAPI ReleaseSemaphore( HANDLE handle, LONG count, LONG *previous )
 {
-    struct release_semaphore_request req;
-    struct release_semaphore_reply reply;
+    struct release_semaphore_request *req = get_req_buffer();
 
     if (count < 0)
     {
         SetLastError( ERROR_INVALID_PARAMETER );
         return FALSE;
     }
-    req.handle = handle;
-    req.count  = (unsigned int)count;
-    CLIENT_SendRequest( REQ_RELEASE_SEMAPHORE, -1, 1, &req, sizeof(req) );
-    if (CLIENT_WaitSimpleReply( &reply, sizeof(reply), NULL )) return FALSE;
-    if (previous) *previous = reply.prev_count;
+    req->handle = handle;
+    req->count  = (unsigned int)count;
+    if (server_call( REQ_RELEASE_SEMAPHORE )) return FALSE;
+    if (previous) *previous = req->prev_count;
     return TRUE;
 }
diff --git a/scheduler/synchro.c b/scheduler/synchro.c
index 550465621fb2bf6d6109f1306c03913bfef91d83..7c57e5168818c3b3c36268e354bacaeb8d868a4f 100644
--- a/scheduler/synchro.c
+++ b/scheduler/synchro.c
@@ -17,6 +17,27 @@
 #include "x11drv.h"
 #include "server.h"
 
+/***********************************************************************
+ *              call_apcs
+ *
+ * Call outstanding APCs.
+ */
+static void call_apcs(void)
+{
+#define MAX_APCS 16
+    int i;
+    void *buffer[MAX_APCS * 2];
+    struct get_apcs_request *req = get_req_buffer();
+
+    if (server_call( REQ_GET_APCS ) || !req->count) return;
+    assert( req->count <= MAX_APCS );
+    memcpy( buffer, req->apcs, req->count * 2 * sizeof(req->apcs[0]) );
+    for (i = 0; i < req->count * 2; i += 2)
+    {
+        PAPCFUNC func = (PAPCFUNC)req->apcs[i];
+        if (func) func( (ULONG_PTR)req->apcs[i+1] );
+    }
+}
 
 /***********************************************************************
  *              Sleep  (KERNEL32.679)
@@ -73,11 +94,8 @@ DWORD WINAPI WaitForMultipleObjectsEx( DWORD count, const HANDLE *handles,
                                        BOOL wait_all, DWORD timeout,
                                        BOOL alertable )
 {
-    struct select_request req;
-    struct select_reply reply;
-    int server_handle[MAXIMUM_WAIT_OBJECTS];
-    void *apc[32];
-    int i, len;
+    struct select_request *req = get_req_buffer();
+    int i, ret;
 
     if (count > MAXIMUM_WAIT_OBJECTS)
     {
@@ -99,32 +117,18 @@ DWORD WINAPI WaitForMultipleObjectsEx( DWORD count, const HANDLE *handles,
             EVENT_Synchronize( FALSE );
     }
 
-    for (i = 0; i < count; i++) server_handle[i] = handles[i];
-
-    req.count   = count;
-    req.flags   = 0;
-    req.timeout = timeout;
+    req->count   = count;
+    req->flags   = 0;
+    req->timeout = timeout;
+    for (i = 0; i < count; i++) req->handles[i] = handles[i];
 
-    if (wait_all) req.flags |= SELECT_ALL;
-    if (alertable) req.flags |= SELECT_ALERTABLE;
-    if (timeout != INFINITE) req.flags |= SELECT_TIMEOUT;
+    if (wait_all) req->flags |= SELECT_ALL;
+    if (alertable) req->flags |= SELECT_ALERTABLE;
+    if (timeout != INFINITE) req->flags |= SELECT_TIMEOUT;
 
-    CLIENT_SendRequest( REQ_SELECT, -1, 2,
-                        &req, sizeof(req),
-                        server_handle, count * sizeof(int) );
-    CLIENT_WaitReply( &len, NULL, 2, &reply, sizeof(reply),
-                      apc, sizeof(apc) );
-    if ((reply.signaled == STATUS_USER_APC) && (len > sizeof(reply)))
-    {
-        int i;
-        len -= sizeof(reply);
-        for (i = 0; i < len / sizeof(void*); i += 2)
-        {
-            PAPCFUNC func = (PAPCFUNC)apc[i];
-            if ( func ) func( (ULONG_PTR)apc[i+1] );
-        }
-    }
-    return reply.signaled;
+    server_call( REQ_SELECT );
+    if ((ret = req->signaled) == STATUS_USER_APC) call_apcs();
+    return ret;
 }
 
 
diff --git a/scheduler/thread.c b/scheduler/thread.c
index 7a5b9deccbd949edb828ff360c3c37fbb0ac2de5..62e4dc77e96c69a61503c9faad478554635f2659 100644
--- a/scheduler/thread.c
+++ b/scheduler/thread.c
@@ -199,8 +199,7 @@ TEB *THREAD_CreateInitialThread( PDB *pdb, int server_fd )
 TEB *THREAD_Create( PDB *pdb, DWORD flags, DWORD stack_size, BOOL alloc_stack16,
                      LPSECURITY_ATTRIBUTES sa, int *server_handle )
 {
-    struct new_thread_request request;
-    struct new_thread_reply reply = { NULL, -1 };
+    struct new_thread_request *req = get_req_buffer();
     int fd[2];
     HANDLE cleanup_object;
 
@@ -217,6 +216,7 @@ TEB *THREAD_Create( PDB *pdb, DWORD flags, DWORD stack_size, BOOL alloc_stack16,
 
     /* Allocate the TEB selector (%fs register) */
 
+    *server_handle = -1;
     teb->teb_sel = SELECTOR_AllocBlock( teb, 0x1000, SEGMENT_DATA, TRUE, FALSE );
     if (!teb->teb_sel) goto error;
 
@@ -232,13 +232,12 @@ TEB *THREAD_Create( PDB *pdb, DWORD flags, DWORD stack_size, BOOL alloc_stack16,
 
     /* Create the thread on the server side */
 
-    request.pid     = teb->process->server_pid;
-    request.suspend = ((flags & CREATE_SUSPENDED) != 0);
-    request.inherit = (sa && (sa->nLength>=sizeof(*sa)) && sa->bInheritHandle);
-    CLIENT_SendRequest( REQ_NEW_THREAD, fd[1], 1, &request, sizeof(request) );
-    if (CLIENT_WaitSimpleReply( &reply, sizeof(reply), NULL )) goto error;
-    teb->tid = reply.tid;
-    *server_handle = reply.handle;
+    req->pid     = teb->process->server_pid;
+    req->suspend = ((flags & CREATE_SUSPENDED) != 0);
+    req->inherit = (sa && (sa->nLength>=sizeof(*sa)) && sa->bInheritHandle);
+    if (server_call_fd( REQ_NEW_THREAD, fd[1], NULL )) goto error;
+    teb->tid = req->tid;
+    *server_handle = req->handle;
 
     /* Do the rest of the initialization */
 
@@ -255,7 +254,7 @@ TEB *THREAD_Create( PDB *pdb, DWORD flags, DWORD stack_size, BOOL alloc_stack16,
     return teb;
 
 error:
-    if (reply.handle != -1) CloseHandle( reply.handle );
+    if (*server_handle != -1) CloseHandle( *server_handle );
     if (teb->teb_sel) SELECTOR_FreeBlock( teb->teb_sel, 1 );
     if (teb->socket != -1) close( teb->socket );
     HeapFree( SystemHeap, 0, teb );
@@ -532,13 +531,11 @@ BOOL WINAPI GetThreadContext(
 INT WINAPI GetThreadPriority(
     HANDLE hthread) /* [in] Handle to thread */
 {
-    struct get_thread_info_request req;
-    struct get_thread_info_reply reply;
-    req.handle = hthread;
-    CLIENT_SendRequest( REQ_GET_THREAD_INFO, -1, 1, &req, sizeof(req) );
-    if (CLIENT_WaitSimpleReply( &reply, sizeof(reply), NULL ))
-        return THREAD_PRIORITY_ERROR_RETURN;
-    return reply.priority;
+    INT ret = THREAD_PRIORITY_ERROR_RETURN;
+    struct get_thread_info_request *req = get_req_buffer();
+    req->handle = hthread;
+    if (!server_call( REQ_GET_THREAD_INFO )) ret = req->priority;
+    return ret;
 }
 
 
@@ -553,12 +550,11 @@ BOOL WINAPI SetThreadPriority(
     HANDLE hthread, /* [in] Handle to thread */
     INT priority)   /* [in] Thread priority level */
 {
-    struct set_thread_info_request req;
-    req.handle   = hthread;
-    req.priority = priority;
-    req.mask     = SET_THREAD_INFO_PRIORITY;
-    CLIENT_SendRequest( REQ_SET_THREAD_INFO, -1, 1, &req, sizeof(req) );
-    return !CLIENT_WaitReply( NULL, NULL, 0 );
+    struct set_thread_info_request *req = get_req_buffer();
+    req->handle   = hthread;
+    req->priority = priority;
+    req->mask     = SET_THREAD_INFO_PRIORITY;
+    return !server_call( REQ_SET_THREAD_INFO );
 }
 
 
@@ -567,12 +563,11 @@ BOOL WINAPI SetThreadPriority(
  */
 DWORD WINAPI SetThreadAffinityMask( HANDLE hThread, DWORD dwThreadAffinityMask )
 {
-    struct set_thread_info_request req;
-    req.handle   = hThread;
-    req.affinity = dwThreadAffinityMask;
-    req.mask     = SET_THREAD_INFO_AFFINITY;
-    CLIENT_SendRequest( REQ_SET_THREAD_INFO, -1, 1, &req, sizeof(req) );
-    if (CLIENT_WaitReply( NULL, NULL, 0 )) return 0;
+    struct set_thread_info_request *req = get_req_buffer();
+    req->handle   = hThread;
+    req->affinity = dwThreadAffinityMask;
+    req->mask     = SET_THREAD_INFO_AFFINITY;
+    if (server_call( REQ_SET_THREAD_INFO )) return 0;
     return 1;  /* FIXME: should return previous value */
 }
 
@@ -588,11 +583,10 @@ BOOL WINAPI TerminateThread(
     HANDLE handle, /* [in] Handle to thread */
     DWORD exitcode)  /* [in] Exit code for thread */
 {
-    struct terminate_thread_request req;
-    req.handle    = handle;
-    req.exit_code = exitcode;
-    CLIENT_SendRequest( REQ_TERMINATE_THREAD, -1, 1, &req, sizeof(req) );
-    return !CLIENT_WaitReply( NULL, NULL, 0 );
+    struct terminate_thread_request *req = get_req_buffer();
+    req->handle    = handle;
+    req->exit_code = exitcode;
+    return !server_call( REQ_TERMINATE_THREAD );
 }
 
 
@@ -607,13 +601,15 @@ BOOL WINAPI GetExitCodeThread(
     HANDLE hthread, /* [in]  Handle to thread */
     LPDWORD exitcode) /* [out] Address to receive termination status */
 {
-    struct get_thread_info_request req;
-    struct get_thread_info_reply reply;
-    req.handle = hthread;
-    CLIENT_SendRequest( REQ_GET_THREAD_INFO, -1, 1, &req, sizeof(req) );
-    if (CLIENT_WaitSimpleReply( &reply, sizeof(reply), NULL )) return FALSE;
-    if (exitcode) *exitcode = reply.exit_code;
-    return TRUE;
+    BOOL ret = FALSE;
+    struct get_thread_info_request *req = get_req_buffer();
+    req->handle = hthread;
+    if (!server_call( REQ_GET_THREAD_INFO ))
+    {
+        if (exitcode) *exitcode = req->exit_code;
+        ret = TRUE;
+    }
+    return ret;
 }
 
 
@@ -631,12 +627,11 @@ BOOL WINAPI GetExitCodeThread(
 DWORD WINAPI ResumeThread(
     HANDLE hthread) /* [in] Identifies thread to restart */
 {
-    struct resume_thread_request req;
-    struct resume_thread_reply reply;
-    req.handle = hthread;
-    CLIENT_SendRequest( REQ_RESUME_THREAD, -1, 1, &req, sizeof(req) );
-    if (CLIENT_WaitSimpleReply( &reply, sizeof(reply), NULL )) return 0xffffffff;
-    return reply.count;
+    DWORD ret = 0xffffffff;
+    struct resume_thread_request *req = get_req_buffer();
+    req->handle = hthread;
+    if (!server_call( REQ_RESUME_THREAD )) ret = req->count;
+    return ret;
 }
 
 
@@ -650,12 +645,11 @@ DWORD WINAPI ResumeThread(
 DWORD WINAPI SuspendThread(
     HANDLE hthread) /* [in] Handle to the thread */
 {
-    struct suspend_thread_request req;
-    struct suspend_thread_reply reply;
-    req.handle = hthread;
-    CLIENT_SendRequest( REQ_SUSPEND_THREAD, -1, 1, &req, sizeof(req) );
-    if (CLIENT_WaitSimpleReply( &reply, sizeof(reply), NULL )) return 0xffffffff;
-    return reply.count;
+    DWORD ret = 0xffffffff;
+    struct suspend_thread_request *req = get_req_buffer();
+    req->handle = hthread;
+    if (!server_call( REQ_SUSPEND_THREAD )) ret = req->count;
+    return ret;
 }
 
 
@@ -664,12 +658,11 @@ DWORD WINAPI SuspendThread(
  */
 DWORD WINAPI QueueUserAPC( PAPCFUNC func, HANDLE hthread, ULONG_PTR data )
 {
-    struct queue_apc_request req;
-    req.handle = hthread;
-    req.func   = func;
-    req.param  = (void *)data;
-    CLIENT_SendRequest( REQ_QUEUE_APC, -1, 1, &req, sizeof(req) );
-    return !CLIENT_WaitReply( NULL, NULL, 0 );
+    struct queue_apc_request *req = get_req_buffer();
+    req->handle = hthread;
+    req->func   = func;
+    req->param  = (void *)data;
+    return !server_call( REQ_QUEUE_APC );
 }
 
 
diff --git a/server/change.c b/server/change.c
index fb1f0cb4ac7f59a6483c901cd1a7e4363a3d2b01..50f193eded79cdcfcd9003b758e5cf7629acadd3 100644
--- a/server/change.c
+++ b/server/change.c
@@ -41,13 +41,15 @@ static const struct object_ops change_ops =
 };
 
 
-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 @@ static int change_signaled( struct object *obj, struct thread *thread )
 /* 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 a4792b82197d6e10583a8c3899b4e3f0226510a9..4790f90139b78eac1b63cf3c1d5ca33428707cab 100644
--- a/server/console.c
+++ b/server/console.c
@@ -69,7 +69,7 @@ static int screen_buffer_get_write_fd( struct object *obj );
 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 @@ int free_console( struct process *process )
     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 @@ static int set_console_fd( int handle, int fd, int pid )
     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 @@ static int set_console_fd( int handle, int fd, int pid )
     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)
-    {
-        *mode = ((struct console_input *)obj)->mode;
-        ret = 1;
-    }
-    else if (obj->ops == &screen_buffer_ops)
+    if ((obj = get_handle_obj( current->process, handle, GENERIC_READ, NULL )))
     {
-        *mode = ((struct screen_buffer *)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 set_error( ERROR_INVALID_HANDLE );
-    release_object( obj );
     return ret;
 }
 
@@ -316,21 +296,6 @@ static int set_console_info( int handle, struct set_console_info_request *req,
     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 @@ static int write_console_input( int handle, int count, INPUT_RECORD *records )
 }
 
 /* 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 @@ static int console_input_get_read_fd( struct object *obj )
     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 @@ static void screen_buffer_destroy( struct object *obj )
     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 @@ DECL_HANDLER(alloc_console)
     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 @@ DECL_HANDLER(free_console)
 /* 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 @@ DECL_HANDLER(set_console_mode)
 /* 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 0181d71c89e2287f82bc3128e1f768e2ab61f909..404206e8a23d7fa0156a6464e1a23dd68791df0e 100644
--- a/server/debugger.c
+++ b/server/debugger.c
@@ -146,16 +146,16 @@ static void build_event_reply( struct debug_ctx *debug_ctx )
 {
     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 @@ static void build_event_reply( struct debug_ctx *debug_ctx )
         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 @@ static int continue_debug_event( struct process *process, struct thread *thread,
     {
         /* 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 @@ DECL_HANDLER(wait_debug_event)
 {
     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 @@ DECL_HANDLER(send_debug_event)
     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 d167c67c36df4690d3b2b78425178db678bf6f9e..b9f488e7cb814890f019a1c5d83b549f303dca94 100644
--- a/server/device.c
+++ b/server/device.c
@@ -30,7 +30,7 @@ struct device
 };
 
 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 @@ static void device_dump( struct object *obj, int verbose )
     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 @@ static int device_get_info( struct object *obj, struct get_file_info_reply *repl
 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 4d3ee7e5aa18ac28a92a6d28252a14bf921d6a90..81d4ba70ec2ccc26eb1e63a9a3ee60b900722898 100644
--- a/server/event.c
+++ b/server/event.c
@@ -128,25 +128,22 @@ static int event_satisfied( struct object *obj, struct thread *thread )
 /* 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 @@ DECL_HANDLER(event_op)
         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 8e9fd802e80540496f301799daedd8577808ce78..4b0feae28c9ad63747a8d458b2c2b00a11276bd0 100644
--- a/server/file.c
+++ b/server/file.c
@@ -47,7 +47,7 @@ static int file_signaled( struct object *obj, struct thread *thread );
 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 *create_temp_file( int access )
     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 @@ static int file_flush( struct object *obj )
     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 @@ static int file_get_info( struct object *obj, struct get_file_info_reply *reply
         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 @@ static int file_unlock( struct file *file, int offset_high, int offset_low,
     /* 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 );
+        req->handle = alloc_handle( current->process, file, req->access, req->inherit );
+        release_object( file );
     }
-    if (file)
+}
+
+/* allocate a file handle for a Unix fd */
+DECL_HANDLER(alloc_file_handle)
+{
+    struct file *file;
+
+    req->handle = -1;
+    if ((fd = dup(fd)) != -1)
     {
-        reply->handle = alloc_handle( current->process, file, req->access, req->inherit );
-        release_object( file );
+        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 reply->handle = -1;
+    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(set_file_time)
 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 4b5c303062be133bc8aee38990df6f1a1a8940c2..8619e8ba65f67cd1d777eaecfb008181ccae0e54 100644
--- a/server/handle.c
+++ b/server/handle.c
@@ -403,8 +403,7 @@ DECL_HANDLER(close_handle)
 /* 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 @@ DECL_HANDLER(set_handle_info)
 /* 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 @@ DECL_HANDLER(dup_handle)
             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 b3367492792a7f95898fe37e931a0ca5334fafa3..dc0690c68da086e57cb162f85b580e14e20f5966 100644
--- a/server/mapping.c
+++ b/server/mapping.c
@@ -104,11 +104,11 @@ static struct object *create_mapping( int size_high, int size_low, int protect,
         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 @@ static struct object *create_mapping( int size_high, int size_low, int protect,
     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 @@ static void mapping_destroy( struct object *obj )
 /* 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 f171d955313f4b34c986975aec1c376fc11bfc6b..32b74075be5ee8e2b288518f87ef97896f39f2c6 100644
--- a/server/mutex.c
+++ b/server/mutex.c
@@ -126,25 +126,22 @@ static int mutex_satisfied( struct object *obj, struct thread *thread )
 /* 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 7054e41a13f76a99d66710148f96b3fe425bdccc..d50fd7d7052ef1f0232aafcc108fc12efca42be6 100644
--- a/server/object.c
+++ b/server/object.c
@@ -240,7 +240,7 @@ int no_flush( struct object *obj )
     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 8da0c81786facb7779cd6e3aa342d5ebcca61047..0e23b18c3d01fe81468093626833b3d4186fe497 100644
--- a/server/object.h
+++ b/server/object.h
@@ -47,7 +47,7 @@ struct object_ops
     /* 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_satisfied( struct object *obj, struct thread *thread );
 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 @@ struct client;
 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 9eaf93dcbc6a30ed06343aaf69b43ce59e0d3b69..00c2863c169c68ee7d5bbae9d19853b833649a44 100644
--- a/server/pipe.c
+++ b/server/pipe.c
@@ -39,7 +39,7 @@ static void pipe_remove_queue( struct object *obj, struct wait_queue_entry *entr
 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 @@ static int pipe_get_write_fd( struct object *obj )
     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 @@ static void pipe_destroy( struct object *obj )
 /* 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 b1e4df712f39c526d1c80f83b74dd70f5bef2ab7..9f68c2e1a97bf943af0712f4e6b992dac271432c 100644
--- a/server/process.c
+++ b/server/process.c
@@ -82,10 +82,10 @@ static struct process *create_process( struct process *parent, struct new_proces
     /* 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 @@ void kill_process( struct process *process, int exit_code )
 }
 
 /* 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 @@ struct process_snapshot *process_snap( int *count )
 /* 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(terminate_process)
 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 a8cab9c6767cbe07b79c3c1e108eb358052df339..56b394d72de44096df765fb8a9b4db5d2cdc5f29 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 @@ void set_reply_fd( struct thread *thread, int pass_fd )
 /* 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 b161a558a08908c6f726f2957fce1410cced2633..f9e0c95cbeeff011c52f20a34b83eef410e82555 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 send_reply( struct thread *thread );
 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 );
-
-
-/* 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.
- */
+extern void trace_reply( struct thread *thread, unsigned int res, int pass_fd );
 
-/* 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)
-{
-    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 )
+static inline size_t get_req_strlen( const char *str )
 {
-    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(new_thread);
 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(suspend_thread);
 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(create_semaphore);
 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 @@ static const struct handler {
     { (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 @@ static const struct handler {
     { (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 @@ static const struct handler {
     { (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 6b2caecb01aeb619cbfb6312ccd98d9e67542ca4..f9fb671934418a866df0ba9d46e163c66f847daf 100644
--- a/server/semaphore.c
+++ b/server/semaphore.c
@@ -64,31 +64,33 @@ static struct semaphore *create_semaphore( const char *name, size_t len,
     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)
-    {
-        set_error( ERROR_TOO_MANY_POSTS );
-    }
-    else if (sem->count)
+    if ((sem = (struct semaphore *)get_handle_obj( current->process, handle,
+                                                   SEMAPHORE_MODIFY_STATE, &semaphore_ops )))
     {
-        /* 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 );
+        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 );
     }
-    release_object( sem );
+    return prev;
 }
 
 static void semaphore_dump( struct object *obj, int verbose )
@@ -118,30 +120,26 @@ static int semaphore_satisfied( struct object *obj, struct thread *thread )
 /* 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 6aebf1b5a9f853cc558a9c2a6e1a742f434d5b27..5ac30ccd6a46b46f2cc9a9c13a0909f9c97b9752 100644
--- a/server/snapshot.c
+++ b/server/snapshot.c
@@ -64,31 +64,25 @@ static struct snapshot *create_snapshot( int flags )
 }
 
 /* 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 @@ static void snapshot_destroy( struct object *obj )
 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 9b78e07eec21d3adbe538560f7da9afd0ded8856..5628c1e5529119d85d6896cb51750e7aa7578f1c 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 @@ static void do_read( struct client *client )
         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 @@ struct client *add_client( int fd, struct thread *self )
     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 @@ void client_pass_fd( struct client *client, int pass_fd )
 }
 
 /* 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 aa9febc12c279067ed820b6d3e27d30784231238..d85a1492ee95bc4fbd2f4f0cf55835bfbcec9418 100644
--- a/server/thread.c
+++ b/server/thread.c
@@ -84,10 +84,9 @@ static int alloc_client_buffer( struct thread *thread )
     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 @@ static struct thread *create_thread( int fd, struct process *process, int suspen
     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 @@ static struct thread *create_thread( int fd, struct process *process, int suspen
         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 @@ static void destroy_thread( struct object *obj )
     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 @@ static int check_wait( struct thread *thread, int *signaled )
             /* 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 @@ static int check_wait( struct thread *thread, int *signaled )
     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 @@ void thread_killed( struct thread *thread, int exit_code )
 /* 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 @@ DECL_HANDLER(init_thread)
     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(terminate_thread)
 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(set_thread_info)
 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(suspend_thread)
 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 @@ DECL_HANDLER(resume_thread)
 /* 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 @@ DECL_HANDLER(queue_apc)
         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 cb8c2486f8b91d0ad7c61ef0b013f22866def548..006dd2eb3dbfd95fa74c999519903e7dfbf8a7c8 100644
--- a/server/thread.h
+++ b/server/thread.h
@@ -49,9 +49,6 @@ struct thread
     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 10ca05d6e9f451c986dec7911c5140887c3c354d..b7110aafeb829507e68e1163a1e1debe0595cff2 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 @@ static int dump_new_process_request( struct new_process_request *req, int len )
     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 @@ static int dump_init_process_reply( struct init_process_reply *req, int len )
     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 @@ static int dump_dup_handle_request( struct dup_handle_request *req, int len )
     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 void dump_create_file_reply( struct create_file_request *req )
+{
+    fprintf( stderr, " handle=%d", req->handle );
+}
+
+static void dump_alloc_file_handle_request( struct alloc_file_handle_request *req )
+{
+    fprintf( stderr, " access=%08x", req->access );
 }
 
-static int dump_create_file_reply( struct create_file_reply *req, int len )
+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_read_fd_request( struct get_read_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_get_write_fd_request( struct get_write_fd_request *req, int len )
+static void dump_get_write_fd_request( struct get_write_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_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 @@ static int dump_get_file_info_reply( struct get_file_info_reply *req, int len )
     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 @@ static const dump_func req_dumpers[REQ_NB_REQUESTS] = {
     (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 @@ static const dump_func req_dumpers[REQ_NB_REQUESTS] = {
     (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 @@ static const dump_func req_dumpers[REQ_NB_REQUESTS] = {
     (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 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] = {
     (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 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] = {
     (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 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] = {
     (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 @@ static const char * const req_names[REQ_NB_REQUESTS] = {
     "set_debug",
     "init_process",
     "init_thread",
+    "get_thread_buffer",
     "terminate_process",
     "terminate_thread",
     "get_process_info",
@@ -925,6 +844,7 @@ static const char * const req_names[REQ_NB_REQUESTS] = {
     "resume_thread",
     "debugger",
     "queue_apc",
+    "get_apcs",
     "close_handle",
     "get_handle_info",
     "set_handle_info",
@@ -941,6 +861,7 @@ static const char * const req_names[REQ_NB_REQUESTS] = {
     "release_semaphore",
     "open_semaphore",
     "create_file",
+    "alloc_file_handle",
     "get_read_fd",
     "get_write_fd",
     "set_file_pointer",
@@ -979,16 +900,14 @@ static const char * const req_names[REQ_NB_REQUESTS] = {
 
 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 @@ void trace_kill( int exit_code )
              (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 );
diff --git a/tools/make_requests b/tools/make_requests
index b18f7ac58583640d16c0ca29abd1f4d39caadc26..e5af2601349f9c890ebbdd548d5fbaf960e4e1e6 100755
--- a/tools/make_requests
+++ b/tools/make_requests
@@ -14,9 +14,7 @@
     "unsigned int" => "%08x",
     "void*"        => "%p",
     "time_t"       => "%ld",
-    "char[0]"      => "dump_chars",
-    "int[0]"       => "dump_ints",
-    "void*[0]"     => "dump_ptrs"
+    "char[1]"      => "\\\"%s\\\""
 );
 
 my @requests = ();
@@ -31,7 +29,6 @@ my @trace_lines = ();
 while (<SERVER>)
 {
     if (/^struct +(\w+)_request/) { &DO_REQUEST($1); }
-    if (/^struct +(\w+)_reply/)   { &DO_REPLY($1); }
 }
 
 ### Output the dumping function tables
@@ -92,71 +89,56 @@ REPLACE_IN_FILE( "server/request.h", @request_lines );
 sub DO_REQUEST
 {
     my $name = shift;
-    my @struct = ();
+    my @in_struct = ();
+    my @out_struct = ();
     while (<SERVER>)
     {
+	my ($dir, $type, $var);
 	last if /^};$/;
         next if /^{$/;
 	s!/\*.*\*/!!g;
 	next if /^\s*$/;
-	/ *(\w+\**( +\w+\**)*) +(\w+)(\[0\])?;/ or die "Unrecognized syntax $_";
-	my $type = $1 . ($4 || "");
-	my $var = $3;
-        die "Unrecognized type $type" unless defined($formats{$type});
-	push @struct, $type, $var;
+	/^\s*(IN|OUT)\s*(\w+\**(\s+\w+\**)*)\s+(\w+)(\[[1]\])?;/ or die "Unrecognized syntax $_";
+	$dir = $1;
+	$type = $2 . ($5 || "");
+	$var = $4;
+	die "Unrecognized type $type" unless (defined($formats{$type}) || $5);
+	if ($dir =~ /IN/) { push @in_struct, $type, $var; }
+	if ($dir =~ /OUT/) { push @out_struct, $type, $var; }
     }
     push @requests, $name;
-    &DO_DUMP_FUNC( $name . "_request",@struct);
-}
-
-### Handle a reply structure definition
-
-sub DO_REPLY
-{
-    my $name = shift;
-    my @struct = ();
-    while (<SERVER>)
+    &DO_DUMP_FUNC( $name, "request", @in_struct);
+    if ($#out_struct >= 0)
     {
-	last if /^};$/;
-        next if /^{$/;
-	s!/\*.*\*/!!g;
-	next if /^\s*$/;
-	/ *(\w+\**( +\w+\**)*) +(\w+)(\[0\])?;/ or die "Unrecognized syntax $_";
-	my $type = $1 . ($4 || "");
-	my $var = $3;
-        die "Unrecognized type $type" unless defined($formats{$type});
-	push @struct, $type, $var;
+	$replies{$name} = 1;
+	&DO_DUMP_FUNC( $name, "reply", @out_struct);
     }
-    $replies{$name} = 1;
-    &DO_DUMP_FUNC( $name . "_reply" ,@struct);
 }
 
 ### Generate a dumping function
 
 sub DO_DUMP_FUNC
 {
-    my $vararg = 0;
     my $name = shift;
-    push @trace_lines, "static int dump_$name( struct $name *req, int len )\n{\n";
+    my $req = shift;
+    push @trace_lines, "static void dump_${name}_$req( struct ${name}_request *req )\n{\n";
     while ($#_ >= 0)
     {
 	my $type = shift;
 	my $var = shift;
-	if ($type =~ /\[0\]$/)  # vararg type?
-	{
-	    $vararg = 1;
-	    push @trace_lines, "    fprintf( stderr, \" $var=\" );\n";
-	    push @trace_lines, "    return $formats{$type}( req+1, len - (int)sizeof(*req) ) + sizeof(*req);\n";
-	}
-	else
+	if (defined($formats{$type}))
 	{
 	    push @trace_lines, "    fprintf( stderr, \" $var=$formats{$type}";
 	    push @trace_lines, "," if ($#_ > 0);
 	    push @trace_lines, "\", ";
 	    push @trace_lines, "req->$var );\n";
+	}
+	else  # must be some varargs format
+	{
+	    push @trace_lines, "    fprintf( stderr, \" $var=\" );\n";
+	    push @trace_lines, "    dump_varargs_${name}( req );\n";
         }
     }
-    push @trace_lines, "    return (int)sizeof(*req);\n" unless $vararg;
     push @trace_lines, "}\n\n";
 }
 
diff --git a/win32/console.c b/win32/console.c
index ebb371dbdb83e9c84ffbae28ab09e9076b26d70c..6f8281a0b88272300c304cf4c2b8d52789a2d9fb 100644
--- a/win32/console.c
+++ b/win32/console.c
@@ -55,15 +55,14 @@ FILE *wine_openpty(int *master, int *slave, char *name,
                    struct termios *term, struct winsize *winsize);
 
 /****************************************************************************
- *		CONSOLE_GetInfo
+ *		CONSOLE_GetPid
  */
-static BOOL CONSOLE_GetInfo( HANDLE handle, struct get_console_info_reply *reply )
+static int CONSOLE_GetPid( HANDLE handle )
 {
-    struct get_console_info_request req;
-
-    req.handle = handle;
-    CLIENT_SendRequest( REQ_GET_CONSOLE_INFO, -1, 1, &req, sizeof(req) );
-    return !CLIENT_WaitReply( NULL, NULL, 1, reply, sizeof(*reply) );
+    struct get_console_info_request *req = get_req_buffer();
+    req->handle = handle;
+    if (server_call( REQ_GET_CONSOLE_INFO )) return 0;
+    return req->pid;
 }
 
 /****************************************************************************
@@ -428,9 +427,7 @@ DWORD WINAPI GetLargestConsoleWindowSize( HANDLE hConsoleOutput )
  */
 BOOL WINAPI FreeConsole(VOID)
 {
-    struct free_console_request req;
-    CLIENT_SendRequest( REQ_FREE_CONSOLE, -1, 1, &req, sizeof(req) );
-    return !CLIENT_WaitReply( NULL, NULL, 0 );
+    return !server_call( REQ_FREE_CONSOLE );
 }
 
 
@@ -441,16 +438,15 @@ BOOL WINAPI FreeConsole(VOID)
  */
 HANDLE CONSOLE_OpenHandle( BOOL output, DWORD access, LPSECURITY_ATTRIBUTES sa )
 {
-    struct open_console_request req;
-    struct open_console_reply reply;
+    int ret = -1;
+    struct open_console_request *req = get_req_buffer();
 
-    req.output  = output;
-    req.access  = access;
-    req.inherit = (sa && (sa->nLength>=sizeof(*sa)) && sa->bInheritHandle);
-    CLIENT_SendRequest( REQ_OPEN_CONSOLE, -1, 1, &req, sizeof(req) );
+    req->output  = output;
+    req->access  = access;
+    req->inherit = (sa && (sa->nLength>=sizeof(*sa)) && sa->bInheritHandle);
     SetLastError(0);
-    if (!CLIENT_WaitSimpleReply( &reply, sizeof(reply), NULL )) return reply.handle;
-    return -1;
+    if (!server_call( REQ_OPEN_CONSOLE )) ret = req->handle;
+    return ret;
 }
 
 
@@ -470,17 +466,13 @@ HANDLE CONSOLE_OpenHandle( BOOL output, DWORD access, LPSECURITY_ATTRIBUTES sa )
  */
 static BOOL CONSOLE_make_complex(HANDLE handle)
 {
-        struct set_console_fd_request req;
-        struct get_console_info_reply info;
+        struct set_console_fd_request *req = get_req_buffer();
 	struct termios term;
 	char buf[256];
 	char c = '\0';
-	int status = 0;
-	int i,xpid,master,slave;
-	DWORD	xlen;
+	int i,xpid,master,slave,pty_handle;
 
-        if (!CONSOLE_GetInfo( handle, &info )) return FALSE;
-        if (info.pid) return TRUE; /* already complex */
+        if (CONSOLE_GetPid( handle )) return TRUE; /* already complex */
 
 	MESSAGE("Console: Making console complex (creating an xterm)...\n");
 
@@ -494,6 +486,7 @@ static BOOL CONSOLE_make_complex(HANDLE handle)
 
 	if ((xpid=fork()) == 0) {
 		tcsetattr(slave, TCSADRAIN, &term);
+                close( slave );
 		sprintf(buf, "-Sxx%d", master);
 		/* "-fn vga" for VGA font. Harmless if vga is not present:
 		 *  xterm: unable to open font "vga", trying "fixed".... 
@@ -502,35 +495,41 @@ static BOOL CONSOLE_make_complex(HANDLE handle)
 		ERR("error creating AllocConsole xterm\n");
 		exit(1);
 	}
-
-        req.handle = handle;
-        req.pid = xpid;
-        CLIENT_SendRequest( REQ_SET_CONSOLE_FD, dup(slave), 1, &req, sizeof(req) );
-        CLIENT_WaitReply( NULL, NULL, 0 );
+        pty_handle = FILE_DupUnixHandle( slave, GENERIC_READ | GENERIC_WRITE );
+        close( master );
+        close( slave );
+        if (pty_handle == -1) return FALSE;
 
 	/* most xterms like to print their window ID when used with -S;
 	 * read it and continue before the user has a chance...
 	 */
-	for (i=0; c!='\n'; (status=read(slave, &c, 1)), i++) {
-		if (status == -1 && c == '\0') {
-				/* wait for xterm to be created */
-			usleep(100);
-		}
-		if (i > 10000) {
-			ERR("can't read xterm WID\n");
-			kill(xpid, SIGKILL);
-			return FALSE;
-		}
+        for (i = 0; i < 10000; i++)
+        {
+            BOOL ok = ReadFile( pty_handle, &c, 1, NULL, NULL );
+            if (!ok && !c) usleep(100); /* wait for xterm to be created */
+            else if (c == '\n') break;
+        }
+        if (i == 10000)
+        {
+            ERR("can't read xterm WID\n");
+            CloseHandle( pty_handle );
+            return FALSE;
 	}
+        req->handle = handle;
+        req->file_handle = pty_handle;
+        req->pid = xpid;
+        server_call( REQ_SET_CONSOLE_FD );
+        CloseHandle( pty_handle );
+
 	/* enable mouseclicks */
-	sprintf(buf,"%c[?1001s%c[?1000h",27,27);
-	WriteFile(handle,buf,strlen(buf),&xlen,NULL);
-        
-        if (GetConsoleTitleA( buf, sizeof(buf) ))
+	strcpy( buf, "\033[?1001s\033[?1000h" );
+	WriteFile(handle,buf,strlen(buf),NULL,NULL);
+
+        strcpy( buf, "\033]2;" );
+        if (GetConsoleTitleA( buf + 4, sizeof(buf) - 5 ))
         {
-	    WriteFile(handle,"\033]2;",4,&xlen,NULL);
-	    WriteFile(handle,buf,strlen(buf),&xlen,NULL);
-	    WriteFile(handle,"\a",1,&xlen,NULL);
+            strcat( buf, "\a" );
+	    WriteFile(handle,buf,strlen(buf),NULL,NULL);
 	}
 	return TRUE;
 
@@ -544,29 +543,29 @@ static BOOL CONSOLE_make_complex(HANDLE handle)
  */
 BOOL WINAPI AllocConsole(VOID)
 {
-    struct alloc_console_request req;
-    struct alloc_console_reply reply;
+    struct alloc_console_request *req = get_req_buffer();
     HANDLE hStderr;
+    int handle_in, handle_out;
 
     TRACE("()\n");
-    req.access  = GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE;
-    req.inherit = FALSE;
-    CLIENT_SendRequest( REQ_ALLOC_CONSOLE, -1, 1, &req, sizeof(req) );
-    if (CLIENT_WaitSimpleReply( &reply, sizeof(reply), NULL ) != ERROR_SUCCESS)
-        return FALSE;
+    req->access  = GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE;
+    req->inherit = FALSE;
+    if (server_call( REQ_ALLOC_CONSOLE )) return FALSE;
+    handle_in = req->handle_in;
+    handle_out = req->handle_out;
 
-    if (!DuplicateHandle( GetCurrentProcess(), reply.handle_out, GetCurrentProcess(), &hStderr,
+    if (!DuplicateHandle( GetCurrentProcess(), req->handle_out, GetCurrentProcess(), &hStderr,
                           0, TRUE, DUPLICATE_SAME_ACCESS ))
     {
-        CloseHandle( reply.handle_in );
-        CloseHandle( reply.handle_out );
+        CloseHandle( handle_in );
+        CloseHandle( handle_out );
         FreeConsole();
         return FALSE;
     }
 
     /* NT resets the STD_*_HANDLEs on console alloc */
-    SetStdHandle( STD_INPUT_HANDLE, reply.handle_in );
-    SetStdHandle( STD_OUTPUT_HANDLE, reply.handle_out );
+    SetStdHandle( STD_INPUT_HANDLE, handle_in );
+    SetStdHandle( STD_OUTPUT_HANDLE, handle_out );
     SetStdHandle( STD_ERROR_HANDLE, hStderr );
 
     SetLastError(ERROR_SUCCESS);
@@ -600,14 +599,15 @@ UINT WINAPI GetConsoleOutputCP(VOID)
  */
 BOOL WINAPI GetConsoleMode(HANDLE hcon,LPDWORD mode)
 {
-    struct get_console_mode_request req;
-    struct get_console_mode_reply reply;
-
-    req.handle = hcon;
-    CLIENT_SendRequest( REQ_GET_CONSOLE_MODE, -1, 1, &req, sizeof(req));
-    if (CLIENT_WaitSimpleReply( &reply, sizeof(reply), NULL )) return FALSE;
-    *mode = reply.mode;
-    return TRUE;
+    BOOL ret = FALSE;
+    struct get_console_mode_request *req = get_req_buffer();
+    req->handle = hcon;
+    if (!server_call( REQ_GET_CONSOLE_MODE ))
+    {
+        if (mode) *mode = req->mode;
+        ret = TRUE;
+    }
+    return ret;
 }
 
 
@@ -624,12 +624,10 @@ BOOL WINAPI GetConsoleMode(HANDLE hcon,LPDWORD mode)
  */
 BOOL WINAPI SetConsoleMode( HANDLE hcon, DWORD mode )
 {
-    struct set_console_mode_request req;
-
-    req.handle = hcon;
-    req.mode = mode;
-    CLIENT_SendRequest( REQ_SET_CONSOLE_MODE, -1, 1, &req, sizeof(req));
-    return !CLIENT_WaitReply( NULL, NULL, 0 );
+    struct set_console_mode_request *req = get_req_buffer();
+    req->handle = hcon;
+    req->mode = mode;
+    return !server_call( REQ_SET_CONSOLE_MODE );
 }
 
 
@@ -638,21 +636,18 @@ BOOL WINAPI SetConsoleMode( HANDLE hcon, DWORD mode )
  */
 DWORD WINAPI GetConsoleTitleA(LPSTR title,DWORD size)
 {
-    struct get_console_info_request req;
-    struct get_console_info_reply reply;
-    int len;
+    struct get_console_info_request *req = get_req_buffer();
     DWORD ret = 0;
     HANDLE hcon;
 
     if ((hcon = CreateFileA( "CONOUT$", GENERIC_READ, 0, NULL,
                                OPEN_EXISTING, 0, 0 )) == INVALID_HANDLE_VALUE)
         return 0;
-    req.handle = hcon;
-    CLIENT_SendRequest( REQ_GET_CONSOLE_INFO, -1, 1, &req, sizeof(req) );
-    if (!CLIENT_WaitReply( &len, NULL, 2, &reply, sizeof(reply), title, size ))
+    req->handle = hcon;
+    if (!server_call( REQ_GET_CONSOLE_INFO ))
     {
-        if (len > sizeof(reply)+size) title[size-1] = 0;
-        ret = strlen(title);
+        lstrcpynA( title, req->title, size );
+        ret = strlen(req->title);
     }
     CloseHandle( hcon );
     return ret;
@@ -722,7 +717,7 @@ BOOL WINAPI WriteConsoleOutputA( HANDLE hConsoleOutput,
 	1,5,3,7,
     };
     CONSOLE_make_complex(hConsoleOutput);
-    buffer = HeapAlloc(GetProcessHeap(),0,100);;
+    buffer = HeapAlloc(GetProcessHeap(),0,100);
     curbufsize = 100;
 
     TRACE("wr: top = %d, bottom=%d, left=%d,right=%d\n",
@@ -790,8 +785,6 @@ BOOL WINAPI ReadConsoleA( HANDLE hConsoleInput,
 {
     int		charsread = 0;
     LPSTR	xbuf = (LPSTR)lpBuffer;
-    struct read_console_input_request req;
-    struct read_console_input_reply reply;
     INPUT_RECORD	ir;
 
     TRACE("(%d,%p,%ld,%p,%p)\n",
@@ -801,21 +794,15 @@ BOOL WINAPI ReadConsoleA( HANDLE hConsoleInput,
 
     CONSOLE_get_input(hConsoleInput,FALSE);
 
-    req.handle = hConsoleInput;
-    req.count = 1;
-    req.flush = 1;
-
     /* FIXME: should we read at least 1 char? The SDK does not say */
     while (charsread<nNumberOfCharsToRead)
     {
-    	int len;
-
-        CLIENT_SendRequest( REQ_READ_CONSOLE_INPUT, -1, 1, &req, sizeof(req) );
-        if (CLIENT_WaitReply( &len, NULL, 2, &reply, sizeof(reply), &ir, sizeof(ir) ))
-            return FALSE;
-        len -= sizeof(reply);
-        assert( !(len % sizeof(ir)) );
-        if (!len) break;
+        struct read_console_input_request *req = get_req_buffer();
+        req->handle = hConsoleInput;
+        req->count = 1;
+        req->flush = 1;
+        if (server_call( REQ_READ_CONSOLE_INPUT )) return FALSE;
+        if (!req->read) break;
     	if (!ir.Event.KeyEvent.bKeyDown)
 		continue;
     	if (ir.EventType != KEY_EVENT)
@@ -867,33 +854,27 @@ BOOL WINAPI ReadConsoleW( HANDLE hConsoleInput,
  *    Success: TRUE
  *    Failure: FALSE
  */
-BOOL WINAPI ReadConsoleInputA(HANDLE hConsoleInput,
-				  LPINPUT_RECORD lpBuffer,
-				  DWORD nLength, LPDWORD lpNumberOfEventsRead)
+BOOL WINAPI ReadConsoleInputA(HANDLE hConsoleInput, LPINPUT_RECORD lpBuffer,
+                              DWORD nLength, LPDWORD lpNumberOfEventsRead)
 {
-    struct read_console_input_request req;
-    struct read_console_input_reply reply;
-    int len;
-
-    req.handle = hConsoleInput;
-    req.count = nLength;
-    req.flush = 1;
+    struct read_console_input_request *req = get_req_buffer();
 
     /* loop until we get at least one event */
     for (;;)
     {
-        CLIENT_SendRequest( REQ_READ_CONSOLE_INPUT, -1, 1, &req, sizeof(req) );
-        if (CLIENT_WaitReply( &len, NULL, 2, &reply, sizeof(reply),
-                              lpBuffer, nLength * sizeof(*lpBuffer) ))
-            return FALSE;
-        len -= sizeof(reply);
-        assert( !(len % sizeof(INPUT_RECORD)) );
-        if (len) break;
+        req->handle = hConsoleInput;
+        req->count = nLength;
+        req->flush = 1;
+        if (server_call( REQ_READ_CONSOLE_INPUT )) return FALSE;
+        if (req->read)
+        {
+            memcpy( lpBuffer, req + 1, req->read * sizeof(*lpBuffer) );
+            if (lpNumberOfEventsRead) *lpNumberOfEventsRead = req->read;
+            return TRUE;
+        }
 	CONSOLE_get_input(hConsoleInput,TRUE);
         /*WaitForSingleObject( hConsoleInput, INFINITE32 );*/
     }
-    if (lpNumberOfEventsRead) *lpNumberOfEventsRead = len / sizeof(INPUT_RECORD);
-    return TRUE;
 }
 
 
@@ -913,14 +894,11 @@ BOOL WINAPI ReadConsoleInputW( HANDLE handle, LPINPUT_RECORD buffer,
  */
 BOOL WINAPI FlushConsoleInputBuffer( HANDLE handle )
 {
-    struct read_console_input_request req;
-    int len;
-
-    req.handle = handle;
-    req.count = -1;  /* get all records */
-    req.flush = 1;
-    CLIENT_SendRequest( REQ_READ_CONSOLE_INPUT, -1, 1, &req, sizeof(req) );
-    return !CLIENT_WaitReply( &len, NULL, 0 );
+    struct read_console_input_request *req = get_req_buffer();
+    req->handle = handle;
+    req->count = -1;  /* get all records */
+    req->flush = 1;
+    return !server_call( REQ_READ_CONSOLE_INPUT );
 }
 
 
@@ -934,22 +912,16 @@ BOOL WINAPI FlushConsoleInputBuffer( HANDLE handle )
 BOOL WINAPI PeekConsoleInputA( HANDLE handle, LPINPUT_RECORD buffer,
                                    DWORD count, LPDWORD read )
 {
-    struct read_console_input_request req;
-    struct read_console_input_reply reply;
-    int len;
+    struct read_console_input_request *req = get_req_buffer();
 
     CONSOLE_get_input(handle,FALSE);
-    req.handle = handle;
-    req.count = count;
-    req.flush = 0;
 
-    CLIENT_SendRequest( REQ_READ_CONSOLE_INPUT, -1, 1, &req, sizeof(req) );
-    if (CLIENT_WaitReply( &len, NULL, 2, &reply, sizeof(reply),
-                          buffer, count * sizeof(*buffer) ))
-        return FALSE;
-    len -= sizeof(reply);
-    assert( !(len % sizeof(INPUT_RECORD)) );
-    if (read) *read = len / sizeof(INPUT_RECORD);
+    req->handle = handle;
+    req->count = count;
+    req->flush = 0;
+    if (server_call( REQ_READ_CONSOLE_INPUT )) return FALSE;
+    if (req->read) memcpy( buffer, req + 1, req->read * sizeof(*buffer) );
+    if (read) *read = req->read;
     return TRUE;
 }
 
@@ -972,17 +944,23 @@ BOOL WINAPI PeekConsoleInputW(HANDLE hConsoleInput,
  *
  */
 BOOL WINAPI WriteConsoleInputA( HANDLE handle, INPUT_RECORD *buffer,
-                                    DWORD count, LPDWORD written )
+                                DWORD count, LPDWORD written )
 {
-    struct write_console_input_request req;
-    struct write_console_input_reply reply;
-
-    req.handle = handle;
-    req.count = count;
-    CLIENT_SendRequest( REQ_WRITE_CONSOLE_INPUT, -1, 2, &req, sizeof(req),
-                        buffer, count * sizeof(*buffer) );
-    if (CLIENT_WaitSimpleReply( &reply, sizeof(reply), NULL )) return FALSE;
-    if (written) *written = reply.written;
+    struct write_console_input_request *req = get_req_buffer();
+    const DWORD max = server_remaining( req + 1 ) / sizeof(INPUT_RECORD);
+
+    if (written) *written = 0;
+    while (count)
+    {
+        DWORD len = count < max ? count : max;
+        req->count = len;
+        req->handle = handle;
+        memcpy( req + 1, buffer, len * sizeof(*buffer) );
+        if (server_call( REQ_WRITE_CONSOLE_INPUT )) return FALSE;
+        if (written) *written += req->written;
+        count -= len;
+        buffer += len;
+    }
     return TRUE;
 }
 
@@ -998,20 +976,18 @@ BOOL WINAPI WriteConsoleInputA( HANDLE handle, INPUT_RECORD *buffer,
  */
 BOOL WINAPI SetConsoleTitleA(LPCSTR title)
 {
-    struct set_console_info_request req;
-    struct get_console_info_reply info;
+    struct set_console_info_request *req = get_req_buffer();
     HANDLE hcon;
     DWORD written;
 
     if ((hcon = CreateFileA( "CONOUT$", GENERIC_READ|GENERIC_WRITE, 0, NULL,
                                OPEN_EXISTING, 0, 0 )) == INVALID_HANDLE_VALUE)
         return FALSE;
-    req.handle = hcon;
-    req.mask = SET_CONSOLE_INFO_TITLE;
-    CLIENT_SendRequest( REQ_SET_CONSOLE_INFO, -1, 2, &req, sizeof(req),
-                        title, strlen(title)+1 );
-    if (CLIENT_WaitReply( NULL, NULL, 0 )) goto error;
-    if (CONSOLE_GetInfo( hcon, &info ) && info.pid)
+    req->handle = hcon;
+    req->mask = SET_CONSOLE_INFO_TITLE;
+    lstrcpynA( req->title, title, server_remaining(req->title) );
+    if (server_call( REQ_SET_CONSOLE_INFO )) goto error;
+    if (CONSOLE_GetPid( hcon ))
     {
         /* only set title for complex console (own xterm) */
         WriteFile( hcon, "\033]2;", 4, &written, NULL );
@@ -1112,16 +1088,15 @@ BOOL WINAPI GetNumberOfConsoleMouseButtons(LPDWORD nrofbuttons)
  *    Success: TRUE
  *    Failure: FALSE
  */
-BOOL WINAPI GetConsoleCursorInfo( HANDLE hcon,
-                                      LPCONSOLE_CURSOR_INFO cinfo )
+BOOL WINAPI GetConsoleCursorInfo( HANDLE hcon, LPCONSOLE_CURSOR_INFO cinfo )
 {
-    struct get_console_info_reply reply;
-
-    if (!CONSOLE_GetInfo( hcon, &reply )) return FALSE;
+    struct get_console_info_request *req = get_req_buffer();
+    req->handle = hcon;
+    if (server_call( REQ_GET_CONSOLE_INFO )) return FALSE;
     if (cinfo)
     {
-        cinfo->dwSize = reply.cursor_size;
-        cinfo->bVisible = reply.cursor_visible;
+        cinfo->dwSize = req->cursor_size;
+        cinfo->bVisible = req->cursor_visible;
     }
     return TRUE;
 }
@@ -1138,20 +1113,19 @@ BOOL WINAPI SetConsoleCursorInfo(
     HANDLE hcon,                /* [in] Handle to console screen buffer */
     LPCONSOLE_CURSOR_INFO cinfo)  /* [in] Address of cursor information */
 {
-    struct set_console_info_request req;
+    struct set_console_info_request *req = get_req_buffer();
     char	buf[8];
     DWORD	xlen;
 
-    req.handle = hcon;
     CONSOLE_make_complex(hcon);
     sprintf(buf,"\033[?25%c",cinfo->bVisible?'h':'l');
     WriteFile(hcon,buf,strlen(buf),&xlen,NULL);
 
-    req.cursor_size    = cinfo->dwSize;
-    req.cursor_visible = cinfo->bVisible;
-    req.mask           = SET_CONSOLE_INFO_CURSOR;
-    CLIENT_SendRequest( REQ_SET_CONSOLE_INFO, -1, 1, &req, sizeof(req) );
-    return !CLIENT_WaitReply( NULL, NULL, 0 );
+    req->handle         = hcon;
+    req->cursor_size    = cinfo->dwSize;
+    req->cursor_visible = cinfo->bVisible;
+    req->mask           = SET_CONSOLE_INFO_CURSOR;
+    return !server_call( REQ_SET_CONSOLE_INFO );
 }
 
 
diff --git a/win32/device.c b/win32/device.c
index 21c16657cafd1131106716be408a39a7576d4ccb..8c6f1789651c16709fb842fded29512920f7458f 100644
--- a/win32/device.c
+++ b/win32/device.c
@@ -285,20 +285,16 @@ HANDLE DEVICE_Open( LPCSTR filename, DWORD access,
 
 static const struct VxDInfo *DEVICE_GetInfo( HANDLE handle )
 {
-    struct get_file_info_request req;
-    struct get_file_info_reply reply;
-
-    req.handle = handle;
-    CLIENT_SendRequest( REQ_GET_FILE_INFO, -1, 1, &req, sizeof(req) );
-    if (!CLIENT_WaitSimpleReply( &reply, sizeof(reply), NULL ) &&
-        (reply.type == FILE_TYPE_UNKNOWN) &&
-        (reply.attr & 0x10000))
+    struct get_file_info_request *req = get_req_buffer();
+
+    req->handle = handle;
+    if (!server_call( REQ_GET_FILE_INFO ) &&
+        (req->type == FILE_TYPE_UNKNOWN) &&
+        (req->attr & 0x10000))
     {
         const struct VxDInfo *info;
-
         for (info = VxDList; info->name; info++)
-            if (info->id == LOWORD(reply.attr)) break;
-        return info;
+            if (info->id == LOWORD(req->attr)) return info;
     }
     return NULL;
 }