Converted a few more server requests to the new mechanism.

diff --git a/dlls/advapi32/registry.c b/dlls/advapi32/registry.c
index 26aa450..24560e2 100644
--- a/dlls/advapi32/registry.c
+++ b/dlls/advapi32/registry.c
@@ -43,30 +43,6 @@
     return (type == REG_SZ) || (type == REG_EXPAND_SZ) || (type == REG_MULTI_SZ);
 }
 
-/* copy a key name into the request buffer */
-static inline DWORD copy_nameW( LPWSTR dest, LPCWSTR name )
-{
-    if (name)
-    {
-        if (strlenW(name) > MAX_PATH) return ERROR_MORE_DATA;
-        strcpyW( dest, name );
-    }
-    else dest[0] = 0;
-    return ERROR_SUCCESS;
-}
-
-/* copy a key name into the request buffer */
-static inline DWORD copy_nameAtoW( LPWSTR dest, LPCSTR name )
-{
-    if (name)
-    {
-        if (strlen(name) > MAX_PATH) return ERROR_MORE_DATA;
-        lstrcpyAtoW( dest, name );
-    }
-    else dest[0] = 0;
-    return ERROR_SUCCESS;
-}
-
 /* do a server call without setting the last error code */
 static inline int reg_server_call( enum request req )
 {
@@ -856,7 +832,7 @@
  *           RegQueryValueExA   [ADVAPI32.157]
  *
  * NOTES:
- * the documentation is wrong: if the buffer is to small it remains untouched 
+ * the documentation is wrong: if the buffer is too small it remains untouched 
  */
 DWORD WINAPI RegQueryValueExA( HKEY hkey, LPCSTR name, LPDWORD reserved, LPDWORD type,
                                LPBYTE data, LPDWORD count )
@@ -923,7 +899,11 @@
                 }
                 total_size = len + info_size;
             }
-            else if (data) memcpy( data, buf_ptr + info_size, total_size - info_size );
+            else if (data)
+            {
+                if (total_size - info_size > *count) status = STATUS_BUFFER_OVERFLOW;
+                else memcpy( data, buf_ptr + info_size, total_size - info_size );
+            }
         }
         else if (status != STATUS_BUFFER_OVERFLOW) goto done;
     }
