From ebe29ef37611f246fcb4900a2f351c6ef69660bb Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Sat, 26 Jun 1999 08:43:26 +0000 Subject: [PATCH] Further server optimizations: - merged request and reply structures - build requests directly into the buffer to avoid a copy --- files/change.c | 19 +- files/dos_fs.c | 15 +- files/file.c | 201 ++++++------- include/server.h | 663 ++++++++++++++++++------------------------ include/thread.h | 6 +- loader/dos/module.c | 14 +- memory/virtual.c | 75 ++--- misc/comm.c | 82 +++--- misc/toolhelp.c | 30 +- scheduler/client.c | 274 +++++------------ scheduler/debugger.c | 148 ++++------ scheduler/event.c | 44 ++- scheduler/handle.c | 71 ++--- scheduler/mutex.c | 40 ++- scheduler/pipe.c | 14 +- scheduler/process.c | 175 ++++++----- scheduler/semaphore.c | 47 ++- scheduler/synchro.c | 62 ++-- scheduler/thread.c | 111 ++++--- server/change.c | 24 +- server/console.c | 141 +++++---- server/debugger.c | 45 ++- server/device.c | 22 +- server/event.c | 17 +- server/file.c | 98 +++---- server/handle.c | 14 +- server/mapping.c | 55 ++-- server/mutex.c | 15 +- server/object.c | 2 +- server/object.h | 6 +- server/pipe.c | 40 ++- server/process.c | 63 ++-- server/request.c | 63 ++-- server/request.h | 63 ++-- server/semaphore.c | 60 ++-- server/snapshot.c | 33 +-- server/socket.c | 121 +++----- server/thread.c | 119 ++++---- server/thread.h | 3 - server/trace.c | 439 +++++++++++----------------- tools/make_requests | 64 ++-- win32/console.c | 312 +++++++++----------- win32/device.c | 16 +- 43 files changed, 1649 insertions(+), 2277 deletions(-) diff --git a/files/change.c b/files/change.c index 4142d39b0ee..c5f63109c24 100644 --- a/files/change.c +++ b/files/change.c @@ -19,20 +19,17 @@ /**************************************************************************** - * FindFirstChangeNotification32A (KERNEL32.248) + * FindFirstChangeNotificationA (KERNEL32.248) */ -HANDLE WINAPI FindFirstChangeNotificationA( LPCSTR lpPathName, - BOOL bWatchSubtree, - DWORD dwNotifyFilter ) +HANDLE WINAPI FindFirstChangeNotificationA( LPCSTR lpPathName, BOOL bWatchSubtree, + DWORD dwNotifyFilter ) { - struct create_change_notification_request req; - struct create_change_notification_reply reply; + struct create_change_notification_request *req = get_req_buffer(); - req.subtree = bWatchSubtree; - req.filter = dwNotifyFilter; - CLIENT_SendRequest( REQ_CREATE_CHANGE_NOTIFICATION, -1, 1, &req, sizeof(req) ); - CLIENT_WaitSimpleReply( &reply, sizeof(reply), NULL ); - return reply.handle; + req->subtree = bWatchSubtree; + req->filter = dwNotifyFilter; + server_call( REQ_CREATE_CHANGE_NOTIFICATION ); + return req->handle; } /**************************************************************************** diff --git a/files/dos_fs.c b/files/dos_fs.c index c708b540f9e..fdcb3544dd1 100644 --- a/files/dos_fs.c +++ b/files/dos_fs.c @@ -613,17 +613,14 @@ const DOS_DEVICE *DOSFS_GetDevice( const char *name ) */ const DOS_DEVICE *DOSFS_GetDeviceByHandle( HFILE hFile ) { - struct get_file_info_request req; - struct get_file_info_reply reply; + struct get_file_info_request *req = get_req_buffer(); - req.handle = hFile; - CLIENT_SendRequest( REQ_GET_FILE_INFO, -1, 1, &req, sizeof(req) ); - if (!CLIENT_WaitSimpleReply( &reply, sizeof(reply), NULL ) && - (reply.type == FILE_TYPE_UNKNOWN)) + req->handle = hFile; + if (!server_call( REQ_GET_FILE_INFO ) && (req->type == FILE_TYPE_UNKNOWN)) { - if ((reply.attr >= 0) && - (reply.attr < sizeof(DOSFS_Devices)/sizeof(DOSFS_Devices[0]))) - return &DOSFS_Devices[reply.attr]; + if ((req->attr >= 0) && + (req->attr < sizeof(DOSFS_Devices)/sizeof(DOSFS_Devices[0]))) + return &DOSFS_Devices[req->attr]; } return NULL; } diff --git a/files/file.c b/files/file.c index d7e8558250b..edce50779d0 100644 --- a/files/file.c +++ b/files/file.c @@ -304,24 +304,16 @@ void FILE_SetDosError(void) HFILE FILE_DupUnixHandle( int fd, DWORD access ) { int unix_handle; - struct create_file_request req; - struct create_file_reply reply; + struct alloc_file_handle_request *req = get_req_buffer(); if ((unix_handle = dup(fd)) == -1) { FILE_SetDosError(); return INVALID_HANDLE_VALUE; } - req.access = access; - req.inherit = 1; - req.sharing = FILE_SHARE_READ | FILE_SHARE_WRITE; - req.create = 0; - req.attrs = 0; - - CLIENT_SendRequest( REQ_CREATE_FILE, unix_handle, 1, - &req, sizeof(req) ); - CLIENT_WaitSimpleReply( &reply, sizeof(reply), NULL ); - return reply.handle; + req->access = access; + server_call_fd( REQ_ALLOC_FILE_HANDLE, unix_handle, NULL ); + return req->handle; } @@ -334,38 +326,28 @@ HFILE FILE_CreateFile( LPCSTR filename, DWORD access, DWORD sharing, LPSECURITY_ATTRIBUTES sa, DWORD creation, DWORD attributes, HANDLE template ) { - struct create_file_request req; - struct create_file_reply reply; + struct create_file_request *req = get_req_buffer(); - req.access = access; - req.inherit = (sa && (sa->nLength>=sizeof(*sa)) && sa->bInheritHandle); - req.sharing = sharing; - req.create = creation; - req.attrs = attributes; - CLIENT_SendRequest( REQ_CREATE_FILE, -1, 2, - &req, sizeof(req), - filename, strlen(filename) + 1 ); + req->access = access; + req->inherit = (sa && (sa->nLength>=sizeof(*sa)) && sa->bInheritHandle); + req->sharing = sharing; + req->create = creation; + req->attrs = attributes; + lstrcpynA( req->name, filename, server_remaining(req->name) ); SetLastError(0); - CLIENT_WaitSimpleReply( &reply, sizeof(reply), NULL ); + server_call( REQ_CREATE_FILE ); /* If write access failed, retry without GENERIC_WRITE */ - if ((reply.handle == -1) && !Options.failReadOnly && + if ((req->handle == -1) && !Options.failReadOnly && (access & GENERIC_WRITE)) { DWORD lasterror = GetLastError(); - if ((lasterror == ERROR_ACCESS_DENIED) || - (lasterror == ERROR_WRITE_PROTECT)) - { - req.access &= ~GENERIC_WRITE; - CLIENT_SendRequest( REQ_CREATE_FILE, -1, 2, - &req, sizeof(req), - filename, strlen(filename) + 1 ); - SetLastError(0); - CLIENT_WaitSimpleReply( &reply, sizeof(reply), NULL ); - } + if ((lasterror == ERROR_ACCESS_DENIED) || (lasterror == ERROR_WRITE_PROTECT)) + return FILE_CreateFile( filename, access & ~GENERIC_WRITE, sharing, + sa, creation, attributes, template ); } - return reply.handle; + return req->handle; } @@ -376,16 +358,14 @@ HFILE FILE_CreateFile( LPCSTR filename, DWORD access, DWORD sharing, */ HFILE FILE_CreateDevice( int client_id, DWORD access, LPSECURITY_ATTRIBUTES sa ) { - struct create_device_request req; - struct create_device_reply reply; + struct create_device_request *req = get_req_buffer(); - req.access = access; - req.inherit = (sa && (sa->nLength>=sizeof(*sa)) && sa->bInheritHandle); - req.id = client_id; - CLIENT_SendRequest( REQ_CREATE_DEVICE, -1, 1, &req, sizeof(req) ); + req->access = access; + req->inherit = (sa && (sa->nLength>=sizeof(*sa)) && sa->bInheritHandle); + req->id = client_id; SetLastError(0); - CLIENT_WaitSimpleReply( &reply, sizeof(reply), NULL ); - return reply.handle; + server_call( REQ_CREATE_DEVICE ); + return req->handle; } @@ -562,24 +542,21 @@ BOOL FILE_Stat( LPCSTR unixName, BY_HANDLE_FILE_INFORMATION *info ) DWORD WINAPI GetFileInformationByHandle( HFILE hFile, BY_HANDLE_FILE_INFORMATION *info ) { - struct get_file_info_request req; - struct get_file_info_reply reply; + struct get_file_info_request *req = get_req_buffer(); if (!info) return 0; - req.handle = hFile; - CLIENT_SendRequest( REQ_GET_FILE_INFO, -1, 1, &req, sizeof(req) ); - if (CLIENT_WaitSimpleReply( &reply, sizeof(reply), NULL )) - return 0; - DOSFS_UnixTimeToFileTime( reply.write_time, &info->ftCreationTime, 0 ); - DOSFS_UnixTimeToFileTime( reply.write_time, &info->ftLastWriteTime, 0 ); - DOSFS_UnixTimeToFileTime( reply.access_time, &info->ftLastAccessTime, 0 ); - info->dwFileAttributes = reply.attr; - info->dwVolumeSerialNumber = reply.serial; - info->nFileSizeHigh = reply.size_high; - info->nFileSizeLow = reply.size_low; - info->nNumberOfLinks = reply.links; - info->nFileIndexHigh = reply.index_high; - info->nFileIndexLow = reply.index_low; + req->handle = hFile; + if (server_call( REQ_GET_FILE_INFO )) return 0; + DOSFS_UnixTimeToFileTime( req->write_time, &info->ftCreationTime, 0 ); + DOSFS_UnixTimeToFileTime( req->write_time, &info->ftLastWriteTime, 0 ); + DOSFS_UnixTimeToFileTime( req->access_time, &info->ftLastAccessTime, 0 ); + info->dwFileAttributes = req->attr; + info->dwVolumeSerialNumber = req->serial; + info->nFileSizeHigh = req->size_high; + info->nFileSizeLow = req->size_low; + info->nNumberOfLinks = req->links; + info->nFileIndexHigh = req->index_high; + info->nFileIndexLow = req->index_low; return 1; } @@ -1121,7 +1098,7 @@ HFILE WINAPI _lclose( HFILE hFile ) BOOL WINAPI ReadFile( HANDLE hFile, LPVOID buffer, DWORD bytesToRead, LPDWORD bytesRead, LPOVERLAPPED overlapped ) { - struct get_read_fd_request req; + struct get_read_fd_request *req = get_req_buffer(); int unix_handle, result; TRACE(file, "%d %p %ld\n", hFile, buffer, bytesToRead ); @@ -1129,9 +1106,8 @@ BOOL WINAPI ReadFile( HANDLE hFile, LPVOID buffer, DWORD bytesToRead, if (bytesRead) *bytesRead = 0; /* Do this before anything else */ if (!bytesToRead) return TRUE; - req.handle = hFile; - CLIENT_SendRequest( REQ_GET_READ_FD, -1, 1, &req, sizeof(req) ); - CLIENT_WaitReply( NULL, &unix_handle, 0 ); + req->handle = hFile; + server_call_fd( REQ_GET_READ_FD, -1, &unix_handle ); if (unix_handle == -1) return FALSE; while ((result = read( unix_handle, buffer, bytesToRead )) == -1) { @@ -1153,7 +1129,7 @@ BOOL WINAPI ReadFile( HANDLE hFile, LPVOID buffer, DWORD bytesToRead, BOOL WINAPI WriteFile( HANDLE hFile, LPCVOID buffer, DWORD bytesToWrite, LPDWORD bytesWritten, LPOVERLAPPED overlapped ) { - struct get_write_fd_request req; + struct get_write_fd_request *req = get_req_buffer(); int unix_handle, result; TRACE(file, "%d %p %ld\n", hFile, buffer, bytesToWrite ); @@ -1161,9 +1137,8 @@ BOOL WINAPI WriteFile( HANDLE hFile, LPCVOID buffer, DWORD bytesToWrite, if (bytesWritten) *bytesWritten = 0; /* Do this before anything else */ if (!bytesToWrite) return TRUE; - req.handle = hFile; - CLIENT_SendRequest( REQ_GET_WRITE_FD, -1, 1, &req, sizeof(req) ); - CLIENT_WaitReply( NULL, &unix_handle, 0 ); + req->handle = hFile; + server_call_fd( REQ_GET_WRITE_FD, -1, &unix_handle ); if (unix_handle == -1) return FALSE; while ((result = write( unix_handle, buffer, bytesToWrite )) == -1) { @@ -1254,8 +1229,7 @@ HFILE WINAPI _lcreat( LPCSTR path, INT attr ) DWORD WINAPI SetFilePointer( HFILE hFile, LONG distance, LONG *highword, DWORD method ) { - struct set_file_pointer_request req; - struct set_file_pointer_reply reply; + struct set_file_pointer_request *req = get_req_buffer(); if (highword && *highword) { @@ -1266,16 +1240,15 @@ DWORD WINAPI SetFilePointer( HFILE hFile, LONG distance, LONG *highword, TRACE(file, "handle %d offset %ld origin %ld\n", hFile, distance, method ); - req.handle = hFile; - req.low = distance; - req.high = highword ? *highword : 0; + req->handle = hFile; + req->low = distance; + req->high = highword ? *highword : 0; /* FIXME: assumes 1:1 mapping between Windows and Unix seek constants */ - req.whence = method; - CLIENT_SendRequest( REQ_SET_FILE_POINTER, -1, 1, &req, sizeof(req) ); - if (CLIENT_WaitSimpleReply( &reply, sizeof(reply), NULL )) return 0xffffffff; + req->whence = method; SetLastError( 0 ); - if (highword) *highword = reply.high; - return reply.low; + if (server_call( REQ_SET_FILE_POINTER )) return 0xffffffff; + if (highword) *highword = req->new_high; + return req->new_low; } @@ -1462,11 +1435,9 @@ UINT WINAPI SetHandleCount( UINT count ) */ BOOL WINAPI FlushFileBuffers( HFILE hFile ) { - struct flush_file_request req; - - req.handle = hFile; - CLIENT_SendRequest( REQ_FLUSH_FILE, -1, 1, &req, sizeof(req) ); - return !CLIENT_WaitReply( NULL, NULL, 0 ); + struct flush_file_request *req = get_req_buffer(); + req->handle = hFile; + return !server_call( REQ_FLUSH_FILE ); } @@ -1475,11 +1446,9 @@ BOOL WINAPI FlushFileBuffers( HFILE hFile ) */ BOOL WINAPI SetEndOfFile( HFILE hFile ) { - struct truncate_file_request req; - - req.handle = hFile; - CLIENT_SendRequest( REQ_TRUNCATE_FILE, -1, 1, &req, sizeof(req) ); - return !CLIENT_WaitReply( NULL, NULL, 0 ); + struct truncate_file_request *req = get_req_buffer(); + req->handle = hFile; + return !server_call( REQ_TRUNCATE_FILE ); } @@ -1631,14 +1600,10 @@ int FILE_munmap( LPVOID start, DWORD size_high, DWORD size_low ) */ DWORD WINAPI GetFileType( HFILE hFile ) { - struct get_file_info_request req; - struct get_file_info_reply reply; - - req.handle = hFile; - CLIENT_SendRequest( REQ_GET_FILE_INFO, -1, 1, &req, sizeof(req) ); - if (CLIENT_WaitSimpleReply( &reply, sizeof(reply), NULL )) - return FILE_TYPE_UNKNOWN; - return reply.type; + struct get_file_info_request *req = get_req_buffer(); + req->handle = hFile; + if (server_call( REQ_GET_FILE_INFO )) return FILE_TYPE_UNKNOWN; + return req->type; } @@ -1913,20 +1878,18 @@ BOOL WINAPI SetFileTime( HFILE hFile, const FILETIME *lpLastAccessTime, const FILETIME *lpLastWriteTime ) { - struct set_file_time_request req; + struct set_file_time_request *req = get_req_buffer(); - req.handle = hFile; + req->handle = hFile; if (lpLastAccessTime) - req.access_time = DOSFS_FileTimeToUnixTime(lpLastAccessTime, NULL); + req->access_time = DOSFS_FileTimeToUnixTime(lpLastAccessTime, NULL); else - req.access_time = 0; /* FIXME */ + req->access_time = 0; /* FIXME */ if (lpLastWriteTime) - req.write_time = DOSFS_FileTimeToUnixTime(lpLastWriteTime, NULL); + req->write_time = DOSFS_FileTimeToUnixTime(lpLastWriteTime, NULL); else - req.write_time = 0; /* FIXME */ - - CLIENT_SendRequest( REQ_SET_FILE_TIME, -1, 1, &req, sizeof(req) ); - return !CLIENT_WaitReply( NULL, NULL, 0 ); + req->write_time = 0; /* FIXME */ + return !server_call( REQ_SET_FILE_TIME ); } @@ -1936,15 +1899,14 @@ BOOL WINAPI SetFileTime( HFILE hFile, BOOL WINAPI LockFile( HFILE hFile, DWORD dwFileOffsetLow, DWORD dwFileOffsetHigh, DWORD nNumberOfBytesToLockLow, DWORD nNumberOfBytesToLockHigh ) { - struct lock_file_request req; + struct lock_file_request *req = get_req_buffer(); - req.handle = hFile; - req.offset_low = dwFileOffsetLow; - req.offset_high = dwFileOffsetHigh; - req.count_low = nNumberOfBytesToLockLow; - req.count_high = nNumberOfBytesToLockHigh; - CLIENT_SendRequest( REQ_LOCK_FILE, -1, 1, &req, sizeof(req) ); - return !CLIENT_WaitReply( NULL, NULL, 0 ); + req->handle = hFile; + req->offset_low = dwFileOffsetLow; + req->offset_high = dwFileOffsetHigh; + req->count_low = nNumberOfBytesToLockLow; + req->count_high = nNumberOfBytesToLockHigh; + return !server_call( REQ_LOCK_FILE ); } /************************************************************************** @@ -1984,15 +1946,14 @@ BOOL WINAPI LockFileEx( HANDLE hFile, DWORD flags, DWORD reserved, BOOL WINAPI UnlockFile( HFILE hFile, DWORD dwFileOffsetLow, DWORD dwFileOffsetHigh, DWORD nNumberOfBytesToUnlockLow, DWORD nNumberOfBytesToUnlockHigh ) { - struct unlock_file_request req; + struct unlock_file_request *req = get_req_buffer(); - req.handle = hFile; - req.offset_low = dwFileOffsetLow; - req.offset_high = dwFileOffsetHigh; - req.count_low = nNumberOfBytesToUnlockLow; - req.count_high = nNumberOfBytesToUnlockHigh; - CLIENT_SendRequest( REQ_UNLOCK_FILE, -1, 1, &req, sizeof(req) ); - return !CLIENT_WaitReply( NULL, NULL, 0 ); + req->handle = hFile; + req->offset_low = dwFileOffsetLow; + req->offset_high = dwFileOffsetHigh; + req->count_low = nNumberOfBytesToUnlockLow; + req->count_high = nNumberOfBytesToUnlockHigh; + return !server_call( REQ_UNLOCK_FILE ); } diff --git a/include/server.h b/include/server.h index b2f5426cc51..f7084768188 100644 --- a/include/server.h +++ b/include/server.h @@ -10,144 +10,122 @@ #include #include -/* message header as sent on the wire */ -struct header -{ - unsigned int len; /* total msg length (including this header) */ - unsigned int type; /* msg type */ -}; - -/* max msg length (including the header) */ -#define MAX_MSG_LENGTH 16384 - -/* data structure used to pass an fd with sendmsg/recvmsg */ -struct cmsg_fd -{ - int len; /* sizeof structure */ - int level; /* SOL_SOCKET */ - int type; /* SCM_RIGHTS */ - int fd; /* fd to pass */ -}; - /* Request structures */ -/* following are the definitions of all the client<->server */ -/* communication format; requests are from client to server, */ -/* replies are from server to client. All requests must have */ -/* a corresponding structure; the replies can be empty in */ -/* which case it isn't necessary to define a structure. */ +/* Following are the definitions of all the client<->server */ +/* communication format; if you make any change in this file, */ +/* you must run tools/make_requests again. */ + + +/* These empty macros are used by tools/make_requests */ +/* to generate the request/reply tracing functions */ +#define IN /*nothing*/ +#define OUT /*nothing*/ /* Create a new process from the context of the parent */ struct new_process_request { - int inherit; /* inherit flag */ - int inherit_all; /* inherit all handles from parent */ - int create_flags; /* creation flags */ - int start_flags; /* flags from startup info */ - int hstdin; /* handle for stdin */ - int hstdout; /* handle for stdout */ - int hstderr; /* handle for stderr */ - int cmd_show; /* main window show mode */ - void* env_ptr; /* pointer to environment (FIXME: hack) */ - char cmd_line[0]; /* command line */ -}; -struct new_process_reply -{ - void* pid; /* process id */ - int handle; /* process handle (in the current process) */ + IN int inherit; /* inherit flag */ + IN int inherit_all; /* inherit all handles from parent */ + IN int create_flags; /* creation flags */ + IN int start_flags; /* flags from startup info */ + IN int hstdin; /* handle for stdin */ + IN int hstdout; /* handle for stdout */ + IN int hstderr; /* handle for stderr */ + IN int cmd_show; /* main window show mode */ + IN void* env_ptr; /* pointer to environment (FIXME: hack) */ + OUT void* pid; /* process id */ + OUT int handle; /* process handle (in the current process) */ + IN char cmdline[1]; /* command line */ }; /* Create a new thread from the context of the parent */ struct new_thread_request { - void* pid; /* process id for the new thread */ - int suspend; /* new thread should be suspended on creation */ - int inherit; /* inherit flag */ -}; -struct new_thread_reply -{ - void* tid; /* thread id */ - int handle; /* thread handle (in the current process) */ + IN void* pid; /* process id for the new thread */ + IN int suspend; /* new thread should be suspended on creation */ + IN int inherit; /* inherit flag */ + OUT void* tid; /* thread id */ + OUT int handle; /* thread handle (in the current process) */ }; /* Set the server debug level */ struct set_debug_request { - int level; /* New debug level */ + IN int level; /* New debug level */ }; /* Initialize a process; called from the new process context */ struct init_process_request { - int dummy; -}; -struct init_process_reply -{ - int start_flags; /* flags from startup info */ - int hstdin; /* handle for stdin */ - int hstdout; /* handle for stdout */ - int hstderr; /* handle for stderr */ - int cmd_show; /* main window show mode */ - void* env_ptr; /* pointer to environment (FIXME: hack) */ - char cmdline[0]; /* command line */ + OUT int start_flags; /* flags from startup info */ + OUT int hstdin; /* handle for stdin */ + OUT int hstdout; /* handle for stdout */ + OUT int hstderr; /* handle for stderr */ + OUT int cmd_show; /* main window show mode */ + OUT void* env_ptr; /* pointer to environment (FIXME: hack) */ + OUT char cmdline[1]; /* command line */ }; /* Initialize a thread; called from the child after fork()/clone() */ struct init_thread_request { - int unix_pid; /* Unix pid of new thread */ - void* teb; /* TEB of new thread (in thread address space) */ + IN int unix_pid; /* Unix pid of new thread */ + IN void* teb; /* TEB of new thread (in thread address space) */ + OUT void* pid; /* process id of the new thread's process */ + OUT void* tid; /* thread id of the new thread */ }; -struct init_thread_reply + + +/* Retrieve the thread buffer file descriptor */ +/* The reply to this request is the first thing a newly */ +/* created thread gets (without having to request it) */ +struct get_thread_buffer_request { - void* pid; /* process id of the new thread's process */ - void* tid; /* thread id of the new thread */ + IN int dummy; }; /* Terminate a process */ struct terminate_process_request { - int handle; /* process handle to terminate */ - int exit_code; /* process exit code */ + IN int handle; /* process handle to terminate */ + IN int exit_code; /* process exit code */ }; /* Terminate a thread */ struct terminate_thread_request { - int handle; /* thread handle to terminate */ - int exit_code; /* thread exit code */ + IN int handle; /* thread handle to terminate */ + IN int exit_code; /* thread exit code */ }; /* Retrieve information about a process */ struct get_process_info_request { - int handle; /* process handle */ -}; -struct get_process_info_reply -{ - void* pid; /* server process id */ - int exit_code; /* process exit code */ - int priority; /* priority class */ - int process_affinity; /* process affinity mask */ - int system_affinity; /* system affinity mask */ + IN int handle; /* process handle */ + OUT void* pid; /* server process id */ + OUT int exit_code; /* process exit code */ + OUT int priority; /* priority class */ + OUT int process_affinity; /* process affinity mask */ + OUT int system_affinity; /* system affinity mask */ }; /* Set a process informations */ struct set_process_info_request { - int handle; /* process handle */ - int mask; /* setting mask (see below) */ - int priority; /* priority class */ - int affinity; /* affinity mask */ + IN int handle; /* process handle */ + IN int mask; /* setting mask (see below) */ + IN int priority; /* priority class */ + IN int affinity; /* affinity mask */ }; #define SET_PROCESS_INFO_PRIORITY 0x01 #define SET_PROCESS_INFO_AFFINITY 0x02 @@ -156,23 +134,20 @@ struct set_process_info_request /* Retrieve information about a thread */ struct get_thread_info_request { - int handle; /* thread handle */ -}; -struct get_thread_info_reply -{ - void* tid; /* server thread id */ - int exit_code; /* thread exit code */ - int priority; /* thread priority level */ + IN int handle; /* thread handle */ + OUT void* tid; /* server thread id */ + OUT int exit_code; /* thread exit code */ + OUT int priority; /* thread priority level */ }; /* Set a thread informations */ struct set_thread_info_request { - int handle; /* thread handle */ - int mask; /* setting mask (see below) */ - int priority; /* priority class */ - int affinity; /* affinity mask */ + IN int handle; /* thread handle */ + IN int mask; /* setting mask (see below) */ + IN int priority; /* priority class */ + IN int affinity; /* affinity mask */ }; #define SET_THREAD_INFO_PRIORITY 0x01 #define SET_THREAD_INFO_AFFINITY 0x02 @@ -181,29 +156,23 @@ struct set_thread_info_request /* Suspend a thread */ struct suspend_thread_request { - int handle; /* thread handle */ -}; -struct suspend_thread_reply -{ - int count; /* new suspend count */ + IN int handle; /* thread handle */ + OUT int count; /* new suspend count */ }; /* Resume a thread */ struct resume_thread_request { - int handle; /* thread handle */ -}; -struct resume_thread_reply -{ - int count; /* new suspend count */ + IN int handle; /* thread handle */ + OUT int count; /* new suspend count */ }; /* Debugger support: freeze / unfreeze */ struct debugger_request { - int op; /* operation type */ + IN int op; /* operation type */ }; enum debugger_op { DEBUGGER_FREEZE_ALL, DEBUGGER_UNFREEZE_ALL }; @@ -212,83 +181,78 @@ enum debugger_op { DEBUGGER_FREEZE_ALL, DEBUGGER_UNFREEZE_ALL }; /* Queue an APC for a thread */ struct queue_apc_request { - int handle; /* thread handle */ - void* func; /* function to call */ - void* param; /* param for function to call */ + IN int handle; /* thread handle */ + IN void* func; /* function to call */ + IN void* param; /* param for function to call */ +}; + + +/* Get list of APC to call */ +struct get_apcs_request +{ + OUT int count; /* number of apcs */ + OUT void* apcs[1]; /* async procedures to call */ }; /* Close a handle for the current process */ struct close_handle_request { - int handle; /* handle to close */ + IN int handle; /* handle to close */ }; /* Get information about a handle */ struct get_handle_info_request { - int handle; /* handle we are interested in */ -}; -struct get_handle_info_reply -{ - int flags; /* handle flags */ + IN int handle; /* handle we are interested in */ + OUT int flags; /* handle flags */ }; /* Set a handle information */ struct set_handle_info_request { - int handle; /* handle we are interested in */ - int flags; /* new handle flags */ - int mask; /* mask for flags to set */ + IN int handle; /* handle we are interested in */ + IN int flags; /* new handle flags */ + IN int mask; /* mask for flags to set */ }; /* Duplicate a handle */ struct dup_handle_request { - int src_process; /* src process handle */ - int src_handle; /* src handle to duplicate */ - int dst_process; /* dst process handle */ - unsigned int access; /* wanted access rights */ - int inherit; /* inherit flag */ - int options; /* duplicate options (see below) */ + IN int src_process; /* src process handle */ + IN int src_handle; /* src handle to duplicate */ + IN int dst_process; /* dst process handle */ + IN unsigned int access; /* wanted access rights */ + IN int inherit; /* inherit flag */ + IN int options; /* duplicate options (see below) */ + OUT int handle; /* duplicated handle in dst process */ }; #define DUP_HANDLE_CLOSE_SOURCE DUPLICATE_CLOSE_SOURCE #define DUP_HANDLE_SAME_ACCESS DUPLICATE_SAME_ACCESS #define DUP_HANDLE_MAKE_GLOBAL 0x80000000 /* Not a Windows flag */ -struct dup_handle_reply -{ - int handle; /* duplicated handle in dst process */ -}; /* Open a handle to a process */ struct open_process_request { - void* pid; /* process id to open */ - unsigned int access; /* wanted access rights */ - int inherit; /* inherit flag */ -}; -struct open_process_reply -{ - int handle; /* handle to the process */ + IN void* pid; /* process id to open */ + IN unsigned int access; /* wanted access rights */ + IN int inherit; /* inherit flag */ + OUT int handle; /* handle to the process */ }; /* Wait for handles */ struct select_request { - int count; /* handles count */ - int flags; /* wait flags (see below) */ - int timeout; /* timeout in ms */ - int handles[0]; /* handles to select on */ -}; -struct select_reply -{ - int signaled; /* signaled handle */ - void* apcs[0]; /* async procedures to call */ + IN int count; /* handles count */ + IN int flags; /* wait flags (see below) */ + IN int timeout; /* timeout in ms */ + OUT int signaled; /* signaled handle */ + IN int handles[1]; /* handles to select on */ }; #define SELECT_ALL 1 #define SELECT_ALERTABLE 2 @@ -298,21 +262,18 @@ struct select_reply /* Create an event */ struct create_event_request { - int manual_reset; /* manual reset event */ - int initial_state; /* initial state of the event */ - int inherit; /* inherit flag */ - char name[0]; /* event name */ -}; -struct create_event_reply -{ - int handle; /* handle to the event */ + IN int manual_reset; /* manual reset event */ + IN int initial_state; /* initial state of the event */ + IN int inherit; /* inherit flag */ + OUT int handle; /* handle to the event */ + IN char name[1]; /* event name */ }; /* Event operation */ struct event_op_request { - int handle; /* handle to event */ - int op; /* event operation (see below) */ + IN int handle; /* handle to event */ + IN int op; /* event operation (see below) */ }; enum event_op { PULSE_EVENT, SET_EVENT, RESET_EVENT }; @@ -320,278 +281,248 @@ enum event_op { PULSE_EVENT, SET_EVENT, RESET_EVENT }; /* Open an event */ struct open_event_request { - unsigned int access; /* wanted access rights */ - int inherit; /* inherit flag */ - char name[0]; /* object name */ -}; -struct open_event_reply -{ - int handle; /* handle to the event */ + IN unsigned int access; /* wanted access rights */ + IN int inherit; /* inherit flag */ + OUT int handle; /* handle to the event */ + IN char name[1]; /* object name */ }; /* Create a mutex */ struct create_mutex_request { - int owned; /* initially owned? */ - int inherit; /* inherit flag */ - char name[0]; /* mutex name */ -}; -struct create_mutex_reply -{ - int handle; /* handle to the mutex */ + IN int owned; /* initially owned? */ + IN int inherit; /* inherit flag */ + OUT int handle; /* handle to the mutex */ + IN char name[1]; /* mutex name */ }; /* Release a mutex */ struct release_mutex_request { - int handle; /* handle to the mutex */ + IN int handle; /* handle to the mutex */ }; /* Open a mutex */ struct open_mutex_request { - unsigned int access; /* wanted access rights */ - int inherit; /* inherit flag */ - char name[0]; /* object name */ -}; -struct open_mutex_reply -{ - int handle; /* handle to the mutex */ + IN unsigned int access; /* wanted access rights */ + IN int inherit; /* inherit flag */ + OUT int handle; /* handle to the mutex */ + IN char name[1]; /* object name */ }; /* Create a semaphore */ struct create_semaphore_request { - unsigned int initial; /* initial count */ - unsigned int max; /* maximum count */ - int inherit; /* inherit flag */ - char name[0]; /* semaphore name */ -}; -struct create_semaphore_reply -{ - int handle; /* handle to the semaphore */ + IN unsigned int initial; /* initial count */ + IN unsigned int max; /* maximum count */ + IN int inherit; /* inherit flag */ + OUT int handle; /* handle to the semaphore */ + IN char name[1]; /* semaphore name */ }; /* Release a semaphore */ struct release_semaphore_request { - int handle; /* handle to the semaphore */ - unsigned int count; /* count to add to semaphore */ -}; -struct release_semaphore_reply -{ - unsigned int prev_count; /* previous semaphore count */ + IN int handle; /* handle to the semaphore */ + IN unsigned int count; /* count to add to semaphore */ + OUT unsigned int prev_count; /* previous semaphore count */ }; /* Open a semaphore */ struct open_semaphore_request { - unsigned int access; /* wanted access rights */ - int inherit; /* inherit flag */ - char name[0]; /* object name */ -}; -struct open_semaphore_reply -{ - int handle; /* handle to the semaphore */ + IN unsigned int access; /* wanted access rights */ + IN int inherit; /* inherit flag */ + OUT int handle; /* handle to the semaphore */ + IN char name[1]; /* object name */ }; /* Create a file */ struct create_file_request { - unsigned int access; /* wanted access rights */ - int inherit; /* inherit flag */ - unsigned int sharing; /* sharing flags */ - int create; /* file create action */ - unsigned int attrs; /* file attributes for creation */ - char name[0]; /* file name */ + IN unsigned int access; /* wanted access rights */ + IN int inherit; /* inherit flag */ + IN unsigned int sharing; /* sharing flags */ + IN int create; /* file create action */ + IN unsigned int attrs; /* file attributes for creation */ + OUT int handle; /* handle to the file */ + IN char name[1]; /* file name */ }; -struct create_file_reply + + +/* Allocate a file handle for a Unix fd */ +struct alloc_file_handle_request { - int handle; /* handle to the file */ + IN unsigned int access; /* wanted access rights */ + OUT int handle; /* handle to the file */ }; /* Get a Unix fd to read from a file */ struct get_read_fd_request { - int handle; /* handle to the file */ + IN int handle; /* handle to the file */ }; /* Get a Unix fd to write to a file */ struct get_write_fd_request { - int handle; /* handle to the file */ + IN int handle; /* handle to the file */ }; /* Set a file current position */ struct set_file_pointer_request { - int handle; /* handle to the file */ - int low; /* position low word */ - int high; /* position high word */ - int whence; /* whence to seek */ -}; -struct set_file_pointer_reply -{ - int low; /* new position low word */ - int high; /* new position high word */ + IN int handle; /* handle to the file */ + IN int low; /* position low word */ + IN int high; /* position high word */ + IN int whence; /* whence to seek */ + OUT int new_low; /* new position low word */ + OUT int new_high; /* new position high word */ }; /* Truncate (or extend) a file */ struct truncate_file_request { - int handle; /* handle to the file */ + IN int handle; /* handle to the file */ }; /* Set a file access and modification times */ struct set_file_time_request { - int handle; /* handle to the file */ - time_t access_time; /* last access time */ - time_t write_time; /* last write time */ + IN int handle; /* handle to the file */ + IN time_t access_time; /* last access time */ + IN time_t write_time; /* last write time */ }; /* Flush a file buffers */ struct flush_file_request { - int handle; /* handle to the file */ + IN int handle; /* handle to the file */ }; /* Get information about a file */ struct get_file_info_request { - int handle; /* handle to the file */ -}; -struct get_file_info_reply -{ - int type; /* file type */ - int attr; /* file attributes */ - time_t access_time; /* last access time */ - time_t write_time; /* last write time */ - int size_high; /* file size */ - int size_low; /* file size */ - int links; /* number of links */ - int index_high; /* unique index */ - int index_low; /* unique index */ - unsigned int serial; /* volume serial number */ + IN int handle; /* handle to the file */ + OUT int type; /* file type */ + OUT int attr; /* file attributes */ + OUT time_t access_time; /* last access time */ + OUT time_t write_time; /* last write time */ + OUT int size_high; /* file size */ + OUT int size_low; /* file size */ + OUT int links; /* number of links */ + OUT int index_high; /* unique index */ + OUT int index_low; /* unique index */ + OUT unsigned int serial; /* volume serial number */ }; /* Lock a region of a file */ struct lock_file_request { - int handle; /* handle to the file */ - unsigned int offset_low; /* offset of start of lock */ - unsigned int offset_high; /* offset of start of lock */ - unsigned int count_low; /* count of bytes to lock */ - unsigned int count_high; /* count of bytes to lock */ + IN int handle; /* handle to the file */ + IN unsigned int offset_low; /* offset of start of lock */ + IN unsigned int offset_high; /* offset of start of lock */ + IN unsigned int count_low; /* count of bytes to lock */ + IN unsigned int count_high; /* count of bytes to lock */ }; /* Unlock a region of a file */ struct unlock_file_request { - int handle; /* handle to the file */ - unsigned int offset_low; /* offset of start of unlock */ - unsigned int offset_high; /* offset of start of unlock */ - unsigned int count_low; /* count of bytes to unlock */ - unsigned int count_high; /* count of bytes to unlock */ + IN int handle; /* handle to the file */ + IN unsigned int offset_low; /* offset of start of unlock */ + IN unsigned int offset_high; /* offset of start of unlock */ + IN unsigned int count_low; /* count of bytes to unlock */ + IN unsigned int count_high; /* count of bytes to unlock */ }; /* Create an anonymous pipe */ struct create_pipe_request { - int inherit; /* inherit flag */ -}; -struct create_pipe_reply -{ - int handle_read; /* handle to the read-side of the pipe */ - int handle_write; /* handle to the write-side of the pipe */ + IN int inherit; /* inherit flag */ + OUT int handle_read; /* handle to the read-side of the pipe */ + OUT int handle_write; /* handle to the write-side of the pipe */ }; /* Allocate a console for the current process */ struct alloc_console_request { - unsigned int access; /* wanted access rights */ - int inherit; /* inherit flag */ -}; -struct alloc_console_reply -{ - int handle_in; /* handle to console input */ - int handle_out; /* handle to console output */ + IN unsigned int access; /* wanted access rights */ + IN int inherit; /* inherit flag */ + OUT int handle_in; /* handle to console input */ + OUT int handle_out; /* handle to console output */ }; /* Free the console of the current process */ struct free_console_request { - int dummy; + IN int dummy; }; /* Open a handle to the process console */ struct open_console_request { - int output; /* input or output? */ - unsigned int access; /* wanted access rights */ - int inherit; /* inherit flag */ -}; -struct open_console_reply -{ - int handle; /* handle to the console */ + IN int output; /* input or output? */ + IN unsigned int access; /* wanted access rights */ + IN int inherit; /* inherit flag */ + OUT int handle; /* handle to the console */ }; /* Set a console file descriptor */ struct set_console_fd_request { - int handle; /* handle to the console */ - int pid; /* pid of xterm (hack) */ + IN int handle; /* handle to the console */ + IN int file_handle; /* handle of file to use as file descriptor */ + IN int pid; /* pid of xterm (hack) */ }; /* Get a console mode (input or output) */ struct get_console_mode_request { - int handle; /* handle to the console */ -}; -struct get_console_mode_reply -{ - int mode; /* console mode */ + IN int handle; /* handle to the console */ + OUT int mode; /* console mode */ }; /* Set a console mode (input or output) */ struct set_console_mode_request { - int handle; /* handle to the console */ - int mode; /* console mode */ + IN int handle; /* handle to the console */ + IN int mode; /* console mode */ }; /* Set info about a console (output only) */ struct set_console_info_request { - int handle; /* handle to the console */ - int mask; /* setting mask (see below) */ - int cursor_size; /* size of cursor (percentage filled) */ - int cursor_visible;/* cursor visibility flag */ - char title[0]; /* console title */ + IN int handle; /* handle to the console */ + IN int mask; /* setting mask (see below) */ + IN int cursor_size; /* size of cursor (percentage filled) */ + IN int cursor_visible;/* cursor visibility flag */ + IN char title[1]; /* console title */ }; #define SET_CONSOLE_INFO_CURSOR 0x01 #define SET_CONSOLE_INFO_TITLE 0x02 @@ -599,68 +530,53 @@ struct set_console_info_request /* Get info about a console (output only) */ struct get_console_info_request { - int handle; /* handle to the console */ -}; -struct get_console_info_reply -{ - int cursor_size; /* size of cursor (percentage filled) */ - int cursor_visible;/* cursor visibility flag */ - int pid; /* pid of xterm (hack) */ - char title[0]; /* console title */ + IN int handle; /* handle to the console */ + OUT int cursor_size; /* size of cursor (percentage filled) */ + OUT int cursor_visible;/* cursor visibility flag */ + OUT int pid; /* pid of xterm (hack) */ + OUT char title[1]; /* console title */ }; /* Add input records to a console input queue */ struct write_console_input_request { - int handle; /* handle to the console input */ - int count; /* number of input records */ -/* INPUT_RECORD records[0]; */ /* input records */ -}; -struct write_console_input_reply -{ - int written; /* number of records written */ + IN int handle; /* handle to the console input */ + IN int count; /* number of input records */ + OUT int written; /* number of records written */ + /* INPUT_RECORD records[0]; */ /* input records */ }; /* Fetch input records from a console input queue */ struct read_console_input_request { - int handle; /* handle to the console input */ - int count; /* max number of records to retrieve */ - int flush; /* flush the retrieved records from the queue? */ -}; -struct read_console_input_reply -{ - int dummy; -/* INPUT_RECORD records[0]; */ /* input records */ + IN int handle; /* handle to the console input */ + IN int count; /* max number of records to retrieve */ + IN int flush; /* flush the retrieved records from the queue? */ + OUT int read; /* number of records read */ + /* INPUT_RECORD records[0]; */ /* input records */ }; /* Create a change notification */ struct create_change_notification_request { - int subtree; /* watch all the subtree */ - int filter; /* notification filter */ -}; -struct create_change_notification_reply -{ - int handle; /* handle to the change notification */ + IN int subtree; /* watch all the subtree */ + IN int filter; /* notification filter */ + OUT int handle; /* handle to the change notification */ }; /* Create a file mapping */ struct create_mapping_request { - int size_high; /* mapping size */ - int size_low; /* mapping size */ - int protect; /* protection flags (see below) */ - int inherit; /* inherit flag */ - int handle; /* file handle */ - char name[0]; /* object name */ -}; -struct create_mapping_reply -{ - int handle; /* handle to the mapping */ + IN int size_high; /* mapping size */ + IN int size_low; /* mapping size */ + IN int protect; /* protection flags (see below) */ + IN int inherit; /* inherit flag */ + IN int file_handle; /* file handle */ + OUT int handle; /* handle to the mapping */ + IN char name[1]; /* object name */ }; /* protection flags */ #define VPROT_READ 0x01 @@ -675,91 +591,70 @@ struct create_mapping_reply /* Open a mapping */ struct open_mapping_request { - unsigned int access; /* wanted access rights */ - int inherit; /* inherit flag */ - char name[0]; /* object name */ -}; -struct open_mapping_reply -{ - int handle; /* handle to the mapping */ + IN unsigned int access; /* wanted access rights */ + IN int inherit; /* inherit flag */ + OUT int handle; /* handle to the mapping */ + IN char name[1]; /* object name */ }; /* Get information about a file mapping */ struct get_mapping_info_request { - int handle; /* handle to the mapping */ -}; -struct get_mapping_info_reply -{ - int size_high; /* mapping size */ - int size_low; /* mapping size */ - int protect; /* protection flags */ + IN int handle; /* handle to the mapping */ + OUT int size_high; /* mapping size */ + OUT int size_low; /* mapping size */ + OUT int protect; /* protection flags */ }; /* Create a device */ struct create_device_request { - unsigned int access; /* wanted access rights */ - int inherit; /* inherit flag */ - int id; /* client private id */ -}; -struct create_device_reply -{ - int handle; /* handle to the device */ + IN unsigned int access; /* wanted access rights */ + IN int inherit; /* inherit flag */ + IN int id; /* client private id */ + OUT int handle; /* handle to the device */ }; /* Create a snapshot */ struct create_snapshot_request { - int inherit; /* inherit flag */ - int flags; /* snapshot flags (TH32CS_*) */ -}; -struct create_snapshot_reply -{ - int handle; /* handle to the snapshot */ + IN int inherit; /* inherit flag */ + IN int flags; /* snapshot flags (TH32CS_*) */ + OUT int handle; /* handle to the snapshot */ }; /* Get the next process from a snapshot */ struct next_process_request { - int handle; /* handle to the snapshot */ - int reset; /* reset snapshot position? */ -}; -struct next_process_reply -{ - void* pid; /* process id */ - int threads; /* number of threads */ - int priority; /* process priority */ + IN int handle; /* handle to the snapshot */ + IN int reset; /* reset snapshot position? */ + OUT void* pid; /* process id */ + OUT int threads; /* number of threads */ + OUT int priority; /* process priority */ }; /* Wait for a debug event */ struct wait_debug_event_request { - int timeout; /* timeout in ms */ -}; -struct wait_debug_event_reply -{ - int code; /* event code */ - void* pid; /* process id */ - void* tid; /* thread id */ - /* followed by the event data (see below) */ + IN int timeout; /* timeout in ms */ + OUT int code; /* event code */ + OUT void* pid; /* process id */ + OUT void* tid; /* thread id */ +/* OUT union debug_event_data data; */ }; /* Send a debug event */ struct send_debug_event_request { - int code; /* event code */ - /* followed by the event data (see below) */ -}; -struct send_debug_event_reply -{ - int status; /* event continuation status */ + IN int code; /* event code */ + OUT int status; /* event continuation status */ +/* IN union debug_event_data data; */ }; @@ -837,16 +732,16 @@ union debug_event_data /* Continue a debug event */ struct continue_debug_event_request { - void* pid; /* process id to continue */ - void* tid; /* thread id to continue */ - int status; /* continuation status */ + IN void* pid; /* process id to continue */ + IN void* tid; /* thread id to continue */ + IN int status; /* continuation status */ }; /* Start debugging an existing process */ struct debug_process_request { - void* pid; /* id of the process to debug */ + IN void* pid; /* id of the process to debug */ }; @@ -860,6 +755,7 @@ enum request REQ_SET_DEBUG, REQ_INIT_PROCESS, REQ_INIT_THREAD, + REQ_GET_THREAD_BUFFER, REQ_TERMINATE_PROCESS, REQ_TERMINATE_THREAD, REQ_GET_PROCESS_INFO, @@ -870,6 +766,7 @@ enum request REQ_RESUME_THREAD, REQ_DEBUGGER, REQ_QUEUE_APC, + REQ_GET_APCS, REQ_CLOSE_HANDLE, REQ_GET_HANDLE_INFO, REQ_SET_HANDLE_INFO, @@ -886,6 +783,7 @@ enum request REQ_RELEASE_SEMAPHORE, REQ_OPEN_SEMAPHORE, REQ_CREATE_FILE, + REQ_ALLOC_FILE_HANDLE, REQ_GET_READ_FD, REQ_GET_WRITE_FD, REQ_SET_FILE_POINTER, @@ -930,31 +828,24 @@ enum request #include "thread.h" -/* make space for some data in the server arguments buffer */ -static inline void *server_add_data( int len ) +/* client communication functions */ + +/* get a pointer to the request buffer */ +static inline void *get_req_buffer(void) { - void *old = NtCurrentTeb()->buffer_args; - NtCurrentTeb()->buffer_args = (char *)old + len; - return old; + return NtCurrentTeb()->buffer; } -/* maximum remaining size in the server arguments buffer */ -static inline int server_remaining(void) +/* maximum remaining size in the server buffer */ +static inline int server_remaining( const void *ptr ) { - TEB *teb = NtCurrentTeb(); - return (char *)teb->buffer + teb->buffer_size - (char *)teb->buffer_args; + return (char *)NtCurrentTeb()->buffer + NtCurrentTeb()->buffer_size - (char *)ptr; } extern unsigned int server_call( enum request req ); -extern unsigned int server_call_fd( enum request req, int *fd ); +extern unsigned int server_call_fd( enum request req, int fd_out, int *fd_in ); +extern void server_protocol_error( const char *err, ... ); -/* client communication functions */ -extern void CLIENT_ProtocolError( const char *err, ... ); -extern void CLIENT_SendRequest( enum request req, int pass_fd, - int n, ... /* arg_1, len_1, etc. */ ); -extern unsigned int CLIENT_WaitReply( int *len, int *passed_fd, - int n, ... /* arg_1, len_1, etc. */ ); -extern unsigned int CLIENT_WaitSimpleReply( void *reply, int len, int *passed_fd ); extern int CLIENT_InitServer(void); extern int CLIENT_SetDebug( int level ); extern int CLIENT_DebuggerRequest( int op ); diff --git a/include/thread.h b/include/thread.h index 6db75502800..36c8ad5ea4c 100644 --- a/include/thread.h +++ b/include/thread.h @@ -39,8 +39,8 @@ typedef struct _TEB WORD teb_sel; /* 3c Selector to TEB */ WORD emu_sel; /* 3e 80387 emulator selector */ void *buffer; /* 40 Buffer shared with server */ - void *buffer_args; /* 44 Current position of arguments in server buffer */ - int buffer_size; /* 48 Size of server buffer */ + int buffer_size; /* 44 Size of server buffer */ + void (*startup)(void); /* 48 Thread startup routine */ int thread_errno; /* 4c Per-thread errno (was: ring0_thread) */ int thread_h_errno; /* 50 Per-thread h_errno (was: ptr to tdbx structure) */ void *stack_base; /* 54 Base of the stack */ @@ -69,8 +69,6 @@ typedef struct _TEB SYSLEVEL *sys_mutex[4]; /* 1d8 Syslevel mutex pointers */ DWORD unknown6[2]; /* 1e8 Unknown */ /* The following are Wine-specific fields */ - unsigned int seq; /* Server sequence number */ - void (*startup)(void); /* Thread startup routine */ struct _TEB *next; /* Global thread list */ DWORD cleanup; /* Cleanup service handle */ } TEB; diff --git a/loader/dos/module.c b/loader/dos/module.c index 4a34576ffdb..56ebf9d6367 100644 --- a/loader/dos/module.c +++ b/loader/dos/module.c @@ -344,8 +344,8 @@ BOOL MZ_InitTask( LPDOSTASK lpDosTask ) pid_t child; char *fname,*farg,arg[16],fproc[64],path[256],*fpath; SECURITY_ATTRIBUTES attr={sizeof(attr),NULL,TRUE}; - struct get_read_fd_request r_req; - struct get_write_fd_request w_req; + struct get_read_fd_request *r_req = get_req_buffer(); + struct get_write_fd_request *w_req = get_req_buffer(); if (!lpDosTask) return FALSE; /* create pipes */ @@ -357,12 +357,10 @@ BOOL MZ_InitTask( LPDOSTASK lpDosTask ) CloseHandle(lpDosTask->hXPipe); return FALSE; } - r_req.handle = lpDosTask->hReadPipe; - CLIENT_SendRequest( REQ_GET_READ_FD, -1, 1, &r_req, sizeof(r_req) ); - CLIENT_WaitReply( NULL, &(lpDosTask->read_pipe), 0 ); - w_req.handle = lpDosTask->hXPipe; - CLIENT_SendRequest( REQ_GET_WRITE_FD, -1, 1, &w_req, sizeof(w_req) ); - CLIENT_WaitReply( NULL, &x_fd, 0 ); + r_req->handle = lpDosTask->hReadPipe; + server_call_fd( REQ_GET_READ_FD, -1, &lpDosTask->read_pipe ); + w_req->handle = lpDosTask->hXPipe; + server_call_fd( REQ_GET_WRITE_FD, -1, &x_fd ); TRACE("win32 pipe: read=%d, write=%d, unix pipe: read=%d, write=%d\n", lpDosTask->hReadPipe,lpDosTask->hXPipe,lpDosTask->read_pipe,x_fd); diff --git a/memory/virtual.c b/memory/virtual.c index 71a0e60f4b2..09b5d4934d1 100644 --- a/memory/virtual.c +++ b/memory/virtual.c @@ -1051,8 +1051,7 @@ HANDLE WINAPI CreateFileMappingA( DWORD size_low, /* [in] Low-order 32 bits of object size */ LPCSTR name /* [in] Name of file-mapping object */ ) { - struct create_mapping_request req; - struct create_mapping_reply reply; + struct create_mapping_request *req = get_req_buffer(); BYTE vprot; /* Check parameters */ @@ -1074,19 +1073,16 @@ HANDLE WINAPI CreateFileMappingA( /* Create the server object */ - if (!name) name = ""; - req.handle = hFile; - req.size_high = size_high; - req.size_low = size_low; - req.protect = vprot; - req.inherit = (sa && (sa->nLength>=sizeof(*sa)) && sa->bInheritHandle); - CLIENT_SendRequest( REQ_CREATE_MAPPING, -1, 2, - &req, sizeof(req), - name, strlen(name) + 1 ); + req->file_handle = hFile; + req->size_high = size_high; + req->size_low = size_low; + req->protect = vprot; + req->inherit = (sa && (sa->nLength>=sizeof(*sa)) && sa->bInheritHandle); + lstrcpynA( req->name, name ? name : "", server_remaining(req->name) ); SetLastError(0); - CLIENT_WaitSimpleReply( &reply, sizeof(reply), NULL ); - if (reply.handle == -1) return 0; - return reply.handle; + server_call( REQ_CREATE_MAPPING ); + if (req->handle == -1) return 0; + return req->handle; } @@ -1119,16 +1115,14 @@ HANDLE WINAPI OpenFileMappingA( BOOL inherit, /* [in] Inherit flag */ LPCSTR name ) /* [in] Name of file-mapping object */ { - struct open_mapping_request req; - struct open_mapping_reply reply; - int len = name ? strlen(name) + 1 : 0; + struct open_mapping_request *req = get_req_buffer(); - req.access = access; - req.inherit = inherit; - CLIENT_SendRequest( REQ_OPEN_MAPPING, -1, 2, &req, sizeof(req), name, len ); - CLIENT_WaitSimpleReply( &reply, sizeof(reply), NULL ); - if (reply.handle == -1) return 0; /* must return 0 on failure, not -1 */ - return reply.handle; + req->access = access; + req->inherit = inherit; + lstrcpynA( req->name, name ? name : "", server_remaining(req->name) ); + server_call( REQ_OPEN_MAPPING ); + if (req->handle == -1) return 0; /* must return 0 on failure, not -1 */ + return req->handle; } @@ -1185,8 +1179,8 @@ LPVOID WINAPI MapViewOfFileEx( UINT ptr = (UINT)-1, size = 0; int flags = MAP_PRIVATE; int unix_handle = -1; - struct get_mapping_info_request req; - struct get_mapping_info_reply info; + int prot; + struct get_mapping_info_request *req = get_req_buffer(); /* Check parameters */ @@ -1197,29 +1191,28 @@ LPVOID WINAPI MapViewOfFileEx( return NULL; } - req.handle = handle; - CLIENT_SendRequest( REQ_GET_MAPPING_INFO, -1, 1, &req, sizeof(req) ); - if (CLIENT_WaitSimpleReply( &info, sizeof(info), &unix_handle )) - goto error; + req->handle = handle; + if (server_call_fd( REQ_GET_MAPPING_INFO, -1, &unix_handle )) goto error; - if (info.size_high || offset_high) + if (req->size_high || offset_high) ERR("Offsets larger than 4Gb not supported\n"); - if ((offset_low >= info.size_low) || - (count > info.size_low - offset_low)) + if ((offset_low >= req->size_low) || + (count > req->size_low - offset_low)) { SetLastError( ERROR_INVALID_PARAMETER ); goto error; } if (count) size = ROUND_SIZE( offset_low, count ); - else size = info.size_low - offset_low; + else size = req->size_low - offset_low; + prot = req->protect; switch(access) { case FILE_MAP_ALL_ACCESS: case FILE_MAP_WRITE: case FILE_MAP_WRITE | FILE_MAP_READ: - if (!(info.protect & VPROT_WRITE)) + if (!(prot & VPROT_WRITE)) { SetLastError( ERROR_INVALID_PARAMETER ); goto error; @@ -1229,7 +1222,7 @@ LPVOID WINAPI MapViewOfFileEx( case FILE_MAP_READ: case FILE_MAP_COPY: case FILE_MAP_COPY | FILE_MAP_READ: - if (info.protect & VPROT_READ) break; + if (prot & VPROT_READ) break; /* fall through */ default: SetLastError( ERROR_INVALID_PARAMETER ); @@ -1238,13 +1231,10 @@ LPVOID WINAPI MapViewOfFileEx( /* Map the file */ - TRACE("handle=%x size=%x offset=%lx\n", - handle, size, offset_low ); + TRACE("handle=%x size=%x offset=%lx\n", handle, size, offset_low ); - ptr = (UINT)FILE_dommap( unix_handle, - addr, 0, size, 0, offset_low, - VIRTUAL_GetUnixProt( info.protect ), - flags ); + ptr = (UINT)FILE_dommap( unix_handle, addr, 0, size, 0, offset_low, + VIRTUAL_GetUnixProt( prot ), flags ); if (ptr == (UINT)-1) { /* KB: Q125713, 25-SEP-1995, "Common File Mapping Problems and * Platform Differences": @@ -1259,8 +1249,7 @@ LPVOID WINAPI MapViewOfFileEx( goto error; } - if (!(view = VIRTUAL_CreateView( ptr, size, offset_low, 0, - info.protect, handle ))) + if (!(view = VIRTUAL_CreateView( ptr, size, offset_low, 0, prot, handle ))) { SetLastError( ERROR_OUTOFMEMORY ); goto error; diff --git a/misc/comm.c b/misc/comm.c index f20a63f9914..b8cee05d7f9 100644 --- a/misc/comm.c +++ b/misc/comm.c @@ -1476,31 +1476,30 @@ BOOL WINAPI BuildCommDCBW(LPCWSTR devid,LPDCB lpdcb) } /***************************************************************************** - * COMM_Handle2fd - * returns a file descriptor for reading from or writing to - * mode is GENERIC_READ or GENERIC_WRITE. Make sure to close - * the handle afterwards! + * COMM_GetReadFd + * Returns a file descriptor for reading. + * Make sure to close the handle afterwards! */ -int COMM_Handle2fd(HANDLE handle, int mode) { - struct get_read_fd_request r_req; - struct get_write_fd_request w_req; +static int COMM_GetReadFd( HANDLE handle) +{ int fd; + struct get_read_fd_request *req = get_req_buffer(); + req->handle = handle; + server_call_fd( REQ_GET_READ_FD, -1, &fd ); + return fd; +} - w_req.handle = r_req.handle = handle; - - switch(mode) { - case GENERIC_WRITE: - CLIENT_SendRequest( REQ_GET_WRITE_FD, -1, 1, &w_req, sizeof(w_req) ); - break; - case GENERIC_READ: - CLIENT_SendRequest( REQ_GET_READ_FD, -1, 1, &r_req, sizeof(r_req) ); - break; - default: - ERR(comm,"COMM_Handle2fd: Don't know what type of fd is required.\n"); - return -1; - } - CLIENT_WaitReply( NULL, &fd, 0 ); - +/***************************************************************************** + * COMM_GetWriteFd + * Returns a file descriptor for writing. + * Make sure to close the handle afterwards! + */ +static int COMM_GetWriteFd( HANDLE handle) +{ + int fd; + struct get_write_fd_request *req = get_req_buffer(); + req->handle = handle; + server_call_fd( REQ_GET_WRITE_FD, -1, &fd ); return fd; } @@ -1534,7 +1533,7 @@ BOOL WINAPI EscapeCommFunction(HANDLE handle,UINT nFunction) struct termios port; TRACE(comm,"handle %d, function=%d\n", handle, nFunction); - fd = COMM_Handle2fd(handle, GENERIC_WRITE); + fd = COMM_GetWriteFd(handle); if(fd<0) return FALSE; @@ -1611,7 +1610,7 @@ BOOL WINAPI PurgeComm( HANDLE handle, DWORD flags) TRACE(comm,"handle %d, flags %lx\n", handle, flags); - fd = COMM_Handle2fd(handle, GENERIC_WRITE); + fd = COMM_GetWriteFd(handle); if(fd<0) return FALSE; @@ -1648,7 +1647,7 @@ BOOL WINAPI ClearCommError(INT handle,LPDWORD errors,LPCOMSTAT lpStat) { int fd; - fd=COMM_Handle2fd(handle,GENERIC_READ); + fd=COMM_GetReadFd(handle); if(0>fd) { return FALSE; @@ -1693,7 +1692,7 @@ BOOL WINAPI SetupComm( HANDLE handle, DWORD insize, DWORD outsize) int fd; FIXME(comm, "insize %ld outsize %ld unimplemented stub\n", insize, outsize); - fd=COMM_Handle2fd(handle,GENERIC_WRITE); + fd=COMM_GetWriteFd(handle); if(0>fd) { return FALSE; @@ -1710,7 +1709,7 @@ BOOL WINAPI GetCommMask(HANDLE handle,LPDWORD evtmask) int fd; TRACE(comm, "handle %d, mask %p\n", handle, evtmask); - if(0>(fd=COMM_Handle2fd(handle,GENERIC_READ))) + if(0>(fd=COMM_GetReadFd(handle))) { return FALSE; } @@ -1727,7 +1726,7 @@ BOOL WINAPI SetCommMask(INT handle,DWORD evtmask) int fd; TRACE(comm, "handle %d, mask %lx\n", handle, evtmask); - if(0>(fd=COMM_Handle2fd(handle,GENERIC_WRITE))) { + if(0>(fd=COMM_GetWriteFd(handle))) { return FALSE; } close(fd); @@ -1742,19 +1741,14 @@ BOOL WINAPI SetCommState(INT handle,LPDCB lpdcb) { struct termios port; int fd; - struct get_write_fd_request req; TRACE(comm,"handle %d, ptr %p\n", handle, lpdcb); - req.handle = handle; - CLIENT_SendRequest( REQ_GET_WRITE_FD, -1, 1, &req, sizeof(req) ); - CLIENT_WaitReply( NULL, &fd, 0 ); - - if(fd<0) - return FALSE; + if ((fd = COMM_GetWriteFd(handle)) < 0) return FALSE; if (tcgetattr(fd,&port) == -1) { - commerror = WinError(); + commerror = WinError(); + close( fd ); return FALSE; } @@ -1821,6 +1815,7 @@ BOOL WINAPI SetCommState(INT handle,LPDCB lpdcb) break; default: commerror = IE_BAUDRATE; + close( fd ); return FALSE; } #elif !defined(__EMX__) @@ -1863,6 +1858,7 @@ BOOL WINAPI SetCommState(INT handle,LPDCB lpdcb) break; default: commerror = IE_BAUDRATE; + close( fd ); return FALSE; } port.c_ispeed = port.c_ospeed; @@ -1884,6 +1880,7 @@ BOOL WINAPI SetCommState(INT handle,LPDCB lpdcb) break; default: commerror = IE_BYTESIZE; + close( fd ); return FALSE; } @@ -1904,6 +1901,7 @@ BOOL WINAPI SetCommState(INT handle,LPDCB lpdcb) break; default: commerror = IE_BYTESIZE; + close( fd ); return FALSE; } @@ -1918,6 +1916,7 @@ BOOL WINAPI SetCommState(INT handle,LPDCB lpdcb) break; default: commerror = IE_BYTESIZE; + close( fd ); return FALSE; } #ifdef CRTSCTS @@ -1941,9 +1940,11 @@ BOOL WINAPI SetCommState(INT handle,LPDCB lpdcb) if (tcsetattr(fd,TCSADRAIN,&port)==-1) { commerror = WinError(); + close( fd ); return FALSE; } else { commerror = 0; + close( fd ); return TRUE; } } @@ -1956,21 +1957,18 @@ BOOL WINAPI GetCommState(INT handle, LPDCB lpdcb) { struct termios port; int fd; - struct get_read_fd_request req; TRACE(comm,"handle %d, ptr %p\n", handle, lpdcb); - req.handle = handle; - CLIENT_SendRequest( REQ_GET_READ_FD, -1, 1, &req, sizeof(req) ); - CLIENT_WaitReply( NULL, &fd, 0 ); - if(fd<0) - return FALSE; + if ((fd = COMM_GetReadFd(handle)) < 0) return FALSE; if (tcgetattr(fd, &port) == -1) { TRACE(comm,"tcgetattr(%d, ...) returned -1",fd); commerror = WinError(); + close( fd ); return FALSE; } + close( fd ); #ifndef __EMX__ #ifdef CBAUD switch (port.c_cflag & CBAUD) { diff --git a/misc/toolhelp.c b/misc/toolhelp.c index d437530bc06..7abf041ad27 100644 --- a/misc/toolhelp.c +++ b/misc/toolhelp.c @@ -116,8 +116,7 @@ FARPROC16 tmp; */ HANDLE WINAPI CreateToolhelp32Snapshot( DWORD flags, DWORD process ) { - struct create_snapshot_request req; - struct create_snapshot_reply reply; + struct create_snapshot_request *req = get_req_buffer(); TRACE( toolhelp, "%lx,%lx\n", flags, process ); if (flags & (TH32CS_SNAPHEAPLIST|TH32CS_SNAPMODULE|TH32CS_SNAPTHREAD)) @@ -127,13 +126,12 @@ HANDLE WINAPI CreateToolhelp32Snapshot( DWORD flags, DWORD process ) SetLastError( ERROR_CALL_NOT_IMPLEMENTED ); return INVALID_HANDLE_VALUE; } - + /* Now do the snapshot */ - req.flags = flags & ~TH32CS_INHERIT; - req.inherit = (flags & TH32CS_INHERIT) != 0; - CLIENT_SendRequest( REQ_CREATE_SNAPSHOT, -1, 1, &req, sizeof(req) ); - CLIENT_WaitSimpleReply( &reply, sizeof(reply), NULL ); - return reply.handle; + req->flags = flags & ~TH32CS_INHERIT; + req->inherit = (flags & TH32CS_INHERIT) != 0; + server_call( REQ_CREATE_SNAPSHOT ); + return req->handle; } @@ -144,8 +142,7 @@ HANDLE WINAPI CreateToolhelp32Snapshot( DWORD flags, DWORD process ) */ static BOOL TOOLHELP_Process32Next( HANDLE handle, LPPROCESSENTRY lppe, BOOL first ) { - struct next_process_request req; - struct next_process_reply reply; + struct next_process_request *req = get_req_buffer(); if (lppe->dwSize < sizeof (PROCESSENTRY)) { @@ -153,17 +150,16 @@ static BOOL TOOLHELP_Process32Next( HANDLE handle, LPPROCESSENTRY lppe, BOOL fir ERR (toolhelp, "Result buffer too small\n"); return FALSE; } - req.handle = handle; - req.reset = first; - CLIENT_SendRequest( REQ_NEXT_PROCESS, -1, 1, &req, sizeof(req) ); - if (CLIENT_WaitSimpleReply( &reply, sizeof(reply), NULL )) return FALSE; + req->handle = handle; + req->reset = first; + if (server_call( REQ_NEXT_PROCESS )) return FALSE; lppe->cntUsage = 1; - lppe->th32ProcessID = (DWORD)reply.pid; + lppe->th32ProcessID = (DWORD)req->pid; lppe->th32DefaultHeapID = 0; /* FIXME */ lppe->th32ModuleID = 0; /* FIXME */ - lppe->cntThreads = reply.threads; + lppe->cntThreads = req->threads; lppe->th32ParentProcessID = 0; /* FIXME */ - lppe->pcPriClassBase = reply.priority; + lppe->pcPriClassBase = req->priority; lppe->dwFlags = -1; /* FIXME */ lppe->szExeFile[0] = 0; /* FIXME */ return TRUE; diff --git a/scheduler/client.c b/scheduler/client.c index 4f5dbdb8099..bc62f539de1 100644 --- a/scheduler/client.c +++ b/scheduler/client.c @@ -26,6 +26,14 @@ #define SCM_RIGHTS 1 #endif +/* data structure used to pass an fd with sendmsg/recvmsg */ +struct cmsg_fd +{ + int len; /* sizeof structure */ + int level; /* SOL_SOCKET */ + int type; /* SCM_RIGHTS */ + int fd; /* fd to pass */ +}; /*********************************************************************** * CLIENT_Die @@ -39,9 +47,9 @@ static void CLIENT_Die(void) } /*********************************************************************** - * CLIENT_ProtocolError + * server_protocol_error */ -void CLIENT_ProtocolError( const char *err, ... ) +void server_protocol_error( const char *err, ... ) { va_list args; @@ -54,9 +62,9 @@ void CLIENT_ProtocolError( const char *err, ... ) /*********************************************************************** - * CLIENT_perror + * server_perror */ -void CLIENT_perror( const char *err ) +static void server_perror( const char *err ) { fprintf( stderr, "Client protocol error:%p: ", NtCurrentTeb()->tid ); perror( err ); @@ -71,24 +79,15 @@ void CLIENT_perror( const char *err ) */ static void send_request( enum request req ) { - struct header *head = NtCurrentTeb()->buffer; - int ret, seq = NtCurrentTeb()->seq++; - - assert( server_remaining() >= 0 ); - - head->type = req; - head->len = (char *)NtCurrentTeb()->buffer_args - (char *)NtCurrentTeb()->buffer; - - NtCurrentTeb()->buffer_args = head + 1; /* reset the args buffer */ - - if ((ret = write( NtCurrentTeb()->socket, &seq, sizeof(seq) )) == sizeof(seq)) + int ret; + if ((ret = write( NtCurrentTeb()->socket, &req, sizeof(req) )) == sizeof(req)) return; if (ret == -1) { if (errno == EPIPE) CLIENT_Die(); - CLIENT_perror( "sendmsg" ); + server_perror( "sendmsg" ); } - CLIENT_ProtocolError( "partial seq sent %d/%d\n", ret, sizeof(seq) ); + server_protocol_error( "partial msg sent %d/%d\n", ret, sizeof(req) ); } /*********************************************************************** @@ -98,23 +97,15 @@ static void send_request( enum request req ) */ static void send_request_fd( enum request req, int fd ) { - struct header *head = NtCurrentTeb()->buffer; - int ret, seq = NtCurrentTeb()->seq++; + int ret; #ifndef HAVE_MSGHDR_ACCRIGHTS struct cmsg_fd cmsg; #endif struct msghdr msghdr; struct iovec vec; - assert( server_remaining() >= 0 ); - - head->type = req; - head->len = (char *)NtCurrentTeb()->buffer_args - (char *)NtCurrentTeb()->buffer; - - NtCurrentTeb()->buffer_args = head + 1; /* reset the args buffer */ - - vec.iov_base = &seq; - vec.iov_len = sizeof(seq); + vec.iov_base = &req; + vec.iov_len = sizeof(req); msghdr.msg_name = NULL; msghdr.msg_namelen = 0; @@ -134,13 +125,13 @@ static void send_request_fd( enum request req, int fd ) msghdr.msg_flags = 0; #endif /* HAVE_MSGHDR_ACCRIGHTS */ - if ((ret = sendmsg( NtCurrentTeb()->socket, &msghdr, 0 )) == sizeof(seq)) return; + if ((ret = sendmsg( NtCurrentTeb()->socket, &msghdr, 0 )) == sizeof(req)) return; if (ret == -1) { if (errno == EPIPE) CLIENT_Die(); - CLIENT_perror( "sendmsg" ); + server_perror( "sendmsg" ); } - CLIENT_ProtocolError( "partial seq sent %d/%d\n", ret, sizeof(seq) ); + server_protocol_error( "partial msg sent %d/%d\n", ret, sizeof(req) ); } /*********************************************************************** @@ -148,26 +139,23 @@ static void send_request_fd( enum request req, int fd ) * * Wait for a reply from the server. */ -static void wait_reply(void) +static unsigned int wait_reply(void) { - int seq, ret; + int ret; + unsigned int res; for (;;) { - if ((ret = read( NtCurrentTeb()->socket, &seq, sizeof(seq) )) == sizeof(seq)) - { - if (seq != NtCurrentTeb()->seq++) - CLIENT_ProtocolError( "sequence %08x instead of %08x\n", seq, NtCurrentTeb()->seq - 1 ); - return; - } + if ((ret = read( NtCurrentTeb()->socket, &res, sizeof(res) )) == sizeof(res)) + return res; if (ret == -1) { if (errno == EINTR) continue; if (errno == EPIPE) CLIENT_Die(); - CLIENT_perror("read"); + server_perror("read"); } if (!ret) CLIENT_Die(); /* the server closed the connection; time to die... */ - CLIENT_ProtocolError( "partial seq received %d/%d\n", ret, sizeof(seq) ); + server_protocol_error( "partial msg received %d/%d\n", ret, sizeof(res) ); } } @@ -177,17 +165,18 @@ static void wait_reply(void) * * Wait for a reply from the server, when a file descriptor is passed. */ -static int wait_reply_fd(void) +static unsigned int wait_reply_fd( int *fd ) { struct iovec vec; - int seq, ret; + int ret; + unsigned int res; #ifdef HAVE_MSGHDR_ACCRIGHTS struct msghdr msghdr; - int fd = -1; - msghdr.msg_accrights = (void *)&fd; - msghdr.msg_accrightslen = sizeof(int); + *fd = -1; + msghdr.msg_accrights = (void *)fd; + msghdr.msg_accrightslen = sizeof(*fd); #else /* HAVE_MSGHDR_ACCRIGHTS */ struct msghdr msghdr; struct cmsg_fd cmsg; @@ -205,29 +194,26 @@ static int wait_reply_fd(void) msghdr.msg_namelen = 0; msghdr.msg_iov = &vec; msghdr.msg_iovlen = 1; - vec.iov_base = &seq; - vec.iov_len = sizeof(seq); + vec.iov_base = &res; + vec.iov_len = sizeof(res); for (;;) { - if ((ret = recvmsg( NtCurrentTeb()->socket, &msghdr, 0 )) == sizeof(seq)) + if ((ret = recvmsg( NtCurrentTeb()->socket, &msghdr, 0 )) == sizeof(res)) { - if (seq != NtCurrentTeb()->seq++) - CLIENT_ProtocolError( "sequence %08x instead of %08x\n", seq, NtCurrentTeb()->seq - 1 ); -#ifdef HAVE_MSGHDR_ACCRIGHTS - return fd; -#else - return cmsg.fd; +#ifndef HAVE_MSGHDR_ACCRIGHTS + *fd = cmsg.fd; #endif + return res; } if (ret == -1) { if (errno == EINTR) continue; if (errno == EPIPE) CLIENT_Die(); - CLIENT_perror("recvmsg"); + server_perror("recvmsg"); } if (!ret) CLIENT_Die(); /* the server closed the connection; time to die... */ - CLIENT_ProtocolError( "partial seq received %d/%d\n", ret, sizeof(seq) ); + server_protocol_error( "partial seq received %d/%d\n", ret, sizeof(res) ); } } @@ -239,18 +225,15 @@ static int wait_reply_fd(void) */ unsigned int server_call( enum request req ) { - struct header *head; + unsigned int res; send_request( req ); - wait_reply(); - - head = (struct header *)NtCurrentTeb()->buffer; - if ((head->len < sizeof(*head)) || (head->len > NtCurrentTeb()->buffer_size)) - CLIENT_ProtocolError( "header length %d\n", head->len ); - if (head->type) SetLastError( head->type ); - return head->type; /* error code */ + res = wait_reply(); + if (res) SetLastError( res ); + return res; /* error code */ } + /*********************************************************************** * server_call_fd * @@ -258,125 +241,17 @@ unsigned int server_call( enum request req ) * If *fd is != -1, it will be passed to the server. * If the server passes an fd, it will be stored into *fd. */ -unsigned int server_call_fd( enum request req, int *fd ) +unsigned int server_call_fd( enum request req, int fd_out, int *fd_in ) { - struct header *head; + unsigned int res; - if (*fd == -1) send_request( req ); - else send_request_fd( req, *fd ); - *fd = wait_reply_fd(); + if (fd_out == -1) send_request( req ); + else send_request_fd( req, fd_out ); - head = (struct header *)NtCurrentTeb()->buffer; - if ((head->len < sizeof(*head)) || (head->len > NtCurrentTeb()->buffer_size)) - CLIENT_ProtocolError( "header length %d\n", head->len ); - if (head->type) SetLastError( head->type ); - return head->type; /* error code */ -} - -/*********************************************************************** - * CLIENT_SendRequest - * - * Send a request to the server. - */ -void CLIENT_SendRequest( enum request req, int pass_fd, - int n, ... /* arg_1, len_1, etc. */ ) -{ - va_list args; - - va_start( args, n ); - while (n--) - { - void *ptr = va_arg( args, void * ); - int len = va_arg( args, int ); - memcpy( server_add_data( len ), ptr, len ); - } - va_end( args ); - - if (pass_fd == -1) send_request( req ); - else - { - send_request_fd( req, pass_fd ); - close( pass_fd ); /* we passed the fd now we can close it */ - } -} - - -/*********************************************************************** - * CLIENT_WaitReply_v - * - * Wait for a reply from the server. - * Returns the error code (or 0 if OK). - */ -static unsigned int CLIENT_WaitReply_v( int *len, int *passed_fd, - struct iovec *vec, int veclen ) -{ - struct header *head; - char *ptr; - int i, remaining; - - if (passed_fd) *passed_fd = wait_reply_fd(); - else wait_reply(); - - head = (struct header *)NtCurrentTeb()->buffer; - if ((head->len < sizeof(*head)) || (head->len > NtCurrentTeb()->buffer_size)) - CLIENT_ProtocolError( "header length %d\n", head->len ); - - remaining = head->len - sizeof(*head); - ptr = (char *)(head + 1); - for (i = 0; i < veclen; i++, vec++) - { - int len = MIN( remaining, vec->iov_len ); - memcpy( vec->iov_base, ptr, len ); - ptr += len; - if (!(remaining -= len)) break; - } - if (len) *len = head->len - sizeof(*head); - if (head->type) SetLastError( head->type ); - return head->type; /* error code */ -} - - -/*********************************************************************** - * CLIENT_WaitReply - * - * Wait for a reply from the server. - */ -unsigned int CLIENT_WaitReply( int *len, int *passed_fd, - int n, ... /* arg_1, len_1, etc. */ ) -{ - struct iovec vec[16]; - va_list args; - int i; - - assert( n < 16 ); - va_start( args, n ); - for (i = 0; i < n; i++) - { - vec[i].iov_base = va_arg( args, void * ); - vec[i].iov_len = va_arg( args, int ); - } - va_end( args ); - return CLIENT_WaitReply_v( len, passed_fd, vec, n ); -} - - -/*********************************************************************** - * CLIENT_WaitSimpleReply - * - * Wait for a simple fixed-length reply from the server. - */ -unsigned int CLIENT_WaitSimpleReply( void *reply, int len, int *passed_fd ) -{ - struct iovec vec; - unsigned int ret; - int got; - - vec.iov_base = reply; - vec.iov_len = len; - ret = CLIENT_WaitReply_v( &got, passed_fd, &vec, 1 ); - if (got != len) - CLIENT_ProtocolError( "WaitSimpleReply: len %d != %d\n", len, got ); - return ret; + if (fd_in) res = wait_reply_fd( fd_in ); + else res = wait_reply(); + if (res) SetLastError( res ); + return res; /* error code */ } @@ -427,24 +302,23 @@ int CLIENT_InitServer(void) */ int CLIENT_InitThread(void) { - struct init_thread_request req; - struct init_thread_reply reply; + struct init_thread_request *req; TEB *teb = NtCurrentTeb(); + int fd; - int fd = wait_reply_fd(); - if (fd == -1) CLIENT_ProtocolError( "no fd passed on first request\n" ); - if ((teb->buffer_size = lseek( fd, 0, SEEK_END )) == -1) CLIENT_perror( "lseek" ); + if (wait_reply_fd( &fd ) || (fd == -1)) + server_protocol_error( "no fd passed on first request\n" ); + if ((teb->buffer_size = lseek( fd, 0, SEEK_END )) == -1) server_perror( "lseek" ); teb->buffer = mmap( 0, teb->buffer_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0 ); close( fd ); - if (teb->buffer == (void*)-1) CLIENT_perror( "mmap" ); - teb->buffer_args = (char *)teb->buffer + sizeof(struct header); + if (teb->buffer == (void*)-1) server_perror( "mmap" ); - req.unix_pid = getpid(); - req.teb = teb; - CLIENT_SendRequest( REQ_INIT_THREAD, -1, 1, &req, sizeof(req) ); - if (CLIENT_WaitSimpleReply( &reply, sizeof(reply), NULL )) return -1; - teb->process->server_pid = reply.pid; - teb->tid = reply.tid; + req = get_req_buffer(); + req->unix_pid = getpid(); + req->teb = teb; + if (server_call( REQ_INIT_THREAD )) return -1; + teb->process->server_pid = req->pid; + teb->tid = req->tid; return 0; } @@ -456,8 +330,9 @@ int CLIENT_InitThread(void) */ int CLIENT_SetDebug( int level ) { - CLIENT_SendRequest( REQ_SET_DEBUG, -1, 1, &level, sizeof(level) ); - return CLIENT_WaitReply( NULL, NULL, 0 ); + struct set_debug_request *req = get_req_buffer(); + req->level = level; + return server_call( REQ_SET_DEBUG ); } /*********************************************************************** @@ -467,9 +342,8 @@ int CLIENT_SetDebug( int level ) */ int CLIENT_DebuggerRequest( int op ) { - struct debugger_request req; - req.op = op; - CLIENT_SendRequest( REQ_DEBUGGER, -1, 1, &req, sizeof(req) ); - return CLIENT_WaitReply( NULL, NULL, 0 ); + struct debugger_request *req = get_req_buffer(); + req->op = op; + return server_call( REQ_DEBUGGER ); } diff --git a/scheduler/debugger.c b/scheduler/debugger.c index fd969858e3b..e5a4beae93c 100644 --- a/scheduler/debugger.c +++ b/scheduler/debugger.c @@ -17,13 +17,12 @@ */ static DWORD DEBUG_SendEvent( int code, void *data, int size ) { - struct send_debug_event_request req; - struct send_debug_event_reply reply; - - req.code = code; - CLIENT_SendRequest( REQ_SEND_DEBUG_EVENT, -1, 2, &req, sizeof(req), data, size ); - if (CLIENT_WaitSimpleReply( &reply, sizeof(reply), NULL )) return 0; - return reply.status; + DWORD ret = 0; + struct send_debug_event_request *req = get_req_buffer(); + req->code = code; + memcpy( req + 1, data, size ); + if (!server_call( REQ_SEND_DEBUG_EVENT )) ret = req->status; + return ret; } @@ -135,94 +134,74 @@ DWORD DEBUG_SendUnloadDLLEvent( HMODULE module ) */ BOOL WINAPI WaitForDebugEvent( LPDEBUG_EVENT event, DWORD timeout ) { - /* size of the event data */ - static const int event_sizes[] = - { - 0, - sizeof(struct debug_event_exception), /* EXCEPTION_DEBUG_EVENT */ - sizeof(struct debug_event_create_thread), /* CREATE_THREAD_DEBUG_EVENT */ - sizeof(struct debug_event_create_process), /* CREATE_PROCESS_DEBUG_EVENT */ - sizeof(struct debug_event_exit), /* EXIT_THREAD_DEBUG_EVENT */ - sizeof(struct debug_event_exit), /* EXIT_PROCESS_DEBUG_EVENT */ - sizeof(struct debug_event_load_dll), /* LOAD_DLL_DEBUG_EVENT */ - sizeof(struct debug_event_unload_dll), /* UNLOAD_DLL_DEBUG_EVENT */ - sizeof(struct debug_event_output_string), /* OUTPUT_DEBUG_STRING_EVENT */ - sizeof(struct debug_event_rip_info) /* RIP_EVENT */ - }; + struct wait_debug_event_request *req = get_req_buffer(); + union debug_event_data *data = (union debug_event_data *)(req + 1); + int i; - struct wait_debug_event_request req; - struct wait_debug_event_reply reply; - union debug_event_data data; - int i, len; + req->timeout = timeout; + if (server_call( REQ_WAIT_DEBUG_EVENT )) return FALSE; + if ((req->code < 0) || (req->code > RIP_EVENT)) + server_protocol_error( "WaitForDebugEvent: bad code %d\n", req->code ); - req.timeout = timeout; - CLIENT_SendRequest( REQ_WAIT_DEBUG_EVENT, -1, 1, &req, sizeof(req) ); - if (CLIENT_WaitReply( &len, NULL, 2, &reply, sizeof(reply), - &data, sizeof(data) )) return FALSE; - if ((reply.code < 0) || (reply.code > RIP_EVENT)) - CLIENT_ProtocolError( "WaitForDebugEvent: bad code %d\n", reply.code ); - if (len != sizeof(reply) + event_sizes[reply.code]) - CLIENT_ProtocolError( "WaitForDebugEvent: bad len %d for code %d\n", len, reply.code ); - - event->dwDebugEventCode = reply.code; - event->dwProcessId = (DWORD)reply.pid; - event->dwThreadId = (DWORD)reply.tid; - switch(reply.code) + event->dwDebugEventCode = req->code; + event->dwProcessId = (DWORD)req->pid; + event->dwThreadId = (DWORD)req->tid; + switch(req->code) { case EXCEPTION_DEBUG_EVENT: - event->u.Exception.ExceptionRecord.ExceptionCode = data.exception.code; - event->u.Exception.ExceptionRecord.ExceptionFlags = data.exception.flags; - event->u.Exception.ExceptionRecord.ExceptionRecord = data.exception.record; - event->u.Exception.ExceptionRecord.ExceptionAddress = data.exception.addr; - event->u.Exception.ExceptionRecord.NumberParameters = data.exception.nb_params; - for (i = 0; i < data.exception.nb_params; i++) - event->u.Exception.ExceptionRecord.ExceptionInformation[i] = data.exception.params[i]; - event->u.Exception.dwFirstChance = data.exception.first_chance; + event->u.Exception.ExceptionRecord.ExceptionCode = data->exception.code; + event->u.Exception.ExceptionRecord.ExceptionFlags = data->exception.flags; + event->u.Exception.ExceptionRecord.ExceptionRecord = data->exception.record; + event->u.Exception.ExceptionRecord.ExceptionAddress = data->exception.addr; + event->u.Exception.ExceptionRecord.NumberParameters = data->exception.nb_params; + for (i = 0; i < data->exception.nb_params; i++) + event->u.Exception.ExceptionRecord.ExceptionInformation[i] = data->exception.params[i]; + event->u.Exception.dwFirstChance = data->exception.first_chance; break; case CREATE_THREAD_DEBUG_EVENT: - event->u.CreateThread.hThread = data.create_thread.handle; - event->u.CreateThread.lpThreadLocalBase = data.create_thread.teb; - event->u.CreateThread.lpStartAddress = data.create_thread.start; + event->u.CreateThread.hThread = data->create_thread.handle; + event->u.CreateThread.lpThreadLocalBase = data->create_thread.teb; + event->u.CreateThread.lpStartAddress = data->create_thread.start; break; case CREATE_PROCESS_DEBUG_EVENT: - event->u.CreateProcessInfo.hFile = data.create_process.file; - event->u.CreateProcessInfo.hProcess = data.create_process.process; - event->u.CreateProcessInfo.hThread = data.create_process.thread; - event->u.CreateProcessInfo.lpBaseOfImage = data.create_process.base; - event->u.CreateProcessInfo.dwDebugInfoFileOffset = data.create_process.dbg_offset; - event->u.CreateProcessInfo.nDebugInfoSize = data.create_process.dbg_size; - event->u.CreateProcessInfo.lpThreadLocalBase = data.create_process.teb; - event->u.CreateProcessInfo.lpStartAddress = data.create_process.start; - event->u.CreateProcessInfo.lpImageName = data.create_process.name; - event->u.CreateProcessInfo.fUnicode = data.create_process.unicode; - if (data.create_process.file == -1) event->u.CreateProcessInfo.hFile = 0; + event->u.CreateProcessInfo.hFile = data->create_process.file; + event->u.CreateProcessInfo.hProcess = data->create_process.process; + event->u.CreateProcessInfo.hThread = data->create_process.thread; + event->u.CreateProcessInfo.lpBaseOfImage = data->create_process.base; + event->u.CreateProcessInfo.dwDebugInfoFileOffset = data->create_process.dbg_offset; + event->u.CreateProcessInfo.nDebugInfoSize = data->create_process.dbg_size; + event->u.CreateProcessInfo.lpThreadLocalBase = data->create_process.teb; + event->u.CreateProcessInfo.lpStartAddress = data->create_process.start; + event->u.CreateProcessInfo.lpImageName = data->create_process.name; + event->u.CreateProcessInfo.fUnicode = data->create_process.unicode; + if (data->create_process.file == -1) event->u.CreateProcessInfo.hFile = 0; break; case EXIT_THREAD_DEBUG_EVENT: - event->u.ExitThread.dwExitCode = data.exit.exit_code; + event->u.ExitThread.dwExitCode = data->exit.exit_code; break; case EXIT_PROCESS_DEBUG_EVENT: - event->u.ExitProcess.dwExitCode = data.exit.exit_code; + event->u.ExitProcess.dwExitCode = data->exit.exit_code; break; case LOAD_DLL_DEBUG_EVENT: - event->u.LoadDll.hFile = data.load_dll.handle; - event->u.LoadDll.lpBaseOfDll = data.load_dll.base; - event->u.LoadDll.dwDebugInfoFileOffset = data.load_dll.dbg_offset; - event->u.LoadDll.nDebugInfoSize = data.load_dll.dbg_size; - event->u.LoadDll.lpImageName = data.load_dll.name; - event->u.LoadDll.fUnicode = data.load_dll.unicode; - if (data.load_dll.handle == -1) event->u.LoadDll.hFile = 0; + event->u.LoadDll.hFile = data->load_dll.handle; + event->u.LoadDll.lpBaseOfDll = data->load_dll.base; + event->u.LoadDll.dwDebugInfoFileOffset = data->load_dll.dbg_offset; + event->u.LoadDll.nDebugInfoSize = data->load_dll.dbg_size; + event->u.LoadDll.lpImageName = data->load_dll.name; + event->u.LoadDll.fUnicode = data->load_dll.unicode; + if (data->load_dll.handle == -1) event->u.LoadDll.hFile = 0; break; case UNLOAD_DLL_DEBUG_EVENT: - event->u.UnloadDll.lpBaseOfDll = data.unload_dll.base; + event->u.UnloadDll.lpBaseOfDll = data->unload_dll.base; break; case OUTPUT_DEBUG_STRING_EVENT: - event->u.DebugString.lpDebugStringData = data.output_string.string; - event->u.DebugString.fUnicode = data.output_string.unicode; - event->u.DebugString.nDebugStringLength = data.output_string.length; + event->u.DebugString.lpDebugStringData = data->output_string.string; + event->u.DebugString.fUnicode = data->output_string.unicode; + event->u.DebugString.nDebugStringLength = data->output_string.length; break; case RIP_EVENT: - event->u.RipInfo.dwError = data.rip_info.error; - event->u.RipInfo.dwType = data.rip_info.type; + event->u.RipInfo.dwError = data->rip_info.error; + event->u.RipInfo.dwType = data->rip_info.type; break; } return TRUE; @@ -234,13 +213,11 @@ BOOL WINAPI WaitForDebugEvent( LPDEBUG_EVENT event, DWORD timeout ) */ BOOL WINAPI ContinueDebugEvent( DWORD pid, DWORD tid, DWORD status ) { - struct continue_debug_event_request req; - - req.pid = (void *)pid; - req.tid = (void *)tid; - req.status = status; - CLIENT_SendRequest( REQ_CONTINUE_DEBUG_EVENT, -1, 1, &req, sizeof(req) ); - return !CLIENT_WaitReply( NULL, NULL, 0 ); + struct continue_debug_event_request *req = get_req_buffer(); + req->pid = (void *)pid; + req->tid = (void *)tid; + req->status = status; + return !server_call( REQ_CONTINUE_DEBUG_EVENT ); } @@ -249,10 +226,9 @@ BOOL WINAPI ContinueDebugEvent( DWORD pid, DWORD tid, DWORD status ) */ BOOL WINAPI DebugActiveProcess( DWORD pid ) { - struct debug_process_request req; - req.pid = (void *)pid; - CLIENT_SendRequest( REQ_DEBUG_PROCESS, -1, 1, &req, sizeof(req) ); - return !CLIENT_WaitReply( NULL, NULL, 0 ); + struct debug_process_request *req = get_req_buffer(); + req->pid = (void *)pid; + return !server_call( REQ_DEBUG_PROCESS ); } diff --git a/scheduler/event.c b/scheduler/event.c index a145c766ac9..9c37bc34494 100644 --- a/scheduler/event.c +++ b/scheduler/event.c @@ -18,18 +18,16 @@ HANDLE WINAPI CreateEventA( SECURITY_ATTRIBUTES *sa, BOOL manual_reset, BOOL initial_state, LPCSTR name ) { - struct create_event_request req; - struct create_event_reply reply; + struct create_event_request *req = get_req_buffer(); - if (!name) name = ""; - req.manual_reset = manual_reset; - req.initial_state = initial_state; - req.inherit = (sa && (sa->nLength>=sizeof(*sa)) && sa->bInheritHandle); - CLIENT_SendRequest( REQ_CREATE_EVENT, -1, 2, &req, sizeof(req), name, strlen(name)+1 ); + req->manual_reset = manual_reset; + req->initial_state = initial_state; + req->inherit = (sa && (sa->nLength>=sizeof(*sa)) && sa->bInheritHandle); + lstrcpynA( req->name, name ? name : "", server_remaining(req->name) ); SetLastError(0); - CLIENT_WaitSimpleReply( &reply, sizeof(reply), NULL ); - if (reply.handle == -1) return 0; - return reply.handle; + server_call( REQ_CREATE_EVENT ); + if (req->handle == -1) return 0; + return req->handle; } @@ -59,16 +57,14 @@ HANDLE WINAPI WIN16_CreateEvent( BOOL manual_reset, BOOL initial_state ) */ HANDLE WINAPI OpenEventA( DWORD access, BOOL inherit, LPCSTR name ) { - struct open_event_request req; - struct open_event_reply reply; - int len = name ? strlen(name) + 1 : 0; + struct open_event_request *req = get_req_buffer(); - req.access = access; - req.inherit = inherit; - CLIENT_SendRequest( REQ_OPEN_EVENT, -1, 2, &req, sizeof(req), name, len ); - CLIENT_WaitSimpleReply( &reply, sizeof(reply), NULL ); - if (reply.handle == -1) return 0; /* must return 0 on failure, not -1 */ - return (HANDLE)reply.handle; + req->access = access; + req->inherit = inherit; + lstrcpynA( req->name, name ? name : "", server_remaining(req->name) ); + server_call( REQ_OPEN_EVENT ); + if (req->handle == -1) return 0; /* must return 0 on failure, not -1 */ + return req->handle; } @@ -91,12 +87,10 @@ HANDLE WINAPI OpenEventW( DWORD access, BOOL inherit, LPCWSTR name ) */ static BOOL EVENT_Operation( HANDLE handle, enum event_op op ) { - struct event_op_request req; - - req.handle = handle; - req.op = op; - CLIENT_SendRequest( REQ_EVENT_OP, -1, 1, &req, sizeof(req) ); - return !CLIENT_WaitReply( NULL, NULL, 0 ); + struct event_op_request *req = get_req_buffer(); + req->handle = handle; + req->op = op; + return !server_call( REQ_EVENT_OP ); } diff --git a/scheduler/handle.c b/scheduler/handle.c index 98d9c59d9c8..8555a465fa1 100644 --- a/scheduler/handle.c +++ b/scheduler/handle.c @@ -18,11 +18,9 @@ DEFAULT_DEBUG_CHANNEL(win32) */ BOOL WINAPI CloseHandle( HANDLE handle ) { - struct close_handle_request req; - - req.handle = handle; - CLIENT_SendRequest( REQ_CLOSE_HANDLE, -1, 1, &req, sizeof(req) ); - return !CLIENT_WaitReply( NULL, NULL, 0 ); + struct close_handle_request *req = get_req_buffer(); + req->handle = handle; + return !server_call( REQ_CLOSE_HANDLE ); } @@ -31,13 +29,10 @@ BOOL WINAPI CloseHandle( HANDLE handle ) */ BOOL WINAPI GetHandleInformation( HANDLE handle, LPDWORD flags ) { - struct get_handle_info_request req; - struct get_handle_info_reply reply; - - req.handle = handle; - CLIENT_SendRequest( REQ_GET_HANDLE_INFO, -1, 1, &req, sizeof(req) ); - if (CLIENT_WaitSimpleReply( &reply, sizeof(reply), NULL )) return FALSE; - if (flags) *flags = reply.flags; + struct get_handle_info_request *req = get_req_buffer(); + req->handle = handle; + if (server_call( REQ_GET_HANDLE_INFO )) return FALSE; + if (flags) *flags = req->flags; return TRUE; } @@ -47,13 +42,11 @@ BOOL WINAPI GetHandleInformation( HANDLE handle, LPDWORD flags ) */ BOOL WINAPI SetHandleInformation( HANDLE handle, DWORD mask, DWORD flags ) { - struct set_handle_info_request req; - - req.handle = handle; - req.flags = flags; - req.mask = mask; - CLIENT_SendRequest( REQ_SET_HANDLE_INFO, -1, 1, &req, sizeof(req) ); - return !CLIENT_WaitReply( NULL, NULL, 0 ); + struct set_handle_info_request *req = get_req_buffer(); + req->handle = handle; + req->flags = flags; + req->mask = mask; + return !server_call( REQ_SET_HANDLE_INFO ); } @@ -64,19 +57,17 @@ BOOL WINAPI DuplicateHandle( HANDLE source_process, HANDLE source, HANDLE dest_process, HANDLE *dest, DWORD access, BOOL inherit, DWORD options ) { - struct dup_handle_request req; - struct dup_handle_reply reply; + struct dup_handle_request *req = get_req_buffer(); - req.src_process = source_process; - req.src_handle = source; - req.dst_process = dest_process; - req.access = access; - req.inherit = inherit; - req.options = options; + req->src_process = source_process; + req->src_handle = source; + req->dst_process = dest_process; + req->access = access; + req->inherit = inherit; + req->options = options; - CLIENT_SendRequest( REQ_DUP_HANDLE, -1, 1, &req, sizeof(req) ); - if (CLIENT_WaitSimpleReply( &reply, sizeof(reply), NULL )) return FALSE; - if (dest) *dest = reply.handle; + if (server_call( REQ_DUP_HANDLE )) return FALSE; + if (dest) *dest = req->handle; return TRUE; } @@ -86,19 +77,17 @@ BOOL WINAPI DuplicateHandle( HANDLE source_process, HANDLE source, */ HANDLE WINAPI ConvertToGlobalHandle(HANDLE hSrc) { - struct dup_handle_request req; - struct dup_handle_reply reply; + struct dup_handle_request *req = get_req_buffer(); - req.src_process = GetCurrentProcess(); - req.src_handle = hSrc; - req.dst_process = -1; - req.access = 0; - req.inherit = FALSE; - req.options = DUP_HANDLE_MAKE_GLOBAL | DUP_HANDLE_SAME_ACCESS; + req->src_process = GetCurrentProcess(); + req->src_handle = hSrc; + req->dst_process = -1; + req->access = 0; + req->inherit = FALSE; + req->options = DUP_HANDLE_MAKE_GLOBAL | DUP_HANDLE_SAME_ACCESS; - CLIENT_SendRequest( REQ_DUP_HANDLE, -1, 1, &req, sizeof(req) ); - CLIENT_WaitSimpleReply( &reply, sizeof(reply), NULL ); - return reply.handle; + server_call( REQ_DUP_HANDLE ); + return req->handle; } /*********************************************************************** diff --git a/scheduler/mutex.c b/scheduler/mutex.c index 956749532a5..94110f1aaa6 100644 --- a/scheduler/mutex.c +++ b/scheduler/mutex.c @@ -16,17 +16,15 @@ */ HANDLE WINAPI CreateMutexA( SECURITY_ATTRIBUTES *sa, BOOL owner, LPCSTR name ) { - struct create_mutex_request req; - struct create_mutex_reply reply; + struct create_mutex_request *req = get_req_buffer(); - if (!name) name = ""; - req.owned = owner; - req.inherit = (sa && (sa->nLength>=sizeof(*sa)) && sa->bInheritHandle); - CLIENT_SendRequest( REQ_CREATE_MUTEX, -1, 2, &req, sizeof(req), name, strlen(name)+1 ); + req->owned = owner; + req->inherit = (sa && (sa->nLength>=sizeof(*sa)) && sa->bInheritHandle); + lstrcpynA( req->name, name ? name : "", server_remaining(req->name) ); SetLastError(0); - CLIENT_WaitSimpleReply( &reply, sizeof(reply), NULL ); - if (reply.handle == -1) return 0; - return reply.handle; + server_call( REQ_CREATE_MUTEX ); + if (req->handle == -1) return 0; + return req->handle; } @@ -48,16 +46,14 @@ HANDLE WINAPI CreateMutexW( SECURITY_ATTRIBUTES *sa, BOOL owner, */ HANDLE WINAPI OpenMutexA( DWORD access, BOOL inherit, LPCSTR name ) { - struct open_mutex_request req; - struct open_mutex_reply reply; - int len = name ? strlen(name) + 1 : 0; + struct open_mutex_request *req = get_req_buffer(); - req.access = access; - req.inherit = inherit; - CLIENT_SendRequest( REQ_OPEN_MUTEX, -1, 2, &req, sizeof(req), name, len ); - CLIENT_WaitSimpleReply( &reply, sizeof(reply), NULL ); - if (reply.handle == -1) return 0; /* must return 0 on failure, not -1 */ - return reply.handle; + req->access = access; + req->inherit = inherit; + lstrcpynA( req->name, name ? name : "", server_remaining(req->name) ); + server_call( REQ_OPEN_MUTEX ); + if (req->handle == -1) return 0; /* must return 0 on failure, not -1 */ + return req->handle; } @@ -78,9 +74,7 @@ HANDLE WINAPI OpenMutexW( DWORD access, BOOL inherit, LPCWSTR name ) */ BOOL WINAPI ReleaseMutex( HANDLE handle ) { - struct release_mutex_request req; - - req.handle = handle; - CLIENT_SendRequest( REQ_RELEASE_MUTEX, -1, 1, &req, sizeof(req) ); - return !CLIENT_WaitReply( NULL, NULL, 0 ); + struct release_mutex_request *req = get_req_buffer(); + req->handle = handle; + return !server_call( REQ_RELEASE_MUTEX ); } diff --git a/scheduler/pipe.c b/scheduler/pipe.c index 74fff8c58be..6b018c7a93a 100644 --- a/scheduler/pipe.c +++ b/scheduler/pipe.c @@ -16,15 +16,11 @@ BOOL WINAPI CreatePipe( PHANDLE hReadPipe, PHANDLE hWritePipe, LPSECURITY_ATTRIBUTES sa, DWORD size ) { - struct create_pipe_request req; - struct create_pipe_reply reply; - int len; + struct create_pipe_request *req = get_req_buffer(); - req.inherit = (sa && (sa->nLength>=sizeof(*sa)) && sa->bInheritHandle); - CLIENT_SendRequest( REQ_CREATE_PIPE, -1, 1, &req, sizeof(req) ); - if (CLIENT_WaitReply( &len, NULL, 1, &reply, sizeof(reply) ) != ERROR_SUCCESS) - return FALSE; - *hReadPipe = reply.handle_read; - *hWritePipe = reply.handle_write; + req->inherit = (sa && (sa->nLength>=sizeof(*sa)) && sa->bInheritHandle); + if (server_call( REQ_CREATE_PIPE )) return FALSE; + *hReadPipe = req->handle_read; + *hWritePipe = req->handle_write; return TRUE; } diff --git a/scheduler/process.c b/scheduler/process.c index 20d2737de39..70cc70921da 100644 --- a/scheduler/process.c +++ b/scheduler/process.c @@ -73,20 +73,6 @@ PDB *PROCESS_Initial(void) return &initial_pdb; } -/*********************************************************************** - * PROCESS_QueryInfo - * - * Retrieve information about a process - */ -static BOOL PROCESS_QueryInfo( HANDLE handle, - struct get_process_info_reply *reply ) -{ - struct get_process_info_request req; - req.handle = handle; - CLIENT_SendRequest( REQ_GET_PROCESS_INFO, -1, 1, &req, sizeof(req) ); - return !CLIENT_WaitSimpleReply( reply, sizeof(*reply), NULL ); -} - /*********************************************************************** * PROCESS_IsCurrent * @@ -94,9 +80,10 @@ static BOOL PROCESS_QueryInfo( HANDLE handle, */ BOOL PROCESS_IsCurrent( HANDLE handle ) { - struct get_process_info_reply reply; - return (PROCESS_QueryInfo( handle, &reply ) && - (reply.pid == PROCESS_Current()->server_pid)); + struct get_process_info_request *req = get_req_buffer(); + req->handle = handle; + return (!server_call( REQ_GET_PROCESS_INFO ) && + (req->pid == PROCESS_Current()->server_pid)); } @@ -252,21 +239,12 @@ void PROCESS_CallUserSignalProc( UINT uCode, HMODULE hModule ) */ static BOOL PROCESS_CreateEnvDB(void) { - struct init_process_request req; - struct init_process_reply reply; + struct init_process_request *req = get_req_buffer(); STARTUPINFOA *startup; ENVDB *env_db; char cmd_line[4096]; - int len; PDB *pdb = PROCESS_Current(); - /* Retrieve startup info from the server */ - - req.dummy = 0; - CLIENT_SendRequest( REQ_INIT_PROCESS, -1, 1, &req, sizeof(req) ); - if (CLIENT_WaitReply( &len, NULL, 2, &reply, sizeof(reply), cmd_line, sizeof(cmd_line) )) - return FALSE; - /* Allocate the env DB */ if (!(env_db = HeapAlloc( pdb->heap, HEAP_ZERO_MEMORY, sizeof(ENVDB) ))) @@ -278,15 +256,20 @@ static BOOL PROCESS_CreateEnvDB(void) if (!(startup = HeapAlloc( pdb->heap, HEAP_ZERO_MEMORY, sizeof(STARTUPINFOA) ))) return FALSE; env_db->startup_info = startup; - startup->dwFlags = reply.start_flags; - startup->wShowWindow = reply.cmd_show; - env_db->hStdin = startup->hStdInput = reply.hstdin; - env_db->hStdout = startup->hStdOutput = reply.hstdout; - env_db->hStderr = startup->hStdError = reply.hstderr; + + /* Retrieve startup info from the server */ + + if (server_call( REQ_INIT_PROCESS )) return FALSE; + startup->dwFlags = req->start_flags; + startup->wShowWindow = req->cmd_show; + env_db->hStdin = startup->hStdInput = req->hstdin; + env_db->hStdout = startup->hStdOutput = req->hstdout; + env_db->hStderr = startup->hStdError = req->hstderr; + lstrcpynA( cmd_line, req->cmdline, sizeof(cmd_line) ); /* Copy the parent environment */ - if (!ENV_InheritEnvironment( pdb, reply.env_ptr )) return FALSE; + if (!ENV_InheritEnvironment( pdb, req->env_ptr )) return FALSE; /* Copy the command line */ @@ -527,8 +510,7 @@ PDB *PROCESS_Create( NE_MODULE *pModule, LPCSTR cmd_line, LPCSTR env, HANDLE handles[2], load_done_evt = INVALID_HANDLE_VALUE; DWORD exitcode, size; int server_thandle; - struct new_process_request req; - struct new_process_reply reply; + struct new_process_request *req = get_req_buffer(); TEB *teb = NULL; PDB *parent = PROCESS_Current(); PDB *pdb = PROCESS_CreatePDB( parent, inherit ); @@ -538,29 +520,28 @@ PDB *PROCESS_Create( NE_MODULE *pModule, LPCSTR cmd_line, LPCSTR env, /* Create the process on the server side */ - req.inherit = (psa && (psa->nLength >= sizeof(*psa)) && psa->bInheritHandle); - req.inherit_all = inherit; - req.create_flags = flags; - req.start_flags = startup->dwFlags; + req->inherit = (psa && (psa->nLength >= sizeof(*psa)) && psa->bInheritHandle); + req->inherit_all = inherit; + req->create_flags = flags; + req->start_flags = startup->dwFlags; if (startup->dwFlags & STARTF_USESTDHANDLES) { - req.hstdin = startup->hStdInput; - req.hstdout = startup->hStdOutput; - req.hstderr = startup->hStdError; + req->hstdin = startup->hStdInput; + req->hstdout = startup->hStdOutput; + req->hstderr = startup->hStdError; } else { - req.hstdin = GetStdHandle( STD_INPUT_HANDLE ); - req.hstdout = GetStdHandle( STD_OUTPUT_HANDLE ); - req.hstderr = GetStdHandle( STD_ERROR_HANDLE ); + req->hstdin = GetStdHandle( STD_INPUT_HANDLE ); + req->hstdout = GetStdHandle( STD_OUTPUT_HANDLE ); + req->hstderr = GetStdHandle( STD_ERROR_HANDLE ); } - req.cmd_show = startup->wShowWindow; - req.env_ptr = (void*)env; /* FIXME: hack */ - CLIENT_SendRequest( REQ_NEW_PROCESS, -1, 2, - &req, sizeof(req), cmd_line, strlen(cmd_line) + 1 ); - if (CLIENT_WaitSimpleReply( &reply, sizeof(reply), NULL )) goto error; - pdb->server_pid = reply.pid; - info->hProcess = reply.handle; + req->cmd_show = startup->wShowWindow; + req->env_ptr = (void*)env; /* FIXME: hack */ + lstrcpynA( req->cmdline, cmd_line, server_remaining(req->cmdline) ); + if (server_call( REQ_NEW_PROCESS )) goto error; + pdb->server_pid = req->pid; + info->hProcess = req->handle; info->dwProcessId = (DWORD)pdb->server_pid; if ((flags & DEBUG_PROCESS) || @@ -675,11 +656,10 @@ void WINAPI ExitProcess16( WORD status ) */ BOOL WINAPI TerminateProcess( HANDLE handle, DWORD exit_code ) { - struct terminate_process_request req; - req.handle = handle; - req.exit_code = exit_code; - CLIENT_SendRequest( REQ_TERMINATE_PROCESS, -1, 1, &req, sizeof(req) ); - return !CLIENT_WaitReply( NULL, NULL, 0 ); + struct terminate_process_request *req = get_req_buffer(); + req->handle = handle; + req->exit_code = exit_code; + return !server_call( REQ_TERMINATE_PROCESS ); } @@ -816,15 +796,14 @@ HANDLE WINAPI GetCurrentProcess(void) */ HANDLE WINAPI OpenProcess( DWORD access, BOOL inherit, DWORD id ) { - struct open_process_request req; - struct open_process_reply reply; + HANDLE ret = 0; + struct open_process_request *req = get_req_buffer(); - req.pid = (void *)id; - req.access = access; - req.inherit = inherit; - CLIENT_SendRequest( REQ_OPEN_PROCESS, -1, 1, &req, sizeof(req) ); - if (CLIENT_WaitSimpleReply( &reply, sizeof(reply), NULL )) return 0; - return reply.handle; + req->pid = (void *)id; + req->access = access; + req->inherit = inherit; + if (!server_call( REQ_OPEN_PROCESS )) ret = req->handle; + return ret; } /********************************************************************* @@ -832,9 +811,11 @@ HANDLE WINAPI OpenProcess( DWORD access, BOOL inherit, DWORD id ) */ DWORD WINAPI MapProcessHandle( HANDLE handle ) { - struct get_process_info_reply reply; - if ( !PROCESS_QueryInfo( handle, &reply ) ) return 0; - return (DWORD)reply.pid; + DWORD ret = 0; + struct get_process_info_request *req = get_req_buffer(); + req->handle = handle; + if (!server_call( REQ_GET_PROCESS_INFO )) ret = (DWORD)req->pid; + return ret; } /*********************************************************************** @@ -870,12 +851,11 @@ LCID WINAPI GetThreadLocale(void) */ BOOL WINAPI SetPriorityClass( HANDLE hprocess, DWORD priorityclass ) { - struct set_process_info_request req; - req.handle = hprocess; - req.priority = priorityclass; - req.mask = SET_PROCESS_INFO_PRIORITY; - CLIENT_SendRequest( REQ_SET_PROCESS_INFO, -1, 1, &req, sizeof(req) ); - return !CLIENT_WaitReply( NULL, NULL, 0 ); + struct set_process_info_request *req = get_req_buffer(); + req->handle = hprocess; + req->priority = priorityclass; + req->mask = SET_PROCESS_INFO_PRIORITY; + return !server_call( REQ_SET_PROCESS_INFO ); } @@ -884,9 +864,11 @@ BOOL WINAPI SetPriorityClass( HANDLE hprocess, DWORD priorityclass ) */ DWORD WINAPI GetPriorityClass(HANDLE hprocess) { - struct get_process_info_reply reply; - if (!PROCESS_QueryInfo( hprocess, &reply )) return 0; - return reply.priority; + DWORD ret = 0; + struct get_process_info_request *req = get_req_buffer(); + req->handle = hprocess; + if (!server_call( REQ_GET_PROCESS_INFO )) ret = req->priority; + return ret; } @@ -895,12 +877,11 @@ DWORD WINAPI GetPriorityClass(HANDLE hprocess) */ BOOL WINAPI SetProcessAffinityMask( HANDLE hProcess, DWORD affmask ) { - struct set_process_info_request req; - req.handle = hProcess; - req.affinity = affmask; - req.mask = SET_PROCESS_INFO_AFFINITY; - CLIENT_SendRequest( REQ_SET_PROCESS_INFO, -1, 1, &req, sizeof(req) ); - return !CLIENT_WaitReply( NULL, NULL, 0 ); + struct set_process_info_request *req = get_req_buffer(); + req->handle = hProcess; + req->affinity = affmask; + req->mask = SET_PROCESS_INFO_AFFINITY; + return !server_call( REQ_SET_PROCESS_INFO ); } /********************************************************************** @@ -910,11 +891,16 @@ BOOL WINAPI GetProcessAffinityMask( HANDLE hProcess, LPDWORD lpProcessAffinityMask, LPDWORD lpSystemAffinityMask ) { - struct get_process_info_reply reply; - if (!PROCESS_QueryInfo( hProcess, &reply )) return FALSE; - if (lpProcessAffinityMask) *lpProcessAffinityMask = reply.process_affinity; - if (lpSystemAffinityMask) *lpSystemAffinityMask = reply.system_affinity; - return TRUE; + BOOL ret = FALSE; + struct get_process_info_request *req = get_req_buffer(); + req->handle = hProcess; + if (!server_call( REQ_GET_PROCESS_INFO )) + { + if (lpProcessAffinityMask) *lpProcessAffinityMask = req->process_affinity; + if (lpSystemAffinityMask) *lpSystemAffinityMask = req->system_affinity; + ret = TRUE; + } + return ret; } @@ -1119,10 +1105,15 @@ BOOL WINAPI GetExitCodeProcess( HANDLE hProcess, /* [I] handle to the process */ LPDWORD lpExitCode) /* [O] address to receive termination status */ { - struct get_process_info_reply reply; - if (!PROCESS_QueryInfo( hProcess, &reply )) return FALSE; - if (lpExitCode) *lpExitCode = reply.exit_code; - return TRUE; + BOOL ret = FALSE; + struct get_process_info_request *req = get_req_buffer(); + req->handle = hProcess; + if (!server_call( REQ_GET_PROCESS_INFO )) + { + if (lpExitCode) *lpExitCode = req->exit_code; + ret = TRUE; + } + return ret; } diff --git a/scheduler/semaphore.c b/scheduler/semaphore.c index 018606be503..890efa8b1f1 100644 --- a/scheduler/semaphore.c +++ b/scheduler/semaphore.c @@ -16,8 +16,7 @@ */ HANDLE WINAPI CreateSemaphoreA( SECURITY_ATTRIBUTES *sa, LONG initial, LONG max, LPCSTR name ) { - struct create_semaphore_request req; - struct create_semaphore_reply reply; + struct create_semaphore_request *req = get_req_buffer(); /* Check parameters */ @@ -27,16 +26,14 @@ HANDLE WINAPI CreateSemaphoreA( SECURITY_ATTRIBUTES *sa, LONG initial, LONG max, return 0; } - if (!name) name = ""; - req.initial = (unsigned int)initial; - req.max = (unsigned int)max; - req.inherit = (sa && (sa->nLength>=sizeof(*sa)) && sa->bInheritHandle); - - CLIENT_SendRequest( REQ_CREATE_SEMAPHORE, -1, 2, &req, sizeof(req), name, strlen(name)+1 ); + req->initial = (unsigned int)initial; + req->max = (unsigned int)max; + req->inherit = (sa && (sa->nLength>=sizeof(*sa)) && sa->bInheritHandle); + lstrcpynA( req->name, name ? name : "", server_remaining(req->name) ); SetLastError(0); - CLIENT_WaitSimpleReply( &reply, sizeof(reply), NULL ); - if (reply.handle == -1) return 0; - return reply.handle; + server_call( REQ_CREATE_SEMAPHORE ); + if (req->handle == -1) return 0; + return req->handle; } @@ -58,16 +55,14 @@ HANDLE WINAPI CreateSemaphoreW( SECURITY_ATTRIBUTES *sa, LONG initial, */ HANDLE WINAPI OpenSemaphoreA( DWORD access, BOOL inherit, LPCSTR name ) { - struct open_semaphore_request req; - struct open_semaphore_reply reply; - int len = name ? strlen(name) + 1 : 0; + struct open_semaphore_request *req = get_req_buffer(); - req.access = access; - req.inherit = inherit; - CLIENT_SendRequest( REQ_OPEN_SEMAPHORE, -1, 2, &req, sizeof(req), name, len ); - CLIENT_WaitSimpleReply( &reply, sizeof(reply), NULL ); - if (reply.handle == -1) return 0; /* must return 0 on failure, not -1 */ - return reply.handle; + req->access = access; + req->inherit = inherit; + lstrcpynA( req->name, name ? name : "", server_remaining(req->name) ); + server_call( REQ_OPEN_SEMAPHORE ); + if (req->handle == -1) return 0; /* must return 0 on failure, not -1 */ + return req->handle; } @@ -88,18 +83,16 @@ HANDLE WINAPI OpenSemaphoreW( DWORD access, BOOL inherit, LPCWSTR name ) */ BOOL WINAPI ReleaseSemaphore( HANDLE handle, LONG count, LONG *previous ) { - struct release_semaphore_request req; - struct release_semaphore_reply reply; + struct release_semaphore_request *req = get_req_buffer(); if (count < 0) { SetLastError( ERROR_INVALID_PARAMETER ); return FALSE; } - req.handle = handle; - req.count = (unsigned int)count; - CLIENT_SendRequest( REQ_RELEASE_SEMAPHORE, -1, 1, &req, sizeof(req) ); - if (CLIENT_WaitSimpleReply( &reply, sizeof(reply), NULL )) return FALSE; - if (previous) *previous = reply.prev_count; + req->handle = handle; + req->count = (unsigned int)count; + if (server_call( REQ_RELEASE_SEMAPHORE )) return FALSE; + if (previous) *previous = req->prev_count; return TRUE; } diff --git a/scheduler/synchro.c b/scheduler/synchro.c index 550465621fb..7c57e516881 100644 --- a/scheduler/synchro.c +++ b/scheduler/synchro.c @@ -17,6 +17,27 @@ #include "x11drv.h" #include "server.h" +/*********************************************************************** + * call_apcs + * + * Call outstanding APCs. + */ +static void call_apcs(void) +{ +#define MAX_APCS 16 + int i; + void *buffer[MAX_APCS * 2]; + struct get_apcs_request *req = get_req_buffer(); + + if (server_call( REQ_GET_APCS ) || !req->count) return; + assert( req->count <= MAX_APCS ); + memcpy( buffer, req->apcs, req->count * 2 * sizeof(req->apcs[0]) ); + for (i = 0; i < req->count * 2; i += 2) + { + PAPCFUNC func = (PAPCFUNC)req->apcs[i]; + if (func) func( (ULONG_PTR)req->apcs[i+1] ); + } +} /*********************************************************************** * Sleep (KERNEL32.679) @@ -73,11 +94,8 @@ DWORD WINAPI WaitForMultipleObjectsEx( DWORD count, const HANDLE *handles, BOOL wait_all, DWORD timeout, BOOL alertable ) { - struct select_request req; - struct select_reply reply; - int server_handle[MAXIMUM_WAIT_OBJECTS]; - void *apc[32]; - int i, len; + struct select_request *req = get_req_buffer(); + int i, ret; if (count > MAXIMUM_WAIT_OBJECTS) { @@ -99,32 +117,18 @@ DWORD WINAPI WaitForMultipleObjectsEx( DWORD count, const HANDLE *handles, EVENT_Synchronize( FALSE ); } - for (i = 0; i < count; i++) server_handle[i] = handles[i]; + req->count = count; + req->flags = 0; + req->timeout = timeout; + for (i = 0; i < count; i++) req->handles[i] = handles[i]; - req.count = count; - req.flags = 0; - req.timeout = timeout; + if (wait_all) req->flags |= SELECT_ALL; + if (alertable) req->flags |= SELECT_ALERTABLE; + if (timeout != INFINITE) req->flags |= SELECT_TIMEOUT; - if (wait_all) req.flags |= SELECT_ALL; - if (alertable) req.flags |= SELECT_ALERTABLE; - if (timeout != INFINITE) req.flags |= SELECT_TIMEOUT; - - CLIENT_SendRequest( REQ_SELECT, -1, 2, - &req, sizeof(req), - server_handle, count * sizeof(int) ); - CLIENT_WaitReply( &len, NULL, 2, &reply, sizeof(reply), - apc, sizeof(apc) ); - if ((reply.signaled == STATUS_USER_APC) && (len > sizeof(reply))) - { - int i; - len -= sizeof(reply); - for (i = 0; i < len / sizeof(void*); i += 2) - { - PAPCFUNC func = (PAPCFUNC)apc[i]; - if ( func ) func( (ULONG_PTR)apc[i+1] ); - } - } - return reply.signaled; + server_call( REQ_SELECT ); + if ((ret = req->signaled) == STATUS_USER_APC) call_apcs(); + return ret; } diff --git a/scheduler/thread.c b/scheduler/thread.c index 7a5b9deccbd..62e4dc77e96 100644 --- a/scheduler/thread.c +++ b/scheduler/thread.c @@ -199,8 +199,7 @@ TEB *THREAD_CreateInitialThread( PDB *pdb, int server_fd ) TEB *THREAD_Create( PDB *pdb, DWORD flags, DWORD stack_size, BOOL alloc_stack16, LPSECURITY_ATTRIBUTES sa, int *server_handle ) { - struct new_thread_request request; - struct new_thread_reply reply = { NULL, -1 }; + struct new_thread_request *req = get_req_buffer(); int fd[2]; HANDLE cleanup_object; @@ -217,6 +216,7 @@ TEB *THREAD_Create( PDB *pdb, DWORD flags, DWORD stack_size, BOOL alloc_stack16, /* Allocate the TEB selector (%fs register) */ + *server_handle = -1; teb->teb_sel = SELECTOR_AllocBlock( teb, 0x1000, SEGMENT_DATA, TRUE, FALSE ); if (!teb->teb_sel) goto error; @@ -232,13 +232,12 @@ TEB *THREAD_Create( PDB *pdb, DWORD flags, DWORD stack_size, BOOL alloc_stack16, /* Create the thread on the server side */ - request.pid = teb->process->server_pid; - request.suspend = ((flags & CREATE_SUSPENDED) != 0); - request.inherit = (sa && (sa->nLength>=sizeof(*sa)) && sa->bInheritHandle); - CLIENT_SendRequest( REQ_NEW_THREAD, fd[1], 1, &request, sizeof(request) ); - if (CLIENT_WaitSimpleReply( &reply, sizeof(reply), NULL )) goto error; - teb->tid = reply.tid; - *server_handle = reply.handle; + req->pid = teb->process->server_pid; + req->suspend = ((flags & CREATE_SUSPENDED) != 0); + req->inherit = (sa && (sa->nLength>=sizeof(*sa)) && sa->bInheritHandle); + if (server_call_fd( REQ_NEW_THREAD, fd[1], NULL )) goto error; + teb->tid = req->tid; + *server_handle = req->handle; /* Do the rest of the initialization */ @@ -255,7 +254,7 @@ TEB *THREAD_Create( PDB *pdb, DWORD flags, DWORD stack_size, BOOL alloc_stack16, return teb; error: - if (reply.handle != -1) CloseHandle( reply.handle ); + if (*server_handle != -1) CloseHandle( *server_handle ); if (teb->teb_sel) SELECTOR_FreeBlock( teb->teb_sel, 1 ); if (teb->socket != -1) close( teb->socket ); HeapFree( SystemHeap, 0, teb ); @@ -532,13 +531,11 @@ BOOL WINAPI GetThreadContext( INT WINAPI GetThreadPriority( HANDLE hthread) /* [in] Handle to thread */ { - struct get_thread_info_request req; - struct get_thread_info_reply reply; - req.handle = hthread; - CLIENT_SendRequest( REQ_GET_THREAD_INFO, -1, 1, &req, sizeof(req) ); - if (CLIENT_WaitSimpleReply( &reply, sizeof(reply), NULL )) - return THREAD_PRIORITY_ERROR_RETURN; - return reply.priority; + INT ret = THREAD_PRIORITY_ERROR_RETURN; + struct get_thread_info_request *req = get_req_buffer(); + req->handle = hthread; + if (!server_call( REQ_GET_THREAD_INFO )) ret = req->priority; + return ret; } @@ -553,12 +550,11 @@ BOOL WINAPI SetThreadPriority( HANDLE hthread, /* [in] Handle to thread */ INT priority) /* [in] Thread priority level */ { - struct set_thread_info_request req; - req.handle = hthread; - req.priority = priority; - req.mask = SET_THREAD_INFO_PRIORITY; - CLIENT_SendRequest( REQ_SET_THREAD_INFO, -1, 1, &req, sizeof(req) ); - return !CLIENT_WaitReply( NULL, NULL, 0 ); + struct set_thread_info_request *req = get_req_buffer(); + req->handle = hthread; + req->priority = priority; + req->mask = SET_THREAD_INFO_PRIORITY; + return !server_call( REQ_SET_THREAD_INFO ); } @@ -567,12 +563,11 @@ BOOL WINAPI SetThreadPriority( */ DWORD WINAPI SetThreadAffinityMask( HANDLE hThread, DWORD dwThreadAffinityMask ) { - struct set_thread_info_request req; - req.handle = hThread; - req.affinity = dwThreadAffinityMask; - req.mask = SET_THREAD_INFO_AFFINITY; - CLIENT_SendRequest( REQ_SET_THREAD_INFO, -1, 1, &req, sizeof(req) ); - if (CLIENT_WaitReply( NULL, NULL, 0 )) return 0; + struct set_thread_info_request *req = get_req_buffer(); + req->handle = hThread; + req->affinity = dwThreadAffinityMask; + req->mask = SET_THREAD_INFO_AFFINITY; + if (server_call( REQ_SET_THREAD_INFO )) return 0; return 1; /* FIXME: should return previous value */ } @@ -588,11 +583,10 @@ BOOL WINAPI TerminateThread( HANDLE handle, /* [in] Handle to thread */ DWORD exitcode) /* [in] Exit code for thread */ { - struct terminate_thread_request req; - req.handle = handle; - req.exit_code = exitcode; - CLIENT_SendRequest( REQ_TERMINATE_THREAD, -1, 1, &req, sizeof(req) ); - return !CLIENT_WaitReply( NULL, NULL, 0 ); + struct terminate_thread_request *req = get_req_buffer(); + req->handle = handle; + req->exit_code = exitcode; + return !server_call( REQ_TERMINATE_THREAD ); } @@ -607,13 +601,15 @@ BOOL WINAPI GetExitCodeThread( HANDLE hthread, /* [in] Handle to thread */ LPDWORD exitcode) /* [out] Address to receive termination status */ { - struct get_thread_info_request req; - struct get_thread_info_reply reply; - req.handle = hthread; - CLIENT_SendRequest( REQ_GET_THREAD_INFO, -1, 1, &req, sizeof(req) ); - if (CLIENT_WaitSimpleReply( &reply, sizeof(reply), NULL )) return FALSE; - if (exitcode) *exitcode = reply.exit_code; - return TRUE; + BOOL ret = FALSE; + struct get_thread_info_request *req = get_req_buffer(); + req->handle = hthread; + if (!server_call( REQ_GET_THREAD_INFO )) + { + if (exitcode) *exitcode = req->exit_code; + ret = TRUE; + } + return ret; } @@ -631,12 +627,11 @@ BOOL WINAPI GetExitCodeThread( DWORD WINAPI ResumeThread( HANDLE hthread) /* [in] Identifies thread to restart */ { - struct resume_thread_request req; - struct resume_thread_reply reply; - req.handle = hthread; - CLIENT_SendRequest( REQ_RESUME_THREAD, -1, 1, &req, sizeof(req) ); - if (CLIENT_WaitSimpleReply( &reply, sizeof(reply), NULL )) return 0xffffffff; - return reply.count; + DWORD ret = 0xffffffff; + struct resume_thread_request *req = get_req_buffer(); + req->handle = hthread; + if (!server_call( REQ_RESUME_THREAD )) ret = req->count; + return ret; } @@ -650,12 +645,11 @@ DWORD WINAPI ResumeThread( DWORD WINAPI SuspendThread( HANDLE hthread) /* [in] Handle to the thread */ { - struct suspend_thread_request req; - struct suspend_thread_reply reply; - req.handle = hthread; - CLIENT_SendRequest( REQ_SUSPEND_THREAD, -1, 1, &req, sizeof(req) ); - if (CLIENT_WaitSimpleReply( &reply, sizeof(reply), NULL )) return 0xffffffff; - return reply.count; + DWORD ret = 0xffffffff; + struct suspend_thread_request *req = get_req_buffer(); + req->handle = hthread; + if (!server_call( REQ_SUSPEND_THREAD )) ret = req->count; + return ret; } @@ -664,12 +658,11 @@ DWORD WINAPI SuspendThread( */ DWORD WINAPI QueueUserAPC( PAPCFUNC func, HANDLE hthread, ULONG_PTR data ) { - struct queue_apc_request req; - req.handle = hthread; - req.func = func; - req.param = (void *)data; - CLIENT_SendRequest( REQ_QUEUE_APC, -1, 1, &req, sizeof(req) ); - return !CLIENT_WaitReply( NULL, NULL, 0 ); + struct queue_apc_request *req = get_req_buffer(); + req->handle = hthread; + req->func = func; + req->param = (void *)data; + return !server_call( REQ_QUEUE_APC ); } diff --git a/server/change.c b/server/change.c index fb1f0cb4ac7..50f193eded7 100644 --- a/server/change.c +++ b/server/change.c @@ -41,13 +41,15 @@ static const struct object_ops change_ops = }; -static struct object *create_change_notification( int subtree, int filter ) +static struct change *create_change_notification( int subtree, int filter ) { struct change *change; - if (!(change = alloc_object( &change_ops ))) return NULL; - change->subtree = subtree; - change->filter = filter; - return &change->obj; + if ((change = alloc_object( &change_ops ))) + { + change->subtree = subtree; + change->filter = filter; + } + return change; } static void change_dump( struct object *obj, int verbose ) @@ -68,13 +70,13 @@ static int change_signaled( struct object *obj, struct thread *thread ) /* create a change notification */ DECL_HANDLER(create_change_notification) { - struct object *obj; - struct create_change_notification_reply *reply = push_reply_data( current, sizeof(*reply) ); + struct change *change; - if ((obj = create_change_notification( req->subtree, req->filter ))) + req->handle = -1; + if ((change = create_change_notification( req->subtree, req->filter ))) { - reply->handle = alloc_handle( current->process, obj, - STANDARD_RIGHTS_REQUIRED|SYNCHRONIZE, 0 ); - release_object( obj ); + req->handle = alloc_handle( current->process, change, + STANDARD_RIGHTS_REQUIRED|SYNCHRONIZE, 0 ); + release_object( change ); } } diff --git a/server/console.c b/server/console.c index a4792b82197..4790f90139b 100644 --- a/server/console.c +++ b/server/console.c @@ -69,7 +69,7 @@ static int screen_buffer_get_write_fd( struct object *obj ); static void screen_buffer_destroy( struct object *obj ); /* common routine */ -static int console_get_info( struct object *obj, struct get_file_info_reply *reply ); +static int console_get_info( struct object *obj, struct get_file_info_request *req ); static const struct object_ops console_input_ops = { @@ -183,12 +183,11 @@ int free_console( struct process *process ) return 1; } -static int set_console_fd( int handle, int fd, int pid ) +static int set_console_fd( int handle, int fd_in, int fd_out, int pid ) { struct console_input *input; struct screen_buffer *output; struct object *obj; - int fd_in, fd_out; if (!(obj = get_handle_obj( current->process, handle, 0, NULL ))) return 0; @@ -215,21 +214,6 @@ static int set_console_fd( int handle, int fd, int pid ) assert( !input->obj.head ); assert( !output->obj.head ); - if ((fd_in = dup(fd)) == -1) - { - file_set_error(); - release_object( input ); - release_object( output ); - return 0; - } - if ((fd_out = dup(fd)) == -1) - { - file_set_error(); - close( fd_in ); - release_object( input ); - release_object( output ); - return 0; - } unregister_select_user( &input->select ); unregister_select_user( &output->select ); close( input->select.fd ); @@ -244,25 +228,21 @@ static int set_console_fd( int handle, int fd, int pid ) return 1; } -static int get_console_mode( int handle, int *mode ) +static int get_console_mode( int handle ) { struct object *obj; int ret = 0; - if (!(obj = get_handle_obj( current->process, handle, GENERIC_READ, NULL ))) - return 0; - if (obj->ops == &console_input_ops) + if ((obj = get_handle_obj( current->process, handle, GENERIC_READ, NULL ))) { - *mode = ((struct console_input *)obj)->mode; - ret = 1; + if (obj->ops == &console_input_ops) + ret = ((struct console_input *)obj)->mode; + else if (obj->ops == &screen_buffer_ops) + ret = ((struct screen_buffer *)obj)->mode; + else + set_error( ERROR_INVALID_HANDLE ); + release_object( obj ); } - else if (obj->ops == &screen_buffer_ops) - { - *mode = ((struct screen_buffer *)obj)->mode; - ret = 1; - } - else set_error( ERROR_INVALID_HANDLE ); - release_object( obj ); return ret; } @@ -316,21 +296,6 @@ static int set_console_info( int handle, struct set_console_info_request *req, return 1; } -/* get misc console information (output handle only) */ -static int get_console_info( int handle, struct get_console_info_reply *reply, const char **title ) -{ - struct screen_buffer *console; - if (!(console = (struct screen_buffer *)get_handle_obj( current->process, handle, - GENERIC_READ, &screen_buffer_ops ))) - return 0; - reply->cursor_size = console->cursor_size; - reply->cursor_visible = console->cursor_visible; - reply->pid = console->pid; - *title = console->title; - release_object( console ); - return 1; -} - /* add input events to a console input queue */ static int write_console_input( int handle, int count, INPUT_RECORD *records ) { @@ -355,16 +320,16 @@ static int write_console_input( int handle, int count, INPUT_RECORD *records ) } /* retrieve a pointer to the console input records */ -static int read_console_input( int handle, int count, int flush ) +static int read_console_input( int handle, int count, INPUT_RECORD *rec, int max, int flush ) { struct console_input *console; - struct read_console_input_reply *reply = push_reply_data( current, sizeof(*reply) ); if (!(console = (struct console_input *)get_handle_obj( current->process, handle, GENERIC_READ, &console_input_ops ))) return -1; if ((count < 0) || (count > console->recnum)) count = console->recnum; - add_reply_data( current, console->records, count * sizeof(INPUT_RECORD) ); + if (count > max) count = max; + memcpy( rec, console->records, count * sizeof(INPUT_RECORD) ); if (flush) { int i; @@ -440,10 +405,18 @@ static int console_input_get_read_fd( struct object *obj ) return dup( console->select.fd ); } -static int console_get_info( struct object *obj, struct get_file_info_reply *reply ) +static int console_get_info( struct object *obj, struct get_file_info_request *req ) { - memset( reply, 0, sizeof(*reply) ); - reply->type = FILE_TYPE_CHAR; + req->type = FILE_TYPE_CHAR; + req->attr = 0; + req->access_time = 0; + req->write_time = 0; + req->size_high = 0; + req->size_low = 0; + req->links = 0; + req->index_high = 0; + req->index_low = 0; + req->serial = 0; return 1; } @@ -517,14 +490,12 @@ static void screen_buffer_destroy( struct object *obj ) unregister_select_user( &console->select ); close( console->select.fd ); if (console->input) console->input->output = NULL; - if (console->pid) kill( console->pid, SIGTERM ); if (console->title) free( console->title ); } /* allocate a console for the current process */ DECL_HANDLER(alloc_console) { - struct alloc_console_reply *reply = push_reply_data( current, sizeof(*reply) ); int in = -1, out = -1; if (!alloc_console( current->process )) goto done; @@ -541,8 +512,8 @@ DECL_HANDLER(alloc_console) free_console( current->process ); done: - reply->handle_in = in; - reply->handle_out = out; + req->handle_in = in; + req->handle_out = out; } /* free the console of the current process */ @@ -554,40 +525,61 @@ DECL_HANDLER(free_console) /* open a handle to the process console */ DECL_HANDLER(open_console) { - struct open_console_reply *reply = push_reply_data( current, sizeof(*reply) ); struct object *obj= req->output ? current->process->console_out : current->process->console_in; - if (obj) reply->handle = alloc_handle( current->process, obj, req->access, req->inherit ); + if (obj) req->handle = alloc_handle( current->process, obj, req->access, req->inherit ); else set_error( ERROR_ACCESS_DENIED ); } /* set info about a console (output only) */ DECL_HANDLER(set_console_info) { - size_t len = get_req_strlen(); - set_console_info( req->handle, req, get_req_data( len + 1 ), len ); + size_t len = get_req_strlen( req->title ); + set_console_info( req->handle, req, req->title, len ); } /* get info about a console (output only) */ DECL_HANDLER(get_console_info) { - struct get_console_info_reply *reply = push_reply_data( current, sizeof(*reply) ); - const char *title; - get_console_info( req->handle, reply, &title ); - if (title) add_reply_data( current, title, strlen(title) + 1 ); + struct screen_buffer *console; + if ((console = (struct screen_buffer *)get_handle_obj( current->process, req->handle, + GENERIC_READ, &screen_buffer_ops ))) + { + req->cursor_size = console->cursor_size; + req->cursor_visible = console->cursor_visible; + req->pid = console->pid; + strcpy( req->title, console->title ? console->title : "" ); + release_object( console ); + } } /* set a console fd */ DECL_HANDLER(set_console_fd) { - set_console_fd( req->handle, fd, req->pid ); + struct object *obj; + int fd_in, fd_out; + + if (!(obj = get_handle_obj( current->process, req->file_handle, + GENERIC_READ | GENERIC_WRITE, NULL ))) return; + if ((fd_in = obj->ops->get_read_fd( obj )) == -1) + { + release_object( obj ); + return; + } + fd_out = obj->ops->get_write_fd( obj ); + release_object( obj ); + if (fd_out != -1) + { + if (set_console_fd( req->handle, fd_in, fd_out, req->pid )) return; + close( fd_out ); + } + close( fd_in ); } /* get a console mode (input or output) */ DECL_HANDLER(get_console_mode) { - struct get_console_mode_reply *reply = push_reply_data( current, sizeof(*reply) ); - get_console_mode( req->handle, &reply->mode ); + req->mode = get_console_mode( req->handle ); } /* set a console mode (input or output) */ @@ -599,18 +591,17 @@ DECL_HANDLER(set_console_mode) /* add input records to a console input queue */ DECL_HANDLER(write_console_input) { - struct write_console_input_reply *reply = push_reply_data( current, sizeof(*reply) ); + int max = get_req_size( req + 1, sizeof(INPUT_RECORD) ); + int count = req->count; - if (check_req_data( req->count * sizeof(INPUT_RECORD))) - { - INPUT_RECORD *records = get_req_data( req->count * sizeof(INPUT_RECORD) ); - reply->written = write_console_input( req->handle, req->count, records ); - } - else fatal_protocol_error( "write_console_input: bad length" ); + if (count > max) count = max; + req->written = write_console_input( req->handle, count, (INPUT_RECORD *)(req + 1) ); } /* fetch input records from a console input queue */ DECL_HANDLER(read_console_input) { - read_console_input( req->handle, req->count, req->flush ); + int max = get_req_size( req + 1, sizeof(INPUT_RECORD) ); + req->read = read_console_input( req->handle, req->count, (INPUT_RECORD *)(req + 1), + max, req->flush ); } diff --git a/server/debugger.c b/server/debugger.c index 0181d71c89e..404206e8a23 100644 --- a/server/debugger.c +++ b/server/debugger.c @@ -146,16 +146,16 @@ static void build_event_reply( struct debug_ctx *debug_ctx ) { struct debug_event *event = debug_ctx->event_head; struct thread *thread = event->thread; - struct wait_debug_event_reply *reply = push_reply_data( debug_ctx->owner, sizeof(*reply) ); + struct wait_debug_event_request *req = get_req_ptr( debug_ctx->owner ); assert( event ); assert( debug_ctx->waiting ); unlink_event( debug_ctx, event ); event->sent = 1; - reply->code = event->code; - reply->pid = thread->process; - reply->tid = thread; + req->code = event->code; + req->pid = thread->process; + req->tid = thread; debug_ctx->waiting = 0; if (debug_ctx->timeout) { @@ -163,20 +163,20 @@ static void build_event_reply( struct debug_ctx *debug_ctx ) debug_ctx->timeout = NULL; } debug_ctx->owner->error = 0; - add_reply_data( debug_ctx->owner, &event->data, event_sizes[event->code] ); + memcpy( req + 1, &event->data, event_sizes[event->code] ); } /* timeout callback while waiting for a debug event */ static void wait_event_timeout( void *ctx ) { struct debug_ctx *debug_ctx = (struct debug_ctx *)ctx; - struct wait_debug_event_reply *reply = push_reply_data( debug_ctx->owner, sizeof(*reply) ); + struct wait_debug_event_request *req = get_req_ptr( debug_ctx->owner ); assert( debug_ctx->waiting ); - reply->code = 0; - reply->pid = 0; - reply->tid = 0; + req->code = 0; + req->pid = 0; + req->tid = 0; debug_ctx->waiting = 0; debug_ctx->timeout = NULL; debug_ctx->owner->error = WAIT_TIMEOUT; @@ -232,8 +232,8 @@ static int continue_debug_event( struct process *process, struct thread *thread, { /* only send a reply if the thread is still there */ /* (we can get a continue on an exit thread/process event) */ - struct send_debug_event_reply *reply = push_reply_data( thread, sizeof(*reply) ); - reply->status = status; + struct send_debug_event_request *req = get_req_ptr( thread ); + req->status = status; send_reply( thread ); } free_event( event ); @@ -380,10 +380,9 @@ DECL_HANDLER(wait_debug_event) { if (!wait_for_debug_event( req->timeout )) { - struct wait_debug_event_reply *reply = push_reply_data( current, sizeof(*reply) ); - reply->code = 0; - reply->pid = NULL; - reply->tid = NULL; + req->code = 0; + req->pid = NULL; + req->tid = NULL; } } @@ -423,23 +422,13 @@ DECL_HANDLER(send_debug_event) assert( !current->debug_event ); if ((req->code <= 0) || (req->code > RIP_EVENT)) { - fatal_protocol_error( "send_debug_event: bad event code" ); + fatal_protocol_error( current, "send_debug_event: bad code %d\n", req->code ); return; } - if (!check_req_data( event_sizes[req->code] )) - { - fatal_protocol_error( "send_debug_event: bad length" ); - return; - } - if (debugger && queue_debug_event( debugger, current, req->code, - get_req_data( event_sizes[req->code] ))) + req->status = 0; + if (debugger && queue_debug_event( debugger, current, req->code, req + 1 )) { /* wait for continue_debug_event */ current->state = SLEEPING; } - else - { - struct send_debug_event_reply *reply = push_reply_data( current, sizeof(*reply) ); - reply->status = 0; - } } diff --git a/server/device.c b/server/device.c index d167c67c36d..b9f488e7cb8 100644 --- a/server/device.c +++ b/server/device.c @@ -30,7 +30,7 @@ struct device }; static void device_dump( struct object *obj, int verbose ); -static int device_get_info( struct object *obj, struct get_file_info_reply *reply ); +static int device_get_info( struct object *obj, struct get_file_info_request *req ); static const struct object_ops device_ops = { @@ -64,13 +64,20 @@ static void device_dump( struct object *obj, int verbose ) fprintf( stderr, "Device id=%08x\n", dev->id ); } -static int device_get_info( struct object *obj, struct get_file_info_reply *reply ) +static int device_get_info( struct object *obj, struct get_file_info_request *req ) { struct device *dev = (struct device *)obj; assert( obj->ops == &device_ops ); - memset( reply, 0, sizeof(*reply) ); - reply->type = FILE_TYPE_UNKNOWN; - reply->attr = dev->id; /* hack! */ + req->type = FILE_TYPE_UNKNOWN; + req->attr = dev->id; /* hack! */ + req->access_time = 0; + req->write_time = 0; + req->size_high = 0; + req->size_low = 0; + req->links = 0; + req->index_high = 0; + req->index_low = 0; + req->serial = 0; return 1; } @@ -78,12 +85,11 @@ static int device_get_info( struct object *obj, struct get_file_info_reply *repl DECL_HANDLER(create_device) { struct device *dev; - struct create_device_reply *reply = push_reply_data( current, sizeof(*reply) ); + req->handle = -1; if ((dev = create_device( req->id ))) { - reply->handle = alloc_handle( current->process, dev, req->access, req->inherit ); + req->handle = alloc_handle( current->process, dev, req->access, req->inherit ); release_object( dev ); } - else reply->handle = -1; } diff --git a/server/event.c b/server/event.c index 4d3ee7e5aa1..81d4ba70ec2 100644 --- a/server/event.c +++ b/server/event.c @@ -128,25 +128,22 @@ static int event_satisfied( struct object *obj, struct thread *thread ) /* create an event */ DECL_HANDLER(create_event) { - size_t len = get_req_strlen(); - struct create_event_reply *reply = push_reply_data( current, sizeof(*reply) ); + size_t len = get_req_strlen( req->name ); struct event *event; - if ((event = create_event( get_req_data(len+1), len, req->manual_reset, req->initial_state ))) + req->handle = -1; + if ((event = create_event( req->name, len, req->manual_reset, req->initial_state ))) { - reply->handle = alloc_handle( current->process, event, EVENT_ALL_ACCESS, req->inherit ); + req->handle = alloc_handle( current->process, event, EVENT_ALL_ACCESS, req->inherit ); release_object( event ); } - else reply->handle = -1; } /* open a handle to an event */ DECL_HANDLER(open_event) { - size_t len = get_req_strlen(); - struct open_event_reply *reply = push_reply_data( current, sizeof(*reply) ); - reply->handle = open_object( get_req_data( len + 1 ), len, &event_ops, - req->access, req->inherit ); + size_t len = get_req_strlen( req->name ); + req->handle = open_object( req->name, len, &event_ops, req->access, req->inherit ); } /* do an event operation */ @@ -164,6 +161,6 @@ DECL_HANDLER(event_op) reset_event( req->handle ); break; default: - fatal_protocol_error( "event_op: invalid operation" ); + fatal_protocol_error( current, "event_op: invalid operation %d\n", req->op ); } } diff --git a/server/file.c b/server/file.c index 8e9fd802e80..4b0feae28c9 100644 --- a/server/file.c +++ b/server/file.c @@ -47,7 +47,7 @@ static int file_signaled( struct object *obj, struct thread *thread ); static int file_get_read_fd( struct object *obj ); static int file_get_write_fd( struct object *obj ); static int file_flush( struct object *obj ); -static int file_get_info( struct object *obj, struct get_file_info_reply *reply ); +static int file_get_info( struct object *obj, struct get_file_info_request *req ); static void file_destroy( struct object *obj ); static const struct object_ops file_ops = @@ -208,7 +208,7 @@ struct file *create_temp_file( int access ) struct file *file; int fd; - if ((fd = create_anonymous_file()) != -1) return NULL; + if ((fd = create_anonymous_file()) == -1) return NULL; if (!(file = create_file_for_fd( fd, access, 0, 0 ))) close( fd ); return file; } @@ -295,7 +295,7 @@ static int file_flush( struct object *obj ) return ret; } -static int file_get_info( struct object *obj, struct get_file_info_reply *reply ) +static int file_get_info( struct object *obj, struct get_file_info_request *req ) { struct stat st; struct file *file = (struct file *)obj; @@ -307,19 +307,19 @@ static int file_get_info( struct object *obj, struct get_file_info_reply *reply return 0; } if (S_ISCHR(st.st_mode) || S_ISFIFO(st.st_mode) || - S_ISSOCK(st.st_mode) || isatty(file->select.fd)) reply->type = FILE_TYPE_CHAR; - else reply->type = FILE_TYPE_DISK; - if (S_ISDIR(st.st_mode)) reply->attr = FILE_ATTRIBUTE_DIRECTORY; - else reply->attr = FILE_ATTRIBUTE_ARCHIVE; - if (!(st.st_mode & S_IWUSR)) reply->attr |= FILE_ATTRIBUTE_READONLY; - reply->access_time = st.st_atime; - reply->write_time = st.st_mtime; - reply->size_high = 0; - reply->size_low = S_ISDIR(st.st_mode) ? 0 : st.st_size; - reply->links = st.st_nlink; - reply->index_high = st.st_dev; - reply->index_low = st.st_ino; - reply->serial = 0; /* FIXME */ + S_ISSOCK(st.st_mode) || isatty(file->select.fd)) req->type = FILE_TYPE_CHAR; + else req->type = FILE_TYPE_DISK; + if (S_ISDIR(st.st_mode)) req->attr = FILE_ATTRIBUTE_DIRECTORY; + else req->attr = FILE_ATTRIBUTE_ARCHIVE; + if (!(st.st_mode & S_IWUSR)) req->attr |= FILE_ATTRIBUTE_READONLY; + req->access_time = st.st_atime; + req->write_time = st.st_mtime; + req->size_high = 0; + req->size_low = S_ISDIR(st.st_mode) ? 0 : st.st_size; + req->links = st.st_nlink; + req->index_high = st.st_dev; + req->index_low = st.st_ino; + req->serial = 0; /* FIXME */ return 1; } @@ -485,71 +485,72 @@ static int file_unlock( struct file *file, int offset_high, int offset_low, /* FIXME: implement this */ return 1; } + /* create a file */ DECL_HANDLER(create_file) { - struct create_file_reply *reply = push_reply_data( current, sizeof(*reply) ); - struct file *file = NULL; + size_t len = get_req_strlen( req->name ); + struct file *file; - if (fd == -1) + req->handle = -1; + if ((file = create_file( req->name, len, req->access, + req->sharing, req->create, req->attrs ))) { - size_t len = get_req_strlen(); - file = create_file( get_req_data( len + 1), len, req->access, - req->sharing, req->create, req->attrs ); - } - else - { - if ((fd = dup(fd)) == -1) - file_set_error(); - else - file = create_file_for_fd( fd, req->access, req->sharing, req->attrs ); - } - if (file) - { - reply->handle = alloc_handle( current->process, file, req->access, req->inherit ); + req->handle = alloc_handle( current->process, file, req->access, req->inherit ); release_object( file ); } - else reply->handle = -1; +} + +/* allocate a file handle for a Unix fd */ +DECL_HANDLER(alloc_file_handle) +{ + struct file *file; + + req->handle = -1; + if ((fd = dup(fd)) != -1) + { + if ((file = create_file_for_fd( fd, req->access, FILE_SHARE_READ | FILE_SHARE_WRITE, 0 ))) + { + req->handle = alloc_handle( current->process, file, req->access, 0 ); + release_object( file ); + } + else close( fd ); + } + else file_set_error(); } /* get a Unix fd to read from a file */ DECL_HANDLER(get_read_fd) { struct object *obj; - int read_fd; if ((obj = get_handle_obj( current->process, req->handle, GENERIC_READ, NULL ))) { - read_fd = obj->ops->get_read_fd( obj ); + set_reply_fd( current, obj->ops->get_read_fd( obj ) ); release_object( obj ); } - else read_fd = -1; - set_reply_fd( current, read_fd ); } /* get a Unix fd to write to a file */ DECL_HANDLER(get_write_fd) { struct object *obj; - int write_fd; if ((obj = get_handle_obj( current->process, req->handle, GENERIC_WRITE, NULL ))) { - write_fd = obj->ops->get_write_fd( obj ); + set_reply_fd( current, obj->ops->get_write_fd( obj ) ); release_object( obj ); } - else write_fd = -1; - set_reply_fd( current, write_fd ); } /* set a file current position */ DECL_HANDLER(set_file_pointer) { - struct set_file_pointer_reply reply; - reply.low = req->low; - reply.high = req->high; - set_file_pointer( req->handle, &reply.low, &reply.high, req->whence ); - add_reply_data( current, &reply, sizeof(reply) ); + int high = req->high; + int low = req->low; + set_file_pointer( req->handle, &low, &high, req->whence ); + req->new_low = low; + req->new_high = high; } /* truncate (or extend) a file */ @@ -580,11 +581,10 @@ DECL_HANDLER(set_file_time) DECL_HANDLER(get_file_info) { struct object *obj; - struct get_file_info_reply *reply = push_reply_data( current, sizeof(*reply) ); if ((obj = get_handle_obj( current->process, req->handle, 0, NULL ))) { - obj->ops->get_file_info( obj, reply ); + obj->ops->get_file_info( obj, req ); release_object( obj ); } } diff --git a/server/handle.c b/server/handle.c index 4b5c303062b..8619e8ba65f 100644 --- a/server/handle.c +++ b/server/handle.c @@ -403,8 +403,7 @@ DECL_HANDLER(close_handle) /* get information about a handle */ DECL_HANDLER(get_handle_info) { - struct get_handle_info_reply *reply = push_reply_data( current, sizeof(*reply) ); - reply->flags = set_handle_info( current->process, req->handle, 0, 0 ); + req->flags = set_handle_info( current->process, req->handle, 0, 0 ); } /* set a handle information */ @@ -416,20 +415,20 @@ DECL_HANDLER(set_handle_info) /* duplicate a handle */ DECL_HANDLER(dup_handle) { - struct dup_handle_reply reply = { -1 }; struct process *src, *dst; + req->handle = -1; if ((src = get_process_from_handle( req->src_process, PROCESS_DUP_HANDLE ))) { if (req->options & DUP_HANDLE_MAKE_GLOBAL) { - reply.handle = duplicate_handle( src, req->src_handle, NULL, - req->access, req->inherit, req->options ); + req->handle = duplicate_handle( src, req->src_handle, NULL, + req->access, req->inherit, req->options ); } else if ((dst = get_process_from_handle( req->dst_process, PROCESS_DUP_HANDLE ))) { - reply.handle = duplicate_handle( src, req->src_handle, dst, - req->access, req->inherit, req->options ); + req->handle = duplicate_handle( src, req->src_handle, dst, + req->access, req->inherit, req->options ); release_object( dst ); } /* close the handle no matter what happened */ @@ -437,5 +436,4 @@ DECL_HANDLER(dup_handle) close_handle( src, req->src_handle ); release_object( src ); } - add_reply_data( current, &reply, sizeof(reply) ); } diff --git a/server/mapping.c b/server/mapping.c index b3367492792..dc0690c68da 100644 --- a/server/mapping.c +++ b/server/mapping.c @@ -104,11 +104,11 @@ static struct object *create_mapping( int size_high, int size_low, int protect, if (!(mapping->file = get_file_obj( current->process, handle, access ))) goto error; if (!size_high && !size_low) { - struct get_file_info_reply reply; + struct get_file_info_request req; struct object *obj = (struct object *)mapping->file; - obj->ops->get_file_info( obj, &reply ); - size_high = reply.size_high; - size_low = ROUND_SIZE( 0, reply.size_low ); + obj->ops->get_file_info( obj, &req ); + size_high = req.size_high; + size_low = ROUND_SIZE( 0, req.size_low ); } else if (!grow_file( mapping->file, size_high, size_low )) goto error; } @@ -133,23 +133,6 @@ static struct object *create_mapping( int size_high, int size_low, int protect, return NULL; } -static int get_mapping_info( int handle, struct get_mapping_info_reply *reply ) -{ - struct mapping *mapping; - int fd; - - if (!(mapping = (struct mapping *)get_handle_obj( current->process, handle, - 0, &mapping_ops ))) - return -1; - reply->size_high = mapping->size_high; - reply->size_low = mapping->size_low; - reply->protect = mapping->protect; - if (mapping->file) fd = file_get_mmap_fd( mapping->file ); - else fd = -1; - release_object( mapping ); - return fd; -} - static void mapping_dump( struct object *obj, int verbose ) { struct mapping *mapping = (struct mapping *)obj; @@ -169,34 +152,40 @@ static void mapping_destroy( struct object *obj ) /* create a file mapping */ DECL_HANDLER(create_mapping) { - size_t len = get_req_strlen(); - struct create_mapping_reply *reply = push_reply_data( current, sizeof(*reply) ); + size_t len = get_req_strlen( req->name ); struct object *obj; + req->handle = -1; if ((obj = create_mapping( req->size_high, req->size_low, - req->protect, req->handle, get_req_data( len + 1 ), len ))) + req->protect, req->file_handle, req->name, len ))) { int access = FILE_MAP_ALL_ACCESS; if (!(req->protect & VPROT_WRITE)) access &= ~FILE_MAP_WRITE; - reply->handle = alloc_handle( current->process, obj, access, req->inherit ); + req->handle = alloc_handle( current->process, obj, access, req->inherit ); release_object( obj ); } - else reply->handle = -1; } /* open a handle to a mapping */ DECL_HANDLER(open_mapping) { - size_t len = get_req_strlen(); - struct open_mapping_reply *reply = push_reply_data( current, sizeof(*reply) ); - reply->handle = open_object( get_req_data( len + 1 ), len, &mapping_ops, - req->access, req->inherit ); + size_t len = get_req_strlen( req->name ); + req->handle = open_object( req->name, len, &mapping_ops, req->access, req->inherit ); } /* get a mapping information */ DECL_HANDLER(get_mapping_info) { - struct get_mapping_info_reply *reply = push_reply_data( current, sizeof(*reply) ); - int map_fd = get_mapping_info( req->handle, reply ); - set_reply_fd( current, map_fd ); + struct mapping *mapping; + + if ((mapping = (struct mapping *)get_handle_obj( current->process, req->handle, + 0, &mapping_ops ))) + { + req->size_high = mapping->size_high; + req->size_low = mapping->size_low; + req->protect = mapping->protect; + if (mapping->file) set_reply_fd( current, file_get_mmap_fd( mapping->file ) ); + release_object( mapping ); + } } + diff --git a/server/mutex.c b/server/mutex.c index f171d955313..32b74075be5 100644 --- a/server/mutex.c +++ b/server/mutex.c @@ -126,25 +126,22 @@ static int mutex_satisfied( struct object *obj, struct thread *thread ) /* create a mutex */ DECL_HANDLER(create_mutex) { - size_t len = get_req_strlen(); - struct create_mutex_reply *reply = push_reply_data( current, sizeof(*reply) ); + size_t len = get_req_strlen( req->name ); struct mutex *mutex; - if ((mutex = create_mutex( get_req_data( len + 1 ), len, req->owned ))) + req->handle = -1; + if ((mutex = create_mutex( req->name, len, req->owned ))) { - reply->handle = alloc_handle( current->process, mutex, MUTEX_ALL_ACCESS, req->inherit ); + req->handle = alloc_handle( current->process, mutex, MUTEX_ALL_ACCESS, req->inherit ); release_object( mutex ); } - else reply->handle = -1; } /* open a handle to a mutex */ DECL_HANDLER(open_mutex) { - size_t len = get_req_strlen(); - struct open_mutex_reply *reply = push_reply_data( current, sizeof(*reply) ); - reply->handle = open_object( get_req_data( len + 1 ), len, &mutex_ops, - req->access, req->inherit ); + size_t len = get_req_strlen( req->name ); + req->handle = open_object( req->name, len, &mutex_ops, req->access, req->inherit ); } /* release a mutex */ diff --git a/server/object.c b/server/object.c index 7054e41a13f..d50fd7d7052 100644 --- a/server/object.c +++ b/server/object.c @@ -240,7 +240,7 @@ int no_flush( struct object *obj ) return 0; } -int no_get_file_info( struct object *obj, struct get_file_info_reply *info ) +int no_get_file_info( struct object *obj, struct get_file_info_request *info ) { set_error( ERROR_INVALID_HANDLE ); return 0; diff --git a/server/object.h b/server/object.h index 8da0c81786f..0e23b18c3d0 100644 --- a/server/object.h +++ b/server/object.h @@ -47,7 +47,7 @@ struct object_ops /* flush the object buffers */ int (*flush)(struct object *); /* get file information */ - int (*get_file_info)(struct object *,struct get_file_info_reply *); + int (*get_file_info)(struct object *,struct get_file_info_request *); /* destroy on refcount == 0 */ void (*destroy)(struct object *); }; @@ -80,7 +80,7 @@ extern int no_satisfied( struct object *obj, struct thread *thread ); extern int no_read_fd( struct object *obj ); extern int no_write_fd( struct object *obj ); extern int no_flush( struct object *obj ); -extern int no_get_file_info( struct object *obj, struct get_file_info_reply *info ); +extern int no_get_file_info( struct object *obj, struct get_file_info_request *info ); extern void no_destroy( struct object *obj ); extern void default_select_event( int event, void *private ); #ifdef DEBUG_OBJECTS @@ -123,7 +123,7 @@ struct client; extern struct client *add_client( int client_fd, struct thread *self ); extern void remove_client( struct client *client, int exit_code ); extern void client_pass_fd( struct client *client, int pass_fd ); -extern void client_reply( struct client *client ); +extern void client_reply( struct client *client, unsigned int res ); /* mutex functions */ diff --git a/server/pipe.c b/server/pipe.c index 9eaf93dcbc6..00c2863c169 100644 --- a/server/pipe.c +++ b/server/pipe.c @@ -39,7 +39,7 @@ static void pipe_remove_queue( struct object *obj, struct wait_queue_entry *entr static int pipe_signaled( struct object *obj, struct thread *thread ); static int pipe_get_read_fd( struct object *obj ); static int pipe_get_write_fd( struct object *obj ); -static int pipe_get_info( struct object *obj, struct get_file_info_reply *reply ); +static int pipe_get_info( struct object *obj, struct get_file_info_request *req ); static void pipe_destroy( struct object *obj ); static const struct object_ops pipe_ops = @@ -189,10 +189,18 @@ static int pipe_get_write_fd( struct object *obj ) return dup( pipe->select.fd ); } -static int pipe_get_info( struct object *obj, struct get_file_info_reply *reply ) +static int pipe_get_info( struct object *obj, struct get_file_info_request *req ) { - memset( reply, 0, sizeof(*reply) ); - reply->type = FILE_TYPE_PIPE; + req->type = FILE_TYPE_PIPE; + req->attr = 0; + req->access_time = 0; + req->write_time = 0; + req->size_high = 0; + req->size_low = 0; + req->links = 0; + req->index_high = 0; + req->index_low = 0; + req->serial = 0; return 1; } @@ -209,23 +217,25 @@ static void pipe_destroy( struct object *obj ) /* create an anonymous pipe */ DECL_HANDLER(create_pipe) { - struct create_pipe_reply reply = { -1, -1 }; struct object *obj[2]; + int hread = -1, hwrite = -1; + if (create_pipe( obj )) { - reply.handle_read = alloc_handle( current->process, obj[0], - STANDARD_RIGHTS_REQUIRED|SYNCHRONIZE|GENERIC_READ, - req->inherit ); - if (reply.handle_read != -1) + hread = alloc_handle( current->process, obj[0], + STANDARD_RIGHTS_REQUIRED|SYNCHRONIZE|GENERIC_READ, + req->inherit ); + if (hread != -1) { - reply.handle_write = alloc_handle( current->process, obj[1], - STANDARD_RIGHTS_REQUIRED|SYNCHRONIZE|GENERIC_WRITE, - req->inherit ); - if (reply.handle_write == -1) - close_handle( current->process, reply.handle_read ); + hwrite = alloc_handle( current->process, obj[1], + STANDARD_RIGHTS_REQUIRED|SYNCHRONIZE|GENERIC_WRITE, + req->inherit ); + if (hwrite == -1) + close_handle( current->process, hread ); } release_object( obj[0] ); release_object( obj[1] ); } - add_reply_data( current, &reply, sizeof(reply) ); + req->handle_read = hread; + req->handle_write = hwrite; } diff --git a/server/process.c b/server/process.c index b1e4df712f3..9f68c2e1a97 100644 --- a/server/process.c +++ b/server/process.c @@ -82,10 +82,10 @@ static struct process *create_process( struct process *parent, struct new_proces /* alloc a handle for the process itself */ alloc_handle( process, process, PROCESS_ALL_ACCESS, 0 ); - if (!(process->info = mem_alloc( sizeof(*process->info) + len + 1 ))) goto error; + if (!(process->info = mem_alloc( sizeof(*process->info) + len ))) goto error; memcpy( process->info, req, sizeof(*req) ); - memcpy( process->info->cmd_line, cmd_line, len ); - process->info->cmd_line[len] = 0; + memcpy( process->info->cmdline, cmd_line, len ); + process->info->cmdline[len] = 0; /* set the process console */ if (req->create_flags & CREATE_NEW_CONSOLE) @@ -285,14 +285,13 @@ void kill_process( struct process *process, int exit_code ) } /* get all information about a process */ -static void get_process_info( struct process *process, - struct get_process_info_reply *reply ) +static void get_process_info( struct process *process, struct get_process_info_request *req ) { - reply->pid = process; - reply->exit_code = process->exit_code; - reply->priority = process->priority; - reply->process_affinity = process->affinity; - reply->system_affinity = 1; + req->pid = process; + req->exit_code = process->exit_code; + req->priority = process->priority; + req->process_affinity = process->affinity; + req->system_affinity = 1; } /* set all information about a process */ @@ -333,62 +332,55 @@ struct process_snapshot *process_snap( int *count ) /* create a new process */ DECL_HANDLER(new_process) { - struct new_process_reply *reply = push_reply_data( current, sizeof(*reply) ); - size_t len = get_req_strlen(); + size_t len = get_req_strlen( req->cmdline ); struct process *process; - if ((process = create_process( current->process, req, get_req_data( len + 1 ), len ))) + req->handle = -1; + req->pid = NULL; + if ((process = create_process( current->process, req, req->cmdline, len ))) { - reply->handle = alloc_handle( current->process, process, - PROCESS_ALL_ACCESS, req->inherit ); - reply->pid = process; + req->handle = alloc_handle( current->process, process, PROCESS_ALL_ACCESS, req->inherit ); + req->pid = process; release_object( process ); } - else - { - reply->handle = -1; - reply->pid = NULL; - } } /* initialize a new process */ DECL_HANDLER(init_process) { - struct init_process_reply *reply = push_reply_data( current, sizeof(*reply) ); struct new_process_request *info; if (current->state == STARTING) { - fatal_protocol_error( "init_process: init_thread not called yet\n" ); + fatal_protocol_error( current, "init_process: init_thread not called yet\n" ); return; } if (!(info = current->process->info)) { - fatal_protocol_error( "init_process: called twice\n" ); + fatal_protocol_error( current, "init_process: called twice\n" ); return; } current->process->info = NULL; - reply->start_flags = info->start_flags; - reply->hstdin = info->hstdin; - reply->hstdout = info->hstdout; - reply->hstderr = info->hstderr; - reply->cmd_show = info->cmd_show; - reply->env_ptr = info->env_ptr; - add_reply_data( current, info->cmd_line, strlen(info->cmd_line) + 1 ); + req->start_flags = info->start_flags; + req->hstdin = info->hstdin; + req->hstdout = info->hstdout; + req->hstderr = info->hstderr; + req->cmd_show = info->cmd_show; + req->env_ptr = info->env_ptr; + strcpy( req->cmdline, info->cmdline ); free( info ); } /* open a handle to a process */ DECL_HANDLER(open_process) { - struct open_process_reply *reply = push_reply_data( current, sizeof(*reply) ); struct process *process = get_process_from_id( req->pid ); + req->handle = -1; if (process) { - reply->handle = alloc_handle( current->process, process, req->access, req->inherit ); + req->handle = alloc_handle( current->process, process, req->access, req->inherit ); release_object( process ); } - else reply->handle = -1; } /* terminate a process */ @@ -407,11 +399,10 @@ DECL_HANDLER(terminate_process) DECL_HANDLER(get_process_info) { struct process *process; - struct get_process_info_reply *reply = push_reply_data( current, sizeof(*reply) ); if ((process = get_process_from_handle( req->handle, PROCESS_QUERY_INFORMATION ))) { - get_process_info( process, reply ); + get_process_info( process, req ); release_object( process ); } } diff --git a/server/request.c b/server/request.c index a8cab9c6767..56b394d72de 100644 --- a/server/request.c +++ b/server/request.c @@ -26,55 +26,33 @@ struct thread *current = NULL; /* thread handling the current request */ /* complain about a protocol error and terminate the client connection */ -void fatal_protocol_error( const char *err ) +void fatal_protocol_error( struct thread *thread, const char *err, ... ) { - unsigned char *p; + va_list args; - fprintf( stderr, "Protocol error:%p: %s\n request:", current, err ); - for (p = (unsigned char *)current->buffer; p < (unsigned char *)current->req_end; p++) - fprintf( stderr, " %02x", *p ); - fprintf( stderr, "\n" ); - remove_client( current->client, -2 ); + va_start( args, err ); + fprintf( stderr, "Protocol error:%p: ", thread ); + vfprintf( stderr, err, args ); + va_end( args ); + remove_client( thread->client, PROTOCOL_ERROR ); } /* call a request handler */ -void call_req_handler( struct thread *thread, int fd ) +void call_req_handler( struct thread *thread, enum request req, int fd ) { - const struct handler *handler; - struct header *head; - unsigned int req, len; - current = thread; - assert (current); - - head = (struct header *)current->buffer; - - req = head->type; - len = head->len; - - /* set the buffer pointers */ - current->req_pos = current->reply_pos = (char *)current->buffer + sizeof(struct header); - current->req_end = (char *)current->buffer + len; clear_error(); - if ((len < sizeof(struct header)) || (len > MAX_MSG_LENGTH)) goto bad_header; - if (req >= REQ_NB_REQUESTS) goto bad_header; - if (debug_level) trace_request( req, fd ); - /* now call the handler */ - handler = &req_handlers[req]; - if (!check_req_data( handler->min_size )) goto bad_request; - handler->handler( get_req_data( handler->min_size ), fd ); - if (current && current->state != SLEEPING) send_reply( current ); - current = NULL; - return; - - bad_header: - /* dump only the header */ - current->req_end = (char *)current->buffer + sizeof(struct header); - bad_request: - fatal_protocol_error( "bad request" ); + if (req < REQ_NB_REQUESTS) + { + req_handlers[req].handler( current->buffer, fd ); + if (current && current->state != SLEEPING) send_reply( current ); + current = NULL; + return; + } + fatal_protocol_error( current, "bad request %d\n", req ); } /* handle a client timeout */ @@ -110,15 +88,8 @@ void set_reply_fd( struct thread *thread, int pass_fd ) /* send a reply to a thread */ void send_reply( struct thread *thread ) { - struct header *head = thread->buffer; - int len = (char *)thread->reply_pos - (char *)thread->buffer; - - assert( len < MAX_MSG_LENGTH ); - - head->len = len; - head->type = thread->error; if (thread->state == SLEEPING) thread->state = RUNNING; - client_reply( thread->client ); + client_reply( thread->client, thread->error ); } /* set the debug level */ diff --git a/server/request.h b/server/request.h index b161a558a08..f9e0c95cbee 100644 --- a/server/request.h +++ b/server/request.h @@ -13,14 +13,21 @@ #include "thread.h" -/* request handler definition */ +/* max request length */ +#define MAX_REQUEST_LENGTH 8192 +/* exit code passed to remove_client on communication error */ +#define OUT_OF_MEMORY -1 +#define BROKEN_PIPE -2 +#define PROTOCOL_ERROR -3 + +/* request handler definition */ #define DECL_HANDLER(name) void req_##name( struct name##_request *req, int fd ) /* request functions */ -extern void fatal_protocol_error( const char *err ); -extern void call_req_handler( struct thread *thread, int fd ); +extern void fatal_protocol_error( struct thread *thread, const char *err, ... ); +extern void call_req_handler( struct thread *thread, enum request req, int fd ); extern void call_timeout_handler( void *thread ); extern void call_kill_handler( struct thread *thread, int exit_code ); extern void set_reply_fd( struct thread *thread, int pass_fd ); @@ -29,48 +36,26 @@ extern void send_reply( struct thread *thread ); extern void trace_request( enum request req, int fd ); extern void trace_timeout(void); extern void trace_kill( int exit_code ); -extern void trace_reply( struct thread *thread, int pass_fd ); +extern void trace_reply( struct thread *thread, unsigned int res, int pass_fd ); - -/* Warning: the buffer is shared between request and reply, - * so make sure you are finished using the request before starting - * to add data for the reply. - */ - -/* remove some data from the current request */ -static inline void *get_req_data( size_t len ) +/* get the request buffer */ +static inline void *get_req_ptr( struct thread *thread ) { - void *old = current->req_pos; - current->req_pos = (char *)old + len; - return old; + return thread->buffer; } -/* check that there is enough data available in the current request */ -static inline int check_req_data( size_t len ) +/* get the remaining size in the request buffer for object of a given size */ +static inline int get_req_size( const void *ptr, size_t typesize ) { - return (char *)current->req_pos + len <= (char *)current->req_end; + return ((char *)current->buffer + MAX_REQUEST_LENGTH - (char *)ptr) / typesize; } /* get the length of a request string, without going past the end of the request */ -static inline size_t get_req_strlen(void) +static inline size_t get_req_strlen( const char *str ) { - char *p = current->req_pos; - while (*p && (p < (char *)current->req_end - 1)) p++; - return p - (char *)current->req_pos; -} - -/* make space for some data in the current reply */ -static inline void *push_reply_data( struct thread *thread, size_t len ) -{ - void *old = thread->reply_pos; - thread->reply_pos = (char *)old + len; - return old; -} - -/* add some data to the current reply */ -static inline void add_reply_data( struct thread *thread, const void *data, size_t len ) -{ - memcpy( push_reply_data( thread, len ), data, len ); + const char *p = str; + while (*p && (p < (char *)current->buffer + MAX_REQUEST_LENGTH - 1)) p++; + return p - str; } /* Everything below this line is generated automatically by tools/make_requests */ @@ -81,6 +66,7 @@ DECL_HANDLER(new_thread); DECL_HANDLER(set_debug); DECL_HANDLER(init_process); DECL_HANDLER(init_thread); +DECL_HANDLER(get_thread_buffer); DECL_HANDLER(terminate_process); DECL_HANDLER(terminate_thread); DECL_HANDLER(get_process_info); @@ -91,6 +77,7 @@ DECL_HANDLER(suspend_thread); DECL_HANDLER(resume_thread); DECL_HANDLER(debugger); DECL_HANDLER(queue_apc); +DECL_HANDLER(get_apcs); DECL_HANDLER(close_handle); DECL_HANDLER(get_handle_info); DECL_HANDLER(set_handle_info); @@ -107,6 +94,7 @@ DECL_HANDLER(create_semaphore); DECL_HANDLER(release_semaphore); DECL_HANDLER(open_semaphore); DECL_HANDLER(create_file); +DECL_HANDLER(alloc_file_handle); DECL_HANDLER(get_read_fd); DECL_HANDLER(get_write_fd); DECL_HANDLER(set_file_pointer); @@ -150,6 +138,7 @@ static const struct handler { { (void(*)())req_set_debug, sizeof(struct set_debug_request) }, { (void(*)())req_init_process, sizeof(struct init_process_request) }, { (void(*)())req_init_thread, sizeof(struct init_thread_request) }, + { (void(*)())req_get_thread_buffer, sizeof(struct get_thread_buffer_request) }, { (void(*)())req_terminate_process, sizeof(struct terminate_process_request) }, { (void(*)())req_terminate_thread, sizeof(struct terminate_thread_request) }, { (void(*)())req_get_process_info, sizeof(struct get_process_info_request) }, @@ -160,6 +149,7 @@ static const struct handler { { (void(*)())req_resume_thread, sizeof(struct resume_thread_request) }, { (void(*)())req_debugger, sizeof(struct debugger_request) }, { (void(*)())req_queue_apc, sizeof(struct queue_apc_request) }, + { (void(*)())req_get_apcs, sizeof(struct get_apcs_request) }, { (void(*)())req_close_handle, sizeof(struct close_handle_request) }, { (void(*)())req_get_handle_info, sizeof(struct get_handle_info_request) }, { (void(*)())req_set_handle_info, sizeof(struct set_handle_info_request) }, @@ -176,6 +166,7 @@ static const struct handler { { (void(*)())req_release_semaphore, sizeof(struct release_semaphore_request) }, { (void(*)())req_open_semaphore, sizeof(struct open_semaphore_request) }, { (void(*)())req_create_file, sizeof(struct create_file_request) }, + { (void(*)())req_alloc_file_handle, sizeof(struct alloc_file_handle_request) }, { (void(*)())req_get_read_fd, sizeof(struct get_read_fd_request) }, { (void(*)())req_get_write_fd, sizeof(struct get_write_fd_request) }, { (void(*)())req_set_file_pointer, sizeof(struct set_file_pointer_request) }, diff --git a/server/semaphore.c b/server/semaphore.c index 6b2caecb01a..f9fb6719344 100644 --- a/server/semaphore.c +++ b/server/semaphore.c @@ -64,31 +64,33 @@ static struct semaphore *create_semaphore( const char *name, size_t len, return sem; } -static void release_semaphore( int handle, unsigned int count, unsigned int *prev_count ) +static unsigned int release_semaphore( int handle, unsigned int count ) { struct semaphore *sem; + unsigned int prev = 0; - if (!(sem = (struct semaphore *)get_handle_obj( current->process, handle, - SEMAPHORE_MODIFY_STATE, &semaphore_ops ))) - return; - - *prev_count = sem->count; - if (sem->count + count < sem->count || sem->count + count > sem->max) + if ((sem = (struct semaphore *)get_handle_obj( current->process, handle, + SEMAPHORE_MODIFY_STATE, &semaphore_ops ))) { - set_error( ERROR_TOO_MANY_POSTS ); + prev = sem->count; + if (sem->count + count < sem->count || sem->count + count > sem->max) + { + set_error( ERROR_TOO_MANY_POSTS ); + } + else if (sem->count) + { + /* there cannot be any thread waiting if the count is != 0 */ + assert( !sem->obj.head ); + sem->count += count; + } + else + { + sem->count = count; + wake_up( &sem->obj, count ); + } + release_object( sem ); } - else if (sem->count) - { - /* there cannot be any thread waiting if the count is != 0 */ - assert( !sem->obj.head ); - sem->count += count; - } - else - { - sem->count = count; - wake_up( &sem->obj, count ); - } - release_object( sem ); + return prev; } static void semaphore_dump( struct object *obj, int verbose ) @@ -118,30 +120,26 @@ static int semaphore_satisfied( struct object *obj, struct thread *thread ) /* create a semaphore */ DECL_HANDLER(create_semaphore) { - size_t len = get_req_strlen(); - struct create_semaphore_reply *reply = push_reply_data( current, sizeof(*reply) ); + size_t len = get_req_strlen( req->name ); struct semaphore *sem; - if ((sem = create_semaphore( get_req_data( len + 1 ), len, req->initial, req->max ))) + req->handle = -1; + if ((sem = create_semaphore( req->name, len, req->initial, req->max ))) { - reply->handle = alloc_handle( current->process, sem, SEMAPHORE_ALL_ACCESS, req->inherit ); + req->handle = alloc_handle( current->process, sem, SEMAPHORE_ALL_ACCESS, req->inherit ); release_object( sem ); } - else reply->handle = -1; } /* open a handle to a semaphore */ DECL_HANDLER(open_semaphore) { - size_t len = get_req_strlen(); - struct open_semaphore_reply *reply = push_reply_data( current, sizeof(*reply) ); - reply->handle = open_object( get_req_data( len + 1 ), len, &semaphore_ops, - req->access, req->inherit ); + size_t len = get_req_strlen( req->name ); + req->handle = open_object( req->name, len, &semaphore_ops, req->access, req->inherit ); } /* release a semaphore */ DECL_HANDLER(release_semaphore) { - struct release_semaphore_reply *reply = push_reply_data( current, sizeof(*reply) ); - release_semaphore( req->handle, req->count, &reply->prev_count ); + req->prev_count = release_semaphore( req->handle, req->count ); } diff --git a/server/snapshot.c b/server/snapshot.c index 6aebf1b5a9f..5ac30ccd6a4 100644 --- a/server/snapshot.c +++ b/server/snapshot.c @@ -64,31 +64,25 @@ static struct snapshot *create_snapshot( int flags ) } /* get the next process in the snapshot */ -static int snapshot_next_process( int handle, int reset, struct next_process_reply *reply ) +static int snapshot_next_process( struct snapshot *snapshot, struct next_process_request *req ) { - struct snapshot *snapshot; struct process_snapshot *ptr; - if (!(snapshot = (struct snapshot *)get_handle_obj( current->process, handle, - 0, &snapshot_ops ))) - return 0; + if (!snapshot->process_count) { set_error( ERROR_INVALID_PARAMETER ); /* FIXME */ - release_object( snapshot ); return 0; } - if (reset) snapshot->process_pos = 0; + if (req->reset) snapshot->process_pos = 0; else if (snapshot->process_pos >= snapshot->process_count) { set_error( ERROR_NO_MORE_FILES ); - release_object( snapshot ); return 0; } ptr = &snapshot->process[snapshot->process_pos++]; - reply->pid = ptr->process; - reply->threads = ptr->threads; - reply->priority = ptr->priority; - release_object( snapshot ); + req->pid = ptr->process; + req->threads = ptr->threads; + req->priority = ptr->priority; return 1; } @@ -117,19 +111,24 @@ static void snapshot_destroy( struct object *obj ) DECL_HANDLER(create_snapshot) { struct snapshot *snapshot; - struct create_snapshot_reply *reply = push_reply_data( current, sizeof(*reply) ); + req->handle = -1; if ((snapshot = create_snapshot( req->flags ))) { - reply->handle = alloc_handle( current->process, snapshot, 0, req->inherit ); + req->handle = alloc_handle( current->process, snapshot, 0, req->inherit ); release_object( snapshot ); } - else reply->handle = -1; } /* get the next process from a snapshot */ DECL_HANDLER(next_process) { - struct next_process_reply *reply = push_reply_data( current, sizeof(*reply) ); - snapshot_next_process( req->handle, req->reset, reply ); + struct snapshot *snapshot; + + if ((snapshot = (struct snapshot *)get_handle_obj( current->process, req->handle, + 0, &snapshot_ops ))) + { + snapshot_next_process( snapshot, req ); + release_object( snapshot ); + } } diff --git a/server/socket.c b/server/socket.c index 9b78e07eec2..5628c1e5529 100644 --- a/server/socket.c +++ b/server/socket.c @@ -30,139 +30,102 @@ struct client { struct select_user select; /* select user */ - unsigned int seq; /* current sequence number */ + unsigned int res; /* current result to send */ int pass_fd; /* fd to pass to and from the client */ struct thread *self; /* client thread (opaque pointer) */ struct timeout_user *timeout; /* current timeout (opaque pointer) */ }; -/* exit code passed to remove_client */ -#define OUT_OF_MEMORY -1 -#define BROKEN_PIPE -2 -#define PROTOCOL_ERROR -3 - - -/* signal a client protocol error */ -static void protocol_error( struct client *client, const char *err, ... ) +/* socket communication static structures */ +static struct iovec iovec; +static struct msghdr msghdr = { NULL, 0, &iovec, 1, }; +#ifndef HAVE_MSGHDR_ACCRIGHTS +struct cmsg_fd { - va_list args; + int len; /* sizeof structure */ + int level; /* SOL_SOCKET */ + int type; /* SCM_RIGHTS */ + int fd; /* fd to pass */ +}; +static struct cmsg_fd cmsg = { sizeof(cmsg), SOL_SOCKET, SCM_RIGHTS, -1 }; +#endif /* HAVE_MSGHDR_ACCRIGHTS */ - va_start( args, err ); - fprintf( stderr, "Protocol error:%p: ", client->self ); - vfprintf( stderr, err, args ); - va_end( args ); - remove_client( client, PROTOCOL_ERROR ); -} /* send a message to a client that is ready to receive something */ -static void do_write( struct client *client ) +static int do_write( struct client *client ) { int ret; if (client->pass_fd == -1) { - ret = write( client->select.fd, &client->seq, sizeof(client->seq) ); + ret = write( client->select.fd, &client->res, sizeof(client->res) ); + if (ret == sizeof(client->res)) goto ok; } else /* we have an fd to send */ { - struct iovec vec; - struct msghdr msghdr; - #ifdef HAVE_MSGHDR_ACCRIGHTS + msghdr.msg_accrightslen = sizeof(int); msghdr.msg_accrights = (void *)&client->pass_fd; - msghdr.msg_accrightslen = sizeof(client->pass_fd); #else /* HAVE_MSGHDR_ACCRIGHTS */ - struct cmsg_fd cmsg; - - cmsg.len = sizeof(cmsg); - cmsg.level = SOL_SOCKET; - cmsg.type = SCM_RIGHTS; - cmsg.fd = client->pass_fd; msghdr.msg_control = &cmsg; msghdr.msg_controllen = sizeof(cmsg); - msghdr.msg_flags = 0; + cmsg.fd = client->pass_fd; #endif /* HAVE_MSGHDR_ACCRIGHTS */ - msghdr.msg_name = NULL; - msghdr.msg_namelen = 0; - msghdr.msg_iov = &vec; - msghdr.msg_iovlen = 1; - vec.iov_base = (char *)&client->seq; - vec.iov_len = sizeof(client->seq); + iovec.iov_base = (char *)&client->res; + iovec.iov_len = sizeof(client->res); ret = sendmsg( client->select.fd, &msghdr, 0 ); close( client->pass_fd ); client->pass_fd = -1; - } - if (ret == sizeof(client->seq)) - { - /* everything OK */ - client->seq++; - set_select_events( &client->select, READ_EVENT ); - return; + if (ret == sizeof(client->res)) goto ok; } if (ret == -1) { + if (errno == EWOULDBLOCK) return 0; /* not a fatal error */ if (errno != EPIPE) perror("sendmsg"); - remove_client( client, BROKEN_PIPE ); - return; } - fprintf( stderr, "Partial sequence sent (%d)\n", ret ); + else fprintf( stderr, "Partial message sent %d/%d\n", ret, sizeof(client->res) ); remove_client( client, BROKEN_PIPE ); + return 0; + + ok: + set_select_events( &client->select, READ_EVENT ); + return 1; } /* read a message from a client that has something to say */ static void do_read( struct client *client ) { - struct iovec vec; - int ret, seq; + int ret; + enum request req; #ifdef HAVE_MSGHDR_ACCRIGHTS - struct msghdr msghdr; - - msghdr.msg_accrights = (void *)&client->pass_fd; - msghdr.msg_accrightslen = sizeof(client->pass_fd); + msghdr.msg_accrightslen = sizeof(int); + msghdr.msg_accrights = (void *)&client->pass_fd; #else /* HAVE_MSGHDR_ACCRIGHTS */ - struct msghdr msghdr; - struct cmsg_fd cmsg; - - cmsg.len = sizeof(cmsg); - cmsg.level = SOL_SOCKET; - cmsg.type = SCM_RIGHTS; - cmsg.fd = -1; msghdr.msg_control = &cmsg; msghdr.msg_controllen = sizeof(cmsg); - msghdr.msg_flags = 0; + cmsg.fd = -1; #endif /* HAVE_MSGHDR_ACCRIGHTS */ assert( client->pass_fd == -1 ); - msghdr.msg_name = NULL; - msghdr.msg_namelen = 0; - msghdr.msg_iov = &vec; - msghdr.msg_iovlen = 1; - - vec.iov_base = &seq; - vec.iov_len = sizeof(seq); + iovec.iov_base = &req; + iovec.iov_len = sizeof(req); ret = recvmsg( client->select.fd, &msghdr, 0 ); #ifndef HAVE_MSGHDR_ACCRIGHTS client->pass_fd = cmsg.fd; #endif - if (ret == sizeof(seq)) + if (ret == sizeof(req)) { int pass_fd = client->pass_fd; - if (seq != client->seq++) - { - protocol_error( client, "bad sequence %08x instead of %08x\n", - seq, client->seq - 1 ); - return; - } client->pass_fd = -1; - call_req_handler( client->self, pass_fd ); + call_req_handler( client->self, req, pass_fd ); if (pass_fd != -1) close( pass_fd ); return; } @@ -177,7 +140,7 @@ static void do_read( struct client *client ) remove_client( client, BROKEN_PIPE ); return; } - protocol_error( client, "partial sequence received %d/%d\n", ret, sizeof(seq) ); + fatal_protocol_error( client->self, "partial message received %d/%d\n", ret, sizeof(req) ); } /* handle a client event */ @@ -204,7 +167,6 @@ struct client *add_client( int fd, struct thread *self ) client->select.fd = fd; client->select.func = client_event; client->select.private = client; - client->seq = 0; client->self = self; client->timeout = NULL; client->pass_fd = -1; @@ -237,8 +199,9 @@ void client_pass_fd( struct client *client, int pass_fd ) } /* send a reply to a client */ -void client_reply( struct client *client ) +void client_reply( struct client *client, unsigned int res ) { - if (debug_level) trace_reply( client->self, client->pass_fd ); - set_select_events( &client->select, WRITE_EVENT ); + if (debug_level) trace_reply( client->self, res, client->pass_fd ); + client->res = res; + if (!do_write( client )) set_select_events( &client->select, WRITE_EVENT ); } diff --git a/server/thread.c b/server/thread.c index aa9febc12c2..d85a1492ee9 100644 --- a/server/thread.c +++ b/server/thread.c @@ -84,10 +84,9 @@ static int alloc_client_buffer( struct thread *thread ) int fd; if ((fd = create_anonymous_file()) == -1) return -1; - if (ftruncate( fd, MAX_MSG_LENGTH ) == -1) goto error; - if ((thread->buffer = mmap( 0, MAX_MSG_LENGTH, PROT_READ | PROT_WRITE, + if (ftruncate( fd, MAX_REQUEST_LENGTH ) == -1) goto error; + if ((thread->buffer = mmap( 0, MAX_REQUEST_LENGTH, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0 )) == (void*)-1) goto error; - thread->req_pos = thread->reply_pos = thread->buffer; return fd; error: @@ -123,7 +122,7 @@ static struct thread *create_thread( int fd, struct process *process, int suspen thread->affinity = 1; thread->suspend = (suspend != 0); thread->buffer = (void *)-1; - thread->last_req = 0; + thread->last_req = REQ_GET_THREAD_BUFFER; if (!first_thread) /* creating the first thread */ { @@ -143,7 +142,6 @@ static struct thread *create_thread( int fd, struct process *process, int suspen close( buf_fd ); goto error; } - push_reply_data( thread, sizeof(struct header) ); set_reply_fd( thread, buf_fd ); /* send the fd to the client */ send_reply( thread ); return thread; @@ -173,7 +171,7 @@ static void destroy_thread( struct object *obj ) if (thread->prev) thread->prev->next = thread->next; else first_thread = thread->next; if (thread->apc) free( thread->apc ); - if (thread->buffer != (void *)-1) munmap( thread->buffer, MAX_MSG_LENGTH ); + if (thread->buffer != (void *)-1) munmap( thread->buffer, MAX_REQUEST_LENGTH ); } /* dump a thread on stdout for debugging purposes */ @@ -378,7 +376,7 @@ static int check_wait( struct thread *thread, int *signaled ) /* Wait satisfied: tell it to the object */ *signaled = i; if (entry->obj->ops->satisfied( entry->obj, thread )) - *signaled += STATUS_ABANDONED_WAIT_0; + *signaled = i + STATUS_ABANDONED_WAIT_0; return 1; } } @@ -404,62 +402,48 @@ static int check_wait( struct thread *thread, int *signaled ) return 0; } -/* build a select reply to wake up the client */ -static void build_select_reply( struct thread *thread, int signaled ) -{ - struct select_reply *reply = push_reply_data( thread, sizeof(*reply) ); - reply->signaled = signaled; - if ((signaled == STATUS_USER_APC) && thread->apc) - { - add_reply_data( thread, thread->apc, thread->apc_count * sizeof(*thread->apc) ); - free( thread->apc ); - thread->apc = NULL; - thread->apc_count = 0; - } -} - /* attempt to wake up a thread */ /* return 1 if OK, 0 if the wait condition is still not satisfied */ static int wake_thread( struct thread *thread ) { - int signaled; + struct select_request *req = get_req_ptr( thread ); - if (!check_wait( thread, &signaled )) return 0; + if (!check_wait( thread, &req->signaled )) return 0; end_wait( thread ); - build_select_reply( thread, signaled ); return 1; } /* sleep on a list of objects */ static void sleep_on( struct thread *thread, int count, int *handles, int flags, int timeout ) { + struct select_request *req; assert( !thread->wait ); - if (!wait_on( thread, count, handles, flags, timeout )) - { - build_select_reply( thread, -1 ); - return; - } + if (!wait_on( thread, count, handles, flags, timeout )) goto error; if (wake_thread( thread )) return; /* now we need to wait */ if (flags & SELECT_TIMEOUT) { if (!(thread->wait->user = add_timeout_user( &thread->wait->timeout, call_timeout_handler, thread ))) - { - build_select_reply( thread, -1 ); - return; - } + goto error; } thread->state = SLEEPING; + return; + + error: + req = get_req_ptr( thread ); + req->signaled = -1; } /* timeout for the current thread */ void thread_timeout(void) { + struct select_request *req = get_req_ptr( current ); + assert( current->wait ); current->wait->user = NULL; end_wait( current ); - build_select_reply( current, STATUS_TIMEOUT ); + req->signaled = STATUS_TIMEOUT; send_reply( current ); } @@ -525,39 +509,40 @@ void thread_killed( struct thread *thread, int exit_code ) /* create a new thread */ DECL_HANDLER(new_thread) { - struct new_thread_reply reply; struct thread *thread; struct process *process; - int new_fd; if ((process = get_process_from_id( req->pid ))) { - if ((new_fd = dup(fd)) != -1) + if ((fd = dup(fd)) != -1) { - if ((thread = create_thread( new_fd, process, req->suspend ))) + if ((thread = create_thread( fd, process, req->suspend ))) { - reply.tid = thread; - reply.handle = alloc_handle( current->process, thread, - THREAD_ALL_ACCESS, req->inherit ); - if (reply.handle == -1) release_object( thread ); + req->tid = thread; + if ((req->handle = alloc_handle( current->process, thread, + THREAD_ALL_ACCESS, req->inherit )) == -1) + release_object( thread ); /* else will be released when the thread gets killed */ } - else close( new_fd ); + else close( fd ); } - else set_error( ERROR_TOO_MANY_OPEN_FILES ); + else file_set_error(); release_object( process ); } - add_reply_data( current, &reply, sizeof(reply) ); +} + +/* retrieve the thread buffer file descriptor */ +DECL_HANDLER(get_thread_buffer) +{ + fatal_protocol_error( current, "get_thread_buffer: should never get called directly\n" ); } /* initialize a new thread */ DECL_HANDLER(init_thread) { - struct init_thread_reply *reply = push_reply_data( current, sizeof(*reply) ); - if (current->state != STARTING) { - fatal_protocol_error( "init_thread: already running\n" ); + fatal_protocol_error( current, "init_thread: already running\n" ); return; } current->state = RUNNING; @@ -565,8 +550,8 @@ DECL_HANDLER(init_thread) current->teb = req->teb; if (current->suspend + current->process->suspend > 0) kill( current->unix_pid, SIGSTOP ); - reply->pid = current->process; - reply->tid = current; + req->pid = current->process; + req->tid = current; } /* terminate a thread */ @@ -585,13 +570,12 @@ DECL_HANDLER(terminate_thread) DECL_HANDLER(get_thread_info) { struct thread *thread; - struct get_thread_info_reply *reply = push_reply_data( current, sizeof(*reply) ); if ((thread = get_thread_from_handle( req->handle, THREAD_QUERY_INFORMATION ))) { - reply->tid = thread; - reply->exit_code = thread->exit_code; - reply->priority = thread->priority; + req->tid = thread; + req->exit_code = thread->exit_code; + req->priority = thread->priority; release_object( thread ); } } @@ -612,10 +596,10 @@ DECL_HANDLER(set_thread_info) DECL_HANDLER(suspend_thread) { struct thread *thread; - struct suspend_thread_reply *reply = push_reply_data( current, sizeof(*reply) ); + if ((thread = get_thread_from_handle( req->handle, THREAD_SUSPEND_RESUME ))) { - reply->count = suspend_thread( thread ); + req->count = suspend_thread( thread ); release_object( thread ); } } @@ -624,10 +608,10 @@ DECL_HANDLER(suspend_thread) DECL_HANDLER(resume_thread) { struct thread *thread; - struct resume_thread_reply *reply = push_reply_data( current, sizeof(*reply) ); + if ((thread = get_thread_from_handle( req->handle, THREAD_SUSPEND_RESUME ))) { - reply->count = resume_thread( thread ); + req->count = resume_thread( thread ); release_object( thread ); } } @@ -635,12 +619,7 @@ DECL_HANDLER(resume_thread) /* select on a handle list */ DECL_HANDLER(select) { - if (check_req_data( req->count * sizeof(int) )) - { - sleep_on( current, req->count, get_req_data( req->count * sizeof(int) ), - req->flags, req->timeout ); - } - else fatal_protocol_error( "select: bad length" ); + sleep_on( current, req->count, req->handles, req->flags, req->timeout ); } /* queue an APC for a thread */ @@ -653,3 +632,15 @@ DECL_HANDLER(queue_apc) release_object( thread ); } } + +/* get list of APC to call */ +DECL_HANDLER(get_apcs) +{ + if ((req->count = current->apc_count)) + { + memcpy( req->apcs, current->apc, current->apc_count * sizeof(*current->apc) ); + free( current->apc ); + current->apc = NULL; + current->apc_count = 0; + } +} diff --git a/server/thread.h b/server/thread.h index cb8c2486f8b..006dd2eb3db 100644 --- a/server/thread.h +++ b/server/thread.h @@ -49,9 +49,6 @@ struct thread int affinity; /* affinity mask */ int suspend; /* suspend count */ void *buffer; /* buffer for communication with the client */ - void *req_pos; /* current request position in buffer */ - void *req_end; /* ptr to end of current request */ - void *reply_pos; /* current reply position in buffer */ enum request last_req; /* last request received (for debugging) */ }; diff --git a/server/trace.c b/server/trace.c index 10ca05d6e9f..b7110aafeb8 100644 --- a/server/trace.c +++ b/server/trace.c @@ -9,46 +9,32 @@ #include #include "request.h" -static int dump_chars( void *ptr, int len ) -{ - fprintf( stderr, "\"%.*s\"", len, (char *)ptr ); - return len; -} -static int dump_ints( void *ptr, int len ) +/* dumping for functions for requests that have a variable part */ + +static void dump_varargs_select( struct select_request *req ) { int i; - if (!(len /= sizeof(int))) - { - fprintf( stderr, "{}" ); - return 0; - } - for (i = 0; i < len; i++) - fprintf( stderr, "%c%d", i ? ',' : '{', *((int *)ptr + i) ); + for (i = 0; i < req->count; i++) + fprintf( stderr, "%c%d", i ? ',' : '{', req->handles[i] ); fprintf( stderr, "}" ); - return len * sizeof(int); } -static int dump_ptrs( void *ptr, int len ) +static void dump_varargs_get_apcs( struct get_apcs_request *req ) { int i; - if (!(len /= sizeof(void*))) - { - fprintf( stderr, "{}" ); - return 0; - } - for (i = 0; i < len; i++) - fprintf( stderr, "%c%p", i ? ',' : '{', *((void **)ptr + i) ); + for (i = 0; i < 2 * req->count; i++) + fprintf( stderr, "%c%p", i ? ',' : '{', req->apcs[i] ); fprintf( stderr, "}" ); - return len * sizeof(void*); } -typedef int (*dump_func)( const void *req, int len ); + +typedef void (*dump_func)( const void *req ); /* Everything below this line is generated automatically by tools/make_requests */ /* ### make_requests begin ### */ -static int dump_new_process_request( struct new_process_request *req, int len ) +static void dump_new_process_request( struct new_process_request *req ) { fprintf( stderr, " inherit=%d,", req->inherit ); fprintf( stderr, " inherit_all=%d,", req->inherit_all ); @@ -59,45 +45,38 @@ static int dump_new_process_request( struct new_process_request *req, int len ) fprintf( stderr, " hstderr=%d,", req->hstderr ); fprintf( stderr, " cmd_show=%d,", req->cmd_show ); fprintf( stderr, " env_ptr=%p,", req->env_ptr ); - fprintf( stderr, " cmd_line=" ); - return dump_chars( req+1, len - (int)sizeof(*req) ) + sizeof(*req); + fprintf( stderr, " cmdline=\"%s\"", req->cmdline ); } -static int dump_new_process_reply( struct new_process_reply *req, int len ) +static void dump_new_process_reply( struct new_process_request *req ) { fprintf( stderr, " pid=%p,", req->pid ); fprintf( stderr, " handle=%d", req->handle ); - return (int)sizeof(*req); } -static int dump_new_thread_request( struct new_thread_request *req, int len ) +static void dump_new_thread_request( struct new_thread_request *req ) { fprintf( stderr, " pid=%p,", req->pid ); fprintf( stderr, " suspend=%d,", req->suspend ); fprintf( stderr, " inherit=%d", req->inherit ); - return (int)sizeof(*req); } -static int dump_new_thread_reply( struct new_thread_reply *req, int len ) +static void dump_new_thread_reply( struct new_thread_request *req ) { fprintf( stderr, " tid=%p,", req->tid ); fprintf( stderr, " handle=%d", req->handle ); - return (int)sizeof(*req); } -static int dump_set_debug_request( struct set_debug_request *req, int len ) +static void dump_set_debug_request( struct set_debug_request *req ) { fprintf( stderr, " level=%d", req->level ); - return (int)sizeof(*req); } -static int dump_init_process_request( struct init_process_request *req, int len ) +static void dump_init_process_request( struct init_process_request *req ) { - fprintf( stderr, " dummy=%d", req->dummy ); - return (int)sizeof(*req); } -static int dump_init_process_reply( struct init_process_reply *req, int len ) +static void dump_init_process_reply( struct init_process_request *req ) { fprintf( stderr, " start_flags=%d,", req->start_flags ); fprintf( stderr, " hstdin=%d,", req->hstdin ); @@ -105,151 +84,146 @@ static int dump_init_process_reply( struct init_process_reply *req, int len ) fprintf( stderr, " hstderr=%d,", req->hstderr ); fprintf( stderr, " cmd_show=%d,", req->cmd_show ); fprintf( stderr, " env_ptr=%p,", req->env_ptr ); - fprintf( stderr, " cmdline=" ); - return dump_chars( req+1, len - (int)sizeof(*req) ) + sizeof(*req); + fprintf( stderr, " cmdline=\"%s\"", req->cmdline ); } -static int dump_init_thread_request( struct init_thread_request *req, int len ) +static void dump_init_thread_request( struct init_thread_request *req ) { fprintf( stderr, " unix_pid=%d,", req->unix_pid ); fprintf( stderr, " teb=%p", req->teb ); - return (int)sizeof(*req); } -static int dump_init_thread_reply( struct init_thread_reply *req, int len ) +static void dump_init_thread_reply( struct init_thread_request *req ) { fprintf( stderr, " pid=%p,", req->pid ); fprintf( stderr, " tid=%p", req->tid ); - return (int)sizeof(*req); } -static int dump_terminate_process_request( struct terminate_process_request *req, int len ) +static void dump_get_thread_buffer_request( struct get_thread_buffer_request *req ) +{ + fprintf( stderr, " dummy=%d", req->dummy ); +} + +static void dump_terminate_process_request( struct terminate_process_request *req ) { fprintf( stderr, " handle=%d,", req->handle ); fprintf( stderr, " exit_code=%d", req->exit_code ); - return (int)sizeof(*req); } -static int dump_terminate_thread_request( struct terminate_thread_request *req, int len ) +static void dump_terminate_thread_request( struct terminate_thread_request *req ) { fprintf( stderr, " handle=%d,", req->handle ); fprintf( stderr, " exit_code=%d", req->exit_code ); - return (int)sizeof(*req); } -static int dump_get_process_info_request( struct get_process_info_request *req, int len ) +static void dump_get_process_info_request( struct get_process_info_request *req ) { fprintf( stderr, " handle=%d", req->handle ); - return (int)sizeof(*req); } -static int dump_get_process_info_reply( struct get_process_info_reply *req, int len ) +static void dump_get_process_info_reply( struct get_process_info_request *req ) { fprintf( stderr, " pid=%p,", req->pid ); fprintf( stderr, " exit_code=%d,", req->exit_code ); fprintf( stderr, " priority=%d,", req->priority ); fprintf( stderr, " process_affinity=%d,", req->process_affinity ); fprintf( stderr, " system_affinity=%d", req->system_affinity ); - return (int)sizeof(*req); } -static int dump_set_process_info_request( struct set_process_info_request *req, int len ) +static void dump_set_process_info_request( struct set_process_info_request *req ) { fprintf( stderr, " handle=%d,", req->handle ); fprintf( stderr, " mask=%d,", req->mask ); fprintf( stderr, " priority=%d,", req->priority ); fprintf( stderr, " affinity=%d", req->affinity ); - return (int)sizeof(*req); } -static int dump_get_thread_info_request( struct get_thread_info_request *req, int len ) +static void dump_get_thread_info_request( struct get_thread_info_request *req ) { fprintf( stderr, " handle=%d", req->handle ); - return (int)sizeof(*req); } -static int dump_get_thread_info_reply( struct get_thread_info_reply *req, int len ) +static void dump_get_thread_info_reply( struct get_thread_info_request *req ) { fprintf( stderr, " tid=%p,", req->tid ); fprintf( stderr, " exit_code=%d,", req->exit_code ); fprintf( stderr, " priority=%d", req->priority ); - return (int)sizeof(*req); } -static int dump_set_thread_info_request( struct set_thread_info_request *req, int len ) +static void dump_set_thread_info_request( struct set_thread_info_request *req ) { fprintf( stderr, " handle=%d,", req->handle ); fprintf( stderr, " mask=%d,", req->mask ); fprintf( stderr, " priority=%d,", req->priority ); fprintf( stderr, " affinity=%d", req->affinity ); - return (int)sizeof(*req); } -static int dump_suspend_thread_request( struct suspend_thread_request *req, int len ) +static void dump_suspend_thread_request( struct suspend_thread_request *req ) { fprintf( stderr, " handle=%d", req->handle ); - return (int)sizeof(*req); } -static int dump_suspend_thread_reply( struct suspend_thread_reply *req, int len ) +static void dump_suspend_thread_reply( struct suspend_thread_request *req ) { fprintf( stderr, " count=%d", req->count ); - return (int)sizeof(*req); } -static int dump_resume_thread_request( struct resume_thread_request *req, int len ) +static void dump_resume_thread_request( struct resume_thread_request *req ) { fprintf( stderr, " handle=%d", req->handle ); - return (int)sizeof(*req); } -static int dump_resume_thread_reply( struct resume_thread_reply *req, int len ) +static void dump_resume_thread_reply( struct resume_thread_request *req ) { fprintf( stderr, " count=%d", req->count ); - return (int)sizeof(*req); } -static int dump_debugger_request( struct debugger_request *req, int len ) +static void dump_debugger_request( struct debugger_request *req ) { fprintf( stderr, " op=%d", req->op ); - return (int)sizeof(*req); } -static int dump_queue_apc_request( struct queue_apc_request *req, int len ) +static void dump_queue_apc_request( struct queue_apc_request *req ) { fprintf( stderr, " handle=%d,", req->handle ); fprintf( stderr, " func=%p,", req->func ); fprintf( stderr, " param=%p", req->param ); - return (int)sizeof(*req); } -static int dump_close_handle_request( struct close_handle_request *req, int len ) +static void dump_get_apcs_request( struct get_apcs_request *req ) +{ +} + +static void dump_get_apcs_reply( struct get_apcs_request *req ) +{ + fprintf( stderr, " count=%d,", req->count ); + fprintf( stderr, " apcs=" ); + dump_varargs_get_apcs( req ); +} + +static void dump_close_handle_request( struct close_handle_request *req ) { fprintf( stderr, " handle=%d", req->handle ); - return (int)sizeof(*req); } -static int dump_get_handle_info_request( struct get_handle_info_request *req, int len ) +static void dump_get_handle_info_request( struct get_handle_info_request *req ) { fprintf( stderr, " handle=%d", req->handle ); - return (int)sizeof(*req); } -static int dump_get_handle_info_reply( struct get_handle_info_reply *req, int len ) +static void dump_get_handle_info_reply( struct get_handle_info_request *req ) { fprintf( stderr, " flags=%d", req->flags ); - return (int)sizeof(*req); } -static int dump_set_handle_info_request( struct set_handle_info_request *req, int len ) +static void dump_set_handle_info_request( struct set_handle_info_request *req ) { fprintf( stderr, " handle=%d,", req->handle ); fprintf( stderr, " flags=%d,", req->flags ); fprintf( stderr, " mask=%d", req->mask ); - return (int)sizeof(*req); } -static int dump_dup_handle_request( struct dup_handle_request *req, int len ) +static void dump_dup_handle_request( struct dup_handle_request *req ) { fprintf( stderr, " src_process=%d,", req->src_process ); fprintf( stderr, " src_handle=%d,", req->src_handle ); @@ -257,229 +231,207 @@ static int dump_dup_handle_request( struct dup_handle_request *req, int len ) fprintf( stderr, " access=%08x,", req->access ); fprintf( stderr, " inherit=%d,", req->inherit ); fprintf( stderr, " options=%d", req->options ); - return (int)sizeof(*req); } -static int dump_dup_handle_reply( struct dup_handle_reply *req, int len ) +static void dump_dup_handle_reply( struct dup_handle_request *req ) { fprintf( stderr, " handle=%d", req->handle ); - return (int)sizeof(*req); } -static int dump_open_process_request( struct open_process_request *req, int len ) +static void dump_open_process_request( struct open_process_request *req ) { fprintf( stderr, " pid=%p,", req->pid ); fprintf( stderr, " access=%08x,", req->access ); fprintf( stderr, " inherit=%d", req->inherit ); - return (int)sizeof(*req); } -static int dump_open_process_reply( struct open_process_reply *req, int len ) +static void dump_open_process_reply( struct open_process_request *req ) { fprintf( stderr, " handle=%d", req->handle ); - return (int)sizeof(*req); } -static int dump_select_request( struct select_request *req, int len ) +static void dump_select_request( struct select_request *req ) { fprintf( stderr, " count=%d,", req->count ); fprintf( stderr, " flags=%d,", req->flags ); fprintf( stderr, " timeout=%d,", req->timeout ); fprintf( stderr, " handles=" ); - return dump_ints( req+1, len - (int)sizeof(*req) ) + sizeof(*req); + dump_varargs_select( req ); } -static int dump_select_reply( struct select_reply *req, int len ) +static void dump_select_reply( struct select_request *req ) { - fprintf( stderr, " signaled=%d,", req->signaled ); - fprintf( stderr, " apcs=" ); - return dump_ptrs( req+1, len - (int)sizeof(*req) ) + sizeof(*req); + fprintf( stderr, " signaled=%d", req->signaled ); } -static int dump_create_event_request( struct create_event_request *req, int len ) +static void dump_create_event_request( struct create_event_request *req ) { fprintf( stderr, " manual_reset=%d,", req->manual_reset ); fprintf( stderr, " initial_state=%d,", req->initial_state ); fprintf( stderr, " inherit=%d,", req->inherit ); - fprintf( stderr, " name=" ); - return dump_chars( req+1, len - (int)sizeof(*req) ) + sizeof(*req); + fprintf( stderr, " name=\"%s\"", req->name ); } -static int dump_create_event_reply( struct create_event_reply *req, int len ) +static void dump_create_event_reply( struct create_event_request *req ) { fprintf( stderr, " handle=%d", req->handle ); - return (int)sizeof(*req); } -static int dump_event_op_request( struct event_op_request *req, int len ) +static void dump_event_op_request( struct event_op_request *req ) { fprintf( stderr, " handle=%d,", req->handle ); fprintf( stderr, " op=%d", req->op ); - return (int)sizeof(*req); } -static int dump_open_event_request( struct open_event_request *req, int len ) +static void dump_open_event_request( struct open_event_request *req ) { fprintf( stderr, " access=%08x,", req->access ); fprintf( stderr, " inherit=%d,", req->inherit ); - fprintf( stderr, " name=" ); - return dump_chars( req+1, len - (int)sizeof(*req) ) + sizeof(*req); + fprintf( stderr, " name=\"%s\"", req->name ); } -static int dump_open_event_reply( struct open_event_reply *req, int len ) +static void dump_open_event_reply( struct open_event_request *req ) { fprintf( stderr, " handle=%d", req->handle ); - return (int)sizeof(*req); } -static int dump_create_mutex_request( struct create_mutex_request *req, int len ) +static void dump_create_mutex_request( struct create_mutex_request *req ) { fprintf( stderr, " owned=%d,", req->owned ); fprintf( stderr, " inherit=%d,", req->inherit ); - fprintf( stderr, " name=" ); - return dump_chars( req+1, len - (int)sizeof(*req) ) + sizeof(*req); + fprintf( stderr, " name=\"%s\"", req->name ); } -static int dump_create_mutex_reply( struct create_mutex_reply *req, int len ) +static void dump_create_mutex_reply( struct create_mutex_request *req ) { fprintf( stderr, " handle=%d", req->handle ); - return (int)sizeof(*req); } -static int dump_release_mutex_request( struct release_mutex_request *req, int len ) +static void dump_release_mutex_request( struct release_mutex_request *req ) { fprintf( stderr, " handle=%d", req->handle ); - return (int)sizeof(*req); } -static int dump_open_mutex_request( struct open_mutex_request *req, int len ) +static void dump_open_mutex_request( struct open_mutex_request *req ) { fprintf( stderr, " access=%08x,", req->access ); fprintf( stderr, " inherit=%d,", req->inherit ); - fprintf( stderr, " name=" ); - return dump_chars( req+1, len - (int)sizeof(*req) ) + sizeof(*req); + fprintf( stderr, " name=\"%s\"", req->name ); } -static int dump_open_mutex_reply( struct open_mutex_reply *req, int len ) +static void dump_open_mutex_reply( struct open_mutex_request *req ) { fprintf( stderr, " handle=%d", req->handle ); - return (int)sizeof(*req); } -static int dump_create_semaphore_request( struct create_semaphore_request *req, int len ) +static void dump_create_semaphore_request( struct create_semaphore_request *req ) { fprintf( stderr, " initial=%08x,", req->initial ); fprintf( stderr, " max=%08x,", req->max ); fprintf( stderr, " inherit=%d,", req->inherit ); - fprintf( stderr, " name=" ); - return dump_chars( req+1, len - (int)sizeof(*req) ) + sizeof(*req); + fprintf( stderr, " name=\"%s\"", req->name ); } -static int dump_create_semaphore_reply( struct create_semaphore_reply *req, int len ) +static void dump_create_semaphore_reply( struct create_semaphore_request *req ) { fprintf( stderr, " handle=%d", req->handle ); - return (int)sizeof(*req); } -static int dump_release_semaphore_request( struct release_semaphore_request *req, int len ) +static void dump_release_semaphore_request( struct release_semaphore_request *req ) { fprintf( stderr, " handle=%d,", req->handle ); fprintf( stderr, " count=%08x", req->count ); - return (int)sizeof(*req); } -static int dump_release_semaphore_reply( struct release_semaphore_reply *req, int len ) +static void dump_release_semaphore_reply( struct release_semaphore_request *req ) { fprintf( stderr, " prev_count=%08x", req->prev_count ); - return (int)sizeof(*req); } -static int dump_open_semaphore_request( struct open_semaphore_request *req, int len ) +static void dump_open_semaphore_request( struct open_semaphore_request *req ) { fprintf( stderr, " access=%08x,", req->access ); fprintf( stderr, " inherit=%d,", req->inherit ); - fprintf( stderr, " name=" ); - return dump_chars( req+1, len - (int)sizeof(*req) ) + sizeof(*req); + fprintf( stderr, " name=\"%s\"", req->name ); } -static int dump_open_semaphore_reply( struct open_semaphore_reply *req, int len ) +static void dump_open_semaphore_reply( struct open_semaphore_request *req ) { fprintf( stderr, " handle=%d", req->handle ); - return (int)sizeof(*req); } -static int dump_create_file_request( struct create_file_request *req, int len ) +static void dump_create_file_request( struct create_file_request *req ) { fprintf( stderr, " access=%08x,", req->access ); fprintf( stderr, " inherit=%d,", req->inherit ); fprintf( stderr, " sharing=%08x,", req->sharing ); fprintf( stderr, " create=%d,", req->create ); fprintf( stderr, " attrs=%08x,", req->attrs ); - fprintf( stderr, " name=" ); - return dump_chars( req+1, len - (int)sizeof(*req) ) + sizeof(*req); + fprintf( stderr, " name=\"%s\"", req->name ); } -static int dump_create_file_reply( struct create_file_reply *req, int len ) +static void dump_create_file_reply( struct create_file_request *req ) { fprintf( stderr, " handle=%d", req->handle ); - return (int)sizeof(*req); } -static int dump_get_read_fd_request( struct get_read_fd_request *req, int len ) +static void dump_alloc_file_handle_request( struct alloc_file_handle_request *req ) +{ + fprintf( stderr, " access=%08x", req->access ); +} + +static void dump_alloc_file_handle_reply( struct alloc_file_handle_request *req ) { fprintf( stderr, " handle=%d", req->handle ); - return (int)sizeof(*req); } -static int dump_get_write_fd_request( struct get_write_fd_request *req, int len ) +static void dump_get_read_fd_request( struct get_read_fd_request *req ) { fprintf( stderr, " handle=%d", req->handle ); - return (int)sizeof(*req); } -static int dump_set_file_pointer_request( struct set_file_pointer_request *req, int len ) +static void dump_get_write_fd_request( struct get_write_fd_request *req ) +{ + fprintf( stderr, " handle=%d", req->handle ); +} + +static void dump_set_file_pointer_request( struct set_file_pointer_request *req ) { fprintf( stderr, " handle=%d,", req->handle ); fprintf( stderr, " low=%d,", req->low ); fprintf( stderr, " high=%d,", req->high ); fprintf( stderr, " whence=%d", req->whence ); - return (int)sizeof(*req); } -static int dump_set_file_pointer_reply( struct set_file_pointer_reply *req, int len ) +static void dump_set_file_pointer_reply( struct set_file_pointer_request *req ) { - fprintf( stderr, " low=%d,", req->low ); - fprintf( stderr, " high=%d", req->high ); - return (int)sizeof(*req); + fprintf( stderr, " new_low=%d,", req->new_low ); + fprintf( stderr, " new_high=%d", req->new_high ); } -static int dump_truncate_file_request( struct truncate_file_request *req, int len ) +static void dump_truncate_file_request( struct truncate_file_request *req ) { fprintf( stderr, " handle=%d", req->handle ); - return (int)sizeof(*req); } -static int dump_set_file_time_request( struct set_file_time_request *req, int len ) +static void dump_set_file_time_request( struct set_file_time_request *req ) { fprintf( stderr, " handle=%d,", req->handle ); fprintf( stderr, " access_time=%ld,", req->access_time ); fprintf( stderr, " write_time=%ld", req->write_time ); - return (int)sizeof(*req); } -static int dump_flush_file_request( struct flush_file_request *req, int len ) +static void dump_flush_file_request( struct flush_file_request *req ) { fprintf( stderr, " handle=%d", req->handle ); - return (int)sizeof(*req); } -static int dump_get_file_info_request( struct get_file_info_request *req, int len ) +static void dump_get_file_info_request( struct get_file_info_request *req ) { fprintf( stderr, " handle=%d", req->handle ); - return (int)sizeof(*req); } -static int dump_get_file_info_reply( struct get_file_info_reply *req, int len ) +static void dump_get_file_info_reply( struct get_file_info_request *req ) { fprintf( stderr, " type=%d,", req->type ); fprintf( stderr, " attr=%d,", req->attr ); @@ -491,292 +443,252 @@ static int dump_get_file_info_reply( struct get_file_info_reply *req, int len ) fprintf( stderr, " index_high=%d,", req->index_high ); fprintf( stderr, " index_low=%d,", req->index_low ); fprintf( stderr, " serial=%08x", req->serial ); - return (int)sizeof(*req); } -static int dump_lock_file_request( struct lock_file_request *req, int len ) +static void dump_lock_file_request( struct lock_file_request *req ) { fprintf( stderr, " handle=%d,", req->handle ); fprintf( stderr, " offset_low=%08x,", req->offset_low ); fprintf( stderr, " offset_high=%08x,", req->offset_high ); fprintf( stderr, " count_low=%08x,", req->count_low ); fprintf( stderr, " count_high=%08x", req->count_high ); - return (int)sizeof(*req); } -static int dump_unlock_file_request( struct unlock_file_request *req, int len ) +static void dump_unlock_file_request( struct unlock_file_request *req ) { fprintf( stderr, " handle=%d,", req->handle ); fprintf( stderr, " offset_low=%08x,", req->offset_low ); fprintf( stderr, " offset_high=%08x,", req->offset_high ); fprintf( stderr, " count_low=%08x,", req->count_low ); fprintf( stderr, " count_high=%08x", req->count_high ); - return (int)sizeof(*req); } -static int dump_create_pipe_request( struct create_pipe_request *req, int len ) +static void dump_create_pipe_request( struct create_pipe_request *req ) { fprintf( stderr, " inherit=%d", req->inherit ); - return (int)sizeof(*req); } -static int dump_create_pipe_reply( struct create_pipe_reply *req, int len ) +static void dump_create_pipe_reply( struct create_pipe_request *req ) { fprintf( stderr, " handle_read=%d,", req->handle_read ); fprintf( stderr, " handle_write=%d", req->handle_write ); - return (int)sizeof(*req); } -static int dump_alloc_console_request( struct alloc_console_request *req, int len ) +static void dump_alloc_console_request( struct alloc_console_request *req ) { fprintf( stderr, " access=%08x,", req->access ); fprintf( stderr, " inherit=%d", req->inherit ); - return (int)sizeof(*req); } -static int dump_alloc_console_reply( struct alloc_console_reply *req, int len ) +static void dump_alloc_console_reply( struct alloc_console_request *req ) { fprintf( stderr, " handle_in=%d,", req->handle_in ); fprintf( stderr, " handle_out=%d", req->handle_out ); - return (int)sizeof(*req); } -static int dump_free_console_request( struct free_console_request *req, int len ) +static void dump_free_console_request( struct free_console_request *req ) { fprintf( stderr, " dummy=%d", req->dummy ); - return (int)sizeof(*req); } -static int dump_open_console_request( struct open_console_request *req, int len ) +static void dump_open_console_request( struct open_console_request *req ) { fprintf( stderr, " output=%d,", req->output ); fprintf( stderr, " access=%08x,", req->access ); fprintf( stderr, " inherit=%d", req->inherit ); - return (int)sizeof(*req); } -static int dump_open_console_reply( struct open_console_reply *req, int len ) +static void dump_open_console_reply( struct open_console_request *req ) { fprintf( stderr, " handle=%d", req->handle ); - return (int)sizeof(*req); } -static int dump_set_console_fd_request( struct set_console_fd_request *req, int len ) +static void dump_set_console_fd_request( struct set_console_fd_request *req ) { fprintf( stderr, " handle=%d,", req->handle ); + fprintf( stderr, " file_handle=%d,", req->file_handle ); fprintf( stderr, " pid=%d", req->pid ); - return (int)sizeof(*req); } -static int dump_get_console_mode_request( struct get_console_mode_request *req, int len ) +static void dump_get_console_mode_request( struct get_console_mode_request *req ) { fprintf( stderr, " handle=%d", req->handle ); - return (int)sizeof(*req); } -static int dump_get_console_mode_reply( struct get_console_mode_reply *req, int len ) +static void dump_get_console_mode_reply( struct get_console_mode_request *req ) { fprintf( stderr, " mode=%d", req->mode ); - return (int)sizeof(*req); } -static int dump_set_console_mode_request( struct set_console_mode_request *req, int len ) +static void dump_set_console_mode_request( struct set_console_mode_request *req ) { fprintf( stderr, " handle=%d,", req->handle ); fprintf( stderr, " mode=%d", req->mode ); - return (int)sizeof(*req); } -static int dump_set_console_info_request( struct set_console_info_request *req, int len ) +static void dump_set_console_info_request( struct set_console_info_request *req ) { fprintf( stderr, " handle=%d,", req->handle ); fprintf( stderr, " mask=%d,", req->mask ); fprintf( stderr, " cursor_size=%d,", req->cursor_size ); fprintf( stderr, " cursor_visible=%d,", req->cursor_visible ); - fprintf( stderr, " title=" ); - return dump_chars( req+1, len - (int)sizeof(*req) ) + sizeof(*req); + fprintf( stderr, " title=\"%s\"", req->title ); } -static int dump_get_console_info_request( struct get_console_info_request *req, int len ) +static void dump_get_console_info_request( struct get_console_info_request *req ) { fprintf( stderr, " handle=%d", req->handle ); - return (int)sizeof(*req); } -static int dump_get_console_info_reply( struct get_console_info_reply *req, int len ) +static void dump_get_console_info_reply( struct get_console_info_request *req ) { fprintf( stderr, " cursor_size=%d,", req->cursor_size ); fprintf( stderr, " cursor_visible=%d,", req->cursor_visible ); fprintf( stderr, " pid=%d,", req->pid ); - fprintf( stderr, " title=" ); - return dump_chars( req+1, len - (int)sizeof(*req) ) + sizeof(*req); + fprintf( stderr, " title=\"%s\"", req->title ); } -static int dump_write_console_input_request( struct write_console_input_request *req, int len ) +static void dump_write_console_input_request( struct write_console_input_request *req ) { fprintf( stderr, " handle=%d,", req->handle ); fprintf( stderr, " count=%d", req->count ); - return (int)sizeof(*req); } -static int dump_write_console_input_reply( struct write_console_input_reply *req, int len ) +static void dump_write_console_input_reply( struct write_console_input_request *req ) { fprintf( stderr, " written=%d", req->written ); - return (int)sizeof(*req); } -static int dump_read_console_input_request( struct read_console_input_request *req, int len ) +static void dump_read_console_input_request( struct read_console_input_request *req ) { fprintf( stderr, " handle=%d,", req->handle ); fprintf( stderr, " count=%d,", req->count ); fprintf( stderr, " flush=%d", req->flush ); - return (int)sizeof(*req); } -static int dump_read_console_input_reply( struct read_console_input_reply *req, int len ) +static void dump_read_console_input_reply( struct read_console_input_request *req ) { - fprintf( stderr, " dummy=%d", req->dummy ); - return (int)sizeof(*req); + fprintf( stderr, " read=%d", req->read ); } -static int dump_create_change_notification_request( struct create_change_notification_request *req, int len ) +static void dump_create_change_notification_request( struct create_change_notification_request *req ) { fprintf( stderr, " subtree=%d,", req->subtree ); fprintf( stderr, " filter=%d", req->filter ); - return (int)sizeof(*req); } -static int dump_create_change_notification_reply( struct create_change_notification_reply *req, int len ) +static void dump_create_change_notification_reply( struct create_change_notification_request *req ) { fprintf( stderr, " handle=%d", req->handle ); - return (int)sizeof(*req); } -static int dump_create_mapping_request( struct create_mapping_request *req, int len ) +static void dump_create_mapping_request( struct create_mapping_request *req ) { fprintf( stderr, " size_high=%d,", req->size_high ); fprintf( stderr, " size_low=%d,", req->size_low ); fprintf( stderr, " protect=%d,", req->protect ); fprintf( stderr, " inherit=%d,", req->inherit ); - fprintf( stderr, " handle=%d,", req->handle ); - fprintf( stderr, " name=" ); - return dump_chars( req+1, len - (int)sizeof(*req) ) + sizeof(*req); + fprintf( stderr, " file_handle=%d,", req->file_handle ); + fprintf( stderr, " name=\"%s\"", req->name ); } -static int dump_create_mapping_reply( struct create_mapping_reply *req, int len ) +static void dump_create_mapping_reply( struct create_mapping_request *req ) { fprintf( stderr, " handle=%d", req->handle ); - return (int)sizeof(*req); } -static int dump_open_mapping_request( struct open_mapping_request *req, int len ) +static void dump_open_mapping_request( struct open_mapping_request *req ) { fprintf( stderr, " access=%08x,", req->access ); fprintf( stderr, " inherit=%d,", req->inherit ); - fprintf( stderr, " name=" ); - return dump_chars( req+1, len - (int)sizeof(*req) ) + sizeof(*req); + fprintf( stderr, " name=\"%s\"", req->name ); } -static int dump_open_mapping_reply( struct open_mapping_reply *req, int len ) +static void dump_open_mapping_reply( struct open_mapping_request *req ) { fprintf( stderr, " handle=%d", req->handle ); - return (int)sizeof(*req); } -static int dump_get_mapping_info_request( struct get_mapping_info_request *req, int len ) +static void dump_get_mapping_info_request( struct get_mapping_info_request *req ) { fprintf( stderr, " handle=%d", req->handle ); - return (int)sizeof(*req); } -static int dump_get_mapping_info_reply( struct get_mapping_info_reply *req, int len ) +static void dump_get_mapping_info_reply( struct get_mapping_info_request *req ) { fprintf( stderr, " size_high=%d,", req->size_high ); fprintf( stderr, " size_low=%d,", req->size_low ); fprintf( stderr, " protect=%d", req->protect ); - return (int)sizeof(*req); } -static int dump_create_device_request( struct create_device_request *req, int len ) +static void dump_create_device_request( struct create_device_request *req ) { fprintf( stderr, " access=%08x,", req->access ); fprintf( stderr, " inherit=%d,", req->inherit ); fprintf( stderr, " id=%d", req->id ); - return (int)sizeof(*req); } -static int dump_create_device_reply( struct create_device_reply *req, int len ) +static void dump_create_device_reply( struct create_device_request *req ) { fprintf( stderr, " handle=%d", req->handle ); - return (int)sizeof(*req); } -static int dump_create_snapshot_request( struct create_snapshot_request *req, int len ) +static void dump_create_snapshot_request( struct create_snapshot_request *req ) { fprintf( stderr, " inherit=%d,", req->inherit ); fprintf( stderr, " flags=%d", req->flags ); - return (int)sizeof(*req); } -static int dump_create_snapshot_reply( struct create_snapshot_reply *req, int len ) +static void dump_create_snapshot_reply( struct create_snapshot_request *req ) { fprintf( stderr, " handle=%d", req->handle ); - return (int)sizeof(*req); } -static int dump_next_process_request( struct next_process_request *req, int len ) +static void dump_next_process_request( struct next_process_request *req ) { fprintf( stderr, " handle=%d,", req->handle ); fprintf( stderr, " reset=%d", req->reset ); - return (int)sizeof(*req); } -static int dump_next_process_reply( struct next_process_reply *req, int len ) +static void dump_next_process_reply( struct next_process_request *req ) { fprintf( stderr, " pid=%p,", req->pid ); fprintf( stderr, " threads=%d,", req->threads ); fprintf( stderr, " priority=%d", req->priority ); - return (int)sizeof(*req); } -static int dump_wait_debug_event_request( struct wait_debug_event_request *req, int len ) +static void dump_wait_debug_event_request( struct wait_debug_event_request *req ) { fprintf( stderr, " timeout=%d", req->timeout ); - return (int)sizeof(*req); } -static int dump_wait_debug_event_reply( struct wait_debug_event_reply *req, int len ) +static void dump_wait_debug_event_reply( struct wait_debug_event_request *req ) { fprintf( stderr, " code=%d,", req->code ); fprintf( stderr, " pid=%p,", req->pid ); fprintf( stderr, " tid=%p", req->tid ); - return (int)sizeof(*req); } -static int dump_send_debug_event_request( struct send_debug_event_request *req, int len ) +static void dump_send_debug_event_request( struct send_debug_event_request *req ) { fprintf( stderr, " code=%d", req->code ); - return (int)sizeof(*req); } -static int dump_send_debug_event_reply( struct send_debug_event_reply *req, int len ) +static void dump_send_debug_event_reply( struct send_debug_event_request *req ) { fprintf( stderr, " status=%d", req->status ); - return (int)sizeof(*req); } -static int dump_continue_debug_event_request( struct continue_debug_event_request *req, int len ) +static void dump_continue_debug_event_request( struct continue_debug_event_request *req ) { fprintf( stderr, " pid=%p,", req->pid ); fprintf( stderr, " tid=%p,", req->tid ); fprintf( stderr, " status=%d", req->status ); - return (int)sizeof(*req); } -static int dump_debug_process_request( struct debug_process_request *req, int len ) +static void dump_debug_process_request( struct debug_process_request *req ) { fprintf( stderr, " pid=%p", req->pid ); - return (int)sizeof(*req); } static const dump_func req_dumpers[REQ_NB_REQUESTS] = { @@ -785,6 +697,7 @@ static const dump_func req_dumpers[REQ_NB_REQUESTS] = { (dump_func)dump_set_debug_request, (dump_func)dump_init_process_request, (dump_func)dump_init_thread_request, + (dump_func)dump_get_thread_buffer_request, (dump_func)dump_terminate_process_request, (dump_func)dump_terminate_thread_request, (dump_func)dump_get_process_info_request, @@ -795,6 +708,7 @@ static const dump_func req_dumpers[REQ_NB_REQUESTS] = { (dump_func)dump_resume_thread_request, (dump_func)dump_debugger_request, (dump_func)dump_queue_apc_request, + (dump_func)dump_get_apcs_request, (dump_func)dump_close_handle_request, (dump_func)dump_get_handle_info_request, (dump_func)dump_set_handle_info_request, @@ -811,6 +725,7 @@ static const dump_func req_dumpers[REQ_NB_REQUESTS] = { (dump_func)dump_release_semaphore_request, (dump_func)dump_open_semaphore_request, (dump_func)dump_create_file_request, + (dump_func)dump_alloc_file_handle_request, (dump_func)dump_get_read_fd_request, (dump_func)dump_get_write_fd_request, (dump_func)dump_set_file_pointer_request, @@ -852,6 +767,7 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] = { (dump_func)dump_init_thread_reply, (dump_func)0, (dump_func)0, + (dump_func)0, (dump_func)dump_get_process_info_reply, (dump_func)0, (dump_func)dump_get_thread_info_reply, @@ -860,6 +776,7 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] = { (dump_func)dump_resume_thread_reply, (dump_func)0, (dump_func)0, + (dump_func)dump_get_apcs_reply, (dump_func)0, (dump_func)dump_get_handle_info_reply, (dump_func)0, @@ -876,6 +793,7 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] = { (dump_func)dump_release_semaphore_reply, (dump_func)dump_open_semaphore_reply, (dump_func)dump_create_file_reply, + (dump_func)dump_alloc_file_handle_reply, (dump_func)0, (dump_func)0, (dump_func)dump_set_file_pointer_reply, @@ -915,6 +833,7 @@ static const char * const req_names[REQ_NB_REQUESTS] = { "set_debug", "init_process", "init_thread", + "get_thread_buffer", "terminate_process", "terminate_thread", "get_process_info", @@ -925,6 +844,7 @@ static const char * const req_names[REQ_NB_REQUESTS] = { "resume_thread", "debugger", "queue_apc", + "get_apcs", "close_handle", "get_handle_info", "set_handle_info", @@ -941,6 +861,7 @@ static const char * const req_names[REQ_NB_REQUESTS] = { "release_semaphore", "open_semaphore", "create_file", + "alloc_file_handle", "get_read_fd", "get_write_fd", "set_file_pointer", @@ -979,16 +900,14 @@ static const char * const req_names[REQ_NB_REQUESTS] = { void trace_request( enum request req, int fd ) { - int size, len; current->last_req = req; - fprintf( stderr, "%08x: %s(", (unsigned int)current, req_names[req] ); - len = (char *)current->req_end - (char *)current->req_pos; - size = req_dumpers[req]( current->req_pos, len ); - if ((len -= size) > 0) + if (req < REQ_NB_REQUESTS) { - unsigned char *ptr = (unsigned char *)current->req_pos + size; - while (len--) fprintf( stderr, ", %02x", *ptr++ ); + fprintf( stderr, "%08x: %s(", (unsigned int)current, req_names[req] ); + req_dumpers[req]( current->buffer ); } + else + fprintf( stderr, "%08x: %d(", (unsigned int)current, req ); if (fd != -1) fprintf( stderr, " ) fd=%d\n", fd ); else fprintf( stderr, " )\n" ); } @@ -1004,22 +923,14 @@ void trace_kill( int exit_code ) (unsigned int)current, exit_code ); } -void trace_reply( struct thread *thread, int pass_fd ) +void trace_reply( struct thread *thread, unsigned int res, int pass_fd ) { - struct header *head = thread->buffer; - int len = head->len - sizeof(*head); fprintf( stderr, "%08x: %s() = %d", - (unsigned int)thread, req_names[thread->last_req], head->type ); - if (len) + (unsigned int)thread, req_names[thread->last_req], res ); + if (reply_dumpers[thread->last_req]) { - const unsigned char *data = (unsigned char *)(head + 1); - int res = 0; - fprintf( stderr, " {" ); - if (reply_dumpers[thread->last_req]) - res = reply_dumpers[thread->last_req]( data, len ); - len -= res; - data += res; - while (len--) fprintf( stderr, ", %02x", *data++ ); + fprintf( stderr, " {" ); + reply_dumpers[thread->last_req]( thread->buffer ); fprintf( stderr, " }" ); } if (pass_fd != -1) fprintf( stderr, " fd=%d\n", pass_fd ); diff --git a/tools/make_requests b/tools/make_requests index b18f7ac5858..e5af2601349 100755 --- a/tools/make_requests +++ b/tools/make_requests @@ -14,9 +14,7 @@ "unsigned int" => "%08x", "void*" => "%p", "time_t" => "%ld", - "char[0]" => "dump_chars", - "int[0]" => "dump_ints", - "void*[0]" => "dump_ptrs" + "char[1]" => "\\\"%s\\\"" ); my @requests = (); @@ -31,7 +29,6 @@ my @trace_lines = (); while () { if (/^struct +(\w+)_request/) { &DO_REQUEST($1); } - if (/^struct +(\w+)_reply/) { &DO_REPLY($1); } } ### Output the dumping function tables @@ -92,71 +89,56 @@ REPLACE_IN_FILE( "server/request.h", @request_lines ); sub DO_REQUEST { my $name = shift; - my @struct = (); + my @in_struct = (); + my @out_struct = (); while () { + my ($dir, $type, $var); last if /^};$/; next if /^{$/; s!/\*.*\*/!!g; next if /^\s*$/; - / *(\w+\**( +\w+\**)*) +(\w+)(\[0\])?;/ or die "Unrecognized syntax $_"; - my $type = $1 . ($4 || ""); - my $var = $3; - die "Unrecognized type $type" unless defined($formats{$type}); - push @struct, $type, $var; + /^\s*(IN|OUT)\s*(\w+\**(\s+\w+\**)*)\s+(\w+)(\[[1]\])?;/ or die "Unrecognized syntax $_"; + $dir = $1; + $type = $2 . ($5 || ""); + $var = $4; + die "Unrecognized type $type" unless (defined($formats{$type}) || $5); + if ($dir =~ /IN/) { push @in_struct, $type, $var; } + if ($dir =~ /OUT/) { push @out_struct, $type, $var; } } push @requests, $name; - &DO_DUMP_FUNC( $name . "_request",@struct); -} - -### Handle a reply structure definition - -sub DO_REPLY -{ - my $name = shift; - my @struct = (); - while () + &DO_DUMP_FUNC( $name, "request", @in_struct); + if ($#out_struct >= 0) { - last if /^};$/; - next if /^{$/; - s!/\*.*\*/!!g; - next if /^\s*$/; - / *(\w+\**( +\w+\**)*) +(\w+)(\[0\])?;/ or die "Unrecognized syntax $_"; - my $type = $1 . ($4 || ""); - my $var = $3; - die "Unrecognized type $type" unless defined($formats{$type}); - push @struct, $type, $var; + $replies{$name} = 1; + &DO_DUMP_FUNC( $name, "reply", @out_struct); } - $replies{$name} = 1; - &DO_DUMP_FUNC( $name . "_reply" ,@struct); } ### Generate a dumping function sub DO_DUMP_FUNC { - my $vararg = 0; my $name = shift; - push @trace_lines, "static int dump_$name( struct $name *req, int len )\n{\n"; + my $req = shift; + push @trace_lines, "static void dump_${name}_$req( struct ${name}_request *req )\n{\n"; while ($#_ >= 0) { my $type = shift; my $var = shift; - if ($type =~ /\[0\]$/) # vararg type? - { - $vararg = 1; - push @trace_lines, " fprintf( stderr, \" $var=\" );\n"; - push @trace_lines, " return $formats{$type}( req+1, len - (int)sizeof(*req) ) + sizeof(*req);\n"; - } - else + if (defined($formats{$type})) { push @trace_lines, " fprintf( stderr, \" $var=$formats{$type}"; push @trace_lines, "," if ($#_ > 0); push @trace_lines, "\", "; push @trace_lines, "req->$var );\n"; + } + else # must be some varargs format + { + push @trace_lines, " fprintf( stderr, \" $var=\" );\n"; + push @trace_lines, " dump_varargs_${name}( req );\n"; } } - push @trace_lines, " return (int)sizeof(*req);\n" unless $vararg; push @trace_lines, "}\n\n"; } diff --git a/win32/console.c b/win32/console.c index ebb371dbdb8..6f8281a0b88 100644 --- a/win32/console.c +++ b/win32/console.c @@ -55,15 +55,14 @@ FILE *wine_openpty(int *master, int *slave, char *name, struct termios *term, struct winsize *winsize); /**************************************************************************** - * CONSOLE_GetInfo + * CONSOLE_GetPid */ -static BOOL CONSOLE_GetInfo( HANDLE handle, struct get_console_info_reply *reply ) +static int CONSOLE_GetPid( HANDLE handle ) { - struct get_console_info_request req; - - req.handle = handle; - CLIENT_SendRequest( REQ_GET_CONSOLE_INFO, -1, 1, &req, sizeof(req) ); - return !CLIENT_WaitReply( NULL, NULL, 1, reply, sizeof(*reply) ); + struct get_console_info_request *req = get_req_buffer(); + req->handle = handle; + if (server_call( REQ_GET_CONSOLE_INFO )) return 0; + return req->pid; } /**************************************************************************** @@ -428,9 +427,7 @@ DWORD WINAPI GetLargestConsoleWindowSize( HANDLE hConsoleOutput ) */ BOOL WINAPI FreeConsole(VOID) { - struct free_console_request req; - CLIENT_SendRequest( REQ_FREE_CONSOLE, -1, 1, &req, sizeof(req) ); - return !CLIENT_WaitReply( NULL, NULL, 0 ); + return !server_call( REQ_FREE_CONSOLE ); } @@ -441,16 +438,15 @@ BOOL WINAPI FreeConsole(VOID) */ HANDLE CONSOLE_OpenHandle( BOOL output, DWORD access, LPSECURITY_ATTRIBUTES sa ) { - struct open_console_request req; - struct open_console_reply reply; + int ret = -1; + struct open_console_request *req = get_req_buffer(); - req.output = output; - req.access = access; - req.inherit = (sa && (sa->nLength>=sizeof(*sa)) && sa->bInheritHandle); - CLIENT_SendRequest( REQ_OPEN_CONSOLE, -1, 1, &req, sizeof(req) ); + req->output = output; + req->access = access; + req->inherit = (sa && (sa->nLength>=sizeof(*sa)) && sa->bInheritHandle); SetLastError(0); - if (!CLIENT_WaitSimpleReply( &reply, sizeof(reply), NULL )) return reply.handle; - return -1; + if (!server_call( REQ_OPEN_CONSOLE )) ret = req->handle; + return ret; } @@ -470,17 +466,13 @@ HANDLE CONSOLE_OpenHandle( BOOL output, DWORD access, LPSECURITY_ATTRIBUTES sa ) */ static BOOL CONSOLE_make_complex(HANDLE handle) { - struct set_console_fd_request req; - struct get_console_info_reply info; + struct set_console_fd_request *req = get_req_buffer(); struct termios term; char buf[256]; char c = '\0'; - int status = 0; - int i,xpid,master,slave; - DWORD xlen; + int i,xpid,master,slave,pty_handle; - if (!CONSOLE_GetInfo( handle, &info )) return FALSE; - if (info.pid) return TRUE; /* already complex */ + if (CONSOLE_GetPid( handle )) return TRUE; /* already complex */ MESSAGE("Console: Making console complex (creating an xterm)...\n"); @@ -494,6 +486,7 @@ static BOOL CONSOLE_make_complex(HANDLE handle) if ((xpid=fork()) == 0) { tcsetattr(slave, TCSADRAIN, &term); + close( slave ); sprintf(buf, "-Sxx%d", master); /* "-fn vga" for VGA font. Harmless if vga is not present: * xterm: unable to open font "vga", trying "fixed".... @@ -502,35 +495,41 @@ static BOOL CONSOLE_make_complex(HANDLE handle) ERR("error creating AllocConsole xterm\n"); exit(1); } - - req.handle = handle; - req.pid = xpid; - CLIENT_SendRequest( REQ_SET_CONSOLE_FD, dup(slave), 1, &req, sizeof(req) ); - CLIENT_WaitReply( NULL, NULL, 0 ); + pty_handle = FILE_DupUnixHandle( slave, GENERIC_READ | GENERIC_WRITE ); + close( master ); + close( slave ); + if (pty_handle == -1) return FALSE; /* most xterms like to print their window ID when used with -S; * read it and continue before the user has a chance... */ - for (i=0; c!='\n'; (status=read(slave, &c, 1)), i++) { - if (status == -1 && c == '\0') { - /* wait for xterm to be created */ - usleep(100); - } - if (i > 10000) { - ERR("can't read xterm WID\n"); - kill(xpid, SIGKILL); - return FALSE; - } - } - /* enable mouseclicks */ - sprintf(buf,"%c[?1001s%c[?1000h",27,27); - WriteFile(handle,buf,strlen(buf),&xlen,NULL); - - if (GetConsoleTitleA( buf, sizeof(buf) )) + for (i = 0; i < 10000; i++) { - WriteFile(handle,"\033]2;",4,&xlen,NULL); - WriteFile(handle,buf,strlen(buf),&xlen,NULL); - WriteFile(handle,"\a",1,&xlen,NULL); + BOOL ok = ReadFile( pty_handle, &c, 1, NULL, NULL ); + if (!ok && !c) usleep(100); /* wait for xterm to be created */ + else if (c == '\n') break; + } + if (i == 10000) + { + ERR("can't read xterm WID\n"); + CloseHandle( pty_handle ); + return FALSE; + } + req->handle = handle; + req->file_handle = pty_handle; + req->pid = xpid; + server_call( REQ_SET_CONSOLE_FD ); + CloseHandle( pty_handle ); + + /* enable mouseclicks */ + strcpy( buf, "\033[?1001s\033[?1000h" ); + WriteFile(handle,buf,strlen(buf),NULL,NULL); + + strcpy( buf, "\033]2;" ); + if (GetConsoleTitleA( buf + 4, sizeof(buf) - 5 )) + { + strcat( buf, "\a" ); + WriteFile(handle,buf,strlen(buf),NULL,NULL); } return TRUE; @@ -544,29 +543,29 @@ static BOOL CONSOLE_make_complex(HANDLE handle) */ BOOL WINAPI AllocConsole(VOID) { - struct alloc_console_request req; - struct alloc_console_reply reply; + struct alloc_console_request *req = get_req_buffer(); HANDLE hStderr; + int handle_in, handle_out; TRACE("()\n"); - req.access = GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE; - req.inherit = FALSE; - CLIENT_SendRequest( REQ_ALLOC_CONSOLE, -1, 1, &req, sizeof(req) ); - if (CLIENT_WaitSimpleReply( &reply, sizeof(reply), NULL ) != ERROR_SUCCESS) - return FALSE; + req->access = GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE; + req->inherit = FALSE; + if (server_call( REQ_ALLOC_CONSOLE )) return FALSE; + handle_in = req->handle_in; + handle_out = req->handle_out; - if (!DuplicateHandle( GetCurrentProcess(), reply.handle_out, GetCurrentProcess(), &hStderr, + if (!DuplicateHandle( GetCurrentProcess(), req->handle_out, GetCurrentProcess(), &hStderr, 0, TRUE, DUPLICATE_SAME_ACCESS )) { - CloseHandle( reply.handle_in ); - CloseHandle( reply.handle_out ); + CloseHandle( handle_in ); + CloseHandle( handle_out ); FreeConsole(); return FALSE; } /* NT resets the STD_*_HANDLEs on console alloc */ - SetStdHandle( STD_INPUT_HANDLE, reply.handle_in ); - SetStdHandle( STD_OUTPUT_HANDLE, reply.handle_out ); + SetStdHandle( STD_INPUT_HANDLE, handle_in ); + SetStdHandle( STD_OUTPUT_HANDLE, handle_out ); SetStdHandle( STD_ERROR_HANDLE, hStderr ); SetLastError(ERROR_SUCCESS); @@ -600,14 +599,15 @@ UINT WINAPI GetConsoleOutputCP(VOID) */ BOOL WINAPI GetConsoleMode(HANDLE hcon,LPDWORD mode) { - struct get_console_mode_request req; - struct get_console_mode_reply reply; - - req.handle = hcon; - CLIENT_SendRequest( REQ_GET_CONSOLE_MODE, -1, 1, &req, sizeof(req)); - if (CLIENT_WaitSimpleReply( &reply, sizeof(reply), NULL )) return FALSE; - *mode = reply.mode; - return TRUE; + BOOL ret = FALSE; + struct get_console_mode_request *req = get_req_buffer(); + req->handle = hcon; + if (!server_call( REQ_GET_CONSOLE_MODE )) + { + if (mode) *mode = req->mode; + ret = TRUE; + } + return ret; } @@ -624,12 +624,10 @@ BOOL WINAPI GetConsoleMode(HANDLE hcon,LPDWORD mode) */ BOOL WINAPI SetConsoleMode( HANDLE hcon, DWORD mode ) { - struct set_console_mode_request req; - - req.handle = hcon; - req.mode = mode; - CLIENT_SendRequest( REQ_SET_CONSOLE_MODE, -1, 1, &req, sizeof(req)); - return !CLIENT_WaitReply( NULL, NULL, 0 ); + struct set_console_mode_request *req = get_req_buffer(); + req->handle = hcon; + req->mode = mode; + return !server_call( REQ_SET_CONSOLE_MODE ); } @@ -638,21 +636,18 @@ BOOL WINAPI SetConsoleMode( HANDLE hcon, DWORD mode ) */ DWORD WINAPI GetConsoleTitleA(LPSTR title,DWORD size) { - struct get_console_info_request req; - struct get_console_info_reply reply; - int len; + struct get_console_info_request *req = get_req_buffer(); DWORD ret = 0; HANDLE hcon; if ((hcon = CreateFileA( "CONOUT$", GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, 0 )) == INVALID_HANDLE_VALUE) return 0; - req.handle = hcon; - CLIENT_SendRequest( REQ_GET_CONSOLE_INFO, -1, 1, &req, sizeof(req) ); - if (!CLIENT_WaitReply( &len, NULL, 2, &reply, sizeof(reply), title, size )) + req->handle = hcon; + if (!server_call( REQ_GET_CONSOLE_INFO )) { - if (len > sizeof(reply)+size) title[size-1] = 0; - ret = strlen(title); + lstrcpynA( title, req->title, size ); + ret = strlen(req->title); } CloseHandle( hcon ); return ret; @@ -722,7 +717,7 @@ BOOL WINAPI WriteConsoleOutputA( HANDLE hConsoleOutput, 1,5,3,7, }; CONSOLE_make_complex(hConsoleOutput); - buffer = HeapAlloc(GetProcessHeap(),0,100);; + buffer = HeapAlloc(GetProcessHeap(),0,100); curbufsize = 100; TRACE("wr: top = %d, bottom=%d, left=%d,right=%d\n", @@ -790,8 +785,6 @@ BOOL WINAPI ReadConsoleA( HANDLE hConsoleInput, { int charsread = 0; LPSTR xbuf = (LPSTR)lpBuffer; - struct read_console_input_request req; - struct read_console_input_reply reply; INPUT_RECORD ir; TRACE("(%d,%p,%ld,%p,%p)\n", @@ -801,21 +794,15 @@ BOOL WINAPI ReadConsoleA( HANDLE hConsoleInput, CONSOLE_get_input(hConsoleInput,FALSE); - req.handle = hConsoleInput; - req.count = 1; - req.flush = 1; - /* FIXME: should we read at least 1 char? The SDK does not say */ while (charsreadhandle = hConsoleInput; + req->count = 1; + req->flush = 1; + if (server_call( REQ_READ_CONSOLE_INPUT )) return FALSE; + if (!req->read) break; if (!ir.Event.KeyEvent.bKeyDown) continue; if (ir.EventType != KEY_EVENT) @@ -867,33 +854,27 @@ BOOL WINAPI ReadConsoleW( HANDLE hConsoleInput, * Success: TRUE * Failure: FALSE */ -BOOL WINAPI ReadConsoleInputA(HANDLE hConsoleInput, - LPINPUT_RECORD lpBuffer, - DWORD nLength, LPDWORD lpNumberOfEventsRead) +BOOL WINAPI ReadConsoleInputA(HANDLE hConsoleInput, LPINPUT_RECORD lpBuffer, + DWORD nLength, LPDWORD lpNumberOfEventsRead) { - struct read_console_input_request req; - struct read_console_input_reply reply; - int len; - - req.handle = hConsoleInput; - req.count = nLength; - req.flush = 1; + struct read_console_input_request *req = get_req_buffer(); /* loop until we get at least one event */ for (;;) { - CLIENT_SendRequest( REQ_READ_CONSOLE_INPUT, -1, 1, &req, sizeof(req) ); - if (CLIENT_WaitReply( &len, NULL, 2, &reply, sizeof(reply), - lpBuffer, nLength * sizeof(*lpBuffer) )) - return FALSE; - len -= sizeof(reply); - assert( !(len % sizeof(INPUT_RECORD)) ); - if (len) break; + req->handle = hConsoleInput; + req->count = nLength; + req->flush = 1; + if (server_call( REQ_READ_CONSOLE_INPUT )) return FALSE; + if (req->read) + { + memcpy( lpBuffer, req + 1, req->read * sizeof(*lpBuffer) ); + if (lpNumberOfEventsRead) *lpNumberOfEventsRead = req->read; + return TRUE; + } CONSOLE_get_input(hConsoleInput,TRUE); /*WaitForSingleObject( hConsoleInput, INFINITE32 );*/ } - if (lpNumberOfEventsRead) *lpNumberOfEventsRead = len / sizeof(INPUT_RECORD); - return TRUE; } @@ -913,14 +894,11 @@ BOOL WINAPI ReadConsoleInputW( HANDLE handle, LPINPUT_RECORD buffer, */ BOOL WINAPI FlushConsoleInputBuffer( HANDLE handle ) { - struct read_console_input_request req; - int len; - - req.handle = handle; - req.count = -1; /* get all records */ - req.flush = 1; - CLIENT_SendRequest( REQ_READ_CONSOLE_INPUT, -1, 1, &req, sizeof(req) ); - return !CLIENT_WaitReply( &len, NULL, 0 ); + struct read_console_input_request *req = get_req_buffer(); + req->handle = handle; + req->count = -1; /* get all records */ + req->flush = 1; + return !server_call( REQ_READ_CONSOLE_INPUT ); } @@ -934,22 +912,16 @@ BOOL WINAPI FlushConsoleInputBuffer( HANDLE handle ) BOOL WINAPI PeekConsoleInputA( HANDLE handle, LPINPUT_RECORD buffer, DWORD count, LPDWORD read ) { - struct read_console_input_request req; - struct read_console_input_reply reply; - int len; + struct read_console_input_request *req = get_req_buffer(); CONSOLE_get_input(handle,FALSE); - req.handle = handle; - req.count = count; - req.flush = 0; - CLIENT_SendRequest( REQ_READ_CONSOLE_INPUT, -1, 1, &req, sizeof(req) ); - if (CLIENT_WaitReply( &len, NULL, 2, &reply, sizeof(reply), - buffer, count * sizeof(*buffer) )) - return FALSE; - len -= sizeof(reply); - assert( !(len % sizeof(INPUT_RECORD)) ); - if (read) *read = len / sizeof(INPUT_RECORD); + req->handle = handle; + req->count = count; + req->flush = 0; + if (server_call( REQ_READ_CONSOLE_INPUT )) return FALSE; + if (req->read) memcpy( buffer, req + 1, req->read * sizeof(*buffer) ); + if (read) *read = req->read; return TRUE; } @@ -972,17 +944,23 @@ BOOL WINAPI PeekConsoleInputW(HANDLE hConsoleInput, * */ BOOL WINAPI WriteConsoleInputA( HANDLE handle, INPUT_RECORD *buffer, - DWORD count, LPDWORD written ) + DWORD count, LPDWORD written ) { - struct write_console_input_request req; - struct write_console_input_reply reply; + struct write_console_input_request *req = get_req_buffer(); + const DWORD max = server_remaining( req + 1 ) / sizeof(INPUT_RECORD); - req.handle = handle; - req.count = count; - CLIENT_SendRequest( REQ_WRITE_CONSOLE_INPUT, -1, 2, &req, sizeof(req), - buffer, count * sizeof(*buffer) ); - if (CLIENT_WaitSimpleReply( &reply, sizeof(reply), NULL )) return FALSE; - if (written) *written = reply.written; + if (written) *written = 0; + while (count) + { + DWORD len = count < max ? count : max; + req->count = len; + req->handle = handle; + memcpy( req + 1, buffer, len * sizeof(*buffer) ); + if (server_call( REQ_WRITE_CONSOLE_INPUT )) return FALSE; + if (written) *written += req->written; + count -= len; + buffer += len; + } return TRUE; } @@ -998,20 +976,18 @@ BOOL WINAPI WriteConsoleInputA( HANDLE handle, INPUT_RECORD *buffer, */ BOOL WINAPI SetConsoleTitleA(LPCSTR title) { - struct set_console_info_request req; - struct get_console_info_reply info; + struct set_console_info_request *req = get_req_buffer(); HANDLE hcon; DWORD written; if ((hcon = CreateFileA( "CONOUT$", GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0 )) == INVALID_HANDLE_VALUE) return FALSE; - req.handle = hcon; - req.mask = SET_CONSOLE_INFO_TITLE; - CLIENT_SendRequest( REQ_SET_CONSOLE_INFO, -1, 2, &req, sizeof(req), - title, strlen(title)+1 ); - if (CLIENT_WaitReply( NULL, NULL, 0 )) goto error; - if (CONSOLE_GetInfo( hcon, &info ) && info.pid) + req->handle = hcon; + req->mask = SET_CONSOLE_INFO_TITLE; + lstrcpynA( req->title, title, server_remaining(req->title) ); + if (server_call( REQ_SET_CONSOLE_INFO )) goto error; + if (CONSOLE_GetPid( hcon )) { /* only set title for complex console (own xterm) */ WriteFile( hcon, "\033]2;", 4, &written, NULL ); @@ -1112,16 +1088,15 @@ BOOL WINAPI GetNumberOfConsoleMouseButtons(LPDWORD nrofbuttons) * Success: TRUE * Failure: FALSE */ -BOOL WINAPI GetConsoleCursorInfo( HANDLE hcon, - LPCONSOLE_CURSOR_INFO cinfo ) +BOOL WINAPI GetConsoleCursorInfo( HANDLE hcon, LPCONSOLE_CURSOR_INFO cinfo ) { - struct get_console_info_reply reply; - - if (!CONSOLE_GetInfo( hcon, &reply )) return FALSE; + struct get_console_info_request *req = get_req_buffer(); + req->handle = hcon; + if (server_call( REQ_GET_CONSOLE_INFO )) return FALSE; if (cinfo) { - cinfo->dwSize = reply.cursor_size; - cinfo->bVisible = reply.cursor_visible; + cinfo->dwSize = req->cursor_size; + cinfo->bVisible = req->cursor_visible; } return TRUE; } @@ -1138,20 +1113,19 @@ BOOL WINAPI SetConsoleCursorInfo( HANDLE hcon, /* [in] Handle to console screen buffer */ LPCONSOLE_CURSOR_INFO cinfo) /* [in] Address of cursor information */ { - struct set_console_info_request req; + struct set_console_info_request *req = get_req_buffer(); char buf[8]; DWORD xlen; - req.handle = hcon; CONSOLE_make_complex(hcon); sprintf(buf,"\033[?25%c",cinfo->bVisible?'h':'l'); WriteFile(hcon,buf,strlen(buf),&xlen,NULL); - req.cursor_size = cinfo->dwSize; - req.cursor_visible = cinfo->bVisible; - req.mask = SET_CONSOLE_INFO_CURSOR; - CLIENT_SendRequest( REQ_SET_CONSOLE_INFO, -1, 1, &req, sizeof(req) ); - return !CLIENT_WaitReply( NULL, NULL, 0 ); + req->handle = hcon; + req->cursor_size = cinfo->dwSize; + req->cursor_visible = cinfo->bVisible; + req->mask = SET_CONSOLE_INFO_CURSOR; + return !server_call( REQ_SET_CONSOLE_INFO ); } diff --git a/win32/device.c b/win32/device.c index 21c16657caf..8c6f1789651 100644 --- a/win32/device.c +++ b/win32/device.c @@ -285,20 +285,16 @@ HANDLE DEVICE_Open( LPCSTR filename, DWORD access, static const struct VxDInfo *DEVICE_GetInfo( HANDLE handle ) { - struct get_file_info_request req; - struct get_file_info_reply reply; + struct get_file_info_request *req = get_req_buffer(); - req.handle = handle; - CLIENT_SendRequest( REQ_GET_FILE_INFO, -1, 1, &req, sizeof(req) ); - if (!CLIENT_WaitSimpleReply( &reply, sizeof(reply), NULL ) && - (reply.type == FILE_TYPE_UNKNOWN) && - (reply.attr & 0x10000)) + req->handle = handle; + if (!server_call( REQ_GET_FILE_INFO ) && + (req->type == FILE_TYPE_UNKNOWN) && + (req->attr & 0x10000)) { const struct VxDInfo *info; - for (info = VxDList; info->name; info++) - if (info->id == LOWORD(reply.attr)) break; - return info; + if (info->id == LOWORD(req->attr)) return info; } return NULL; }