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 = ();