@@ -1164,25 +1144,33 @@
  */
 LONG WINAPI RegLoadKeyW( HKEY hkey, LPCWSTR subkey, LPCWSTR filename )
 {
-    struct load_registry_request *req = get_req_buffer();
     HANDLE file;
-    DWORD ret, err = GetLastError();
+    DWORD ret, len, err = GetLastError();
 
     TRACE( "(%x,%s,%s)\n", hkey, debugstr_w(subkey), debugstr_w(filename) );
 
     if (!filename || !*filename) return ERROR_INVALID_PARAMETER;
     if (!subkey || !*subkey) return ERROR_INVALID_PARAMETER;
 
+    len = strlenW( subkey ) * sizeof(WCHAR);
+    if (len > MAX_PATH*sizeof(WCHAR)) return ERROR_INVALID_PARAMETER;
+
     if ((file = CreateFileW( filename, GENERIC_READ, 0, NULL, OPEN_EXISTING,
                              FILE_ATTRIBUTE_NORMAL, -1 )) == INVALID_HANDLE_VALUE)
     {
         ret = GetLastError();
         goto done;
     }
-    req->hkey  = hkey;
-    req->file  = file;
-    if ((ret = copy_nameW( req->name, subkey )) != ERROR_SUCCESS) goto done;
-    ret = reg_server_call( REQ_LOAD_REGISTRY );
+
+    SERVER_START_REQ
+    {
+        struct load_registry_request *req = server_alloc_req( sizeof(*req), len );
+        req->hkey  = hkey;
+        req->file  = file;
+        memcpy( server_data_ptr(req), subkey, len );
+        ret = reg_server_call( REQ_LOAD_REGISTRY );
+    }
+    SERVER_END_REQ;
     CloseHandle( file );
 
  done:
@@ -1196,25 +1184,34 @@
  */
 LONG WINAPI RegLoadKeyA( HKEY hkey, LPCSTR subkey, LPCSTR filename )
 {
-    struct load_registry_request *req = get_req_buffer();
     HANDLE file;
-    DWORD ret, err = GetLastError();
+    DWORD ret, len, err = GetLastError();
 
     TRACE( "(%x,%s,%s)\n", hkey, debugstr_a(subkey), debugstr_a(filename) );
 
     if (!filename || !*filename) return ERROR_INVALID_PARAMETER;
     if (!subkey || !*subkey) return ERROR_INVALID_PARAMETER;
 
+    len = MultiByteToWideChar( CP_ACP, 0, subkey, strlen(subkey), NULL, 0 ) * sizeof(WCHAR);
+    if (len > MAX_PATH*sizeof(WCHAR)) return ERROR_INVALID_PARAMETER;
+
     if ((file = CreateFileA( filename, GENERIC_READ, 0, NULL, OPEN_EXISTING,
                              FILE_ATTRIBUTE_NORMAL, -1 )) == INVALID_HANDLE_VALUE)
     {
         ret = GetLastError();
         goto done;
     }
-    req->hkey  = hkey;
-    req->file  = file;
-    if ((ret = copy_nameAtoW( req->name, subkey )) != ERROR_SUCCESS) goto done;
-    ret = reg_server_call( REQ_LOAD_REGISTRY );
+
+    SERVER_START_REQ
+    {
+        struct load_registry_request *req = server_alloc_req( sizeof(*req), len );
+        req->hkey  = hkey;
+        req->file  = file;
+        MultiByteToWideChar( CP_ACP, 0, subkey, strlen(subkey),
+                             server_data_ptr(req), len/sizeof(WCHAR) );
+        ret = reg_server_call( REQ_LOAD_REGISTRY );
+    }
+    SERVER_END_REQ;
     CloseHandle( file );
 
  done:
@@ -1233,7 +1230,6 @@
  */
 LONG WINAPI RegSaveKeyA( HKEY hkey, LPCSTR file, LPSECURITY_ATTRIBUTES sa )
 {
-    struct save_registry_request *req = get_req_buffer();
     char buffer[1024];
     int count = 0;
     LPSTR name;
@@ -1259,9 +1255,15 @@
             MESSAGE("Wow, we are already fiddling with a temp file %s with an ordinal as high as %d !\nYou might want to delete all corresponding temp files in that directory.\n", buffer, count);
     }
 
-    req->hkey = hkey;
-    req->file = handle;
-    ret = reg_server_call( REQ_SAVE_REGISTRY );
+    SERVER_START_REQ
+    {
+        struct save_registry_request *req = server_alloc_req( sizeof(*req), 0 );
+        req->hkey = hkey;
+        req->file = handle;
+        ret = reg_server_call( REQ_SAVE_REGISTRY );
+    }
+    SERVER_END_REQ;
+
     CloseHandle( handle );
     if (!ret)
     {
diff --git a/dlls/kernel/comm.c b/dlls/kernel/comm.c
index 5b77d41..defa7e0 100644
--- a/dlls/kernel/comm.c
+++ b/dlls/kernel/comm.c
@@ -1906,19 +1906,21 @@
  */
 BOOL WINAPI GetCommMask(HANDLE handle,LPDWORD evtmask)
 {
-    struct get_serial_info_request *req = get_req_buffer();
+    BOOL ret;
 
     TRACE("handle %d, mask %p\n", handle, evtmask);
 
-    req->handle = handle;
-
-    if(server_call( REQ_GET_SERIAL_INFO ))
-        return FALSE;
-
-    if(evtmask)
-        *evtmask = req->eventmask;
-	  
-    return TRUE;
+    SERVER_START_REQ
+    {
+        struct get_serial_info_request *req = server_alloc_req( sizeof(*req), 0 );
+        req->handle = handle;
+        if ((ret = !server_call( REQ_GET_SERIAL_INFO )))
+        {
+            if (evtmask) *evtmask = req->eventmask;
+        }
+    }
+    SERVER_END_REQ;
+    return ret;
 }
 
 /*****************************************************************************
@@ -1926,18 +1928,20 @@
  */
 BOOL WINAPI SetCommMask(HANDLE handle,DWORD evtmask)
 {
-    struct set_serial_info_request *req = get_req_buffer();
+    BOOL ret;
 
     TRACE("handle %d, mask %lx\n", handle, evtmask);
-	  
-    req->handle    = handle;
-    req->flags     = SERIALINFO_SET_MASK;
-    req->eventmask = evtmask;
 
-    if(server_call( REQ_SET_SERIAL_INFO ))
-        return FALSE;
-
-    return TRUE;
+    SERVER_START_REQ
+    {
+        struct set_serial_info_request *req = server_alloc_req( sizeof(*req), 0 );
+        req->handle    = handle;
+        req->flags     = SERIALINFO_SET_MASK;
+        req->eventmask = evtmask;
+        ret = !server_call( REQ_SET_SERIAL_INFO );
+    }
+    SERVER_END_REQ;
+    return ret;
 }
 
 /*****************************************************************************
@@ -2447,7 +2451,7 @@
  */
 BOOL WINAPI GetCommTimeouts(HANDLE hComm,LPCOMMTIMEOUTS lptimeouts)
 {
-    struct get_serial_info_request *req = get_req_buffer();
+    BOOL ret;
 
     TRACE("(%x,%p)\n",hComm,lptimeouts);
 
@@ -2457,18 +2461,21 @@
         return FALSE;
     }
 
-    req->handle = hComm;
-
-    if(server_call( REQ_GET_SERIAL_INFO ))
-        return FALSE;
-
-    lptimeouts->ReadIntervalTimeout         = req->readinterval;
-    lptimeouts->ReadTotalTimeoutMultiplier  = req->readmult;
-    lptimeouts->ReadTotalTimeoutConstant    = req->readconst;
-    lptimeouts->WriteTotalTimeoutMultiplier = req->writemult;
-    lptimeouts->WriteTotalTimeoutConstant   = req->writeconst;
-
-	return TRUE;
+    SERVER_START_REQ
+    {
+        struct get_serial_info_request *req = server_alloc_req( sizeof(*req), 0 );
+        req->handle = hComm;
+        if ((ret = !server_call( REQ_GET_SERIAL_INFO )))
+        {
+            lptimeouts->ReadIntervalTimeout         = req->readinterval;
+            lptimeouts->ReadTotalTimeoutMultiplier  = req->readmult;
+            lptimeouts->ReadTotalTimeoutConstant    = req->readconst;
+            lptimeouts->WriteTotalTimeoutMultiplier = req->writemult;
+            lptimeouts->WriteTotalTimeoutConstant   = req->writeconst;
+        }
+    }
+    SERVER_END_REQ;
+    return ret;
 }
 
 /*****************************************************************************
@@ -2487,8 +2494,8 @@
     HANDLE hComm,              /* [I] handle of COMM device */
     LPCOMMTIMEOUTS lptimeouts /* [I] pointer to COMMTIMEOUTS structure */
 ) {
-    struct set_serial_info_request *req = get_req_buffer();
-	int	fd;
+    BOOL ret;
+    int fd;
     struct termios tios;
 
     TRACE("(%x,%p)\n",hComm,lptimeouts);
@@ -2496,20 +2503,23 @@
     if(!lptimeouts)
     {
         SetLastError(ERROR_INVALID_PARAMETER);
-		return FALSE;
-	}
-
-    req->handle       = hComm;
-    req->flags        = SERIALINFO_SET_TIMEOUTS;
-
-    req->readinterval = lptimeouts->ReadIntervalTimeout ;
-    req->readmult     = lptimeouts->ReadTotalTimeoutMultiplier ;
-    req->readconst    = lptimeouts->ReadTotalTimeoutConstant ;
-    req->writemult    = lptimeouts->WriteTotalTimeoutMultiplier ;
-    req->writeconst   = lptimeouts->WriteTotalTimeoutConstant ;
-
-    if(server_call( REQ_SET_SERIAL_INFO ))
         return FALSE;
+    }
+
+    SERVER_START_REQ
+    {
+        struct set_serial_info_request *req = server_alloc_req( sizeof(*req), 0 );
+        req->handle       = hComm;
+        req->flags        = SERIALINFO_SET_TIMEOUTS;
+        req->readinterval = lptimeouts->ReadIntervalTimeout ;
+        req->readmult     = lptimeouts->ReadTotalTimeoutMultiplier ;
+        req->readconst    = lptimeouts->ReadTotalTimeoutConstant ;
+        req->writemult    = lptimeouts->WriteTotalTimeoutMultiplier ;
+        req->writeconst   = lptimeouts->WriteTotalTimeoutConstant ;
+        ret = !server_call( REQ_SET_SERIAL_INFO );
+    }
+    SERVER_END_REQ;
+    if (!ret) return FALSE;
 
     /* FIXME: move this stuff to the server */
     fd = FILE_GetUnixHandle( hComm, GENERIC_WRITE );
@@ -2518,18 +2528,18 @@
        return FALSE;
     }
 
