diff --git a/dlls/advapi32/registry.c b/dlls/advapi32/registry.c index 26aa450971e..24560e295b8 100644 --- a/dlls/advapi32/registry.c +++ b/dlls/advapi32/registry.c @@ -43,30 +43,6 @@ static inline int is_string( DWORD type ) 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 @@ DWORD WINAPI RegQueryValueExW( HKEY hkey, LPCWSTR name, LPDWORD reserved, LPDWOR * 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 @@ DWORD WINAPI RegQueryValueExA( HKEY hkey, LPCSTR name, LPDWORD reserved, LPDWORD } 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 @@ DWORD WINAPI RegDeleteValueA( HKEY hkey, LPCSTR name ) */ 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 RegLoadKeyW( HKEY hkey, LPCWSTR subkey, LPCWSTR filename ) */ 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 RegLoadKeyA( HKEY hkey, LPCSTR subkey, LPCSTR filename ) */ 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 @@ LONG WINAPI RegSaveKeyA( HKEY hkey, LPCSTR file, LPSECURITY_ATTRIBUTES sa ) 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 5b77d417631..defa7e041a4 100644 --- a/dlls/kernel/comm.c +++ b/dlls/kernel/comm.c @@ -1906,19 +1906,21 @@ BOOL WINAPI SetupComm( HANDLE handle, DWORD insize, DWORD outsize) */ 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 GetCommMask(HANDLE handle,LPDWORD evtmask) */ 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 TransmitCommChar(HANDLE hComm,CHAR chTransmit) */ 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 @@ BOOL WINAPI GetCommTimeouts(HANDLE hComm,LPCOMMTIMEOUTS lptimeouts) 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 @@ BOOL WINAPI SetCommTimeouts( 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 @@ BOOL WINAPI SetCommTimeouts( 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 @@ BOOL WINAPI SetCommTimeouts( 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 2b21acc9f57..d4dd2c3ffd2 100644 --- a/files/dos_fs.c +++ b/files/dos_fs.c @@ -698,8 +698,7 @@ const DOS_DEVICE *DOSFS_GetDeviceByHandle( HFILE hFile ) */ 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 @@ static HANDLE DOSFS_CreateCommPort(LPCSTR name, DWORD access) 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 443c5477005..c6c7d5778bf 100644 --- a/include/server.h +++ b/include/server.h @@ -991,7 +991,7 @@ struct read_process_memory_request 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 @@ struct write_process_memory_request 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 @@ struct load_registry_request 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 @@ struct save_registry_atexit_request { 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 @@ struct create_serial_request 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 @@ union generic_request 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 3b682e5dcda..24560e295b8 100644 --- a/memory/registry.c +++ b/memory/registry.c @@ -43,30 +43,6 @@ static inline int is_string( DWORD type ) 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 @@ DWORD WINAPI RegDeleteValueA( HKEY hkey, LPCSTR name ) */ 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 RegLoadKeyW( HKEY hkey, LPCWSTR subkey, LPCWSTR filename ) */ 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 RegLoadKeyA( HKEY hkey, LPCSTR subkey, LPCSTR filename ) */ 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 @@ LONG WINAPI RegSaveKeyA( HKEY hkey, LPCSTR file, LPSECURITY_ATTRIBUTES sa ) 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 70b3a6c1f21..8ca97551c47 100644 --- a/misc/registry.c +++ b/misc/registry.c @@ -380,11 +380,14 @@ static int _wine_loadsubreg( FILE *F, HKEY hkey, const char *fn ) 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 @@ void _w31_loadreg(void) { } +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 @@ static void SHELL_InitRegistrySaving( HKEY hkey_users_default ) 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 a96a2a35bad..795527be6f9 100644 --- a/scheduler/process.c +++ b/scheduler/process.c @@ -1230,45 +1230,44 @@ BOOL WINAPI SetProcessPriorityBoost(HANDLE hprocess,BOOL disableboost) 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 @@ BOOL WINAPI WriteProcessMemory( HANDLE process, LPVOID addr, LPVOID buffer, DWOR 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 @@ BOOL WINAPI WriteProcessMemory( HANDLE process, LPVOID addr, LPVOID buffer, DWOR 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 dc6d1cf0c74..917785edfb1 100644 --- a/server/process.c +++ b/server/process.c @@ -888,8 +888,8 @@ DECL_HANDLER(read_process_memory) 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 @@ DECL_HANDLER(write_process_memory) 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 944d7312e1f..3ca1c3716c9 100644 --- a/server/registry.c +++ b/server/registry.c @@ -1437,8 +1437,8 @@ static void register_branch_for_saving( struct key *key, const char *path, size_ 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 @@ DECL_HANDLER(save_registry_atexit) 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 64a9956ef9c..d102233670a 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 @@ static int serial_get_poll_events( struct object *obj ); 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 @@ static const struct object_ops serial_ops = 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 @@ static int serial_get_info( struct object *obj, struct get_file_info_request *re 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 b9e02a8135c..4ac36ead89e 100644 --- a/server/trace.c +++ b/server/trace.c @@ -51,25 +51,15 @@ static void dump_bytes( const unsigned char *ptr, int len ) fputc( '}', stderr ); } -static void dump_string( const void *req, const char *str ) -{ - int len = get_req_strlen( req, str ); - fprintf( stderr, "\"%.*s\"", len, str ); -} - -static void dump_unicode_string( const void *req, const WCHAR *str ) +static void dump_path_t( const void *req, const path_t *path ) { + 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 @@ static size_t dump_varargs_input_records( const void *req ) /* 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_request( const struct read_process_memory_r 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 @@ static void dump_write_process_memory_request( const struct write_process_memory 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 @@ static void dump_load_registry_request( const struct load_registry_request *req 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 @@ static void dump_save_registry_atexit_request( const struct save_registry_atexit { 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 @@ static void dump_create_serial_request( const struct create_serial_request *req 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 56b4ddd54e9..bed789e104b 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 = ();