-	if (-1==tcgetattr(fd,&tios)) {
-		FIXME("tcgetattr on fd %d failed!\n",fd);
-		return FALSE;
-	}
-	/* VTIME is in 1/10 seconds */
-	tios.c_cc[VTIME]= (lptimeouts->ReadIntervalTimeout+99)/100;
-	if (-1==tcsetattr(fd,0,&tios)) {
-		FIXME("tcsetattr on fd %d failed!\n",fd);
-		return FALSE;
-	}
+    if (-1==tcgetattr(fd,&tios)) {
+        FIXME("tcgetattr on fd %d failed!\n",fd);
+        return FALSE;
+    }
+    /* VTIME is in 1/10 seconds */
+    tios.c_cc[VTIME]= (lptimeouts->ReadIntervalTimeout+99)/100;
+    if (-1==tcsetattr(fd,0,&tios)) {
+        FIXME("tcsetattr on fd %d failed!\n",fd);
+        return FALSE;
+    }
     close(fd);
-	return TRUE;
+    return TRUE;
 }
 
 /***********************************************************************
diff --git a/files/dos_fs.c b/files/dos_fs.c
index 2b21acc..d4dd2c3 100644
--- a/files/dos_fs.c
+++ b/files/dos_fs.c
@@ -698,8 +698,7 @@
  */
 static HANDLE DOSFS_CreateCommPort(LPCSTR name, DWORD access)
 {
-    struct create_serial_request *req = get_req_buffer();
-    DWORD r;
+    HANDLE ret = INVALID_HANDLE_VALUE;
     char devname[40];
 
     TRACE("%s %lx\n", name, access);
@@ -710,14 +709,22 @@
 
     TRACE("opening %s as %s\n", devname, name);
 
-    req->handle  = 0;
-    req->access  = access;
-    req->sharing = FILE_SHARE_READ|FILE_SHARE_WRITE;
-    lstrcpynA( req->name, devname, server_remaining(req->name) );
-    SetLastError(0);
-    r = server_call( REQ_CREATE_SERIAL );
-    TRACE("create_port_request return %08lX handle = %08X\n",r,req->handle);
-    return req->handle;
+    SERVER_START_REQ
+    {
+        size_t len = strlen(devname);
+        struct create_serial_request *req = server_alloc_req( sizeof(*req), len );
+
+        req->access  = access;
+        req->inherit = 0;  /*FIXME*/
+        req->sharing = FILE_SHARE_READ|FILE_SHARE_WRITE;
+        memcpy( server_data_ptr(req), devname, len );
+        SetLastError(0);
+        if (!(server_call( REQ_CREATE_SERIAL ))) ret = req->handle;
+    }
+    SERVER_END_REQ;
+
+    TRACE("return %08X\n", ret );
+    return ret;
 }
 
 /***********************************************************************
diff --git a/include/server.h b/include/server.h
index 443c547..c6c7d57 100644
--- a/include/server.h
+++ b/include/server.h
@@ -991,7 +991,7 @@
     IN  int          handle;       /* process handle */
     IN  void*        addr;         /* addr to read from (must be int-aligned) */
     IN  int          len;          /* number of ints to read */
-    OUT unsigned int data[1];      /* result data */
+    OUT VARARG(data,bytes);        /* result data */
 };
 
 
@@ -1004,7 +1004,7 @@
     IN  int          len;          /* number of ints to write */
     IN  unsigned int first_mask;   /* mask for first word */
     IN  unsigned int last_mask;    /* mask for last word */
-    IN  unsigned int data[1];      /* data to write */
+    IN  VARARG(data,bytes);        /* result data */
 };
 
 
@@ -1115,7 +1115,7 @@
     REQUEST_HEADER;                /* request header */
     IN  int          hkey;         /* root key to load to */
     IN  int          file;         /* file to load from */
-    IN  path_t       name;         /* subkey name */
+    IN  VARARG(name,unicode_str);  /* subkey name */
 };
 
 
@@ -1133,7 +1133,7 @@
 {
     REQUEST_HEADER;                /* request header */
     IN  int          hkey;         /* key to save */
-    IN  char         file[1];      /* file to save to */
+    IN  VARARG(file,string);       /* file to save to */
 };
 
 
@@ -1299,7 +1299,7 @@
     IN  int          inherit;      /* inherit flag */
     IN  unsigned int sharing;      /* sharing flags */
     OUT int          handle;       /* handle to the port */
-    IN  char         name[1];      /* file name */
+    IN  VARARG(name,string);       /* file name */
 };
 
 struct get_serial_info_request
@@ -1562,7 +1562,7 @@
     struct set_serial_info_request set_serial_info;
 };
 
-#define SERVER_PROTOCOL_VERSION 25
+#define SERVER_PROTOCOL_VERSION 26
 
 /* ### make_requests end ### */
 /* Everything above this line is generated automatically by tools/make_requests */
diff --git a/memory/registry.c b/memory/registry.c
index 3b682e5..24560e2 100644
--- a/memory/registry.c
+++ b/memory/registry.c
@@ -43,30 +43,6 @@
     return (type == REG_SZ) || (type == REG_EXPAND_SZ) || (type == REG_MULTI_SZ);
 }
 
-/* copy a key name into the request buffer */
-static inline DWORD copy_nameW( LPWSTR dest, LPCWSTR name )
-{
-    if (name)
-    {
-        if (strlenW(name) > MAX_PATH) return ERROR_MORE_DATA;
-        strcpyW( dest, name );
-    }
-    else dest[0] = 0;
-    return ERROR_SUCCESS;
-}
-
-/* copy a key name into the request buffer */
-static inline DWORD copy_nameAtoW( LPWSTR dest, LPCSTR name )
-{
-    if (name)
-    {
-        if (strlen(name) > MAX_PATH) return ERROR_MORE_DATA;
-        lstrcpyAtoW( dest, name );
-    }
-    else dest[0] = 0;
-    return ERROR_SUCCESS;
-}
-
 /* do a server call without setting the last error code */
 static inline int reg_server_call( enum request req )
 {
@@ -1168,25 +1144,33 @@
  */
 LONG WINAPI RegLoadKeyW( HKEY hkey, LPCWSTR subkey, LPCWSTR filename )
 {
-    struct load_registry_request *req = get_req_buffer();
     HANDLE file;
-    DWORD ret, err = GetLastError();
+    DWORD ret, len, err = GetLastError();
 
     TRACE( "(%x,%s,%s)\n", hkey, debugstr_w(subkey), debugstr_w(filename) );
 
     if (!filename || !*filename) return ERROR_INVALID_PARAMETER;
     if (!subkey || !*subkey) return ERROR_INVALID_PARAMETER;
 
+    len = strlenW( subkey ) * sizeof(WCHAR);
+    if (len > MAX_PATH*sizeof(WCHAR)) return ERROR_INVALID_PARAMETER;
+
     if ((file = CreateFileW( filename, GENERIC_READ, 0, NULL, OPEN_EXISTING,
                              FILE_ATTRIBUTE_NORMAL, -1 )) == INVALID_HANDLE_VALUE)
     {
         ret = GetLastError();
         goto done;
     }
-    req->hkey  = hkey;
-    req->file  = file;
-    if ((ret = copy_nameW( req->name, subkey )) != ERROR_SUCCESS) goto done;
-    ret = reg_server_call( REQ_LOAD_REGISTRY );
+
+    SERVER_START_REQ
+    {
+        struct load_registry_request *req = server_alloc_req( sizeof(*req), len );
+        req->hkey  = hkey;
+        req->file  = file;
+        memcpy( server_data_ptr(req), subkey, len );
+        ret = reg_server_call( REQ_LOAD_REGISTRY );
+    }
+    SERVER_END_REQ;
     CloseHandle( file );
 
  done:
@@ -1200,25 +1184,34 @@
  */
 LONG WINAPI RegLoadKeyA( HKEY hkey, LPCSTR subkey, LPCSTR filename )
 {
-    struct load_registry_request *req = get_req_buffer();
     HANDLE file;
-    DWORD ret, err = GetLastError();
+    DWORD ret, len, err = GetLastError();
 
     TRACE( "(%x,%s,%s)\n", hkey, debugstr_a(subkey), debugstr_a(filename) );
 
     if (!filename || !*filename) return ERROR_INVALID_PARAMETER;
     if (!subkey || !*subkey) return ERROR_INVALID_PARAMETER;
 
+    len = MultiByteToWideChar( CP_ACP, 0, subkey, strlen(subkey), NULL, 0 ) * sizeof(WCHAR);
+    if (len > MAX_PATH*sizeof(WCHAR)) return ERROR_INVALID_PARAMETER;
+
     if ((file = CreateFileA( filename, GENERIC_READ, 0, NULL, OPEN_EXISTING,
                              FILE_ATTRIBUTE_NORMAL, -1 )) == INVALID_HANDLE_VALUE)
     {
         ret = GetLastError();
         goto done;
     }
-    req->hkey  = hkey;
-    req->file  = file;
-    if ((ret = copy_nameAtoW( req->name, subkey )) != ERROR_SUCCESS) goto done;
-    ret = reg_server_call( REQ_LOAD_REGISTRY );
+
+    SERVER_START_REQ
+    {
+        struct load_registry_request *req = server_alloc_req( sizeof(*req), len );
+        req->hkey  = hkey;
+        req->file  = file;
+        MultiByteToWideChar( CP_ACP, 0, subkey, strlen(subkey),
+                             server_data_ptr(req), len/sizeof(WCHAR) );
+        ret = reg_server_call( REQ_LOAD_REGISTRY );
+    }
+    SERVER_END_REQ;
     CloseHandle( file );
 
  done:
@@ -1237,7 +1230,6 @@
  */
 LONG WINAPI RegSaveKeyA( HKEY hkey, LPCSTR file, LPSECURITY_ATTRIBUTES sa )
 {
-    struct save_registry_request *req = get_req_buffer();
     char buffer[1024];
     int count = 0;
     LPSTR name;
@@ -1263,9 +1255,15 @@
             MESSAGE("Wow, we are already fiddling with a temp file %s with an ordinal as high as %d !\nYou might want to delete all corresponding temp files in that directory.\n", buffer, count);
     }
 
-    req->hkey = hkey;
-    req->file = handle;
-    ret = reg_server_call( REQ_SAVE_REGISTRY );
+    SERVER_START_REQ
+    {
+        struct save_registry_request *req = server_alloc_req( sizeof(*req), 0 );
+        req->hkey = hkey;
+        req->file = handle;
+        ret = reg_server_call( REQ_SAVE_REGISTRY );
+    }
+    SERVER_END_REQ;
+
     CloseHandle( handle );
     if (!ret)
     {
diff --git a/misc/registry.c b/misc/registry.c
index 70b3a6c..8ca9755 100644
--- a/misc/registry.c
+++ b/misc/registry.c
@@ -380,11 +380,14 @@
                 if ((file = FILE_CreateFile( fn, GENERIC_READ, 0, NULL, OPEN_EXISTING,
                                       FILE_ATTRIBUTE_NORMAL, -1, TRUE )) != INVALID_HANDLE_VALUE)
                 {
-                    struct load_registry_request *req = get_req_buffer();
-                    req->hkey    = hkey;
-                    req->file    = file;
-                    req->name[0] = 0;
-                    server_call( REQ_LOAD_REGISTRY );
+                    SERVER_START_REQ
+                    {
+                        struct load_registry_request *req = server_alloc_req( sizeof(*req), 0 );
+                        req->hkey    = hkey;
+                        req->file    = file;
+                        server_call( REQ_LOAD_REGISTRY );
+                    }
+                    SERVER_END_REQ;
                     CloseHandle( file );
                 }
                 free( buf );
@@ -1366,6 +1369,25 @@
 }
 
 
+static void save_at_exit( HKEY hkey, const char *path )
+{
+    const char *confdir = get_config_dir();
+    size_t len = strlen(confdir) + strlen(path) + 2;
+    if (len > REQUEST_MAX_VAR_SIZE)
+    {
+        ERR( "config dir '%s' too long\n", confdir );
+        return;
+    }
+    SERVER_START_REQ
+    {
+        struct save_registry_atexit_request *req = server_alloc_req( sizeof(*req), len );
+        sprintf( server_data_ptr(req), "%s/%s", confdir, path );
+        req->hkey = hkey;
+        server_call( REQ_SAVE_REGISTRY_ATEXIT );
+    }
+    SERVER_END_REQ;
+}
+
 /* configure save files and start the periodic saving timer */
 static void SHELL_InitRegistrySaving( HKEY hkey_users_default )
 {
@@ -1385,35 +1407,9 @@
 
     if (PROFILE_GetWineIniBool("registry","WritetoHomeRegistries",1))
     {
-        struct save_registry_atexit_request *req = get_req_buffer();
-        const char *confdir = get_config_dir();
-        char *str = req->file + strlen(confdir);
-
-        if (str + 20 > req->file + server_remaining(req->file))
-        {
-            ERR("config dir '%s' too long\n", confdir );
-            return;
-        }
-
-        strcpy( req->file, confdir );
-        strcpy( str, "/" SAVE_CURRENT_USER );
-        req->hkey = HKEY_CURRENT_USER;
-        server_call( REQ_SAVE_REGISTRY_ATEXIT );
-
-        strcpy( req->file, confdir );
-        strcpy( str, "/" SAVE_LOCAL_MACHINE );
-        req->hkey = HKEY_LOCAL_MACHINE;
-        server_call( REQ_SAVE_REGISTRY_ATEXIT );
-
-        strcpy( req->file, confdir );
-        strcpy( str, "/" SAVE_DEFAULT_USER );
-        req->hkey = hkey_users_default;
-        server_call( REQ_SAVE_REGISTRY_ATEXIT );
-
-        strcpy( req->file, confdir );
-        strcpy( str, "/" SAVE_LOCAL_USERS_DEFAULT );
-        req->hkey = HKEY_USERS;
-        server_call( REQ_SAVE_REGISTRY_ATEXIT );
+        save_at_exit( HKEY_CURRENT_USER, SAVE_CURRENT_USER );
+        save_at_exit( HKEY_LOCAL_MACHINE, SAVE_LOCAL_MACHINE );
+        save_at_exit( hkey_users_default, SAVE_DEFAULT_USER );
     }
 }
 
diff --git a/scheduler/process.c b/scheduler/process.c
index a96a2a3..795527b 100644
--- a/scheduler/process.c
+++ b/scheduler/process.c
@@ -1230,45 +1230,44 @@
 BOOL WINAPI ReadProcessMemory( HANDLE process, LPCVOID addr, LPVOID buffer, DWORD size,
                                LPDWORD bytes_read )
 {
-    struct read_process_memory_request *req = get_req_buffer();
     unsigned int offset = (unsigned int)addr % sizeof(int);
-    unsigned int max = server_remaining( req->data );  /* max length in one request */
-    unsigned int pos;
+    unsigned int pos = 0, len, max;
+    int res;
 
     if (bytes_read) *bytes_read = size;
 
     /* first time, read total length to check for permissions */
-    req->handle = process;
-    req->addr   = (char *)addr - offset;
-    req->len    = (size + offset + sizeof(int) - 1) / sizeof(int);
-    if (server_call( REQ_READ_PROCESS_MEMORY )) goto error;
+    len = (size + offset + sizeof(int) - 1) / sizeof(int);
+    max = min( REQUEST_MAX_VAR_SIZE, len * sizeof(int) );
 
-    if (size <= max - offset)
+    for (;;)
     {
-        memcpy( buffer, (char *)req->data + offset, size );
-        return TRUE;
+        SERVER_START_REQ
+        {
+            struct read_process_memory_request *req = server_alloc_req( sizeof(*req), max );
+            req->handle = process;
+            req->addr   = (char *)addr + pos - offset;
+            req->len    = len;
+            if (!(res = server_call( REQ_READ_PROCESS_MEMORY )))
+            {
+                size_t result = server_data_size( req );
+                if (result > size + offset) result = size + offset;
+                memcpy( (char *)buffer + pos, server_data_ptr(req) + offset, result - offset );
+                size -= result - offset;
+                pos += result - offset;
+            }
+        }
+        SERVER_END_REQ;
+        if (res)
+        {
+            if (bytes_read) *bytes_read = 0;
+            return FALSE;
+        }
+        if (!size) return TRUE;
+        max = min( REQUEST_MAX_VAR_SIZE, size );
+        len = (max + sizeof(int) - 1) / sizeof(int);
+        offset = 0;
     }
-
-    /* now take care of the remaining data */
-    memcpy( buffer, (char *)req->data + offset, max - offset );
-    pos = max - offset;
-    size -= pos;
-    while (size)
-    {
-        if (max > size) max = size;
-        req->handle = process;
-        req->addr   = (char *)addr + pos;
-        req->len    = (max + sizeof(int) - 1) / sizeof(int);
-        if (server_call( REQ_READ_PROCESS_MEMORY )) goto error;
-        memcpy( (char *)buffer + pos, (char *)req->data, max );
-        size -= max;
-        pos += max;
-    }
-    return TRUE;
-
- error:
-    if (bytes_read) *bytes_read = 0;
-    return FALSE;
 }
 
 
@@ -1279,9 +1278,8 @@
                                 LPDWORD bytes_written )
 {
     unsigned int first_offset, last_offset;
-    struct write_process_memory_request *req = get_req_buffer();
-    unsigned int max = server_remaining( req->data );  /* max length in one request */
-    unsigned int pos, last_mask;
+    unsigned int pos = 0, len, max, first_mask, last_mask;
+    int res;
 
     if (!size)
     {
@@ -1291,57 +1289,54 @@
     if (bytes_written) *bytes_written = size;
 
     /* compute the mask for the first int */
-    req->first_mask = ~0;
+    first_mask = ~0;
     first_offset = (unsigned int)addr % sizeof(int);
-    memset( &req->first_mask, 0, first_offset );
+    memset( &first_mask, 0, first_offset );
 
     /* compute the mask for the last int */
     last_offset = (size + first_offset) % sizeof(int);
     last_mask = 0;
     memset( &last_mask, 0xff, last_offset ? last_offset : sizeof(int) );
 
-    req->handle = process;
-    req->addr = (char *)addr - first_offset;
     /* for the first request, use the total length */
-    req->len = (size + first_offset + sizeof(int) - 1) / sizeof(int);
+    len = (size + first_offset + sizeof(int) - 1) / sizeof(int);
+    max = min( REQUEST_MAX_VAR_SIZE, len * sizeof(int) );
 
-    if (size + first_offset < max)  /* we can do it in one round */
+    for (;;)
     {
-        memcpy( (char *)req->data + first_offset, buffer, size );
-        req->last_mask = last_mask;
-        if (server_call( REQ_WRITE_PROCESS_MEMORY )) goto error;
-        return TRUE;
-    }
-
-    /* needs multiple server calls */
-
-    memcpy( (char *)req->data + first_offset, buffer, max - first_offset );
-    req->last_mask = ~0;
-    if (server_call( REQ_WRITE_PROCESS_MEMORY )) goto error;
-    pos = max - first_offset;
-    size -= pos;
-    while (size)
-    {
-        if (size <= max)  /* last one */
+        SERVER_START_REQ
         {
-            req->last_mask = last_mask;
-            max = size;
+            struct write_process_memory_request *req = server_alloc_req( sizeof(*req), max );
+            req->handle = process;
+            req->addr = (char *)addr - first_offset + pos;
+            req->len = len;
+            req->first_mask = (!pos) ? first_mask : ~0;
+            if (size + first_offset <= max)  /* last round */
+            {
+                req->last_mask = last_mask;
+                max = size + first_offset;
+            }
+            else req->last_mask = ~0;
+
+            memcpy( (char *)server_data_ptr(req) + first_offset, (char *)buffer + pos,
+                    max - first_offset );
+            if (!(res = server_call( REQ_WRITE_PROCESS_MEMORY )))
+            {
+                pos += max - first_offset;
+                size -= max - first_offset;
+            }
         }
-        req->handle = process;
-        req->addr = (char *)addr + pos;
-        req->len = (max + sizeof(int) - 1) / sizeof(int);
-        req->first_mask = ~0;
-        memcpy( req->data, (char *) buffer + pos, max );
-        if (server_call( REQ_WRITE_PROCESS_MEMORY )) goto error;
-        pos += max;
-        size -= max;
+        SERVER_END_REQ;
+        if (res)
+        {
+            if (bytes_written) *bytes_written = 0;
+            return FALSE;
+        }
+        if (!size) return TRUE;
+        first_offset = 0;
+        len = min( size + sizeof(int) - 1, REQUEST_MAX_VAR_SIZE ) / sizeof(int);
+        max = len * sizeof(int);
     }
-    return TRUE;
-
- error:
-    if (bytes_written) *bytes_written = 0;
-    return FALSE;
-
 }
 
 
diff --git a/server/process.c b/server/process.c
index dc6d1cf..917785e 100644
--- a/server/process.c
+++ b/server/process.c
@@ -888,8 +888,8 @@
 
     if ((process = get_process_from_handle( req->handle, PROCESS_VM_READ )))
     {
-        read_process_memory( process, req->addr, req->len,
-                             get_req_size( req, req->data, sizeof(int) ), req->data );
+        size_t maxlen = get_req_data_size(req) / sizeof(int);
+        read_process_memory( process, req->addr, req->len, maxlen, get_req_data(req) );
         release_object( process );
     }
 }
@@ -901,9 +901,9 @@
 
     if ((process = get_process_from_handle( req->handle, PROCESS_VM_WRITE )))
     {
-        write_process_memory( process, req->addr, req->len,
-                              get_req_size( req, req->data, sizeof(int) ),
-                              req->first_mask, req->last_mask, req->data );
+        size_t maxlen = get_req_data_size(req) / sizeof(int);
+        write_process_memory( process, req->addr, req->len, maxlen,
+                              req->first_mask, req->last_mask, get_req_data(req) );
         release_object( process );
     }
 }
diff --git a/server/registry.c b/server/registry.c
index 944d731..3ca1c37 100644
--- a/server/registry.c
+++ b/server/registry.c
@@ -1437,8 +1437,8 @@
         set_error( STATUS_NO_MORE_ENTRIES );
         return;
     }
-    if (!(save_branch_info[save_branch_count].path = memdup( path, len+1 ))) return;
-    save_branch_info[save_branch_count].path[len] = 0;
+    if (!len || !(save_branch_info[save_branch_count].path = memdup( path, len ))) return;
+    save_branch_info[save_branch_count].path[len - 1] = 0;
     save_branch_info[save_branch_count].key = (struct key *)grab_object( key );
     save_branch_count++;
 }
@@ -1757,7 +1757,7 @@
 
     if ((key = get_hkey_obj( req->hkey, KEY_QUERY_VALUE | KEY_ENUMERATE_SUB_KEYS )))
     {
-        register_branch_for_saving( key, req->file, get_req_strlen( req, req->file ) );
+        register_branch_for_saving( key, get_req_data(req), get_req_data_size(req) );
         release_object( key );
     }
 }
diff --git a/server/serial.c b/server/serial.c
index 64a9956..d102233 100644
--- a/server/serial.c
+++ b/server/serial.c
@@ -37,7 +37,6 @@
 #include "request.h"
 
 static void serial_dump( struct object *obj, int verbose );
-static void serial_destroy( struct object *obj );
 static int serial_get_read_fd( struct object *obj );
 static int serial_get_write_fd( struct object *obj );
 static int serial_get_info( struct object *obj, struct get_file_info_request *req );
@@ -46,8 +45,7 @@
 struct serial
 {
     struct object       obj;
-    char                name[16]; /* eg. /dev/ttyS1 */
-    int                 access;
+    unsigned int        access;
 
     /* timeout values */
     unsigned int        readinterval;
@@ -78,24 +76,65 @@
     serial_get_write_fd,          /* get_write_fd */
     no_flush,                     /* flush */
     serial_get_info,              /* get_file_info */
-    serial_destroy                /* destroy */
+    no_destroy                    /* destroy */
 };
 
 /* SERIAL PORT functions */
 
+static struct serial *create_serial( const char *nameptr, size_t len, unsigned int access )
+{
+    struct serial *serial;
+    struct termios tios;
+    int fd, flags = 0;
+    char *name;
+
+    if (!(name = mem_alloc( len + 1 ))) return NULL;
+    memcpy( name, nameptr, len );
+    name[len] = 0;
+
+    switch(access & (GENERIC_READ | GENERIC_WRITE))
+    {
+    case GENERIC_READ:  flags |= O_RDONLY; break;
+    case GENERIC_WRITE: flags |= O_WRONLY; break;
+    case GENERIC_READ|GENERIC_WRITE: flags |= O_RDWR; break;
+    default: break;
+    }
+
+    fd = open( name, flags );
+    free( name );
+    if (fd < 0)
+    {
+        file_set_error();
+        return NULL;
+    }
+
+    /* check its really a serial port */
+    if (tcgetattr(fd,&tios))
+    {
+        file_set_error();
+        close( fd );
+        return NULL;
+    }
+
+    if ((serial = alloc_object( &serial_ops, fd )))
+    {
+        serial->access       = access;
+        serial->readinterval = 0;
+        serial->readmult     = 0;
+        serial->readconst    = 0;
+        serial->writemult    = 0;
+        serial->writeconst   = 0;
+        serial->eventmask    = 0;
+        serial->commerror    = 0;
+    }
+    return serial;
+}
+
 static void serial_dump( struct object *obj, int verbose )
 {
     struct serial *serial = (struct serial *)obj;
     assert( obj->ops == &serial_ops );
-
-    fprintf( stderr, "Port fd=%d name='%s' mask=%x\n", 
-             serial->obj.fd, serial->name,serial->eventmask);
-}
-
-/* same as file_destroy, but don't delete comm ports */
-static void serial_destroy( struct object *obj )
-{
-    assert( obj->ops == &serial_ops );
+    fprintf( stderr, "Port fd=%d mask=%x\n", serial->obj.fd, serial->eventmask );
 }
 
 struct serial *get_serial_obj( struct process *process, int handle, unsigned int access )
@@ -147,50 +186,10 @@
 DECL_HANDLER(create_serial)
 {
     struct serial *serial;
-    int fd,flags;
-    struct termios tios;
 
     req->handle = -1;
-
-    flags = 0;
-    switch(req->access & (GENERIC_READ | GENERIC_WRITE))
+    if ((serial = create_serial( get_req_data(req), get_req_data_size(req), req->access )))
     {
-    case GENERIC_READ:  flags |= O_RDONLY; break;
-    case GENERIC_WRITE: flags |= O_WRONLY; break;
-    case GENERIC_READ|GENERIC_WRITE: flags |= O_RDWR; break;
-    default: break;
-    }
-
-    fd = open( req->name, flags );
-    if(fd < 0)
-    {
-        file_set_error();
-        return;
-    }
-
-    /* check its really a serial port */
-    if(0>tcgetattr(fd,&tios))
-    {
-        file_set_error();
-        close(fd);
-        return;
-    }
-
-    serial = alloc_object( &serial_ops, fd );
-    if (serial)
-    {
-        strncpy(serial->name,req->name,sizeof serial->name);
-        serial->name[sizeof(serial->name)-1] = 0;
-
-        serial->access       = req->access;
-        serial->readinterval = 0;
-        serial->readmult     = 0;
-        serial->readconst    = 0;
-        serial->writemult    = 0;
-        serial->writeconst   = 0;
-        serial->eventmask    = 0;
-        serial->commerror    = 0;
-
         req->handle = alloc_handle( current->process, serial, req->access, req->inherit );
         release_object( serial );
     }
diff --git a/server/trace.c b/server/trace.c
index b9e02a8..4ac36ea 100644
--- a/server/trace.c
+++ b/server/trace.c
@@ -51,25 +51,15 @@
     fputc( '}', stderr );
 }
 
-static void dump_string( const void *req, const char *str )
+static void dump_path_t( const void *req, const path_t *path )
 {
-    int len = get_req_strlen( req, str );
-    fprintf( stderr, "\"%.*s\"", len, str );
-}
-
-static void dump_unicode_string( const void *req, const WCHAR *str )
-{
+    const WCHAR *str = *path;
     size_t len = get_req_strlenW( req, str );
     fprintf( stderr, "L\"" );
     dump_strW( str, len, stderr, "\"\"" );
     fputc( '\"', stderr );
 }
 
-static void dump_path_t( const void *req, const path_t *path )
-{
-    dump_unicode_string( req, *path );
-}
-
 static void dump_context( const CONTEXT *context )
 {
 #ifdef __i386__
@@ -271,18 +261,6 @@
 
 /* dumping for functions for requests that have a variable part */
 
-static void dump_varargs_read_process_memory_reply( const struct read_process_memory_request *req )
-{
-    int count = min( req->len, get_req_size( req, req->data, sizeof(int) ));
-    dump_bytes( (unsigned char *)req->data, count * sizeof(int) );
-}
-
-static void dump_varargs_write_process_memory_request( const struct write_process_memory_request *req )
-{
-    int count = min( req->len, get_req_size( req, req->data, sizeof(int) ));
-    dump_bytes( (unsigned char *)req->data, count * sizeof(int) );
-}
-
 static void dump_varargs_enum_key_value_reply( const struct enum_key_value_request *req )
 {
     int count = min( req->len - req->offset, get_req_size( req, req->data, 1 ));
@@ -1130,7 +1108,7 @@
 static void dump_read_process_memory_reply( const struct read_process_memory_request *req )
 {
     fprintf( stderr, " data=" );
-    dump_varargs_read_process_memory_reply( req );
+    cur_pos += dump_varargs_bytes( req );
 }
 
 static void dump_write_process_memory_request( const struct write_process_memory_request *req )
@@ -1141,7 +1119,7 @@
     fprintf( stderr, " first_mask=%08x,", req->first_mask );
     fprintf( stderr, " last_mask=%08x,", req->last_mask );
     fprintf( stderr, " data=" );
-    dump_varargs_write_process_memory_request( req );
+    cur_pos += dump_varargs_bytes( req );
 }
 
 static void dump_create_key_request( const struct create_key_request *req )
@@ -1263,7 +1241,7 @@
     fprintf( stderr, " hkey=%d,", req->hkey );
     fprintf( stderr, " file=%d,", req->file );
     fprintf( stderr, " name=" );
-    dump_path_t( req, &req->name );
+    cur_pos += dump_varargs_unicode_str( req );
 }
 
 static void dump_save_registry_request( const struct save_registry_request *req )
@@ -1276,7 +1254,7 @@
 {
     fprintf( stderr, " hkey=%d,", req->hkey );
     fprintf( stderr, " file=" );
-    dump_string( req, req->file );
+    cur_pos += dump_varargs_string( req );
 }
 
 static void dump_set_registry_levels_request( const struct set_registry_levels_request *req )
@@ -1440,7 +1418,7 @@
     fprintf( stderr, " inherit=%d,", req->inherit );
     fprintf( stderr, " sharing=%08x,", req->sharing );
     fprintf( stderr, " name=" );
-    dump_string( req, req->name );
+    cur_pos += dump_varargs_string( req );
 }
 
 static void dump_create_serial_reply( const struct create_serial_request *req )
diff --git a/tools/make_requests b/tools/make_requests
index 56b4ddd..bed789e 100755
--- a/tools/make_requests
+++ b/tools/make_requests
@@ -15,8 +15,6 @@
     "void*"         => "%p",
     "time_t"        => "%ld",
     "path_t"        => "&dump_path_t",
-    "char[1]"       => "&dump_string",
-    "WCHAR[1]"      => "&dump_unicode_string"
 );
 
 my @requests = ();