Commit ebe29ef3 authored by Alexandre Julliard's avatar Alexandre Julliard

Further server optimizations:

- merged request and reply structures - build requests directly into the buffer to avoid a copy
parent f26c89e8
......@@ -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;
}
/****************************************************************************
......
......@@ -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;
}
......
......@@ -304,24 +304,16 @@ void FILE_SetDosError(void)
HFILE FILE_DupUnixHandle( int fd, DWORD access )
{
int unix_handle;
struct create_file_request req;
struct create_file_reply reply;
struct alloc_file_handle_request *req = get_req_buffer();
if ((unix_handle = dup(fd)) == -1)
{
FILE_SetDosError();
return INVALID_HANDLE_VALUE;
}
req.access = access;
req.inherit = 1;
req.sharing = FILE_SHARE_READ | FILE_SHARE_WRITE;
req.create = 0;
req.attrs = 0;
CLIENT_SendRequest( REQ_CREATE_FILE, unix_handle, 1,
&req, sizeof(req) );
CLIENT_WaitSimpleReply( &reply, sizeof(reply), NULL );
return reply.handle;
req->access = access;
server_call_fd( REQ_ALLOC_FILE_HANDLE, unix_handle, NULL );
return req->handle;
}
......@@ -334,38 +326,28 @@ HFILE FILE_CreateFile( LPCSTR filename, DWORD access, DWORD sharing,
LPSECURITY_ATTRIBUTES sa, DWORD creation,
DWORD attributes, HANDLE template )
{
struct create_file_request req;
struct create_file_reply reply;
req.access = access;
req.inherit = (sa && (sa->nLength>=sizeof(*sa)) && sa->bInheritHandle);
req.sharing = sharing;
req.create = creation;
req.attrs = attributes;
CLIENT_SendRequest( REQ_CREATE_FILE, -1, 2,
&req, sizeof(req),
filename, strlen(filename) + 1 );
struct create_file_request *req = get_req_buffer();
req->access = access;
req->inherit = (sa && (sa->nLength>=sizeof(*sa)) && sa->bInheritHandle);
req->sharing = sharing;
req->create = creation;
req->attrs = attributes;
lstrcpynA( req->name, filename, server_remaining(req->name) );
SetLastError(0);
CLIENT_WaitSimpleReply( &reply, sizeof(reply), NULL );
server_call( REQ_CREATE_FILE );
/* If write access failed, retry without GENERIC_WRITE */
if ((reply.handle == -1) && !Options.failReadOnly &&
if ((req->handle == -1) && !Options.failReadOnly &&
(access & GENERIC_WRITE))
{
DWORD lasterror = GetLastError();
if ((lasterror == ERROR_ACCESS_DENIED) ||
(lasterror == ERROR_WRITE_PROTECT))
{
req.access &= ~GENERIC_WRITE;
CLIENT_SendRequest( REQ_CREATE_FILE, -1, 2,
&req, sizeof(req),
filename, strlen(filename) + 1 );
SetLastError(0);
CLIENT_WaitSimpleReply( &reply, sizeof(reply), NULL );
}
if ((lasterror == ERROR_ACCESS_DENIED) || (lasterror == ERROR_WRITE_PROTECT))
return FILE_CreateFile( filename, access & ~GENERIC_WRITE, sharing,
sa, creation, attributes, template );
}
return reply.handle;
return req->handle;
}
......@@ -376,16 +358,14 @@ HFILE FILE_CreateFile( LPCSTR filename, DWORD access, DWORD sharing,
*/
HFILE FILE_CreateDevice( int client_id, DWORD access, LPSECURITY_ATTRIBUTES sa )
{
struct create_device_request req;
struct create_device_reply reply;
struct create_device_request *req = get_req_buffer();
req.access = access;
req.inherit = (sa && (sa->nLength>=sizeof(*sa)) && sa->bInheritHandle);
req.id = client_id;
CLIENT_SendRequest( REQ_CREATE_DEVICE, -1, 1, &req, sizeof(req) );
req->access = access;
req->inherit = (sa && (sa->nLength>=sizeof(*sa)) && sa->bInheritHandle);
req->id = client_id;
SetLastError(0);
CLIENT_WaitSimpleReply( &reply, sizeof(reply), NULL );
return reply.handle;
server_call( REQ_CREATE_DEVICE );
return req->handle;
}
......@@ -562,24 +542,21 @@ BOOL FILE_Stat( LPCSTR unixName, BY_HANDLE_FILE_INFORMATION *info )
DWORD WINAPI GetFileInformationByHandle( HFILE hFile,
BY_HANDLE_FILE_INFORMATION *info )
{
struct get_file_info_request req;
struct get_file_info_reply reply;
struct get_file_info_request *req = get_req_buffer();
if (!info) return 0;
req.handle = hFile;
CLIENT_SendRequest( REQ_GET_FILE_INFO, -1, 1, &req, sizeof(req) );
if (CLIENT_WaitSimpleReply( &reply, sizeof(reply), NULL ))
return 0;
DOSFS_UnixTimeToFileTime( reply.write_time, &info->ftCreationTime, 0 );
DOSFS_UnixTimeToFileTime( reply.write_time, &info->ftLastWriteTime, 0 );
DOSFS_UnixTimeToFileTime( reply.access_time, &info->ftLastAccessTime, 0 );
info->dwFileAttributes = reply.attr;
info->dwVolumeSerialNumber = reply.serial;
info->nFileSizeHigh = reply.size_high;
info->nFileSizeLow = reply.size_low;
info->nNumberOfLinks = reply.links;
info->nFileIndexHigh = reply.index_high;
info->nFileIndexLow = reply.index_low;
req->handle = hFile;
if (server_call( REQ_GET_FILE_INFO )) return 0;
DOSFS_UnixTimeToFileTime( req->write_time, &info->ftCreationTime, 0 );
DOSFS_UnixTimeToFileTime( req->write_time, &info->ftLastWriteTime, 0 );
DOSFS_UnixTimeToFileTime( req->access_time, &info->ftLastAccessTime, 0 );
info->dwFileAttributes = req->attr;
info->dwVolumeSerialNumber = req->serial;
info->nFileSizeHigh = req->size_high;
info->nFileSizeLow = req->size_low;
info->nNumberOfLinks = req->links;
info->nFileIndexHigh = req->index_high;
info->nFileIndexLow = req->index_low;
return 1;
}
......@@ -1121,7 +1098,7 @@ HFILE WINAPI _lclose( HFILE hFile )
BOOL WINAPI ReadFile( HANDLE hFile, LPVOID buffer, DWORD bytesToRead,
LPDWORD bytesRead, LPOVERLAPPED overlapped )
{
struct get_read_fd_request req;
struct get_read_fd_request *req = get_req_buffer();
int unix_handle, result;
TRACE(file, "%d %p %ld\n", hFile, buffer, bytesToRead );
......@@ -1129,9 +1106,8 @@ BOOL WINAPI ReadFile( HANDLE hFile, LPVOID buffer, DWORD bytesToRead,
if (bytesRead) *bytesRead = 0; /* Do this before anything else */
if (!bytesToRead) return TRUE;
req.handle = hFile;
CLIENT_SendRequest( REQ_GET_READ_FD, -1, 1, &req, sizeof(req) );
CLIENT_WaitReply( NULL, &unix_handle, 0 );
req->handle = hFile;
server_call_fd( REQ_GET_READ_FD, -1, &unix_handle );
if (unix_handle == -1) return FALSE;
while ((result = read( unix_handle, buffer, bytesToRead )) == -1)
{
......@@ -1153,7 +1129,7 @@ BOOL WINAPI ReadFile( HANDLE hFile, LPVOID buffer, DWORD bytesToRead,
BOOL WINAPI WriteFile( HANDLE hFile, LPCVOID buffer, DWORD bytesToWrite,
LPDWORD bytesWritten, LPOVERLAPPED overlapped )
{
struct get_write_fd_request req;
struct get_write_fd_request *req = get_req_buffer();
int unix_handle, result;
TRACE(file, "%d %p %ld\n", hFile, buffer, bytesToWrite );
......@@ -1161,9 +1137,8 @@ BOOL WINAPI WriteFile( HANDLE hFile, LPCVOID buffer, DWORD bytesToWrite,
if (bytesWritten) *bytesWritten = 0; /* Do this before anything else */
if (!bytesToWrite) return TRUE;
req.handle = hFile;
CLIENT_SendRequest( REQ_GET_WRITE_FD, -1, 1, &req, sizeof(req) );
CLIENT_WaitReply( NULL, &unix_handle, 0 );
req->handle = hFile;
server_call_fd( REQ_GET_WRITE_FD, -1, &unix_handle );
if (unix_handle == -1) return FALSE;
while ((result = write( unix_handle, buffer, bytesToWrite )) == -1)
{
......@@ -1254,8 +1229,7 @@ HFILE WINAPI _lcreat( LPCSTR path, INT attr )
DWORD WINAPI SetFilePointer( HFILE hFile, LONG distance, LONG *highword,
DWORD method )
{
struct set_file_pointer_request req;
struct set_file_pointer_reply reply;
struct set_file_pointer_request *req = get_req_buffer();
if (highword && *highword)
{
......@@ -1266,16 +1240,15 @@ DWORD WINAPI SetFilePointer( HFILE hFile, LONG distance, LONG *highword,
TRACE(file, "handle %d offset %ld origin %ld\n",
hFile, distance, method );
req.handle = hFile;
req.low = distance;
req.high = highword ? *highword : 0;
req->handle = hFile;
req->low = distance;
req->high = highword ? *highword : 0;
/* FIXME: assumes 1:1 mapping between Windows and Unix seek constants */
req.whence = method;
CLIENT_SendRequest( REQ_SET_FILE_POINTER, -1, 1, &req, sizeof(req) );
if (CLIENT_WaitSimpleReply( &reply, sizeof(reply), NULL )) return 0xffffffff;
req->whence = method;
SetLastError( 0 );
if (highword) *highword = reply.high;
return reply.low;
if (server_call( REQ_SET_FILE_POINTER )) return 0xffffffff;
if (highword) *highword = req->new_high;
return req->new_low;
}
......@@ -1462,11 +1435,9 @@ UINT WINAPI SetHandleCount( UINT count )
*/
BOOL WINAPI FlushFileBuffers( HFILE hFile )
{
struct flush_file_request req;
req.handle = hFile;
CLIENT_SendRequest( REQ_FLUSH_FILE, -1, 1, &req, sizeof(req) );
return !CLIENT_WaitReply( NULL, NULL, 0 );
struct flush_file_request *req = get_req_buffer();
req->handle = hFile;
return !server_call( REQ_FLUSH_FILE );
}
......@@ -1475,11 +1446,9 @@ BOOL WINAPI FlushFileBuffers( HFILE hFile )
*/
BOOL WINAPI SetEndOfFile( HFILE hFile )
{
struct truncate_file_request req;
req.handle = hFile;
CLIENT_SendRequest( REQ_TRUNCATE_FILE, -1, 1, &req, sizeof(req) );
return !CLIENT_WaitReply( NULL, NULL, 0 );
struct truncate_file_request *req = get_req_buffer();
req->handle = hFile;
return !server_call( REQ_TRUNCATE_FILE );
}
......@@ -1631,14 +1600,10 @@ int FILE_munmap( LPVOID start, DWORD size_high, DWORD size_low )
*/
DWORD WINAPI GetFileType( HFILE hFile )
{
struct get_file_info_request req;
struct get_file_info_reply reply;
req.handle = hFile;
CLIENT_SendRequest( REQ_GET_FILE_INFO, -1, 1, &req, sizeof(req) );
if (CLIENT_WaitSimpleReply( &reply, sizeof(reply), NULL ))
return FILE_TYPE_UNKNOWN;
return reply.type;
struct get_file_info_request *req = get_req_buffer();
req->handle = hFile;
if (server_call( REQ_GET_FILE_INFO )) return FILE_TYPE_UNKNOWN;
return req->type;
}
......@@ -1913,20 +1878,18 @@ BOOL WINAPI SetFileTime( HFILE hFile,
const FILETIME *lpLastAccessTime,
const FILETIME *lpLastWriteTime )
{
struct set_file_time_request req;
struct set_file_time_request *req = get_req_buffer();
req.handle = hFile;
req->handle = hFile;
if (lpLastAccessTime)
req.access_time = DOSFS_FileTimeToUnixTime(lpLastAccessTime, NULL);
req->access_time = DOSFS_FileTimeToUnixTime(lpLastAccessTime, NULL);
else
req.access_time = 0; /* FIXME */
req->access_time = 0; /* FIXME */
if (lpLastWriteTime)
req.write_time = DOSFS_FileTimeToUnixTime(lpLastWriteTime, NULL);
req->write_time = DOSFS_FileTimeToUnixTime(lpLastWriteTime, NULL);
else
req.write_time = 0; /* FIXME */
CLIENT_SendRequest( REQ_SET_FILE_TIME, -1, 1, &req, sizeof(req) );
return !CLIENT_WaitReply( NULL, NULL, 0 );
req->write_time = 0; /* FIXME */
return !server_call( REQ_SET_FILE_TIME );
}
......@@ -1936,15 +1899,14 @@ BOOL WINAPI SetFileTime( HFILE hFile,
BOOL WINAPI LockFile( HFILE hFile, DWORD dwFileOffsetLow, DWORD dwFileOffsetHigh,
DWORD nNumberOfBytesToLockLow, DWORD nNumberOfBytesToLockHigh )
{
struct lock_file_request req;
struct lock_file_request *req = get_req_buffer();
req.handle = hFile;
req.offset_low = dwFileOffsetLow;
req.offset_high = dwFileOffsetHigh;
req.count_low = nNumberOfBytesToLockLow;
req.count_high = nNumberOfBytesToLockHigh;
CLIENT_SendRequest( REQ_LOCK_FILE, -1, 1, &req, sizeof(req) );
return !CLIENT_WaitReply( NULL, NULL, 0 );
req->handle = hFile;
req->offset_low = dwFileOffsetLow;
req->offset_high = dwFileOffsetHigh;
req->count_low = nNumberOfBytesToLockLow;
req->count_high = nNumberOfBytesToLockHigh;
return !server_call( REQ_LOCK_FILE );
}
/**************************************************************************
......@@ -1984,15 +1946,14 @@ BOOL WINAPI LockFileEx( HANDLE hFile, DWORD flags, DWORD reserved,
BOOL WINAPI UnlockFile( HFILE hFile, DWORD dwFileOffsetLow, DWORD dwFileOffsetHigh,
DWORD nNumberOfBytesToUnlockLow, DWORD nNumberOfBytesToUnlockHigh )
{
struct unlock_file_request req;
struct unlock_file_request *req = get_req_buffer();
req.handle = hFile;
req.offset_low = dwFileOffsetLow;
req.offset_high = dwFileOffsetHigh;
req.count_low = nNumberOfBytesToUnlockLow;
req.count_high = nNumberOfBytesToUnlockHigh;
CLIENT_SendRequest( REQ_UNLOCK_FILE, -1, 1, &req, sizeof(req) );
return !CLIENT_WaitReply( NULL, NULL, 0 );
req->handle = hFile;
req->offset_low = dwFileOffsetLow;
req->offset_high = dwFileOffsetHigh;
req->count_low = nNumberOfBytesToUnlockLow;
req->count_high = nNumberOfBytesToUnlockHigh;
return !server_call( REQ_UNLOCK_FILE );
}
......
......@@ -10,144 +10,122 @@
#include <stdlib.h>
#include <time.h>
/* message header as sent on the wire */
struct header
{
unsigned int len; /* total msg length (including this header) */
unsigned int type; /* msg type */
};
/* max msg length (including the header) */
#define MAX_MSG_LENGTH 16384
/* Request structures */
/* data structure used to pass an fd with sendmsg/recvmsg */
struct cmsg_fd
{
int len; /* sizeof structure */
int level; /* SOL_SOCKET */
int type; /* SCM_RIGHTS */
int fd; /* fd to pass */
};
/* Following are the definitions of all the client<->server */
/* communication format; if you make any change in this file, */
/* you must run tools/make_requests again. */
/* Request structures */
/* following are the definitions of all the client<->server */
/* communication format; requests are from client to server, */
/* replies are from server to client. All requests must have */
/* a corresponding structure; the replies can be empty in */
/* which case it isn't necessary to define a structure. */
/* These empty macros are used by tools/make_requests */
/* to generate the request/reply tracing functions */
#define IN /*nothing*/
#define OUT /*nothing*/
/* Create a new process from the context of the parent */
struct new_process_request
{
int inherit; /* inherit flag */
int inherit_all; /* inherit all handles from parent */
int create_flags; /* creation flags */
int start_flags; /* flags from startup info */
int hstdin; /* handle for stdin */
int hstdout; /* handle for stdout */
int hstderr; /* handle for stderr */
int cmd_show; /* main window show mode */
void* env_ptr; /* pointer to environment (FIXME: hack) */
char cmd_line[0]; /* command line */
};
struct new_process_reply
{
void* pid; /* process id */
int handle; /* process handle (in the current process) */
IN int inherit; /* inherit flag */
IN int inherit_all; /* inherit all handles from parent */
IN int create_flags; /* creation flags */
IN int start_flags; /* flags from startup info */
IN int hstdin; /* handle for stdin */
IN int hstdout; /* handle for stdout */
IN int hstderr; /* handle for stderr */
IN int cmd_show; /* main window show mode */
IN void* env_ptr; /* pointer to environment (FIXME: hack) */
OUT void* pid; /* process id */
OUT int handle; /* process handle (in the current process) */
IN char cmdline[1]; /* command line */
};
/* Create a new thread from the context of the parent */
struct new_thread_request
{
void* pid; /* process id for the new thread */
int suspend; /* new thread should be suspended on creation */
int inherit; /* inherit flag */
};
struct new_thread_reply
{
void* tid; /* thread id */
int handle; /* thread handle (in the current process) */
IN void* pid; /* process id for the new thread */
IN int suspend; /* new thread should be suspended on creation */
IN int inherit; /* inherit flag */
OUT void* tid; /* thread id */
OUT int handle; /* thread handle (in the current process) */
};
/* Set the server debug level */
struct set_debug_request
{
int level; /* New debug level */
IN int level; /* New debug level */
};
/* Initialize a process; called from the new process context */
struct init_process_request
{
int dummy;
};
struct init_process_reply
{
int start_flags; /* flags from startup info */
int hstdin; /* handle for stdin */
int hstdout; /* handle for stdout */
int hstderr; /* handle for stderr */
int cmd_show; /* main window show mode */
void* env_ptr; /* pointer to environment (FIXME: hack) */
char cmdline[0]; /* command line */
OUT int start_flags; /* flags from startup info */
OUT int hstdin; /* handle for stdin */
OUT int hstdout; /* handle for stdout */
OUT int hstderr; /* handle for stderr */
OUT int cmd_show; /* main window show mode */
OUT void* env_ptr; /* pointer to environment (FIXME: hack) */
OUT char cmdline[1]; /* command line */
};
/* Initialize a thread; called from the child after fork()/clone() */
struct init_thread_request
{
int unix_pid; /* Unix pid of new thread */
void* teb; /* TEB of new thread (in thread address space) */
IN int unix_pid; /* Unix pid of new thread */
IN void* teb; /* TEB of new thread (in thread address space) */
OUT void* pid; /* process id of the new thread's process */
OUT void* tid; /* thread id of the new thread */
};
struct init_thread_reply
/* Retrieve the thread buffer file descriptor */
/* The reply to this request is the first thing a newly */
/* created thread gets (without having to request it) */
struct get_thread_buffer_request
{
void* pid; /* process id of the new thread's process */
void* tid; /* thread id of the new thread */
IN int dummy;
};
/* Terminate a process */
struct terminate_process_request
{
int handle; /* process handle to terminate */
int exit_code; /* process exit code */
IN int handle; /* process handle to terminate */
IN int exit_code; /* process exit code */
};
/* Terminate a thread */
struct terminate_thread_request
{
int handle; /* thread handle to terminate */
int exit_code; /* thread exit code */
IN int handle; /* thread handle to terminate */
IN int exit_code; /* thread exit code */
};
/* Retrieve information about a process */
struct get_process_info_request
{
int handle; /* process handle */
};
struct get_process_info_reply
{
void* pid; /* server process id */
int exit_code; /* process exit code */
int priority; /* priority class */
int process_affinity; /* process affinity mask */
int system_affinity; /* system affinity mask */
IN int handle; /* process handle */
OUT void* pid; /* server process id */
OUT int exit_code; /* process exit code */
OUT int priority; /* priority class */
OUT int process_affinity; /* process affinity mask */
OUT int system_affinity; /* system affinity mask */
};
/* Set a process informations */
struct set_process_info_request
{
int handle; /* process handle */
int mask; /* setting mask (see below) */
int priority; /* priority class */
int affinity; /* affinity mask */
IN int handle; /* process handle */
IN int mask; /* setting mask (see below) */
IN int priority; /* priority class */
IN int affinity; /* affinity mask */
};
#define SET_PROCESS_INFO_PRIORITY 0x01
#define SET_PROCESS_INFO_AFFINITY 0x02
......@@ -156,23 +134,20 @@ struct set_process_info_request
/* Retrieve information about a thread */
struct get_thread_info_request
{
int handle; /* thread handle */
};
struct get_thread_info_reply
{
void* tid; /* server thread id */
int exit_code; /* thread exit code */
int priority; /* thread priority level */
IN int handle; /* thread handle */
OUT void* tid; /* server thread id */
OUT int exit_code; /* thread exit code */
OUT int priority; /* thread priority level */
};
/* Set a thread informations */
struct set_thread_info_request
{
int handle; /* thread handle */
int mask; /* setting mask (see below) */
int priority; /* priority class */
int affinity; /* affinity mask */
IN int handle; /* thread handle */
IN int mask; /* setting mask (see below) */
IN int priority; /* priority class */
IN int affinity; /* affinity mask */
};
#define SET_THREAD_INFO_PRIORITY 0x01
#define SET_THREAD_INFO_AFFINITY 0x02
......@@ -181,29 +156,23 @@ struct set_thread_info_request
/* Suspend a thread */
struct suspend_thread_request
{
int handle; /* thread handle */
};
struct suspend_thread_reply
{
int count; /* new suspend count */
IN int handle; /* thread handle */
OUT int count; /* new suspend count */
};
/* Resume a thread */
struct resume_thread_request
{
int handle; /* thread handle */
};
struct resume_thread_reply
{
int count; /* new suspend count */
IN int handle; /* thread handle */
OUT int count; /* new suspend count */
};
/* Debugger support: freeze / unfreeze */
struct debugger_request
{
int op; /* operation type */
IN int op; /* operation type */
};
enum debugger_op { DEBUGGER_FREEZE_ALL, DEBUGGER_UNFREEZE_ALL };
......@@ -212,83 +181,78 @@ enum debugger_op { DEBUGGER_FREEZE_ALL, DEBUGGER_UNFREEZE_ALL };
/* Queue an APC for a thread */
struct queue_apc_request
{
int handle; /* thread handle */
void* func; /* function to call */
void* param; /* param for function to call */
IN int handle; /* thread handle */
IN void* func; /* function to call */
IN void* param; /* param for function to call */
};
/* Get list of APC to call */
struct get_apcs_request
{
OUT int count; /* number of apcs */
OUT void* apcs[1]; /* async procedures to call */
};
/* Close a handle for the current process */
struct close_handle_request
{
int handle; /* handle to close */
IN int handle; /* handle to close */
};
/* Get information about a handle */
struct get_handle_info_request
{
int handle; /* handle we are interested in */
};
struct get_handle_info_reply
{
int flags; /* handle flags */
IN int handle; /* handle we are interested in */
OUT int flags; /* handle flags */
};
/* Set a handle information */
struct set_handle_info_request
{
int handle; /* handle we are interested in */
int flags; /* new handle flags */
int mask; /* mask for flags to set */
IN int handle; /* handle we are interested in */
IN int flags; /* new handle flags */
IN int mask; /* mask for flags to set */
};
/* Duplicate a handle */
struct dup_handle_request
{
int src_process; /* src process handle */
int src_handle; /* src handle to duplicate */
int dst_process; /* dst process handle */
unsigned int access; /* wanted access rights */
int inherit; /* inherit flag */
int options; /* duplicate options (see below) */
IN int src_process; /* src process handle */
IN int src_handle; /* src handle to duplicate */
IN int dst_process; /* dst process handle */
IN unsigned int access; /* wanted access rights */
IN int inherit; /* inherit flag */
IN int options; /* duplicate options (see below) */
OUT int handle; /* duplicated handle in dst process */
};
#define DUP_HANDLE_CLOSE_SOURCE DUPLICATE_CLOSE_SOURCE
#define DUP_HANDLE_SAME_ACCESS DUPLICATE_SAME_ACCESS
#define DUP_HANDLE_MAKE_GLOBAL 0x80000000 /* Not a Windows flag */
struct dup_handle_reply
{
int handle; /* duplicated handle in dst process */
};
/* Open a handle to a process */
struct open_process_request
{
void* pid; /* process id to open */
unsigned int access; /* wanted access rights */
int inherit; /* inherit flag */
};
struct open_process_reply
{
int handle; /* handle to the process */
IN void* pid; /* process id to open */
IN unsigned int access; /* wanted access rights */
IN int inherit; /* inherit flag */
OUT int handle; /* handle to the process */
};
/* Wait for handles */
struct select_request
{
int count; /* handles count */
int flags; /* wait flags (see below) */
int timeout; /* timeout in ms */
int handles[0]; /* handles to select on */
};
struct select_reply
{
int signaled; /* signaled handle */
void* apcs[0]; /* async procedures to call */
IN int count; /* handles count */
IN int flags; /* wait flags (see below) */
IN int timeout; /* timeout in ms */
OUT int signaled; /* signaled handle */
IN int handles[1]; /* handles to select on */
};
#define SELECT_ALL 1
#define SELECT_ALERTABLE 2
......@@ -298,21 +262,18 @@ struct select_reply
/* Create an event */
struct create_event_request
{
int manual_reset; /* manual reset event */
int initial_state; /* initial state of the event */
int inherit; /* inherit flag */
char name[0]; /* event name */
};
struct create_event_reply
{
int handle; /* handle to the event */
IN int manual_reset; /* manual reset event */
IN int initial_state; /* initial state of the event */
IN int inherit; /* inherit flag */
OUT int handle; /* handle to the event */
IN char name[1]; /* event name */
};
/* Event operation */
struct event_op_request
{
int handle; /* handle to event */
int op; /* event operation (see below) */
IN int handle; /* handle to event */
IN int op; /* event operation (see below) */
};
enum event_op { PULSE_EVENT, SET_EVENT, RESET_EVENT };
......@@ -320,278 +281,248 @@ enum event_op { PULSE_EVENT, SET_EVENT, RESET_EVENT };
/* Open an event */
struct open_event_request
{
unsigned int access; /* wanted access rights */
int inherit; /* inherit flag */
char name[0]; /* object name */
};
struct open_event_reply
{
int handle; /* handle to the event */
IN unsigned int access; /* wanted access rights */
IN int inherit; /* inherit flag */
OUT int handle; /* handle to the event */
IN char name[1]; /* object name */
};
/* Create a mutex */
struct create_mutex_request
{
int owned; /* initially owned? */
int inherit; /* inherit flag */
char name[0]; /* mutex name */
};
struct create_mutex_reply
{
int handle; /* handle to the mutex */
IN int owned; /* initially owned? */
IN int inherit; /* inherit flag */
OUT int handle; /* handle to the mutex */
IN char name[1]; /* mutex name */
};
/* Release a mutex */
struct release_mutex_request
{
int handle; /* handle to the mutex */
IN int handle; /* handle to the mutex */
};
/* Open a mutex */
struct open_mutex_request
{
unsigned int access; /* wanted access rights */
int inherit; /* inherit flag */
char name[0]; /* object name */
};
struct open_mutex_reply
{
int handle; /* handle to the mutex */
IN unsigned int access; /* wanted access rights */
IN int inherit; /* inherit flag */
OUT int handle; /* handle to the mutex */
IN char name[1]; /* object name */
};
/* Create a semaphore */
struct create_semaphore_request
{
unsigned int initial; /* initial count */
unsigned int max; /* maximum count */
int inherit; /* inherit flag */
char name[0]; /* semaphore name */
};
struct create_semaphore_reply
{
int handle; /* handle to the semaphore */
IN unsigned int initial; /* initial count */
IN unsigned int max; /* maximum count */
IN int inherit; /* inherit flag */
OUT int handle; /* handle to the semaphore */
IN char name[1]; /* semaphore name */
};
/* Release a semaphore */
struct release_semaphore_request
{
int handle; /* handle to the semaphore */
unsigned int count; /* count to add to semaphore */
};
struct release_semaphore_reply
{
unsigned int prev_count; /* previous semaphore count */
IN int handle; /* handle to the semaphore */
IN unsigned int count; /* count to add to semaphore */
OUT unsigned int prev_count; /* previous semaphore count */
};
/* Open a semaphore */
struct open_semaphore_request
{
unsigned int access; /* wanted access rights */
int inherit; /* inherit flag */
char name[0]; /* object name */
};
struct open_semaphore_reply
{
int handle; /* handle to the semaphore */
IN unsigned int access; /* wanted access rights */
IN int inherit; /* inherit flag */
OUT int handle; /* handle to the semaphore */
IN char name[1]; /* object name */
};
/* Create a file */
struct create_file_request
{
unsigned int access; /* wanted access rights */
int inherit; /* inherit flag */
unsigned int sharing; /* sharing flags */
int create; /* file create action */
unsigned int attrs; /* file attributes for creation */
char name[0]; /* file name */
IN unsigned int access; /* wanted access rights */
IN int inherit; /* inherit flag */
IN unsigned int sharing; /* sharing flags */
IN int create; /* file create action */
IN unsigned int attrs; /* file attributes for creation */
OUT int handle; /* handle to the file */
IN char name[1]; /* file name */
};
struct create_file_reply
/* Allocate a file handle for a Unix fd */
struct alloc_file_handle_request
{
int handle; /* handle to the file */
IN unsigned int access; /* wanted access rights */
OUT int handle; /* handle to the file */
};
/* Get a Unix fd to read from a file */
struct get_read_fd_request
{
int handle; /* handle to the file */
IN int handle; /* handle to the file */
};
/* Get a Unix fd to write to a file */
struct get_write_fd_request
{
int handle; /* handle to the file */
IN int handle; /* handle to the file */
};
/* Set a file current position */
struct set_file_pointer_request
{
int handle; /* handle to the file */
int low; /* position low word */
int high; /* position high word */
int whence; /* whence to seek */
};
struct set_file_pointer_reply
{
int low; /* new position low word */
int high; /* new position high word */
IN int handle; /* handle to the file */
IN int low; /* position low word */
IN int high; /* position high word */
IN int whence; /* whence to seek */
OUT int new_low; /* new position low word */
OUT int new_high; /* new position high word */
};
/* Truncate (or extend) a file */
struct truncate_file_request
{
int handle; /* handle to the file */
IN int handle; /* handle to the file */
};
/* Set a file access and modification times */
struct set_file_time_request
{
int handle; /* handle to the file */
time_t access_time; /* last access time */
time_t write_time; /* last write time */
IN int handle; /* handle to the file */
IN time_t access_time; /* last access time */
IN time_t write_time; /* last write time */
};
/* Flush a file buffers */
struct flush_file_request
{
int handle; /* handle to the file */
IN int handle; /* handle to the file */
};
/* Get information about a file */
struct get_file_info_request
{
int handle; /* handle to the file */
};
struct get_file_info_reply
{
int type; /* file type */
int attr; /* file attributes */
time_t access_time; /* last access time */
time_t write_time; /* last write time */
int size_high; /* file size */
int size_low; /* file size */
int links; /* number of links */
int index_high; /* unique index */
int index_low; /* unique index */
unsigned int serial; /* volume serial number */
IN int handle; /* handle to the file */
OUT int type; /* file type */
OUT int attr; /* file attributes */
OUT time_t access_time; /* last access time */
OUT time_t write_time; /* last write time */
OUT int size_high; /* file size */
OUT int size_low; /* file size */
OUT int links; /* number of links */
OUT int index_high; /* unique index */
OUT int index_low; /* unique index */
OUT unsigned int serial; /* volume serial number */
};
/* Lock a region of a file */
struct lock_file_request
{
int handle; /* handle to the file */
unsigned int offset_low; /* offset of start of lock */
unsigned int offset_high; /* offset of start of lock */
unsigned int count_low; /* count of bytes to lock */
unsigned int count_high; /* count of bytes to lock */
IN int handle; /* handle to the file */
IN unsigned int offset_low; /* offset of start of lock */
IN unsigned int offset_high; /* offset of start of lock */
IN unsigned int count_low; /* count of bytes to lock */
IN unsigned int count_high; /* count of bytes to lock */
};
/* Unlock a region of a file */
struct unlock_file_request
{
int handle; /* handle to the file */
unsigned int offset_low; /* offset of start of unlock */
unsigned int offset_high; /* offset of start of unlock */
unsigned int count_low; /* count of bytes to unlock */
unsigned int count_high; /* count of bytes to unlock */
IN int handle; /* handle to the file */
IN unsigned int offset_low; /* offset of start of unlock */
IN unsigned int offset_high; /* offset of start of unlock */
IN unsigned int count_low; /* count of bytes to unlock */
IN unsigned int count_high; /* count of bytes to unlock */
};
/* Create an anonymous pipe */
struct create_pipe_request
{
int inherit; /* inherit flag */
};
struct create_pipe_reply
{
int handle_read; /* handle to the read-side of the pipe */
int handle_write; /* handle to the write-side of the pipe */
IN int inherit; /* inherit flag */
OUT int handle_read; /* handle to the read-side of the pipe */
OUT int handle_write; /* handle to the write-side of the pipe */
};
/* Allocate a console for the current process */
struct alloc_console_request
{
unsigned int access; /* wanted access rights */
int inherit; /* inherit flag */
};
struct alloc_console_reply
{
int handle_in; /* handle to console input */
int handle_out; /* handle to console output */
IN unsigned int access; /* wanted access rights */
IN int inherit; /* inherit flag */
OUT int handle_in; /* handle to console input */
OUT int handle_out; /* handle to console output */
};
/* Free the console of the current process */
struct free_console_request
{
int dummy;
IN int dummy;
};
/* Open a handle to the process console */
struct open_console_request
{
int output; /* input or output? */
unsigned int access; /* wanted access rights */
int inherit; /* inherit flag */
};
struct open_console_reply
{
int handle; /* handle to the console */
IN int output; /* input or output? */
IN unsigned int access; /* wanted access rights */
IN int inherit; /* inherit flag */
OUT int handle; /* handle to the console */
};
/* Set a console file descriptor */
struct set_console_fd_request
{
int handle; /* handle to the console */
int pid; /* pid of xterm (hack) */
IN int handle; /* handle to the console */
IN int file_handle; /* handle of file to use as file descriptor */
IN int pid; /* pid of xterm (hack) */
};
/* Get a console mode (input or output) */
struct get_console_mode_request
{
int handle; /* handle to the console */
};
struct get_console_mode_reply
{
int mode; /* console mode */
IN int handle; /* handle to the console */
OUT int mode; /* console mode */
};
/* Set a console mode (input or output) */
struct set_console_mode_request
{
int handle; /* handle to the console */
int mode; /* console mode */
IN int handle; /* handle to the console */
IN int mode; /* console mode */
};
/* Set info about a console (output only) */
struct set_console_info_request
{
int handle; /* handle to the console */
int mask; /* setting mask (see below) */
int cursor_size; /* size of cursor (percentage filled) */
int cursor_visible;/* cursor visibility flag */
char title[0]; /* console title */
IN int handle; /* handle to the console */
IN int mask; /* setting mask (see below) */
IN int cursor_size; /* size of cursor (percentage filled) */
IN int cursor_visible;/* cursor visibility flag */
IN char title[1]; /* console title */
};
#define SET_CONSOLE_INFO_CURSOR 0x01
#define SET_CONSOLE_INFO_TITLE 0x02
......@@ -599,68 +530,53 @@ struct set_console_info_request
/* Get info about a console (output only) */
struct get_console_info_request
{
int handle; /* handle to the console */
};
struct get_console_info_reply
{
int cursor_size; /* size of cursor (percentage filled) */
int cursor_visible;/* cursor visibility flag */
int pid; /* pid of xterm (hack) */
char title[0]; /* console title */
IN int handle; /* handle to the console */
OUT int cursor_size; /* size of cursor (percentage filled) */
OUT int cursor_visible;/* cursor visibility flag */
OUT int pid; /* pid of xterm (hack) */
OUT char title[1]; /* console title */
};
/* Add input records to a console input queue */
struct write_console_input_request
{
int handle; /* handle to the console input */
int count; /* number of input records */
/* INPUT_RECORD records[0]; */ /* input records */
};
struct write_console_input_reply
{
int written; /* number of records written */
IN int handle; /* handle to the console input */
IN int count; /* number of input records */
OUT int written; /* number of records written */
/* INPUT_RECORD records[0]; */ /* input records */
};
/* Fetch input records from a console input queue */
struct read_console_input_request
{
int handle; /* handle to the console input */
int count; /* max number of records to retrieve */
int flush; /* flush the retrieved records from the queue? */
};
struct read_console_input_reply
{
int dummy;
/* INPUT_RECORD records[0]; */ /* input records */
IN int handle; /* handle to the console input */
IN int count; /* max number of records to retrieve */
IN int flush; /* flush the retrieved records from the queue? */
OUT int read; /* number of records read */
/* INPUT_RECORD records[0]; */ /* input records */
};
/* Create a change notification */
struct create_change_notification_request
{
int subtree; /* watch all the subtree */
int filter; /* notification filter */
};
struct create_change_notification_reply
{
int handle; /* handle to the change notification */
IN int subtree; /* watch all the subtree */
IN int filter; /* notification filter */
OUT int handle; /* handle to the change notification */
};
/* Create a file mapping */
struct create_mapping_request
{
int size_high; /* mapping size */
int size_low; /* mapping size */
int protect; /* protection flags (see below) */
int inherit; /* inherit flag */
int handle; /* file handle */
char name[0]; /* object name */
};
struct create_mapping_reply
{
int handle; /* handle to the mapping */
IN int size_high; /* mapping size */
IN int size_low; /* mapping size */
IN int protect; /* protection flags (see below) */
IN int inherit; /* inherit flag */
IN int file_handle; /* file handle */
OUT int handle; /* handle to the mapping */
IN char name[1]; /* object name */
};
/* protection flags */
#define VPROT_READ 0x01
......@@ -675,91 +591,70 @@ struct create_mapping_reply
/* Open a mapping */
struct open_mapping_request
{
unsigned int access; /* wanted access rights */
int inherit; /* inherit flag */
char name[0]; /* object name */
};
struct open_mapping_reply
{
int handle; /* handle to the mapping */
IN unsigned int access; /* wanted access rights */
IN int inherit; /* inherit flag */
OUT int handle; /* handle to the mapping */
IN char name[1]; /* object name */
};
/* Get information about a file mapping */
struct get_mapping_info_request
{
int handle; /* handle to the mapping */
};
struct get_mapping_info_reply
{
int size_high; /* mapping size */
int size_low; /* mapping size */
int protect; /* protection flags */
IN int handle; /* handle to the mapping */
OUT int size_high; /* mapping size */
OUT int size_low; /* mapping size */
OUT int protect; /* protection flags */
};
/* Create a device */
struct create_device_request
{
unsigned int access; /* wanted access rights */
int inherit; /* inherit flag */
int id; /* client private id */
};
struct create_device_reply
{
int handle; /* handle to the device */
IN unsigned int access; /* wanted access rights */
IN int inherit; /* inherit flag */
IN int id; /* client private id */
OUT int handle; /* handle to the device */
};
/* Create a snapshot */
struct create_snapshot_request
{
int inherit; /* inherit flag */
int flags; /* snapshot flags (TH32CS_*) */
};
struct create_snapshot_reply
{
int handle; /* handle to the snapshot */
IN int inherit; /* inherit flag */
IN int flags; /* snapshot flags (TH32CS_*) */
OUT int handle; /* handle to the snapshot */
};
/* Get the next process from a snapshot */
struct next_process_request
{
int handle; /* handle to the snapshot */
int reset; /* reset snapshot position? */
};
struct next_process_reply
{
void* pid; /* process id */
int threads; /* number of threads */
int priority; /* process priority */
IN int handle; /* handle to the snapshot */
IN int reset; /* reset snapshot position? */
OUT void* pid; /* process id */
OUT int threads; /* number of threads */
OUT int priority; /* process priority */
};
/* Wait for a debug event */
struct wait_debug_event_request
{
int timeout; /* timeout in ms */
};
struct wait_debug_event_reply
{
int code; /* event code */
void* pid; /* process id */
void* tid; /* thread id */
/* followed by the event data (see below) */
IN int timeout; /* timeout in ms */
OUT int code; /* event code */
OUT void* pid; /* process id */
OUT void* tid; /* thread id */
/* OUT union debug_event_data data; */
};
/* Send a debug event */
struct send_debug_event_request
{
int code; /* event code */
/* followed by the event data (see below) */
};
struct send_debug_event_reply
{
int status; /* event continuation status */
IN int code; /* event code */
OUT int status; /* event continuation status */
/* IN union debug_event_data data; */
};
......@@ -837,16 +732,16 @@ union debug_event_data
/* Continue a debug event */
struct continue_debug_event_request
{
void* pid; /* process id to continue */
void* tid; /* thread id to continue */
int status; /* continuation status */
IN void* pid; /* process id to continue */
IN void* tid; /* thread id to continue */
IN int status; /* continuation status */
};
/* Start debugging an existing process */
struct debug_process_request
{
void* pid; /* id of the process to debug */
IN void* pid; /* id of the process to debug */
};
......@@ -860,6 +755,7 @@ enum request
REQ_SET_DEBUG,
REQ_INIT_PROCESS,
REQ_INIT_THREAD,
REQ_GET_THREAD_BUFFER,
REQ_TERMINATE_PROCESS,
REQ_TERMINATE_THREAD,
REQ_GET_PROCESS_INFO,
......@@ -870,6 +766,7 @@ enum request
REQ_RESUME_THREAD,
REQ_DEBUGGER,
REQ_QUEUE_APC,
REQ_GET_APCS,
REQ_CLOSE_HANDLE,
REQ_GET_HANDLE_INFO,
REQ_SET_HANDLE_INFO,
......@@ -886,6 +783,7 @@ enum request
REQ_RELEASE_SEMAPHORE,
REQ_OPEN_SEMAPHORE,
REQ_CREATE_FILE,
REQ_ALLOC_FILE_HANDLE,
REQ_GET_READ_FD,
REQ_GET_WRITE_FD,
REQ_SET_FILE_POINTER,
......@@ -930,31 +828,24 @@ enum request
#include "thread.h"
/* make space for some data in the server arguments buffer */
static inline void *server_add_data( int len )
/* client communication functions */
/* get a pointer to the request buffer */
static inline void *get_req_buffer(void)
{
void *old = NtCurrentTeb()->buffer_args;
NtCurrentTeb()->buffer_args = (char *)old + len;
return old;
return NtCurrentTeb()->buffer;
}
/* maximum remaining size in the server arguments buffer */
static inline int server_remaining(void)
/* maximum remaining size in the server buffer */
static inline int server_remaining( const void *ptr )
{
TEB *teb = NtCurrentTeb();
return (char *)teb->buffer + teb->buffer_size - (char *)teb->buffer_args;
return (char *)NtCurrentTeb()->buffer + NtCurrentTeb()->buffer_size - (char *)ptr;
}
extern unsigned int server_call( enum request req );
extern unsigned int server_call_fd( enum request req, int *fd );
extern unsigned int server_call_fd( enum request req, int fd_out, int *fd_in );
extern void server_protocol_error( const char *err, ... );
/* client communication functions */
extern void CLIENT_ProtocolError( const char *err, ... );
extern void CLIENT_SendRequest( enum request req, int pass_fd,
int n, ... /* arg_1, len_1, etc. */ );
extern unsigned int CLIENT_WaitReply( int *len, int *passed_fd,
int n, ... /* arg_1, len_1, etc. */ );
extern unsigned int CLIENT_WaitSimpleReply( void *reply, int len, int *passed_fd );
extern int CLIENT_InitServer(void);
extern int CLIENT_SetDebug( int level );
extern int CLIENT_DebuggerRequest( int op );
......
......@@ -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;
......
......@@ -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);
......
......@@ -1051,8 +1051,7 @@ HANDLE WINAPI CreateFileMappingA(
DWORD size_low, /* [in] Low-order 32 bits of object size */
LPCSTR name /* [in] Name of file-mapping object */ )
{
struct create_mapping_request req;
struct create_mapping_reply reply;
struct create_mapping_request *req = get_req_buffer();
BYTE vprot;
/* Check parameters */
......@@ -1074,19 +1073,16 @@ HANDLE WINAPI CreateFileMappingA(
/* Create the server object */
if (!name) name = "";
req.handle = hFile;
req.size_high = size_high;
req.size_low = size_low;
req.protect = vprot;
req.inherit = (sa && (sa->nLength>=sizeof(*sa)) && sa->bInheritHandle);
CLIENT_SendRequest( REQ_CREATE_MAPPING, -1, 2,
&req, sizeof(req),
name, strlen(name) + 1 );
req->file_handle = hFile;
req->size_high = size_high;
req->size_low = size_low;
req->protect = vprot;
req->inherit = (sa && (sa->nLength>=sizeof(*sa)) && sa->bInheritHandle);
lstrcpynA( req->name, name ? name : "", server_remaining(req->name) );
SetLastError(0);
CLIENT_WaitSimpleReply( &reply, sizeof(reply), NULL );
if (reply.handle == -1) return 0;
return reply.handle;
server_call( REQ_CREATE_MAPPING );
if (req->handle == -1) return 0;
return req->handle;
}
......@@ -1119,16 +1115,14 @@ HANDLE WINAPI OpenFileMappingA(
BOOL inherit, /* [in] Inherit flag */
LPCSTR name ) /* [in] Name of file-mapping object */
{
struct open_mapping_request req;
struct open_mapping_reply reply;
int len = name ? strlen(name) + 1 : 0;
req.access = access;
req.inherit = inherit;
CLIENT_SendRequest( REQ_OPEN_MAPPING, -1, 2, &req, sizeof(req), name, len );
CLIENT_WaitSimpleReply( &reply, sizeof(reply), NULL );
if (reply.handle == -1) return 0; /* must return 0 on failure, not -1 */
return reply.handle;
struct open_mapping_request *req = get_req_buffer();
req->access = access;
req->inherit = inherit;
lstrcpynA( req->name, name ? name : "", server_remaining(req->name) );
server_call( REQ_OPEN_MAPPING );
if (req->handle == -1) return 0; /* must return 0 on failure, not -1 */
return req->handle;
}
......@@ -1185,8 +1179,8 @@ LPVOID WINAPI MapViewOfFileEx(
UINT ptr = (UINT)-1, size = 0;
int flags = MAP_PRIVATE;
int unix_handle = -1;
struct get_mapping_info_request req;
struct get_mapping_info_reply info;
int prot;
struct get_mapping_info_request *req = get_req_buffer();
/* Check parameters */
......@@ -1197,29 +1191,28 @@ LPVOID WINAPI MapViewOfFileEx(
return NULL;
}
req.handle = handle;
CLIENT_SendRequest( REQ_GET_MAPPING_INFO, -1, 1, &req, sizeof(req) );
if (CLIENT_WaitSimpleReply( &info, sizeof(info), &unix_handle ))
goto error;
req->handle = handle;
if (server_call_fd( REQ_GET_MAPPING_INFO, -1, &unix_handle )) goto error;
if (info.size_high || offset_high)
if (req->size_high || offset_high)
ERR("Offsets larger than 4Gb not supported\n");
if ((offset_low >= info.size_low) ||
(count > info.size_low - offset_low))
if ((offset_low >= req->size_low) ||
(count > req->size_low - offset_low))
{
SetLastError( ERROR_INVALID_PARAMETER );
goto error;
}
if (count) size = ROUND_SIZE( offset_low, count );
else size = info.size_low - offset_low;
else size = req->size_low - offset_low;
prot = req->protect;
switch(access)
{
case FILE_MAP_ALL_ACCESS:
case FILE_MAP_WRITE:
case FILE_MAP_WRITE | FILE_MAP_READ:
if (!(info.protect & VPROT_WRITE))
if (!(prot & VPROT_WRITE))
{
SetLastError( ERROR_INVALID_PARAMETER );
goto error;
......@@ -1229,7 +1222,7 @@ LPVOID WINAPI MapViewOfFileEx(
case FILE_MAP_READ:
case FILE_MAP_COPY:
case FILE_MAP_COPY | FILE_MAP_READ:
if (info.protect & VPROT_READ) break;
if (prot & VPROT_READ) break;
/* fall through */
default:
SetLastError( ERROR_INVALID_PARAMETER );
......@@ -1238,13 +1231,10 @@ LPVOID WINAPI MapViewOfFileEx(
/* Map the file */
TRACE("handle=%x size=%x offset=%lx\n",
handle, size, offset_low );
TRACE("handle=%x size=%x offset=%lx\n", handle, size, offset_low );
ptr = (UINT)FILE_dommap( unix_handle,
addr, 0, size, 0, offset_low,
VIRTUAL_GetUnixProt( info.protect ),
flags );
ptr = (UINT)FILE_dommap( unix_handle, addr, 0, size, 0, offset_low,
VIRTUAL_GetUnixProt( prot ), flags );
if (ptr == (UINT)-1) {
/* KB: Q125713, 25-SEP-1995, "Common File Mapping Problems and
* Platform Differences":
......@@ -1259,8 +1249,7 @@ LPVOID WINAPI MapViewOfFileEx(
goto error;
}
if (!(view = VIRTUAL_CreateView( ptr, size, offset_low, 0,
info.protect, handle )))
if (!(view = VIRTUAL_CreateView( ptr, size, offset_low, 0, prot, handle )))
{
SetLastError( ERROR_OUTOFMEMORY );
goto error;
......
......@@ -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) {
......
......@@ -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;
......
......@@ -26,6 +26,14 @@
#define SCM_RIGHTS 1
#endif
/* data structure used to pass an fd with sendmsg/recvmsg */
struct cmsg_fd
{
int len; /* sizeof structure */
int level; /* SOL_SOCKET */
int type; /* SCM_RIGHTS */
int fd; /* fd to pass */
};
/***********************************************************************
* CLIENT_Die
......@@ -39,9 +47,9 @@ static void CLIENT_Die(void)
}
/***********************************************************************
* CLIENT_ProtocolError
* server_protocol_error
*/
void CLIENT_ProtocolError( const char *err, ... )
void server_protocol_error( const char *err, ... )
{
va_list args;
......@@ -54,9 +62,9 @@ void CLIENT_ProtocolError( const char *err, ... )
/***********************************************************************
* CLIENT_perror
* server_perror
*/
void CLIENT_perror( const char *err )
static void server_perror( const char *err )
{
fprintf( stderr, "Client protocol error:%p: ", NtCurrentTeb()->tid );
perror( err );
......@@ -71,24 +79,15 @@ void CLIENT_perror( const char *err )
*/
static void send_request( enum request req )
{
struct header *head = NtCurrentTeb()->buffer;
int ret, seq = NtCurrentTeb()->seq++;
assert( server_remaining() >= 0 );
head->type = req;
head->len = (char *)NtCurrentTeb()->buffer_args - (char *)NtCurrentTeb()->buffer;
NtCurrentTeb()->buffer_args = head + 1; /* reset the args buffer */
if ((ret = write( NtCurrentTeb()->socket, &seq, sizeof(seq) )) == sizeof(seq))
int ret;
if ((ret = write( NtCurrentTeb()->socket, &req, sizeof(req) )) == sizeof(req))
return;
if (ret == -1)
{
if (errno == EPIPE) CLIENT_Die();
CLIENT_perror( "sendmsg" );
server_perror( "sendmsg" );
}
CLIENT_ProtocolError( "partial seq sent %d/%d\n", ret, sizeof(seq) );
server_protocol_error( "partial msg sent %d/%d\n", ret, sizeof(req) );
}
/***********************************************************************
......@@ -98,23 +97,15 @@ static void send_request( enum request req )
*/
static void send_request_fd( enum request req, int fd )
{
struct header *head = NtCurrentTeb()->buffer;
int ret, seq = NtCurrentTeb()->seq++;
int ret;
#ifndef HAVE_MSGHDR_ACCRIGHTS
struct cmsg_fd cmsg;
#endif
struct msghdr msghdr;
struct iovec vec;
assert( server_remaining() >= 0 );
head->type = req;
head->len = (char *)NtCurrentTeb()->buffer_args - (char *)NtCurrentTeb()->buffer;
NtCurrentTeb()->buffer_args = head + 1; /* reset the args buffer */
vec.iov_base = &seq;
vec.iov_len = sizeof(seq);
vec.iov_base = &req;
vec.iov_len = sizeof(req);
msghdr.msg_name = NULL;
msghdr.msg_namelen = 0;
......@@ -134,13 +125,13 @@ static void send_request_fd( enum request req, int fd )
msghdr.msg_flags = 0;
#endif /* HAVE_MSGHDR_ACCRIGHTS */
if ((ret = sendmsg( NtCurrentTeb()->socket, &msghdr, 0 )) == sizeof(seq)) return;
if ((ret = sendmsg( NtCurrentTeb()->socket, &msghdr, 0 )) == sizeof(req)) return;
if (ret == -1)
{
if (errno == EPIPE) CLIENT_Die();
CLIENT_perror( "sendmsg" );
server_perror( "sendmsg" );
}
CLIENT_ProtocolError( "partial seq sent %d/%d\n", ret, sizeof(seq) );
server_protocol_error( "partial msg sent %d/%d\n", ret, sizeof(req) );
}
/***********************************************************************
......@@ -148,26 +139,23 @@ static void send_request_fd( enum request req, int fd )
*
* Wait for a reply from the server.
*/
static void wait_reply(void)
static unsigned int wait_reply(void)
{
int seq, ret;
int ret;
unsigned int res;
for (;;)
{
if ((ret = read( NtCurrentTeb()->socket, &seq, sizeof(seq) )) == sizeof(seq))
{
if (seq != NtCurrentTeb()->seq++)
CLIENT_ProtocolError( "sequence %08x instead of %08x\n", seq, NtCurrentTeb()->seq - 1 );
return;
}
if ((ret = read( NtCurrentTeb()->socket, &res, sizeof(res) )) == sizeof(res))
return res;
if (ret == -1)
{
if (errno == EINTR) continue;
if (errno == EPIPE) CLIENT_Die();
CLIENT_perror("read");
server_perror("read");
}
if (!ret) CLIENT_Die(); /* the server closed the connection; time to die... */
CLIENT_ProtocolError( "partial seq received %d/%d\n", ret, sizeof(seq) );
server_protocol_error( "partial msg received %d/%d\n", ret, sizeof(res) );
}
}
......@@ -177,17 +165,18 @@ static void wait_reply(void)
*
* Wait for a reply from the server, when a file descriptor is passed.
*/
static int wait_reply_fd(void)
static unsigned int wait_reply_fd( int *fd )
{
struct iovec vec;
int seq, ret;
int ret;
unsigned int res;
#ifdef HAVE_MSGHDR_ACCRIGHTS
struct msghdr msghdr;
int fd = -1;
msghdr.msg_accrights = (void *)&fd;
msghdr.msg_accrightslen = sizeof(int);
*fd = -1;
msghdr.msg_accrights = (void *)fd;
msghdr.msg_accrightslen = sizeof(*fd);
#else /* HAVE_MSGHDR_ACCRIGHTS */
struct msghdr msghdr;
struct cmsg_fd cmsg;
......@@ -205,29 +194,26 @@ static int wait_reply_fd(void)
msghdr.msg_namelen = 0;
msghdr.msg_iov = &vec;
msghdr.msg_iovlen = 1;
vec.iov_base = &seq;
vec.iov_len = sizeof(seq);
vec.iov_base = &res;
vec.iov_len = sizeof(res);
for (;;)
{
if ((ret = recvmsg( NtCurrentTeb()->socket, &msghdr, 0 )) == sizeof(seq))
if ((ret = recvmsg( NtCurrentTeb()->socket, &msghdr, 0 )) == sizeof(res))
{
if (seq != NtCurrentTeb()->seq++)
CLIENT_ProtocolError( "sequence %08x instead of %08x\n", seq, NtCurrentTeb()->seq - 1 );
#ifdef HAVE_MSGHDR_ACCRIGHTS
return fd;
#else
return cmsg.fd;
#ifndef HAVE_MSGHDR_ACCRIGHTS
*fd = cmsg.fd;
#endif
return res;
}
if (ret == -1)
{
if (errno == EINTR) continue;
if (errno == EPIPE) CLIENT_Die();
CLIENT_perror("recvmsg");
server_perror("recvmsg");
}
if (!ret) CLIENT_Die(); /* the server closed the connection; time to die... */
CLIENT_ProtocolError( "partial seq received %d/%d\n", ret, sizeof(seq) );
server_protocol_error( "partial seq received %d/%d\n", ret, sizeof(res) );
}
}
......@@ -239,18 +225,15 @@ static int wait_reply_fd(void)
*/
unsigned int server_call( enum request req )
{
struct header *head;
unsigned int res;
send_request( req );
wait_reply();
head = (struct header *)NtCurrentTeb()->buffer;
if ((head->len < sizeof(*head)) || (head->len > NtCurrentTeb()->buffer_size))
CLIENT_ProtocolError( "header length %d\n", head->len );
if (head->type) SetLastError( head->type );
return head->type; /* error code */
res = wait_reply();
if (res) SetLastError( res );
return res; /* error code */
}
/***********************************************************************
* server_call_fd
*
......@@ -258,125 +241,17 @@ unsigned int server_call( enum request req )
* If *fd is != -1, it will be passed to the server.
* If the server passes an fd, it will be stored into *fd.
*/
unsigned int server_call_fd( enum request req, int *fd )
{
struct header *head;
if (*fd == -1) send_request( req );
else send_request_fd( req, *fd );
*fd = wait_reply_fd();
head = (struct header *)NtCurrentTeb()->buffer;
if ((head->len < sizeof(*head)) || (head->len > NtCurrentTeb()->buffer_size))
CLIENT_ProtocolError( "header length %d\n", head->len );
if (head->type) SetLastError( head->type );
return head->type; /* error code */
}
/***********************************************************************
* CLIENT_SendRequest
*
* Send a request to the server.
*/
void CLIENT_SendRequest( enum request req, int pass_fd,
int n, ... /* arg_1, len_1, etc. */ )
{
va_list args;
va_start( args, n );
while (n--)
{
void *ptr = va_arg( args, void * );
int len = va_arg( args, int );
memcpy( server_add_data( len ), ptr, len );
}
va_end( args );
if (pass_fd == -1) send_request( req );
else
{
send_request_fd( req, pass_fd );
close( pass_fd ); /* we passed the fd now we can close it */
}
}
/***********************************************************************
* CLIENT_WaitReply_v
*
* Wait for a reply from the server.
* Returns the error code (or 0 if OK).
*/
static unsigned int CLIENT_WaitReply_v( int *len, int *passed_fd,
struct iovec *vec, int veclen )
{
struct header *head;
char *ptr;
int i, remaining;
if (passed_fd) *passed_fd = wait_reply_fd();
else wait_reply();
head = (struct header *)NtCurrentTeb()->buffer;
if ((head->len < sizeof(*head)) || (head->len > NtCurrentTeb()->buffer_size))
CLIENT_ProtocolError( "header length %d\n", head->len );
remaining = head->len - sizeof(*head);
ptr = (char *)(head + 1);
for (i = 0; i < veclen; i++, vec++)
{
int len = MIN( remaining, vec->iov_len );
memcpy( vec->iov_base, ptr, len );
ptr += len;
if (!(remaining -= len)) break;
}
if (len) *len = head->len - sizeof(*head);
if (head->type) SetLastError( head->type );
return head->type; /* error code */
}
/***********************************************************************
* CLIENT_WaitReply
*
* Wait for a reply from the server.
*/
unsigned int CLIENT_WaitReply( int *len, int *passed_fd,
int n, ... /* arg_1, len_1, etc. */ )
unsigned int server_call_fd( enum request req, int fd_out, int *fd_in )
{
struct iovec vec[16];
va_list args;
int i;
assert( n < 16 );
va_start( args, n );
for (i = 0; i < n; i++)
{
vec[i].iov_base = va_arg( args, void * );
vec[i].iov_len = va_arg( args, int );
}
va_end( args );
return CLIENT_WaitReply_v( len, passed_fd, vec, n );
}
unsigned int res;
if (fd_out == -1) send_request( req );
else send_request_fd( req, fd_out );
/***********************************************************************
* CLIENT_WaitSimpleReply
*
* Wait for a simple fixed-length reply from the server.
*/
unsigned int CLIENT_WaitSimpleReply( void *reply, int len, int *passed_fd )
{
struct iovec vec;
unsigned int ret;
int got;
vec.iov_base = reply;
vec.iov_len = len;
ret = CLIENT_WaitReply_v( &got, passed_fd, &vec, 1 );
if (got != len)
CLIENT_ProtocolError( "WaitSimpleReply: len %d != %d\n", len, got );
return ret;
if (fd_in) res = wait_reply_fd( fd_in );
else res = wait_reply();
if (res) SetLastError( res );
return res; /* error code */
}
......@@ -427,24 +302,23 @@ int CLIENT_InitServer(void)
*/
int CLIENT_InitThread(void)
{
struct init_thread_request req;
struct init_thread_reply reply;
struct init_thread_request *req;
TEB *teb = NtCurrentTeb();
int fd;
int fd = wait_reply_fd();
if (fd == -1) CLIENT_ProtocolError( "no fd passed on first request\n" );
if ((teb->buffer_size = lseek( fd, 0, SEEK_END )) == -1) CLIENT_perror( "lseek" );
if (wait_reply_fd( &fd ) || (fd == -1))
server_protocol_error( "no fd passed on first request\n" );
if ((teb->buffer_size = lseek( fd, 0, SEEK_END )) == -1) server_perror( "lseek" );
teb->buffer = mmap( 0, teb->buffer_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0 );
close( fd );
if (teb->buffer == (void*)-1) CLIENT_perror( "mmap" );
teb->buffer_args = (char *)teb->buffer + sizeof(struct header);
req.unix_pid = getpid();
req.teb = teb;
CLIENT_SendRequest( REQ_INIT_THREAD, -1, 1, &req, sizeof(req) );
if (CLIENT_WaitSimpleReply( &reply, sizeof(reply), NULL )) return -1;
teb->process->server_pid = reply.pid;
teb->tid = reply.tid;
if (teb->buffer == (void*)-1) server_perror( "mmap" );
req = get_req_buffer();
req->unix_pid = getpid();
req->teb = teb;
if (server_call( REQ_INIT_THREAD )) return -1;
teb->process->server_pid = req->pid;
teb->tid = req->tid;
return 0;
}
......@@ -456,8 +330,9 @@ int CLIENT_InitThread(void)
*/
int CLIENT_SetDebug( int level )
{
CLIENT_SendRequest( REQ_SET_DEBUG, -1, 1, &level, sizeof(level) );
return CLIENT_WaitReply( NULL, NULL, 0 );
struct set_debug_request *req = get_req_buffer();
req->level = level;
return server_call( REQ_SET_DEBUG );
}
/***********************************************************************
......@@ -467,9 +342,8 @@ int CLIENT_SetDebug( int level )
*/
int CLIENT_DebuggerRequest( int op )
{
struct debugger_request req;
req.op = op;
CLIENT_SendRequest( REQ_DEBUGGER, -1, 1, &req, sizeof(req) );
return CLIENT_WaitReply( NULL, NULL, 0 );
struct debugger_request *req = get_req_buffer();
req->op = op;
return server_call( REQ_DEBUGGER );
}
......@@ -17,13 +17,12 @@
*/
static DWORD DEBUG_SendEvent( int code, void *data, int size )
{
struct send_debug_event_request req;
struct send_debug_event_reply reply;
req.code = code;
CLIENT_SendRequest( REQ_SEND_DEBUG_EVENT, -1, 2, &req, sizeof(req), data, size );
if (CLIENT_WaitSimpleReply( &reply, sizeof(reply), NULL )) return 0;
return reply.status;
DWORD ret = 0;
struct send_debug_event_request *req = get_req_buffer();
req->code = code;
memcpy( req + 1, data, size );
if (!server_call( REQ_SEND_DEBUG_EVENT )) ret = req->status;
return ret;
}
......@@ -135,94 +134,74 @@ DWORD DEBUG_SendUnloadDLLEvent( HMODULE module )
*/
BOOL WINAPI WaitForDebugEvent( LPDEBUG_EVENT event, DWORD timeout )
{
/* size of the event data */
static const int event_sizes[] =
{
0,
sizeof(struct debug_event_exception), /* EXCEPTION_DEBUG_EVENT */
sizeof(struct debug_event_create_thread), /* CREATE_THREAD_DEBUG_EVENT */
sizeof(struct debug_event_create_process), /* CREATE_PROCESS_DEBUG_EVENT */
sizeof(struct debug_event_exit), /* EXIT_THREAD_DEBUG_EVENT */
sizeof(struct debug_event_exit), /* EXIT_PROCESS_DEBUG_EVENT */
sizeof(struct debug_event_load_dll), /* LOAD_DLL_DEBUG_EVENT */
sizeof(struct debug_event_unload_dll), /* UNLOAD_DLL_DEBUG_EVENT */
sizeof(struct debug_event_output_string), /* OUTPUT_DEBUG_STRING_EVENT */
sizeof(struct debug_event_rip_info) /* RIP_EVENT */
};
struct wait_debug_event_request req;
struct wait_debug_event_reply reply;
union debug_event_data data;
int i, len;
req.timeout = timeout;
CLIENT_SendRequest( REQ_WAIT_DEBUG_EVENT, -1, 1, &req, sizeof(req) );
if (CLIENT_WaitReply( &len, NULL, 2, &reply, sizeof(reply),
&data, sizeof(data) )) return FALSE;
if ((reply.code < 0) || (reply.code > RIP_EVENT))
CLIENT_ProtocolError( "WaitForDebugEvent: bad code %d\n", reply.code );
if (len != sizeof(reply) + event_sizes[reply.code])
CLIENT_ProtocolError( "WaitForDebugEvent: bad len %d for code %d\n", len, reply.code );
event->dwDebugEventCode = reply.code;
event->dwProcessId = (DWORD)reply.pid;
event->dwThreadId = (DWORD)reply.tid;
switch(reply.code)
struct wait_debug_event_request *req = get_req_buffer();
union debug_event_data *data = (union debug_event_data *)(req + 1);
int i;
req->timeout = timeout;
if (server_call( REQ_WAIT_DEBUG_EVENT )) return FALSE;
if ((req->code < 0) || (req->code > RIP_EVENT))
server_protocol_error( "WaitForDebugEvent: bad code %d\n", req->code );
event->dwDebugEventCode = req->code;
event->dwProcessId = (DWORD)req->pid;
event->dwThreadId = (DWORD)req->tid;
switch(req->code)
{
case EXCEPTION_DEBUG_EVENT:
event->u.Exception.ExceptionRecord.ExceptionCode = data.exception.code;
event->u.Exception.ExceptionRecord.ExceptionFlags = data.exception.flags;
event->u.Exception.ExceptionRecord.ExceptionRecord = data.exception.record;
event->u.Exception.ExceptionRecord.ExceptionAddress = data.exception.addr;
event->u.Exception.ExceptionRecord.NumberParameters = data.exception.nb_params;
for (i = 0; i < data.exception.nb_params; i++)
event->u.Exception.ExceptionRecord.ExceptionInformation[i] = data.exception.params[i];
event->u.Exception.dwFirstChance = data.exception.first_chance;
event->u.Exception.ExceptionRecord.ExceptionCode = data->exception.code;
event->u.Exception.ExceptionRecord.ExceptionFlags = data->exception.flags;
event->u.Exception.ExceptionRecord.ExceptionRecord = data->exception.record;
event->u.Exception.ExceptionRecord.ExceptionAddress = data->exception.addr;
event->u.Exception.ExceptionRecord.NumberParameters = data->exception.nb_params;
for (i = 0; i < data->exception.nb_params; i++)
event->u.Exception.ExceptionRecord.ExceptionInformation[i] = data->exception.params[i];
event->u.Exception.dwFirstChance = data->exception.first_chance;
break;
case CREATE_THREAD_DEBUG_EVENT:
event->u.CreateThread.hThread = data.create_thread.handle;
event->u.CreateThread.lpThreadLocalBase = data.create_thread.teb;
event->u.CreateThread.lpStartAddress = data.create_thread.start;
event->u.CreateThread.hThread = data->create_thread.handle;
event->u.CreateThread.lpThreadLocalBase = data->create_thread.teb;
event->u.CreateThread.lpStartAddress = data->create_thread.start;
break;
case CREATE_PROCESS_DEBUG_EVENT:
event->u.CreateProcessInfo.hFile = data.create_process.file;
event->u.CreateProcessInfo.hProcess = data.create_process.process;
event->u.CreateProcessInfo.hThread = data.create_process.thread;
event->u.CreateProcessInfo.lpBaseOfImage = data.create_process.base;
event->u.CreateProcessInfo.dwDebugInfoFileOffset = data.create_process.dbg_offset;
event->u.CreateProcessInfo.nDebugInfoSize = data.create_process.dbg_size;
event->u.CreateProcessInfo.lpThreadLocalBase = data.create_process.teb;
event->u.CreateProcessInfo.lpStartAddress = data.create_process.start;
event->u.CreateProcessInfo.lpImageName = data.create_process.name;
event->u.CreateProcessInfo.fUnicode = data.create_process.unicode;
if (data.create_process.file == -1) event->u.CreateProcessInfo.hFile = 0;
event->u.CreateProcessInfo.hFile = data->create_process.file;
event->u.CreateProcessInfo.hProcess = data->create_process.process;
event->u.CreateProcessInfo.hThread = data->create_process.thread;
event->u.CreateProcessInfo.lpBaseOfImage = data->create_process.base;
event->u.CreateProcessInfo.dwDebugInfoFileOffset = data->create_process.dbg_offset;
event->u.CreateProcessInfo.nDebugInfoSize = data->create_process.dbg_size;
event->u.CreateProcessInfo.lpThreadLocalBase = data->create_process.teb;
event->u.CreateProcessInfo.lpStartAddress = data->create_process.start;
event->u.CreateProcessInfo.lpImageName = data->create_process.name;
event->u.CreateProcessInfo.fUnicode = data->create_process.unicode;
if (data->create_process.file == -1) event->u.CreateProcessInfo.hFile = 0;
break;
case EXIT_THREAD_DEBUG_EVENT:
event->u.ExitThread.dwExitCode = data.exit.exit_code;
event->u.ExitThread.dwExitCode = data->exit.exit_code;
break;
case EXIT_PROCESS_DEBUG_EVENT:
event->u.ExitProcess.dwExitCode = data.exit.exit_code;
event->u.ExitProcess.dwExitCode = data->exit.exit_code;
break;
case LOAD_DLL_DEBUG_EVENT:
event->u.LoadDll.hFile = data.load_dll.handle;
event->u.LoadDll.lpBaseOfDll = data.load_dll.base;
event->u.LoadDll.dwDebugInfoFileOffset = data.load_dll.dbg_offset;
event->u.LoadDll.nDebugInfoSize = data.load_dll.dbg_size;
event->u.LoadDll.lpImageName = data.load_dll.name;
event->u.LoadDll.fUnicode = data.load_dll.unicode;
if (data.load_dll.handle == -1) event->u.LoadDll.hFile = 0;
event->u.LoadDll.hFile = data->load_dll.handle;
event->u.LoadDll.lpBaseOfDll = data->load_dll.base;
event->u.LoadDll.dwDebugInfoFileOffset = data->load_dll.dbg_offset;
event->u.LoadDll.nDebugInfoSize = data->load_dll.dbg_size;
event->u.LoadDll.lpImageName = data->load_dll.name;
event->u.LoadDll.fUnicode = data->load_dll.unicode;
if (data->load_dll.handle == -1) event->u.LoadDll.hFile = 0;
break;
case UNLOAD_DLL_DEBUG_EVENT:
event->u.UnloadDll.lpBaseOfDll = data.unload_dll.base;
event->u.UnloadDll.lpBaseOfDll = data->unload_dll.base;
break;
case OUTPUT_DEBUG_STRING_EVENT:
event->u.DebugString.lpDebugStringData = data.output_string.string;
event->u.DebugString.fUnicode = data.output_string.unicode;
event->u.DebugString.nDebugStringLength = data.output_string.length;
event->u.DebugString.lpDebugStringData = data->output_string.string;
event->u.DebugString.fUnicode = data->output_string.unicode;
event->u.DebugString.nDebugStringLength = data->output_string.length;
break;
case RIP_EVENT:
event->u.RipInfo.dwError = data.rip_info.error;
event->u.RipInfo.dwType = data.rip_info.type;
event->u.RipInfo.dwError = data->rip_info.error;
event->u.RipInfo.dwType = data->rip_info.type;
break;
}
return TRUE;
......@@ -234,13 +213,11 @@ BOOL WINAPI WaitForDebugEvent( LPDEBUG_EVENT event, DWORD timeout )
*/
BOOL WINAPI ContinueDebugEvent( DWORD pid, DWORD tid, DWORD status )
{
struct continue_debug_event_request req;
req.pid = (void *)pid;
req.tid = (void *)tid;
req.status = status;
CLIENT_SendRequest( REQ_CONTINUE_DEBUG_EVENT, -1, 1, &req, sizeof(req) );
return !CLIENT_WaitReply( NULL, NULL, 0 );
struct continue_debug_event_request *req = get_req_buffer();
req->pid = (void *)pid;
req->tid = (void *)tid;
req->status = status;
return !server_call( REQ_CONTINUE_DEBUG_EVENT );
}
......@@ -249,10 +226,9 @@ BOOL WINAPI ContinueDebugEvent( DWORD pid, DWORD tid, DWORD status )
*/
BOOL WINAPI DebugActiveProcess( DWORD pid )
{
struct debug_process_request req;
req.pid = (void *)pid;
CLIENT_SendRequest( REQ_DEBUG_PROCESS, -1, 1, &req, sizeof(req) );
return !CLIENT_WaitReply( NULL, NULL, 0 );
struct debug_process_request *req = get_req_buffer();
req->pid = (void *)pid;
return !server_call( REQ_DEBUG_PROCESS );
}
......
......@@ -18,18 +18,16 @@
HANDLE WINAPI CreateEventA( SECURITY_ATTRIBUTES *sa, BOOL manual_reset,
BOOL initial_state, LPCSTR name )
{
struct create_event_request req;
struct create_event_reply reply;
if (!name) name = "";
req.manual_reset = manual_reset;
req.initial_state = initial_state;
req.inherit = (sa && (sa->nLength>=sizeof(*sa)) && sa->bInheritHandle);
CLIENT_SendRequest( REQ_CREATE_EVENT, -1, 2, &req, sizeof(req), name, strlen(name)+1 );
struct create_event_request *req = get_req_buffer();
req->manual_reset = manual_reset;
req->initial_state = initial_state;
req->inherit = (sa && (sa->nLength>=sizeof(*sa)) && sa->bInheritHandle);
lstrcpynA( req->name, name ? name : "", server_remaining(req->name) );
SetLastError(0);
CLIENT_WaitSimpleReply( &reply, sizeof(reply), NULL );
if (reply.handle == -1) return 0;
return reply.handle;
server_call( REQ_CREATE_EVENT );
if (req->handle == -1) return 0;
return req->handle;
}
......@@ -59,16 +57,14 @@ HANDLE WINAPI WIN16_CreateEvent( BOOL manual_reset, BOOL initial_state )
*/
HANDLE WINAPI OpenEventA( DWORD access, BOOL inherit, LPCSTR name )
{
struct open_event_request req;
struct open_event_reply reply;
int len = name ? strlen(name) + 1 : 0;
req.access = access;
req.inherit = inherit;
CLIENT_SendRequest( REQ_OPEN_EVENT, -1, 2, &req, sizeof(req), name, len );
CLIENT_WaitSimpleReply( &reply, sizeof(reply), NULL );
if (reply.handle == -1) return 0; /* must return 0 on failure, not -1 */
return (HANDLE)reply.handle;
struct open_event_request *req = get_req_buffer();
req->access = access;
req->inherit = inherit;
lstrcpynA( req->name, name ? name : "", server_remaining(req->name) );
server_call( REQ_OPEN_EVENT );
if (req->handle == -1) return 0; /* must return 0 on failure, not -1 */
return req->handle;
}
......@@ -91,12 +87,10 @@ HANDLE WINAPI OpenEventW( DWORD access, BOOL inherit, LPCWSTR name )
*/
static BOOL EVENT_Operation( HANDLE handle, enum event_op op )
{
struct event_op_request req;
req.handle = handle;
req.op = op;
CLIENT_SendRequest( REQ_EVENT_OP, -1, 1, &req, sizeof(req) );
return !CLIENT_WaitReply( NULL, NULL, 0 );
struct event_op_request *req = get_req_buffer();
req->handle = handle;
req->op = op;
return !server_call( REQ_EVENT_OP );
}
......
......@@ -18,11 +18,9 @@ DEFAULT_DEBUG_CHANNEL(win32)
*/
BOOL WINAPI CloseHandle( HANDLE handle )
{
struct close_handle_request req;
req.handle = handle;
CLIENT_SendRequest( REQ_CLOSE_HANDLE, -1, 1, &req, sizeof(req) );
return !CLIENT_WaitReply( NULL, NULL, 0 );
struct close_handle_request *req = get_req_buffer();
req->handle = handle;
return !server_call( REQ_CLOSE_HANDLE );
}
......@@ -31,13 +29,10 @@ BOOL WINAPI CloseHandle( HANDLE handle )
*/
BOOL WINAPI GetHandleInformation( HANDLE handle, LPDWORD flags )
{
struct get_handle_info_request req;
struct get_handle_info_reply reply;
req.handle = handle;
CLIENT_SendRequest( REQ_GET_HANDLE_INFO, -1, 1, &req, sizeof(req) );
if (CLIENT_WaitSimpleReply( &reply, sizeof(reply), NULL )) return FALSE;
if (flags) *flags = reply.flags;
struct get_handle_info_request *req = get_req_buffer();
req->handle = handle;
if (server_call( REQ_GET_HANDLE_INFO )) return FALSE;
if (flags) *flags = req->flags;
return TRUE;
}
......@@ -47,13 +42,11 @@ BOOL WINAPI GetHandleInformation( HANDLE handle, LPDWORD flags )
*/
BOOL WINAPI SetHandleInformation( HANDLE handle, DWORD mask, DWORD flags )
{
struct set_handle_info_request req;
req.handle = handle;
req.flags = flags;
req.mask = mask;
CLIENT_SendRequest( REQ_SET_HANDLE_INFO, -1, 1, &req, sizeof(req) );
return !CLIENT_WaitReply( NULL, NULL, 0 );
struct set_handle_info_request *req = get_req_buffer();
req->handle = handle;
req->flags = flags;
req->mask = mask;
return !server_call( REQ_SET_HANDLE_INFO );
}
......@@ -64,19 +57,17 @@ BOOL WINAPI DuplicateHandle( HANDLE source_process, HANDLE source,
HANDLE dest_process, HANDLE *dest,
DWORD access, BOOL inherit, DWORD options )
{
struct dup_handle_request req;
struct dup_handle_reply reply;
req.src_process = source_process;
req.src_handle = source;
req.dst_process = dest_process;
req.access = access;
req.inherit = inherit;
req.options = options;
CLIENT_SendRequest( REQ_DUP_HANDLE, -1, 1, &req, sizeof(req) );
if (CLIENT_WaitSimpleReply( &reply, sizeof(reply), NULL )) return FALSE;
if (dest) *dest = reply.handle;
struct dup_handle_request *req = get_req_buffer();
req->src_process = source_process;
req->src_handle = source;
req->dst_process = dest_process;
req->access = access;
req->inherit = inherit;
req->options = options;
if (server_call( REQ_DUP_HANDLE )) return FALSE;
if (dest) *dest = req->handle;
return TRUE;
}
......@@ -86,19 +77,17 @@ BOOL WINAPI DuplicateHandle( HANDLE source_process, HANDLE source,
*/
HANDLE WINAPI ConvertToGlobalHandle(HANDLE hSrc)
{
struct dup_handle_request req;
struct dup_handle_reply reply;
req.src_process = GetCurrentProcess();
req.src_handle = hSrc;
req.dst_process = -1;
req.access = 0;
req.inherit = FALSE;
req.options = DUP_HANDLE_MAKE_GLOBAL | DUP_HANDLE_SAME_ACCESS;
CLIENT_SendRequest( REQ_DUP_HANDLE, -1, 1, &req, sizeof(req) );
CLIENT_WaitSimpleReply( &reply, sizeof(reply), NULL );
return reply.handle;
struct dup_handle_request *req = get_req_buffer();
req->src_process = GetCurrentProcess();
req->src_handle = hSrc;
req->dst_process = -1;
req->access = 0;
req->inherit = FALSE;
req->options = DUP_HANDLE_MAKE_GLOBAL | DUP_HANDLE_SAME_ACCESS;
server_call( REQ_DUP_HANDLE );
return req->handle;
}
/***********************************************************************
......
......@@ -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 );
}
......@@ -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;
}
......@@ -74,29 +74,16 @@ PDB *PROCESS_Initial(void)
}
/***********************************************************************
* 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
*
* Check if a handle is to the current process
*/
BOOL PROCESS_IsCurrent( HANDLE handle )
{
struct get_process_info_reply reply;
return (PROCESS_QueryInfo( handle, &reply ) &&
(reply.pid == PROCESS_Current()->server_pid));
struct get_process_info_request *req = get_req_buffer();
req->handle = handle;
return (!server_call( REQ_GET_PROCESS_INFO ) &&
(req->pid == PROCESS_Current()->server_pid));
}
......@@ -252,21 +239,12 @@ void PROCESS_CallUserSignalProc( UINT uCode, HMODULE hModule )
*/
static BOOL PROCESS_CreateEnvDB(void)
{
struct init_process_request req;
struct init_process_reply reply;
struct init_process_request *req = get_req_buffer();
STARTUPINFOA *startup;
ENVDB *env_db;
char cmd_line[4096];
int len;
PDB *pdb = PROCESS_Current();
/* Retrieve startup info from the server */
req.dummy = 0;
CLIENT_SendRequest( REQ_INIT_PROCESS, -1, 1, &req, sizeof(req) );
if (CLIENT_WaitReply( &len, NULL, 2, &reply, sizeof(reply), cmd_line, sizeof(cmd_line) ))
return FALSE;
/* Allocate the env DB */
if (!(env_db = HeapAlloc( pdb->heap, HEAP_ZERO_MEMORY, sizeof(ENVDB) )))
......@@ -278,15 +256,20 @@ static BOOL PROCESS_CreateEnvDB(void)
if (!(startup = HeapAlloc( pdb->heap, HEAP_ZERO_MEMORY, sizeof(STARTUPINFOA) )))
return FALSE;
env_db->startup_info = startup;
startup->dwFlags = reply.start_flags;
startup->wShowWindow = reply.cmd_show;
env_db->hStdin = startup->hStdInput = reply.hstdin;
env_db->hStdout = startup->hStdOutput = reply.hstdout;
env_db->hStderr = startup->hStdError = reply.hstderr;
/* Retrieve startup info from the server */
if (server_call( REQ_INIT_PROCESS )) return FALSE;
startup->dwFlags = req->start_flags;
startup->wShowWindow = req->cmd_show;
env_db->hStdin = startup->hStdInput = req->hstdin;
env_db->hStdout = startup->hStdOutput = req->hstdout;
env_db->hStderr = startup->hStdError = req->hstderr;
lstrcpynA( cmd_line, req->cmdline, sizeof(cmd_line) );
/* Copy the parent environment */
if (!ENV_InheritEnvironment( pdb, reply.env_ptr )) return FALSE;
if (!ENV_InheritEnvironment( pdb, req->env_ptr )) return FALSE;
/* Copy the command line */
......@@ -527,8 +510,7 @@ PDB *PROCESS_Create( NE_MODULE *pModule, LPCSTR cmd_line, LPCSTR env,
HANDLE handles[2], load_done_evt = INVALID_HANDLE_VALUE;
DWORD exitcode, size;
int server_thandle;
struct new_process_request req;
struct new_process_reply reply;
struct new_process_request *req = get_req_buffer();
TEB *teb = NULL;
PDB *parent = PROCESS_Current();
PDB *pdb = PROCESS_CreatePDB( parent, inherit );
......@@ -538,29 +520,28 @@ PDB *PROCESS_Create( NE_MODULE *pModule, LPCSTR cmd_line, LPCSTR env,
/* Create the process on the server side */
req.inherit = (psa && (psa->nLength >= sizeof(*psa)) && psa->bInheritHandle);
req.inherit_all = inherit;
req.create_flags = flags;
req.start_flags = startup->dwFlags;
req->inherit = (psa && (psa->nLength >= sizeof(*psa)) && psa->bInheritHandle);
req->inherit_all = inherit;
req->create_flags = flags;
req->start_flags = startup->dwFlags;
if (startup->dwFlags & STARTF_USESTDHANDLES)
{
req.hstdin = startup->hStdInput;
req.hstdout = startup->hStdOutput;
req.hstderr = startup->hStdError;
req->hstdin = startup->hStdInput;
req->hstdout = startup->hStdOutput;
req->hstderr = startup->hStdError;
}
else
{
req.hstdin = GetStdHandle( STD_INPUT_HANDLE );
req.hstdout = GetStdHandle( STD_OUTPUT_HANDLE );
req.hstderr = GetStdHandle( STD_ERROR_HANDLE );
req->hstdin = GetStdHandle( STD_INPUT_HANDLE );
req->hstdout = GetStdHandle( STD_OUTPUT_HANDLE );
req->hstderr = GetStdHandle( STD_ERROR_HANDLE );
}
req.cmd_show = startup->wShowWindow;
req.env_ptr = (void*)env; /* FIXME: hack */
CLIENT_SendRequest( REQ_NEW_PROCESS, -1, 2,
&req, sizeof(req), cmd_line, strlen(cmd_line) + 1 );
if (CLIENT_WaitSimpleReply( &reply, sizeof(reply), NULL )) goto error;
pdb->server_pid = reply.pid;
info->hProcess = reply.handle;
req->cmd_show = startup->wShowWindow;
req->env_ptr = (void*)env; /* FIXME: hack */
lstrcpynA( req->cmdline, cmd_line, server_remaining(req->cmdline) );
if (server_call( REQ_NEW_PROCESS )) goto error;
pdb->server_pid = req->pid;
info->hProcess = req->handle;
info->dwProcessId = (DWORD)pdb->server_pid;
if ((flags & DEBUG_PROCESS) ||
......@@ -675,11 +656,10 @@ void WINAPI ExitProcess16( WORD status )
*/
BOOL WINAPI TerminateProcess( HANDLE handle, DWORD exit_code )
{
struct terminate_process_request req;
req.handle = handle;
req.exit_code = exit_code;
CLIENT_SendRequest( REQ_TERMINATE_PROCESS, -1, 1, &req, sizeof(req) );
return !CLIENT_WaitReply( NULL, NULL, 0 );
struct terminate_process_request *req = get_req_buffer();
req->handle = handle;
req->exit_code = exit_code;
return !server_call( REQ_TERMINATE_PROCESS );
}
......@@ -816,15 +796,14 @@ HANDLE WINAPI GetCurrentProcess(void)
*/
HANDLE WINAPI OpenProcess( DWORD access, BOOL inherit, DWORD id )
{
struct open_process_request req;
struct open_process_reply reply;
req.pid = (void *)id;
req.access = access;
req.inherit = inherit;
CLIENT_SendRequest( REQ_OPEN_PROCESS, -1, 1, &req, sizeof(req) );
if (CLIENT_WaitSimpleReply( &reply, sizeof(reply), NULL )) return 0;
return reply.handle;
HANDLE ret = 0;
struct open_process_request *req = get_req_buffer();
req->pid = (void *)id;
req->access = access;
req->inherit = inherit;
if (!server_call( REQ_OPEN_PROCESS )) ret = req->handle;
return ret;
}
/*********************************************************************
......@@ -832,9 +811,11 @@ HANDLE WINAPI OpenProcess( DWORD access, BOOL inherit, DWORD id )
*/
DWORD WINAPI MapProcessHandle( HANDLE handle )
{
struct get_process_info_reply reply;
if ( !PROCESS_QueryInfo( handle, &reply ) ) return 0;
return (DWORD)reply.pid;
DWORD ret = 0;
struct get_process_info_request *req = get_req_buffer();
req->handle = handle;
if (!server_call( REQ_GET_PROCESS_INFO )) ret = (DWORD)req->pid;
return ret;
}
/***********************************************************************
......@@ -870,12 +851,11 @@ LCID WINAPI GetThreadLocale(void)
*/
BOOL WINAPI SetPriorityClass( HANDLE hprocess, DWORD priorityclass )
{
struct set_process_info_request req;
req.handle = hprocess;
req.priority = priorityclass;
req.mask = SET_PROCESS_INFO_PRIORITY;
CLIENT_SendRequest( REQ_SET_PROCESS_INFO, -1, 1, &req, sizeof(req) );
return !CLIENT_WaitReply( NULL, NULL, 0 );
struct set_process_info_request *req = get_req_buffer();
req->handle = hprocess;
req->priority = priorityclass;
req->mask = SET_PROCESS_INFO_PRIORITY;
return !server_call( REQ_SET_PROCESS_INFO );
}
......@@ -884,9 +864,11 @@ BOOL WINAPI SetPriorityClass( HANDLE hprocess, DWORD priorityclass )
*/
DWORD WINAPI GetPriorityClass(HANDLE hprocess)
{
struct get_process_info_reply reply;
if (!PROCESS_QueryInfo( hprocess, &reply )) return 0;
return reply.priority;
DWORD ret = 0;
struct get_process_info_request *req = get_req_buffer();
req->handle = hprocess;
if (!server_call( REQ_GET_PROCESS_INFO )) ret = req->priority;
return ret;
}
......@@ -895,12 +877,11 @@ DWORD WINAPI GetPriorityClass(HANDLE hprocess)
*/
BOOL WINAPI SetProcessAffinityMask( HANDLE hProcess, DWORD affmask )
{
struct set_process_info_request req;
req.handle = hProcess;
req.affinity = affmask;
req.mask = SET_PROCESS_INFO_AFFINITY;
CLIENT_SendRequest( REQ_SET_PROCESS_INFO, -1, 1, &req, sizeof(req) );
return !CLIENT_WaitReply( NULL, NULL, 0 );
struct set_process_info_request *req = get_req_buffer();
req->handle = hProcess;
req->affinity = affmask;
req->mask = SET_PROCESS_INFO_AFFINITY;
return !server_call( REQ_SET_PROCESS_INFO );
}
/**********************************************************************
......@@ -910,11 +891,16 @@ BOOL WINAPI GetProcessAffinityMask( HANDLE hProcess,
LPDWORD lpProcessAffinityMask,
LPDWORD lpSystemAffinityMask )
{
struct get_process_info_reply reply;
if (!PROCESS_QueryInfo( hProcess, &reply )) return FALSE;
if (lpProcessAffinityMask) *lpProcessAffinityMask = reply.process_affinity;
if (lpSystemAffinityMask) *lpSystemAffinityMask = reply.system_affinity;
return TRUE;
BOOL ret = FALSE;
struct get_process_info_request *req = get_req_buffer();
req->handle = hProcess;
if (!server_call( REQ_GET_PROCESS_INFO ))
{
if (lpProcessAffinityMask) *lpProcessAffinityMask = req->process_affinity;
if (lpSystemAffinityMask) *lpSystemAffinityMask = req->system_affinity;
ret = TRUE;
}
return ret;
}
......@@ -1119,10 +1105,15 @@ BOOL WINAPI GetExitCodeProcess(
HANDLE hProcess, /* [I] handle to the process */
LPDWORD lpExitCode) /* [O] address to receive termination status */
{
struct get_process_info_reply reply;
if (!PROCESS_QueryInfo( hProcess, &reply )) return FALSE;
if (lpExitCode) *lpExitCode = reply.exit_code;
return TRUE;
BOOL ret = FALSE;
struct get_process_info_request *req = get_req_buffer();
req->handle = hProcess;
if (!server_call( REQ_GET_PROCESS_INFO ))
{
if (lpExitCode) *lpExitCode = req->exit_code;
ret = TRUE;
}
return ret;
}
......
......@@ -16,8 +16,7 @@
*/
HANDLE WINAPI CreateSemaphoreA( SECURITY_ATTRIBUTES *sa, LONG initial, LONG max, LPCSTR name )
{
struct create_semaphore_request req;
struct create_semaphore_reply reply;
struct create_semaphore_request *req = get_req_buffer();
/* Check parameters */
......@@ -27,16 +26,14 @@ HANDLE WINAPI CreateSemaphoreA( SECURITY_ATTRIBUTES *sa, LONG initial, LONG max,
return 0;
}
if (!name) name = "";
req.initial = (unsigned int)initial;
req.max = (unsigned int)max;
req.inherit = (sa && (sa->nLength>=sizeof(*sa)) && sa->bInheritHandle);
CLIENT_SendRequest( REQ_CREATE_SEMAPHORE, -1, 2, &req, sizeof(req), name, strlen(name)+1 );
req->initial = (unsigned int)initial;
req->max = (unsigned int)max;
req->inherit = (sa && (sa->nLength>=sizeof(*sa)) && sa->bInheritHandle);
lstrcpynA( req->name, name ? name : "", server_remaining(req->name) );
SetLastError(0);
CLIENT_WaitSimpleReply( &reply, sizeof(reply), NULL );
if (reply.handle == -1) return 0;
return reply.handle;
server_call( REQ_CREATE_SEMAPHORE );
if (req->handle == -1) return 0;
return req->handle;
}
......@@ -58,16 +55,14 @@ HANDLE WINAPI CreateSemaphoreW( SECURITY_ATTRIBUTES *sa, LONG initial,
*/
HANDLE WINAPI OpenSemaphoreA( DWORD access, BOOL inherit, LPCSTR name )
{
struct open_semaphore_request req;
struct open_semaphore_reply reply;
int len = name ? strlen(name) + 1 : 0;
req.access = access;
req.inherit = inherit;
CLIENT_SendRequest( REQ_OPEN_SEMAPHORE, -1, 2, &req, sizeof(req), name, len );
CLIENT_WaitSimpleReply( &reply, sizeof(reply), NULL );
if (reply.handle == -1) return 0; /* must return 0 on failure, not -1 */
return reply.handle;
struct open_semaphore_request *req = get_req_buffer();
req->access = access;
req->inherit = inherit;
lstrcpynA( req->name, name ? name : "", server_remaining(req->name) );
server_call( REQ_OPEN_SEMAPHORE );
if (req->handle == -1) return 0; /* must return 0 on failure, not -1 */
return req->handle;
}
......@@ -88,18 +83,16 @@ HANDLE WINAPI OpenSemaphoreW( DWORD access, BOOL inherit, LPCWSTR name )
*/
BOOL WINAPI ReleaseSemaphore( HANDLE handle, LONG count, LONG *previous )
{
struct release_semaphore_request req;
struct release_semaphore_reply reply;
struct release_semaphore_request *req = get_req_buffer();
if (count < 0)
{
SetLastError( ERROR_INVALID_PARAMETER );
return FALSE;
}
req.handle = handle;
req.count = (unsigned int)count;
CLIENT_SendRequest( REQ_RELEASE_SEMAPHORE, -1, 1, &req, sizeof(req) );
if (CLIENT_WaitSimpleReply( &reply, sizeof(reply), NULL )) return FALSE;
if (previous) *previous = reply.prev_count;
req->handle = handle;
req->count = (unsigned int)count;
if (server_call( REQ_RELEASE_SEMAPHORE )) return FALSE;
if (previous) *previous = req->prev_count;
return TRUE;
}
......@@ -17,6 +17,27 @@
#include "x11drv.h"
#include "server.h"
/***********************************************************************
* call_apcs
*
* Call outstanding APCs.
*/
static void call_apcs(void)
{
#define MAX_APCS 16
int i;
void *buffer[MAX_APCS * 2];
struct get_apcs_request *req = get_req_buffer();
if (server_call( REQ_GET_APCS ) || !req->count) return;
assert( req->count <= MAX_APCS );
memcpy( buffer, req->apcs, req->count * 2 * sizeof(req->apcs[0]) );
for (i = 0; i < req->count * 2; i += 2)
{
PAPCFUNC func = (PAPCFUNC)req->apcs[i];
if (func) func( (ULONG_PTR)req->apcs[i+1] );
}
}
/***********************************************************************
* Sleep (KERNEL32.679)
......@@ -73,11 +94,8 @@ DWORD WINAPI WaitForMultipleObjectsEx( DWORD count, const HANDLE *handles,
BOOL wait_all, DWORD timeout,
BOOL alertable )
{
struct select_request req;
struct select_reply reply;
int server_handle[MAXIMUM_WAIT_OBJECTS];
void *apc[32];
int i, len;
struct select_request *req = get_req_buffer();
int i, ret;
if (count > MAXIMUM_WAIT_OBJECTS)
{
......@@ -99,32 +117,18 @@ DWORD WINAPI WaitForMultipleObjectsEx( DWORD count, const HANDLE *handles,
EVENT_Synchronize( FALSE );
}
for (i = 0; i < count; i++) server_handle[i] = handles[i];
req.count = count;
req.flags = 0;
req.timeout = timeout;
req->count = count;
req->flags = 0;
req->timeout = timeout;
for (i = 0; i < count; i++) req->handles[i] = handles[i];
if (wait_all) req.flags |= SELECT_ALL;
if (alertable) req.flags |= SELECT_ALERTABLE;
if (timeout != INFINITE) req.flags |= SELECT_TIMEOUT;
if (wait_all) req->flags |= SELECT_ALL;
if (alertable) req->flags |= SELECT_ALERTABLE;
if (timeout != INFINITE) req->flags |= SELECT_TIMEOUT;
CLIENT_SendRequest( REQ_SELECT, -1, 2,
&req, sizeof(req),
server_handle, count * sizeof(int) );
CLIENT_WaitReply( &len, NULL, 2, &reply, sizeof(reply),
apc, sizeof(apc) );
if ((reply.signaled == STATUS_USER_APC) && (len > sizeof(reply)))
{
int i;
len -= sizeof(reply);
for (i = 0; i < len / sizeof(void*); i += 2)
{
PAPCFUNC func = (PAPCFUNC)apc[i];
if ( func ) func( (ULONG_PTR)apc[i+1] );
}
}
return reply.signaled;
server_call( REQ_SELECT );
if ((ret = req->signaled) == STATUS_USER_APC) call_apcs();
return ret;
}
......
......@@ -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 );
}
......
......@@ -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 );
}
}
......@@ -69,7 +69,7 @@ static int screen_buffer_get_write_fd( struct object *obj );
static void screen_buffer_destroy( struct object *obj );
/* common routine */
static int console_get_info( struct object *obj, struct get_file_info_reply *reply );
static int console_get_info( struct object *obj, struct get_file_info_request *req );
static const struct object_ops console_input_ops =
{
......@@ -183,12 +183,11 @@ int free_console( struct process *process )
return 1;
}
static int set_console_fd( int handle, int fd, int pid )
static int set_console_fd( int handle, int fd_in, int fd_out, int pid )
{
struct console_input *input;
struct screen_buffer *output;
struct object *obj;
int fd_in, fd_out;
if (!(obj = get_handle_obj( current->process, handle, 0, NULL )))
return 0;
......@@ -215,21 +214,6 @@ static int set_console_fd( int handle, int fd, int pid )
assert( !input->obj.head );
assert( !output->obj.head );
if ((fd_in = dup(fd)) == -1)
{
file_set_error();
release_object( input );
release_object( output );
return 0;
}
if ((fd_out = dup(fd)) == -1)
{
file_set_error();
close( fd_in );
release_object( input );
release_object( output );
return 0;
}
unregister_select_user( &input->select );
unregister_select_user( &output->select );
close( input->select.fd );
......@@ -244,25 +228,21 @@ static int set_console_fd( int handle, int fd, int pid )
return 1;
}
static int get_console_mode( int handle, int *mode )
static int get_console_mode( int handle )
{
struct object *obj;
int ret = 0;
if (!(obj = get_handle_obj( current->process, handle, GENERIC_READ, NULL )))
return 0;
if (obj->ops == &console_input_ops)
{
*mode = ((struct console_input *)obj)->mode;
ret = 1;
}
else if (obj->ops == &screen_buffer_ops)
if ((obj = get_handle_obj( current->process, handle, GENERIC_READ, NULL )))
{
*mode = ((struct screen_buffer *)obj)->mode;
ret = 1;
if (obj->ops == &console_input_ops)
ret = ((struct console_input *)obj)->mode;
else if (obj->ops == &screen_buffer_ops)
ret = ((struct screen_buffer *)obj)->mode;
else
set_error( ERROR_INVALID_HANDLE );
release_object( obj );
}
else set_error( ERROR_INVALID_HANDLE );
release_object( obj );
return ret;
}
......@@ -316,21 +296,6 @@ static int set_console_info( int handle, struct set_console_info_request *req,
return 1;
}
/* get misc console information (output handle only) */
static int get_console_info( int handle, struct get_console_info_reply *reply, const char **title )
{
struct screen_buffer *console;
if (!(console = (struct screen_buffer *)get_handle_obj( current->process, handle,
GENERIC_READ, &screen_buffer_ops )))
return 0;
reply->cursor_size = console->cursor_size;
reply->cursor_visible = console->cursor_visible;
reply->pid = console->pid;
*title = console->title;
release_object( console );
return 1;
}
/* add input events to a console input queue */
static int write_console_input( int handle, int count, INPUT_RECORD *records )
{
......@@ -355,16 +320,16 @@ static int write_console_input( int handle, int count, INPUT_RECORD *records )
}
/* retrieve a pointer to the console input records */
static int read_console_input( int handle, int count, int flush )
static int read_console_input( int handle, int count, INPUT_RECORD *rec, int max, int flush )
{
struct console_input *console;
struct read_console_input_reply *reply = push_reply_data( current, sizeof(*reply) );
if (!(console = (struct console_input *)get_handle_obj( current->process, handle,
GENERIC_READ, &console_input_ops )))
return -1;
if ((count < 0) || (count > console->recnum)) count = console->recnum;
add_reply_data( current, console->records, count * sizeof(INPUT_RECORD) );
if (count > max) count = max;
memcpy( rec, console->records, count * sizeof(INPUT_RECORD) );
if (flush)
{
int i;
......@@ -440,10 +405,18 @@ static int console_input_get_read_fd( struct object *obj )
return dup( console->select.fd );
}
static int console_get_info( struct object *obj, struct get_file_info_reply *reply )
static int console_get_info( struct object *obj, struct get_file_info_request *req )
{
memset( reply, 0, sizeof(*reply) );
reply->type = FILE_TYPE_CHAR;
req->type = FILE_TYPE_CHAR;
req->attr = 0;
req->access_time = 0;
req->write_time = 0;
req->size_high = 0;
req->size_low = 0;
req->links = 0;
req->index_high = 0;
req->index_low = 0;
req->serial = 0;
return 1;
}
......@@ -517,14 +490,12 @@ static void screen_buffer_destroy( struct object *obj )
unregister_select_user( &console->select );
close( console->select.fd );
if (console->input) console->input->output = NULL;
if (console->pid) kill( console->pid, SIGTERM );
if (console->title) free( console->title );
}
/* allocate a console for the current process */
DECL_HANDLER(alloc_console)
{
struct alloc_console_reply *reply = push_reply_data( current, sizeof(*reply) );
int in = -1, out = -1;
if (!alloc_console( current->process )) goto done;
......@@ -541,8 +512,8 @@ DECL_HANDLER(alloc_console)
free_console( current->process );
done:
reply->handle_in = in;
reply->handle_out = out;
req->handle_in = in;
req->handle_out = out;
}
/* free the console of the current process */
......@@ -554,40 +525,61 @@ DECL_HANDLER(free_console)
/* open a handle to the process console */
DECL_HANDLER(open_console)
{
struct open_console_reply *reply = push_reply_data( current, sizeof(*reply) );
struct object *obj= req->output ? current->process->console_out : current->process->console_in;
if (obj) reply->handle = alloc_handle( current->process, obj, req->access, req->inherit );
if (obj) req->handle = alloc_handle( current->process, obj, req->access, req->inherit );
else set_error( ERROR_ACCESS_DENIED );
}
/* set info about a console (output only) */
DECL_HANDLER(set_console_info)
{
size_t len = get_req_strlen();
set_console_info( req->handle, req, get_req_data( len + 1 ), len );
size_t len = get_req_strlen( req->title );
set_console_info( req->handle, req, req->title, len );
}
/* get info about a console (output only) */
DECL_HANDLER(get_console_info)
{
struct get_console_info_reply *reply = push_reply_data( current, sizeof(*reply) );
const char *title;
get_console_info( req->handle, reply, &title );
if (title) add_reply_data( current, title, strlen(title) + 1 );
struct screen_buffer *console;
if ((console = (struct screen_buffer *)get_handle_obj( current->process, req->handle,
GENERIC_READ, &screen_buffer_ops )))
{
req->cursor_size = console->cursor_size;
req->cursor_visible = console->cursor_visible;
req->pid = console->pid;
strcpy( req->title, console->title ? console->title : "" );
release_object( console );
}
}
/* set a console fd */
DECL_HANDLER(set_console_fd)
{
set_console_fd( req->handle, fd, req->pid );
struct object *obj;
int fd_in, fd_out;
if (!(obj = get_handle_obj( current->process, req->file_handle,
GENERIC_READ | GENERIC_WRITE, NULL ))) return;
if ((fd_in = obj->ops->get_read_fd( obj )) == -1)
{
release_object( obj );
return;
}
fd_out = obj->ops->get_write_fd( obj );
release_object( obj );
if (fd_out != -1)
{
if (set_console_fd( req->handle, fd_in, fd_out, req->pid )) return;
close( fd_out );
}
close( fd_in );
}
/* get a console mode (input or output) */
DECL_HANDLER(get_console_mode)
{
struct get_console_mode_reply *reply = push_reply_data( current, sizeof(*reply) );
get_console_mode( req->handle, &reply->mode );
req->mode = get_console_mode( req->handle );
}
/* set a console mode (input or output) */
......@@ -599,18 +591,17 @@ DECL_HANDLER(set_console_mode)
/* add input records to a console input queue */
DECL_HANDLER(write_console_input)
{
struct write_console_input_reply *reply = push_reply_data( current, sizeof(*reply) );
int max = get_req_size( req + 1, sizeof(INPUT_RECORD) );
int count = req->count;
if (check_req_data( req->count * sizeof(INPUT_RECORD)))
{
INPUT_RECORD *records = get_req_data( req->count * sizeof(INPUT_RECORD) );
reply->written = write_console_input( req->handle, req->count, records );
}
else fatal_protocol_error( "write_console_input: bad length" );
if (count > max) count = max;
req->written = write_console_input( req->handle, count, (INPUT_RECORD *)(req + 1) );
}
/* fetch input records from a console input queue */
DECL_HANDLER(read_console_input)
{
read_console_input( req->handle, req->count, req->flush );
int max = get_req_size( req + 1, sizeof(INPUT_RECORD) );
req->read = read_console_input( req->handle, req->count, (INPUT_RECORD *)(req + 1),
max, req->flush );
}
......@@ -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;
}
}
......@@ -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;
}
......@@ -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 );
}
}
......@@ -47,7 +47,7 @@ static int file_signaled( struct object *obj, struct thread *thread );
static int file_get_read_fd( struct object *obj );
static int file_get_write_fd( struct object *obj );
static int file_flush( struct object *obj );
static int file_get_info( struct object *obj, struct get_file_info_reply *reply );
static int file_get_info( struct object *obj, struct get_file_info_request *req );
static void file_destroy( struct object *obj );
static const struct object_ops file_ops =
......@@ -208,7 +208,7 @@ struct file *create_temp_file( int access )
struct file *file;
int fd;
if ((fd = create_anonymous_file()) != -1) return NULL;
if ((fd = create_anonymous_file()) == -1) return NULL;
if (!(file = create_file_for_fd( fd, access, 0, 0 ))) close( fd );
return file;
}
......@@ -295,7 +295,7 @@ static int file_flush( struct object *obj )
return ret;
}
static int file_get_info( struct object *obj, struct get_file_info_reply *reply )
static int file_get_info( struct object *obj, struct get_file_info_request *req )
{
struct stat st;
struct file *file = (struct file *)obj;
......@@ -307,19 +307,19 @@ static int file_get_info( struct object *obj, struct get_file_info_reply *reply
return 0;
}
if (S_ISCHR(st.st_mode) || S_ISFIFO(st.st_mode) ||
S_ISSOCK(st.st_mode) || isatty(file->select.fd)) reply->type = FILE_TYPE_CHAR;
else reply->type = FILE_TYPE_DISK;
if (S_ISDIR(st.st_mode)) reply->attr = FILE_ATTRIBUTE_DIRECTORY;
else reply->attr = FILE_ATTRIBUTE_ARCHIVE;
if (!(st.st_mode & S_IWUSR)) reply->attr |= FILE_ATTRIBUTE_READONLY;
reply->access_time = st.st_atime;
reply->write_time = st.st_mtime;
reply->size_high = 0;
reply->size_low = S_ISDIR(st.st_mode) ? 0 : st.st_size;
reply->links = st.st_nlink;
reply->index_high = st.st_dev;
reply->index_low = st.st_ino;
reply->serial = 0; /* FIXME */
S_ISSOCK(st.st_mode) || isatty(file->select.fd)) req->type = FILE_TYPE_CHAR;
else req->type = FILE_TYPE_DISK;
if (S_ISDIR(st.st_mode)) req->attr = FILE_ATTRIBUTE_DIRECTORY;
else req->attr = FILE_ATTRIBUTE_ARCHIVE;
if (!(st.st_mode & S_IWUSR)) req->attr |= FILE_ATTRIBUTE_READONLY;
req->access_time = st.st_atime;
req->write_time = st.st_mtime;
req->size_high = 0;
req->size_low = S_ISDIR(st.st_mode) ? 0 : st.st_size;
req->links = st.st_nlink;
req->index_high = st.st_dev;
req->index_low = st.st_ino;
req->serial = 0; /* FIXME */
return 1;
}
......@@ -485,71 +485,72 @@ static int file_unlock( struct file *file, int offset_high, int offset_low,
/* FIXME: implement this */
return 1;
}
/* create a file */
DECL_HANDLER(create_file)
{
struct create_file_reply *reply = push_reply_data( current, sizeof(*reply) );
struct file *file = NULL;
size_t len = get_req_strlen( req->name );
struct file *file;
if (fd == -1)
req->handle = -1;
if ((file = create_file( req->name, len, req->access,
req->sharing, req->create, req->attrs )))
{
size_t len = get_req_strlen();
file = create_file( get_req_data( len + 1), len, req->access,
req->sharing, req->create, req->attrs );
}
else
{
if ((fd = dup(fd)) == -1)
file_set_error();
else
file = create_file_for_fd( fd, req->access, req->sharing, req->attrs );
req->handle = alloc_handle( current->process, file, req->access, req->inherit );
release_object( file );
}
if (file)
}
/* allocate a file handle for a Unix fd */
DECL_HANDLER(alloc_file_handle)
{
struct file *file;
req->handle = -1;
if ((fd = dup(fd)) != -1)
{
reply->handle = alloc_handle( current->process, file, req->access, req->inherit );
release_object( file );
if ((file = create_file_for_fd( fd, req->access, FILE_SHARE_READ | FILE_SHARE_WRITE, 0 )))
{
req->handle = alloc_handle( current->process, file, req->access, 0 );
release_object( file );
}
else close( fd );
}
else reply->handle = -1;
else file_set_error();
}
/* get a Unix fd to read from a file */
DECL_HANDLER(get_read_fd)
{
struct object *obj;
int read_fd;
if ((obj = get_handle_obj( current->process, req->handle, GENERIC_READ, NULL )))
{
read_fd = obj->ops->get_read_fd( obj );
set_reply_fd( current, obj->ops->get_read_fd( obj ) );
release_object( obj );
}
else read_fd = -1;
set_reply_fd( current, read_fd );
}
/* get a Unix fd to write to a file */
DECL_HANDLER(get_write_fd)
{
struct object *obj;
int write_fd;
if ((obj = get_handle_obj( current->process, req->handle, GENERIC_WRITE, NULL )))
{
write_fd = obj->ops->get_write_fd( obj );
set_reply_fd( current, obj->ops->get_write_fd( obj ) );
release_object( obj );
}
else write_fd = -1;
set_reply_fd( current, write_fd );
}
/* set a file current position */
DECL_HANDLER(set_file_pointer)
{
struct set_file_pointer_reply reply;
reply.low = req->low;
reply.high = req->high;
set_file_pointer( req->handle, &reply.low, &reply.high, req->whence );
add_reply_data( current, &reply, sizeof(reply) );
int high = req->high;
int low = req->low;
set_file_pointer( req->handle, &low, &high, req->whence );
req->new_low = low;
req->new_high = high;
}
/* truncate (or extend) a file */
......@@ -580,11 +581,10 @@ DECL_HANDLER(set_file_time)
DECL_HANDLER(get_file_info)
{
struct object *obj;
struct get_file_info_reply *reply = push_reply_data( current, sizeof(*reply) );
if ((obj = get_handle_obj( current->process, req->handle, 0, NULL )))
{
obj->ops->get_file_info( obj, reply );
obj->ops->get_file_info( obj, req );
release_object( obj );
}
}
......
......@@ -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) );
}
......@@ -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 );
}
}
......@@ -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 */
......
......@@ -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;
......
......@@ -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 */
......
......@@ -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;
}
......@@ -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 );
}
}
......
......@@ -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 */
......
......@@ -13,14 +13,21 @@
#include "thread.h"
/* request handler definition */
/* max request length */
#define MAX_REQUEST_LENGTH 8192
/* exit code passed to remove_client on communication error */
#define OUT_OF_MEMORY -1
#define BROKEN_PIPE -2
#define PROTOCOL_ERROR -3
/* request handler definition */
#define DECL_HANDLER(name) void req_##name( struct name##_request *req, int fd )
/* request functions */
extern void fatal_protocol_error( const char *err );
extern void call_req_handler( struct thread *thread, int fd );
extern void fatal_protocol_error( struct thread *thread, const char *err, ... );
extern void call_req_handler( struct thread *thread, enum request req, int fd );
extern void call_timeout_handler( void *thread );
extern void call_kill_handler( struct thread *thread, int exit_code );
extern void set_reply_fd( struct thread *thread, int pass_fd );
......@@ -29,48 +36,26 @@ extern void send_reply( struct thread *thread );
extern void trace_request( enum request req, int fd );
extern void trace_timeout(void);
extern void trace_kill( int exit_code );
extern void trace_reply( struct thread *thread, int pass_fd );
/* Warning: the buffer is shared between request and reply,
* so make sure you are finished using the request before starting
* to add data for the reply.
*/
extern void trace_reply( struct thread *thread, unsigned int res, int pass_fd );
/* remove some data from the current request */
static inline void *get_req_data( size_t len )
/* get the request buffer */
static inline void *get_req_ptr( struct thread *thread )
{
void *old = current->req_pos;
current->req_pos = (char *)old + len;
return old;
return thread->buffer;
}
/* check that there is enough data available in the current request */
static inline int check_req_data( size_t len )
/* get the remaining size in the request buffer for object of a given size */
static inline int get_req_size( const void *ptr, size_t typesize )
{
return (char *)current->req_pos + len <= (char *)current->req_end;
return ((char *)current->buffer + MAX_REQUEST_LENGTH - (char *)ptr) / typesize;
}
/* get the length of a request string, without going past the end of the request */
static inline size_t get_req_strlen(void)
{
char *p = current->req_pos;
while (*p && (p < (char *)current->req_end - 1)) p++;
return p - (char *)current->req_pos;
}
/* make space for some data in the current reply */
static inline void *push_reply_data( struct thread *thread, size_t len )
{
void *old = thread->reply_pos;
thread->reply_pos = (char *)old + len;
return old;
}
/* add some data to the current reply */
static inline void add_reply_data( struct thread *thread, const void *data, size_t len )
static inline size_t get_req_strlen( const char *str )
{
memcpy( push_reply_data( thread, len ), data, len );
const char *p = str;
while (*p && (p < (char *)current->buffer + MAX_REQUEST_LENGTH - 1)) p++;
return p - str;
}
/* Everything below this line is generated automatically by tools/make_requests */
......@@ -81,6 +66,7 @@ DECL_HANDLER(new_thread);
DECL_HANDLER(set_debug);
DECL_HANDLER(init_process);
DECL_HANDLER(init_thread);
DECL_HANDLER(get_thread_buffer);
DECL_HANDLER(terminate_process);
DECL_HANDLER(terminate_thread);
DECL_HANDLER(get_process_info);
......@@ -91,6 +77,7 @@ DECL_HANDLER(suspend_thread);
DECL_HANDLER(resume_thread);
DECL_HANDLER(debugger);
DECL_HANDLER(queue_apc);
DECL_HANDLER(get_apcs);
DECL_HANDLER(close_handle);
DECL_HANDLER(get_handle_info);
DECL_HANDLER(set_handle_info);
......@@ -107,6 +94,7 @@ DECL_HANDLER(create_semaphore);
DECL_HANDLER(release_semaphore);
DECL_HANDLER(open_semaphore);
DECL_HANDLER(create_file);
DECL_HANDLER(alloc_file_handle);
DECL_HANDLER(get_read_fd);
DECL_HANDLER(get_write_fd);
DECL_HANDLER(set_file_pointer);
......@@ -150,6 +138,7 @@ static const struct handler {
{ (void(*)())req_set_debug, sizeof(struct set_debug_request) },
{ (void(*)())req_init_process, sizeof(struct init_process_request) },
{ (void(*)())req_init_thread, sizeof(struct init_thread_request) },
{ (void(*)())req_get_thread_buffer, sizeof(struct get_thread_buffer_request) },
{ (void(*)())req_terminate_process, sizeof(struct terminate_process_request) },
{ (void(*)())req_terminate_thread, sizeof(struct terminate_thread_request) },
{ (void(*)())req_get_process_info, sizeof(struct get_process_info_request) },
......@@ -160,6 +149,7 @@ static const struct handler {
{ (void(*)())req_resume_thread, sizeof(struct resume_thread_request) },
{ (void(*)())req_debugger, sizeof(struct debugger_request) },
{ (void(*)())req_queue_apc, sizeof(struct queue_apc_request) },
{ (void(*)())req_get_apcs, sizeof(struct get_apcs_request) },
{ (void(*)())req_close_handle, sizeof(struct close_handle_request) },
{ (void(*)())req_get_handle_info, sizeof(struct get_handle_info_request) },
{ (void(*)())req_set_handle_info, sizeof(struct set_handle_info_request) },
......@@ -176,6 +166,7 @@ static const struct handler {
{ (void(*)())req_release_semaphore, sizeof(struct release_semaphore_request) },
{ (void(*)())req_open_semaphore, sizeof(struct open_semaphore_request) },
{ (void(*)())req_create_file, sizeof(struct create_file_request) },
{ (void(*)())req_alloc_file_handle, sizeof(struct alloc_file_handle_request) },
{ (void(*)())req_get_read_fd, sizeof(struct get_read_fd_request) },
{ (void(*)())req_get_write_fd, sizeof(struct get_write_fd_request) },
{ (void(*)())req_set_file_pointer, sizeof(struct set_file_pointer_request) },
......
......@@ -64,31 +64,33 @@ static struct semaphore *create_semaphore( const char *name, size_t len,
return sem;
}
static void release_semaphore( int handle, unsigned int count, unsigned int *prev_count )
static unsigned int release_semaphore( int handle, unsigned int count )
{
struct semaphore *sem;
unsigned int prev = 0;
if (!(sem = (struct semaphore *)get_handle_obj( current->process, handle,
SEMAPHORE_MODIFY_STATE, &semaphore_ops )))
return;
*prev_count = sem->count;
if (sem->count + count < sem->count || sem->count + count > sem->max)
{
set_error( ERROR_TOO_MANY_POSTS );
}
else if (sem->count)
if ((sem = (struct semaphore *)get_handle_obj( current->process, handle,
SEMAPHORE_MODIFY_STATE, &semaphore_ops )))
{
/* there cannot be any thread waiting if the count is != 0 */
assert( !sem->obj.head );
sem->count += count;
}
else
{
sem->count = count;
wake_up( &sem->obj, count );
prev = sem->count;
if (sem->count + count < sem->count || sem->count + count > sem->max)
{
set_error( ERROR_TOO_MANY_POSTS );
}
else if (sem->count)
{
/* there cannot be any thread waiting if the count is != 0 */
assert( !sem->obj.head );
sem->count += count;
}
else
{
sem->count = count;
wake_up( &sem->obj, count );
}
release_object( sem );
}
release_object( sem );
return prev;
}
static void semaphore_dump( struct object *obj, int verbose )
......@@ -118,30 +120,26 @@ static int semaphore_satisfied( struct object *obj, struct thread *thread )
/* create a semaphore */
DECL_HANDLER(create_semaphore)
{
size_t len = get_req_strlen();
struct create_semaphore_reply *reply = push_reply_data( current, sizeof(*reply) );
size_t len = get_req_strlen( req->name );
struct semaphore *sem;
if ((sem = create_semaphore( get_req_data( len + 1 ), len, req->initial, req->max )))
req->handle = -1;
if ((sem = create_semaphore( req->name, len, req->initial, req->max )))
{
reply->handle = alloc_handle( current->process, sem, SEMAPHORE_ALL_ACCESS, req->inherit );
req->handle = alloc_handle( current->process, sem, SEMAPHORE_ALL_ACCESS, req->inherit );
release_object( sem );
}
else reply->handle = -1;
}
/* open a handle to a semaphore */
DECL_HANDLER(open_semaphore)
{
size_t len = get_req_strlen();
struct open_semaphore_reply *reply = push_reply_data( current, sizeof(*reply) );
reply->handle = open_object( get_req_data( len + 1 ), len, &semaphore_ops,
req->access, req->inherit );
size_t len = get_req_strlen( req->name );
req->handle = open_object( req->name, len, &semaphore_ops, req->access, req->inherit );
}
/* release a semaphore */
DECL_HANDLER(release_semaphore)
{
struct release_semaphore_reply *reply = push_reply_data( current, sizeof(*reply) );
release_semaphore( req->handle, req->count, &reply->prev_count );
req->prev_count = release_semaphore( req->handle, req->count );
}
......@@ -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 );
}
}
......@@ -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 );
}
......@@ -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;
}
}
......@@ -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) */
};
......
......@@ -9,46 +9,32 @@
#include <sys/uio.h>
#include "request.h"
static int dump_chars( void *ptr, int len )
{
fprintf( stderr, "\"%.*s\"", len, (char *)ptr );
return len;
}
static int dump_ints( void *ptr, int len )
/* dumping for functions for requests that have a variable part */
static void dump_varargs_select( struct select_request *req )
{
int i;
if (!(len /= sizeof(int)))
{
fprintf( stderr, "{}" );
return 0;
}
for (i = 0; i < len; i++)
fprintf( stderr, "%c%d", i ? ',' : '{', *((int *)ptr + i) );
for (i = 0; i < req->count; i++)
fprintf( stderr, "%c%d", i ? ',' : '{', req->handles[i] );
fprintf( stderr, "}" );
return len * sizeof(int);
}
static int dump_ptrs( void *ptr, int len )
static void dump_varargs_get_apcs( struct get_apcs_request *req )
{
int i;
if (!(len /= sizeof(void*)))
{
fprintf( stderr, "{}" );
return 0;
}
for (i = 0; i < len; i++)
fprintf( stderr, "%c%p", i ? ',' : '{', *((void **)ptr + i) );
for (i = 0; i < 2 * req->count; i++)
fprintf( stderr, "%c%p", i ? ',' : '{', req->apcs[i] );
fprintf( stderr, "}" );
return len * sizeof(void*);
}
typedef int (*dump_func)( const void *req, int len );
typedef void (*dump_func)( const void *req );
/* Everything below this line is generated automatically by tools/make_requests */
/* ### make_requests begin ### */
static int dump_new_process_request( struct new_process_request *req, int len )
static void dump_new_process_request( struct new_process_request *req )
{
fprintf( stderr, " inherit=%d,", req->inherit );
fprintf( stderr, " inherit_all=%d,", req->inherit_all );
......@@ -59,45 +45,38 @@ static int dump_new_process_request( struct new_process_request *req, int len )
fprintf( stderr, " hstderr=%d,", req->hstderr );
fprintf( stderr, " cmd_show=%d,", req->cmd_show );
fprintf( stderr, " env_ptr=%p,", req->env_ptr );
fprintf( stderr, " cmd_line=" );
return dump_chars( req+1, len - (int)sizeof(*req) ) + sizeof(*req);
fprintf( stderr, " cmdline=\"%s\"", req->cmdline );
}
static int dump_new_process_reply( struct new_process_reply *req, int len )
static void dump_new_process_reply( struct new_process_request *req )
{
fprintf( stderr, " pid=%p,", req->pid );
fprintf( stderr, " handle=%d", req->handle );
return (int)sizeof(*req);
}
static int dump_new_thread_request( struct new_thread_request *req, int len )
static void dump_new_thread_request( struct new_thread_request *req )
{
fprintf( stderr, " pid=%p,", req->pid );
fprintf( stderr, " suspend=%d,", req->suspend );
fprintf( stderr, " inherit=%d", req->inherit );
return (int)sizeof(*req);
}
static int dump_new_thread_reply( struct new_thread_reply *req, int len )
static void dump_new_thread_reply( struct new_thread_request *req )
{
fprintf( stderr, " tid=%p,", req->tid );
fprintf( stderr, " handle=%d", req->handle );
return (int)sizeof(*req);
}
static int dump_set_debug_request( struct set_debug_request *req, int len )
static void dump_set_debug_request( struct set_debug_request *req )
{
fprintf( stderr, " level=%d", req->level );
return (int)sizeof(*req);
}
static int dump_init_process_request( struct init_process_request *req, int len )
static void dump_init_process_request( struct init_process_request *req )
{
fprintf( stderr, " dummy=%d", req->dummy );
return (int)sizeof(*req);
}
static int dump_init_process_reply( struct init_process_reply *req, int len )
static void dump_init_process_reply( struct init_process_request *req )
{
fprintf( stderr, " start_flags=%d,", req->start_flags );
fprintf( stderr, " hstdin=%d,", req->hstdin );
......@@ -105,151 +84,146 @@ static int dump_init_process_reply( struct init_process_reply *req, int len )
fprintf( stderr, " hstderr=%d,", req->hstderr );
fprintf( stderr, " cmd_show=%d,", req->cmd_show );
fprintf( stderr, " env_ptr=%p,", req->env_ptr );
fprintf( stderr, " cmdline=" );
return dump_chars( req+1, len - (int)sizeof(*req) ) + sizeof(*req);
fprintf( stderr, " cmdline=\"%s\"", req->cmdline );
}
static int dump_init_thread_request( struct init_thread_request *req, int len )
static void dump_init_thread_request( struct init_thread_request *req )
{
fprintf( stderr, " unix_pid=%d,", req->unix_pid );
fprintf( stderr, " teb=%p", req->teb );
return (int)sizeof(*req);
}
static int dump_init_thread_reply( struct init_thread_reply *req, int len )
static void dump_init_thread_reply( struct init_thread_request *req )
{
fprintf( stderr, " pid=%p,", req->pid );
fprintf( stderr, " tid=%p", req->tid );
return (int)sizeof(*req);
}
static int dump_terminate_process_request( struct terminate_process_request *req, int len )
static void dump_get_thread_buffer_request( struct get_thread_buffer_request *req )
{
fprintf( stderr, " dummy=%d", req->dummy );
}
static void dump_terminate_process_request( struct terminate_process_request *req )
{
fprintf( stderr, " handle=%d,", req->handle );
fprintf( stderr, " exit_code=%d", req->exit_code );
return (int)sizeof(*req);
}
static int dump_terminate_thread_request( struct terminate_thread_request *req, int len )
static void dump_terminate_thread_request( struct terminate_thread_request *req )
{
fprintf( stderr, " handle=%d,", req->handle );
fprintf( stderr, " exit_code=%d", req->exit_code );
return (int)sizeof(*req);
}
static int dump_get_process_info_request( struct get_process_info_request *req, int len )
static void dump_get_process_info_request( struct get_process_info_request *req )
{
fprintf( stderr, " handle=%d", req->handle );
return (int)sizeof(*req);
}
static int dump_get_process_info_reply( struct get_process_info_reply *req, int len )
static void dump_get_process_info_reply( struct get_process_info_request *req )
{
fprintf( stderr, " pid=%p,", req->pid );
fprintf( stderr, " exit_code=%d,", req->exit_code );
fprintf( stderr, " priority=%d,", req->priority );
fprintf( stderr, " process_affinity=%d,", req->process_affinity );
fprintf( stderr, " system_affinity=%d", req->system_affinity );
return (int)sizeof(*req);
}
static int dump_set_process_info_request( struct set_process_info_request *req, int len )
static void dump_set_process_info_request( struct set_process_info_request *req )
{
fprintf( stderr, " handle=%d,", req->handle );
fprintf( stderr, " mask=%d,", req->mask );
fprintf( stderr, " priority=%d,", req->priority );
fprintf( stderr, " affinity=%d", req->affinity );
return (int)sizeof(*req);
}
static int dump_get_thread_info_request( struct get_thread_info_request *req, int len )
static void dump_get_thread_info_request( struct get_thread_info_request *req )
{
fprintf( stderr, " handle=%d", req->handle );
return (int)sizeof(*req);
}
static int dump_get_thread_info_reply( struct get_thread_info_reply *req, int len )
static void dump_get_thread_info_reply( struct get_thread_info_request *req )
{
fprintf( stderr, " tid=%p,", req->tid );
fprintf( stderr, " exit_code=%d,", req->exit_code );
fprintf( stderr, " priority=%d", req->priority );
return (int)sizeof(*req);
}
static int dump_set_thread_info_request( struct set_thread_info_request *req, int len )
static void dump_set_thread_info_request( struct set_thread_info_request *req )
{
fprintf( stderr, " handle=%d,", req->handle );
fprintf( stderr, " mask=%d,", req->mask );
fprintf( stderr, " priority=%d,", req->priority );
fprintf( stderr, " affinity=%d", req->affinity );
return (int)sizeof(*req);
}
static int dump_suspend_thread_request( struct suspend_thread_request *req, int len )
static void dump_suspend_thread_request( struct suspend_thread_request *req )
{
fprintf( stderr, " handle=%d", req->handle );
return (int)sizeof(*req);
}
static int dump_suspend_thread_reply( struct suspend_thread_reply *req, int len )
static void dump_suspend_thread_reply( struct suspend_thread_request *req )
{
fprintf( stderr, " count=%d", req->count );
return (int)sizeof(*req);
}
static int dump_resume_thread_request( struct resume_thread_request *req, int len )
static void dump_resume_thread_request( struct resume_thread_request *req )
{
fprintf( stderr, " handle=%d", req->handle );
return (int)sizeof(*req);
}
static int dump_resume_thread_reply( struct resume_thread_reply *req, int len )
static void dump_resume_thread_reply( struct resume_thread_request *req )
{
fprintf( stderr, " count=%d", req->count );
return (int)sizeof(*req);
}
static int dump_debugger_request( struct debugger_request *req, int len )
static void dump_debugger_request( struct debugger_request *req )
{
fprintf( stderr, " op=%d", req->op );
return (int)sizeof(*req);
}
static int dump_queue_apc_request( struct queue_apc_request *req, int len )
static void dump_queue_apc_request( struct queue_apc_request *req )
{
fprintf( stderr, " handle=%d,", req->handle );
fprintf( stderr, " func=%p,", req->func );
fprintf( stderr, " param=%p", req->param );
return (int)sizeof(*req);
}
static int dump_close_handle_request( struct close_handle_request *req, int len )
static void dump_get_apcs_request( struct get_apcs_request *req )
{
}
static void dump_get_apcs_reply( struct get_apcs_request *req )
{
fprintf( stderr, " count=%d,", req->count );
fprintf( stderr, " apcs=" );
dump_varargs_get_apcs( req );
}
static void dump_close_handle_request( struct close_handle_request *req )
{
fprintf( stderr, " handle=%d", req->handle );
return (int)sizeof(*req);
}
static int dump_get_handle_info_request( struct get_handle_info_request *req, int len )
static void dump_get_handle_info_request( struct get_handle_info_request *req )
{
fprintf( stderr, " handle=%d", req->handle );
return (int)sizeof(*req);
}
static int dump_get_handle_info_reply( struct get_handle_info_reply *req, int len )
static void dump_get_handle_info_reply( struct get_handle_info_request *req )
{
fprintf( stderr, " flags=%d", req->flags );
return (int)sizeof(*req);
}
static int dump_set_handle_info_request( struct set_handle_info_request *req, int len )
static void dump_set_handle_info_request( struct set_handle_info_request *req )
{
fprintf( stderr, " handle=%d,", req->handle );
fprintf( stderr, " flags=%d,", req->flags );
fprintf( stderr, " mask=%d", req->mask );
return (int)sizeof(*req);
}
static int dump_dup_handle_request( struct dup_handle_request *req, int len )
static void dump_dup_handle_request( struct dup_handle_request *req )
{
fprintf( stderr, " src_process=%d,", req->src_process );
fprintf( stderr, " src_handle=%d,", req->src_handle );
......@@ -257,229 +231,207 @@ static int dump_dup_handle_request( struct dup_handle_request *req, int len )
fprintf( stderr, " access=%08x,", req->access );
fprintf( stderr, " inherit=%d,", req->inherit );
fprintf( stderr, " options=%d", req->options );
return (int)sizeof(*req);
}
static int dump_dup_handle_reply( struct dup_handle_reply *req, int len )
static void dump_dup_handle_reply( struct dup_handle_request *req )
{
fprintf( stderr, " handle=%d", req->handle );
return (int)sizeof(*req);
}
static int dump_open_process_request( struct open_process_request *req, int len )
static void dump_open_process_request( struct open_process_request *req )
{
fprintf( stderr, " pid=%p,", req->pid );
fprintf( stderr, " access=%08x,", req->access );
fprintf( stderr, " inherit=%d", req->inherit );
return (int)sizeof(*req);
}
static int dump_open_process_reply( struct open_process_reply *req, int len )
static void dump_open_process_reply( struct open_process_request *req )
{
fprintf( stderr, " handle=%d", req->handle );
return (int)sizeof(*req);
}
static int dump_select_request( struct select_request *req, int len )
static void dump_select_request( struct select_request *req )
{
fprintf( stderr, " count=%d,", req->count );
fprintf( stderr, " flags=%d,", req->flags );
fprintf( stderr, " timeout=%d,", req->timeout );
fprintf( stderr, " handles=" );
return dump_ints( req+1, len - (int)sizeof(*req) ) + sizeof(*req);
dump_varargs_select( req );
}
static int dump_select_reply( struct select_reply *req, int len )
static void dump_select_reply( struct select_request *req )
{
fprintf( stderr, " signaled=%d,", req->signaled );
fprintf( stderr, " apcs=" );
return dump_ptrs( req+1, len - (int)sizeof(*req) ) + sizeof(*req);
fprintf( stderr, " signaled=%d", req->signaled );
}
static int dump_create_event_request( struct create_event_request *req, int len )
static void dump_create_event_request( struct create_event_request *req )
{
fprintf( stderr, " manual_reset=%d,", req->manual_reset );
fprintf( stderr, " initial_state=%d,", req->initial_state );
fprintf( stderr, " inherit=%d,", req->inherit );
fprintf( stderr, " name=" );
return dump_chars( req+1, len - (int)sizeof(*req) ) + sizeof(*req);
fprintf( stderr, " name=\"%s\"", req->name );
}
static int dump_create_event_reply( struct create_event_reply *req, int len )
static void dump_create_event_reply( struct create_event_request *req )
{
fprintf( stderr, " handle=%d", req->handle );
return (int)sizeof(*req);
}
static int dump_event_op_request( struct event_op_request *req, int len )
static void dump_event_op_request( struct event_op_request *req )
{
fprintf( stderr, " handle=%d,", req->handle );
fprintf( stderr, " op=%d", req->op );
return (int)sizeof(*req);
}
static int dump_open_event_request( struct open_event_request *req, int len )
static void dump_open_event_request( struct open_event_request *req )
{
fprintf( stderr, " access=%08x,", req->access );
fprintf( stderr, " inherit=%d,", req->inherit );
fprintf( stderr, " name=" );
return dump_chars( req+1, len - (int)sizeof(*req) ) + sizeof(*req);
fprintf( stderr, " name=\"%s\"", req->name );
}
static int dump_open_event_reply( struct open_event_reply *req, int len )
static void dump_open_event_reply( struct open_event_request *req )
{
fprintf( stderr, " handle=%d", req->handle );
return (int)sizeof(*req);
}
static int dump_create_mutex_request( struct create_mutex_request *req, int len )
static void dump_create_mutex_request( struct create_mutex_request *req )
{
fprintf( stderr, " owned=%d,", req->owned );
fprintf( stderr, " inherit=%d,", req->inherit );
fprintf( stderr, " name=" );
return dump_chars( req+1, len - (int)sizeof(*req) ) + sizeof(*req);
fprintf( stderr, " name=\"%s\"", req->name );
}
static int dump_create_mutex_reply( struct create_mutex_reply *req, int len )
static void dump_create_mutex_reply( struct create_mutex_request *req )
{
fprintf( stderr, " handle=%d", req->handle );
return (int)sizeof(*req);
}
static int dump_release_mutex_request( struct release_mutex_request *req, int len )
static void dump_release_mutex_request( struct release_mutex_request *req )
{
fprintf( stderr, " handle=%d", req->handle );
return (int)sizeof(*req);
}
static int dump_open_mutex_request( struct open_mutex_request *req, int len )
static void dump_open_mutex_request( struct open_mutex_request *req )
{
fprintf( stderr, " access=%08x,", req->access );
fprintf( stderr, " inherit=%d,", req->inherit );
fprintf( stderr, " name=" );
return dump_chars( req+1, len - (int)sizeof(*req) ) + sizeof(*req);
fprintf( stderr, " name=\"%s\"", req->name );
}
static int dump_open_mutex_reply( struct open_mutex_reply *req, int len )
static void dump_open_mutex_reply( struct open_mutex_request *req )
{
fprintf( stderr, " handle=%d", req->handle );
return (int)sizeof(*req);
}
static int dump_create_semaphore_request( struct create_semaphore_request *req, int len )
static void dump_create_semaphore_request( struct create_semaphore_request *req )
{
fprintf( stderr, " initial=%08x,", req->initial );
fprintf( stderr, " max=%08x,", req->max );
fprintf( stderr, " inherit=%d,", req->inherit );
fprintf( stderr, " name=" );
return dump_chars( req+1, len - (int)sizeof(*req) ) + sizeof(*req);
fprintf( stderr, " name=\"%s\"", req->name );
}
static int dump_create_semaphore_reply( struct create_semaphore_reply *req, int len )
static void dump_create_semaphore_reply( struct create_semaphore_request *req )
{
fprintf( stderr, " handle=%d", req->handle );
return (int)sizeof(*req);
}
static int dump_release_semaphore_request( struct release_semaphore_request *req, int len )
static void dump_release_semaphore_request( struct release_semaphore_request *req )
{
fprintf( stderr, " handle=%d,", req->handle );
fprintf( stderr, " count=%08x", req->count );
return (int)sizeof(*req);
}
static int dump_release_semaphore_reply( struct release_semaphore_reply *req, int len )
static void dump_release_semaphore_reply( struct release_semaphore_request *req )
{
fprintf( stderr, " prev_count=%08x", req->prev_count );
return (int)sizeof(*req);
}
static int dump_open_semaphore_request( struct open_semaphore_request *req, int len )
static void dump_open_semaphore_request( struct open_semaphore_request *req )
{
fprintf( stderr, " access=%08x,", req->access );
fprintf( stderr, " inherit=%d,", req->inherit );
fprintf( stderr, " name=" );
return dump_chars( req+1, len - (int)sizeof(*req) ) + sizeof(*req);
fprintf( stderr, " name=\"%s\"", req->name );
}
static int dump_open_semaphore_reply( struct open_semaphore_reply *req, int len )
static void dump_open_semaphore_reply( struct open_semaphore_request *req )
{
fprintf( stderr, " handle=%d", req->handle );
return (int)sizeof(*req);
}
static int dump_create_file_request( struct create_file_request *req, int len )
static void dump_create_file_request( struct create_file_request *req )
{
fprintf( stderr, " access=%08x,", req->access );
fprintf( stderr, " inherit=%d,", req->inherit );
fprintf( stderr, " sharing=%08x,", req->sharing );
fprintf( stderr, " create=%d,", req->create );
fprintf( stderr, " attrs=%08x,", req->attrs );
fprintf( stderr, " name=" );
return dump_chars( req+1, len - (int)sizeof(*req) ) + sizeof(*req);
fprintf( stderr, " name=\"%s\"", req->name );
}
static void dump_create_file_reply( struct create_file_request *req )
{
fprintf( stderr, " handle=%d", req->handle );
}
static void dump_alloc_file_handle_request( struct alloc_file_handle_request *req )
{
fprintf( stderr, " access=%08x", req->access );
}
static int dump_create_file_reply( struct create_file_reply *req, int len )
static void dump_alloc_file_handle_reply( struct alloc_file_handle_request *req )
{
fprintf( stderr, " handle=%d", req->handle );
return (int)sizeof(*req);
}
static int dump_get_read_fd_request( struct get_read_fd_request *req, int len )
static void dump_get_read_fd_request( struct get_read_fd_request *req )
{
fprintf( stderr, " handle=%d", req->handle );
return (int)sizeof(*req);
}
static int dump_get_write_fd_request( struct get_write_fd_request *req, int len )
static void dump_get_write_fd_request( struct get_write_fd_request *req )
{
fprintf( stderr, " handle=%d", req->handle );
return (int)sizeof(*req);
}
static int dump_set_file_pointer_request( struct set_file_pointer_request *req, int len )
static void dump_set_file_pointer_request( struct set_file_pointer_request *req )
{
fprintf( stderr, " handle=%d,", req->handle );
fprintf( stderr, " low=%d,", req->low );
fprintf( stderr, " high=%d,", req->high );
fprintf( stderr, " whence=%d", req->whence );
return (int)sizeof(*req);
}
static int dump_set_file_pointer_reply( struct set_file_pointer_reply *req, int len )
static void dump_set_file_pointer_reply( struct set_file_pointer_request *req )
{
fprintf( stderr, " low=%d,", req->low );
fprintf( stderr, " high=%d", req->high );
return (int)sizeof(*req);
fprintf( stderr, " new_low=%d,", req->new_low );
fprintf( stderr, " new_high=%d", req->new_high );
}
static int dump_truncate_file_request( struct truncate_file_request *req, int len )
static void dump_truncate_file_request( struct truncate_file_request *req )
{
fprintf( stderr, " handle=%d", req->handle );
return (int)sizeof(*req);
}
static int dump_set_file_time_request( struct set_file_time_request *req, int len )
static void dump_set_file_time_request( struct set_file_time_request *req )
{
fprintf( stderr, " handle=%d,", req->handle );
fprintf( stderr, " access_time=%ld,", req->access_time );
fprintf( stderr, " write_time=%ld", req->write_time );
return (int)sizeof(*req);
}
static int dump_flush_file_request( struct flush_file_request *req, int len )
static void dump_flush_file_request( struct flush_file_request *req )
{
fprintf( stderr, " handle=%d", req->handle );
return (int)sizeof(*req);
}
static int dump_get_file_info_request( struct get_file_info_request *req, int len )
static void dump_get_file_info_request( struct get_file_info_request *req )
{
fprintf( stderr, " handle=%d", req->handle );
return (int)sizeof(*req);
}
static int dump_get_file_info_reply( struct get_file_info_reply *req, int len )
static void dump_get_file_info_reply( struct get_file_info_request *req )
{
fprintf( stderr, " type=%d,", req->type );
fprintf( stderr, " attr=%d,", req->attr );
......@@ -491,292 +443,252 @@ static int dump_get_file_info_reply( struct get_file_info_reply *req, int len )
fprintf( stderr, " index_high=%d,", req->index_high );
fprintf( stderr, " index_low=%d,", req->index_low );
fprintf( stderr, " serial=%08x", req->serial );
return (int)sizeof(*req);
}
static int dump_lock_file_request( struct lock_file_request *req, int len )
static void dump_lock_file_request( struct lock_file_request *req )
{
fprintf( stderr, " handle=%d,", req->handle );
fprintf( stderr, " offset_low=%08x,", req->offset_low );
fprintf( stderr, " offset_high=%08x,", req->offset_high );
fprintf( stderr, " count_low=%08x,", req->count_low );
fprintf( stderr, " count_high=%08x", req->count_high );
return (int)sizeof(*req);
}
static int dump_unlock_file_request( struct unlock_file_request *req, int len )
static void dump_unlock_file_request( struct unlock_file_request *req )
{
fprintf( stderr, " handle=%d,", req->handle );
fprintf( stderr, " offset_low=%08x,", req->offset_low );
fprintf( stderr, " offset_high=%08x,", req->offset_high );
fprintf( stderr, " count_low=%08x,", req->count_low );
fprintf( stderr, " count_high=%08x", req->count_high );
return (int)sizeof(*req);
}
static int dump_create_pipe_request( struct create_pipe_request *req, int len )
static void dump_create_pipe_request( struct create_pipe_request *req )
{
fprintf( stderr, " inherit=%d", req->inherit );
return (int)sizeof(*req);
}
static int dump_create_pipe_reply( struct create_pipe_reply *req, int len )
static void dump_create_pipe_reply( struct create_pipe_request *req )
{
fprintf( stderr, " handle_read=%d,", req->handle_read );
fprintf( stderr, " handle_write=%d", req->handle_write );
return (int)sizeof(*req);
}
static int dump_alloc_console_request( struct alloc_console_request *req, int len )
static void dump_alloc_console_request( struct alloc_console_request *req )
{
fprintf( stderr, " access=%08x,", req->access );
fprintf( stderr, " inherit=%d", req->inherit );
return (int)sizeof(*req);
}
static int dump_alloc_console_reply( struct alloc_console_reply *req, int len )
static void dump_alloc_console_reply( struct alloc_console_request *req )
{
fprintf( stderr, " handle_in=%d,", req->handle_in );
fprintf( stderr, " handle_out=%d", req->handle_out );
return (int)sizeof(*req);
}
static int dump_free_console_request( struct free_console_request *req, int len )
static void dump_free_console_request( struct free_console_request *req )
{
fprintf( stderr, " dummy=%d", req->dummy );
return (int)sizeof(*req);
}
static int dump_open_console_request( struct open_console_request *req, int len )
static void dump_open_console_request( struct open_console_request *req )
{
fprintf( stderr, " output=%d,", req->output );
fprintf( stderr, " access=%08x,", req->access );
fprintf( stderr, " inherit=%d", req->inherit );
return (int)sizeof(*req);
}
static int dump_open_console_reply( struct open_console_reply *req, int len )
static void dump_open_console_reply( struct open_console_request *req )
{
fprintf( stderr, " handle=%d", req->handle );
return (int)sizeof(*req);
}
static int dump_set_console_fd_request( struct set_console_fd_request *req, int len )
static void dump_set_console_fd_request( struct set_console_fd_request *req )
{
fprintf( stderr, " handle=%d,", req->handle );
fprintf( stderr, " file_handle=%d,", req->file_handle );
fprintf( stderr, " pid=%d", req->pid );
return (int)sizeof(*req);
}
static int dump_get_console_mode_request( struct get_console_mode_request *req, int len )
static void dump_get_console_mode_request( struct get_console_mode_request *req )
{
fprintf( stderr, " handle=%d", req->handle );
return (int)sizeof(*req);
}
static int dump_get_console_mode_reply( struct get_console_mode_reply *req, int len )
static void dump_get_console_mode_reply( struct get_console_mode_request *req )
{
fprintf( stderr, " mode=%d", req->mode );
return (int)sizeof(*req);
}
static int dump_set_console_mode_request( struct set_console_mode_request *req, int len )
static void dump_set_console_mode_request( struct set_console_mode_request *req )
{
fprintf( stderr, " handle=%d,", req->handle );
fprintf( stderr, " mode=%d", req->mode );
return (int)sizeof(*req);
}
static int dump_set_console_info_request( struct set_console_info_request *req, int len )
static void dump_set_console_info_request( struct set_console_info_request *req )
{
fprintf( stderr, " handle=%d,", req->handle );
fprintf( stderr, " mask=%d,", req->mask );
fprintf( stderr, " cursor_size=%d,", req->cursor_size );
fprintf( stderr, " cursor_visible=%d,", req->cursor_visible );
fprintf( stderr, " title=" );
return dump_chars( req+1, len - (int)sizeof(*req) ) + sizeof(*req);
fprintf( stderr, " title=\"%s\"", req->title );
}
static int dump_get_console_info_request( struct get_console_info_request *req, int len )
static void dump_get_console_info_request( struct get_console_info_request *req )
{
fprintf( stderr, " handle=%d", req->handle );
return (int)sizeof(*req);
}
static int dump_get_console_info_reply( struct get_console_info_reply *req, int len )
static void dump_get_console_info_reply( struct get_console_info_request *req )
{
fprintf( stderr, " cursor_size=%d,", req->cursor_size );
fprintf( stderr, " cursor_visible=%d,", req->cursor_visible );
fprintf( stderr, " pid=%d,", req->pid );
fprintf( stderr, " title=" );
return dump_chars( req+1, len - (int)sizeof(*req) ) + sizeof(*req);
fprintf( stderr, " title=\"%s\"", req->title );
}
static int dump_write_console_input_request( struct write_console_input_request *req, int len )
static void dump_write_console_input_request( struct write_console_input_request *req )
{
fprintf( stderr, " handle=%d,", req->handle );
fprintf( stderr, " count=%d", req->count );
return (int)sizeof(*req);
}
static int dump_write_console_input_reply( struct write_console_input_reply *req, int len )
static void dump_write_console_input_reply( struct write_console_input_request *req )
{
fprintf( stderr, " written=%d", req->written );
return (int)sizeof(*req);
}
static int dump_read_console_input_request( struct read_console_input_request *req, int len )
static void dump_read_console_input_request( struct read_console_input_request *req )
{
fprintf( stderr, " handle=%d,", req->handle );
fprintf( stderr, " count=%d,", req->count );
fprintf( stderr, " flush=%d", req->flush );
return (int)sizeof(*req);
}
static int dump_read_console_input_reply( struct read_console_input_reply *req, int len )
static void dump_read_console_input_reply( struct read_console_input_request *req )
{
fprintf( stderr, " dummy=%d", req->dummy );
return (int)sizeof(*req);
fprintf( stderr, " read=%d", req->read );
}
static int dump_create_change_notification_request( struct create_change_notification_request *req, int len )
static void dump_create_change_notification_request( struct create_change_notification_request *req )
{
fprintf( stderr, " subtree=%d,", req->subtree );
fprintf( stderr, " filter=%d", req->filter );
return (int)sizeof(*req);
}
static int dump_create_change_notification_reply( struct create_change_notification_reply *req, int len )
static void dump_create_change_notification_reply( struct create_change_notification_request *req )
{
fprintf( stderr, " handle=%d", req->handle );
return (int)sizeof(*req);
}
static int dump_create_mapping_request( struct create_mapping_request *req, int len )
static void dump_create_mapping_request( struct create_mapping_request *req )
{
fprintf( stderr, " size_high=%d,", req->size_high );
fprintf( stderr, " size_low=%d,", req->size_low );
fprintf( stderr, " protect=%d,", req->protect );
fprintf( stderr, " inherit=%d,", req->inherit );
fprintf( stderr, " handle=%d,", req->handle );
fprintf( stderr, " name=" );
return dump_chars( req+1, len - (int)sizeof(*req) ) + sizeof(*req);
fprintf( stderr, " file_handle=%d,", req->file_handle );
fprintf( stderr, " name=\"%s\"", req->name );
}
static int dump_create_mapping_reply( struct create_mapping_reply *req, int len )
static void dump_create_mapping_reply( struct create_mapping_request *req )
{
fprintf( stderr, " handle=%d", req->handle );
return (int)sizeof(*req);
}
static int dump_open_mapping_request( struct open_mapping_request *req, int len )
static void dump_open_mapping_request( struct open_mapping_request *req )
{
fprintf( stderr, " access=%08x,", req->access );
fprintf( stderr, " inherit=%d,", req->inherit );
fprintf( stderr, " name=" );
return dump_chars( req+1, len - (int)sizeof(*req) ) + sizeof(*req);
fprintf( stderr, " name=\"%s\"", req->name );
}
static int dump_open_mapping_reply( struct open_mapping_reply *req, int len )
static void dump_open_mapping_reply( struct open_mapping_request *req )
{
fprintf( stderr, " handle=%d", req->handle );
return (int)sizeof(*req);
}
static int dump_get_mapping_info_request( struct get_mapping_info_request *req, int len )
static void dump_get_mapping_info_request( struct get_mapping_info_request *req )
{
fprintf( stderr, " handle=%d", req->handle );
return (int)sizeof(*req);
}
static int dump_get_mapping_info_reply( struct get_mapping_info_reply *req, int len )
static void dump_get_mapping_info_reply( struct get_mapping_info_request *req )
{
fprintf( stderr, " size_high=%d,", req->size_high );
fprintf( stderr, " size_low=%d,", req->size_low );
fprintf( stderr, " protect=%d", req->protect );
return (int)sizeof(*req);
}
static int dump_create_device_request( struct create_device_request *req, int len )
static void dump_create_device_request( struct create_device_request *req )
{
fprintf( stderr, " access=%08x,", req->access );
fprintf( stderr, " inherit=%d,", req->inherit );
fprintf( stderr, " id=%d", req->id );
return (int)sizeof(*req);
}
static int dump_create_device_reply( struct create_device_reply *req, int len )
static void dump_create_device_reply( struct create_device_request *req )
{
fprintf( stderr, " handle=%d", req->handle );
return (int)sizeof(*req);
}
static int dump_create_snapshot_request( struct create_snapshot_request *req, int len )
static void dump_create_snapshot_request( struct create_snapshot_request *req )
{
fprintf( stderr, " inherit=%d,", req->inherit );
fprintf( stderr, " flags=%d", req->flags );
return (int)sizeof(*req);
}
static int dump_create_snapshot_reply( struct create_snapshot_reply *req, int len )
static void dump_create_snapshot_reply( struct create_snapshot_request *req )
{
fprintf( stderr, " handle=%d", req->handle );
return (int)sizeof(*req);
}
static int dump_next_process_request( struct next_process_request *req, int len )
static void dump_next_process_request( struct next_process_request *req )
{
fprintf( stderr, " handle=%d,", req->handle );
fprintf( stderr, " reset=%d", req->reset );
return (int)sizeof(*req);
}
static int dump_next_process_reply( struct next_process_reply *req, int len )
static void dump_next_process_reply( struct next_process_request *req )
{
fprintf( stderr, " pid=%p,", req->pid );
fprintf( stderr, " threads=%d,", req->threads );
fprintf( stderr, " priority=%d", req->priority );
return (int)sizeof(*req);
}
static int dump_wait_debug_event_request( struct wait_debug_event_request *req, int len )
static void dump_wait_debug_event_request( struct wait_debug_event_request *req )
{
fprintf( stderr, " timeout=%d", req->timeout );
return (int)sizeof(*req);
}
static int dump_wait_debug_event_reply( struct wait_debug_event_reply *req, int len )
static void dump_wait_debug_event_reply( struct wait_debug_event_request *req )
{
fprintf( stderr, " code=%d,", req->code );
fprintf( stderr, " pid=%p,", req->pid );
fprintf( stderr, " tid=%p", req->tid );
return (int)sizeof(*req);
}
static int dump_send_debug_event_request( struct send_debug_event_request *req, int len )
static void dump_send_debug_event_request( struct send_debug_event_request *req )
{
fprintf( stderr, " code=%d", req->code );
return (int)sizeof(*req);
}
static int dump_send_debug_event_reply( struct send_debug_event_reply *req, int len )
static void dump_send_debug_event_reply( struct send_debug_event_request *req )
{
fprintf( stderr, " status=%d", req->status );
return (int)sizeof(*req);
}
static int dump_continue_debug_event_request( struct continue_debug_event_request *req, int len )
static void dump_continue_debug_event_request( struct continue_debug_event_request *req )
{
fprintf( stderr, " pid=%p,", req->pid );
fprintf( stderr, " tid=%p,", req->tid );
fprintf( stderr, " status=%d", req->status );
return (int)sizeof(*req);
}
static int dump_debug_process_request( struct debug_process_request *req, int len )
static void dump_debug_process_request( struct debug_process_request *req )
{
fprintf( stderr, " pid=%p", req->pid );
return (int)sizeof(*req);
}
static const dump_func req_dumpers[REQ_NB_REQUESTS] = {
......@@ -785,6 +697,7 @@ static const dump_func req_dumpers[REQ_NB_REQUESTS] = {
(dump_func)dump_set_debug_request,
(dump_func)dump_init_process_request,
(dump_func)dump_init_thread_request,
(dump_func)dump_get_thread_buffer_request,
(dump_func)dump_terminate_process_request,
(dump_func)dump_terminate_thread_request,
(dump_func)dump_get_process_info_request,
......@@ -795,6 +708,7 @@ static const dump_func req_dumpers[REQ_NB_REQUESTS] = {
(dump_func)dump_resume_thread_request,
(dump_func)dump_debugger_request,
(dump_func)dump_queue_apc_request,
(dump_func)dump_get_apcs_request,
(dump_func)dump_close_handle_request,
(dump_func)dump_get_handle_info_request,
(dump_func)dump_set_handle_info_request,
......@@ -811,6 +725,7 @@ static const dump_func req_dumpers[REQ_NB_REQUESTS] = {
(dump_func)dump_release_semaphore_request,
(dump_func)dump_open_semaphore_request,
(dump_func)dump_create_file_request,
(dump_func)dump_alloc_file_handle_request,
(dump_func)dump_get_read_fd_request,
(dump_func)dump_get_write_fd_request,
(dump_func)dump_set_file_pointer_request,
......@@ -852,6 +767,7 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] = {
(dump_func)dump_init_thread_reply,
(dump_func)0,
(dump_func)0,
(dump_func)0,
(dump_func)dump_get_process_info_reply,
(dump_func)0,
(dump_func)dump_get_thread_info_reply,
......@@ -860,6 +776,7 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] = {
(dump_func)dump_resume_thread_reply,
(dump_func)0,
(dump_func)0,
(dump_func)dump_get_apcs_reply,
(dump_func)0,
(dump_func)dump_get_handle_info_reply,
(dump_func)0,
......@@ -876,6 +793,7 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] = {
(dump_func)dump_release_semaphore_reply,
(dump_func)dump_open_semaphore_reply,
(dump_func)dump_create_file_reply,
(dump_func)dump_alloc_file_handle_reply,
(dump_func)0,
(dump_func)0,
(dump_func)dump_set_file_pointer_reply,
......@@ -915,6 +833,7 @@ static const char * const req_names[REQ_NB_REQUESTS] = {
"set_debug",
"init_process",
"init_thread",
"get_thread_buffer",
"terminate_process",
"terminate_thread",
"get_process_info",
......@@ -925,6 +844,7 @@ static const char * const req_names[REQ_NB_REQUESTS] = {
"resume_thread",
"debugger",
"queue_apc",
"get_apcs",
"close_handle",
"get_handle_info",
"set_handle_info",
......@@ -941,6 +861,7 @@ static const char * const req_names[REQ_NB_REQUESTS] = {
"release_semaphore",
"open_semaphore",
"create_file",
"alloc_file_handle",
"get_read_fd",
"get_write_fd",
"set_file_pointer",
......@@ -979,16 +900,14 @@ static const char * const req_names[REQ_NB_REQUESTS] = {
void trace_request( enum request req, int fd )
{
int size, len;
current->last_req = req;
fprintf( stderr, "%08x: %s(", (unsigned int)current, req_names[req] );
len = (char *)current->req_end - (char *)current->req_pos;
size = req_dumpers[req]( current->req_pos, len );
if ((len -= size) > 0)
if (req < REQ_NB_REQUESTS)
{
unsigned char *ptr = (unsigned char *)current->req_pos + size;
while (len--) fprintf( stderr, ", %02x", *ptr++ );
fprintf( stderr, "%08x: %s(", (unsigned int)current, req_names[req] );
req_dumpers[req]( current->buffer );
}
else
fprintf( stderr, "%08x: %d(", (unsigned int)current, req );
if (fd != -1) fprintf( stderr, " ) fd=%d\n", fd );
else fprintf( stderr, " )\n" );
}
......@@ -1004,22 +923,14 @@ void trace_kill( int exit_code )
(unsigned int)current, exit_code );
}
void trace_reply( struct thread *thread, int pass_fd )
void trace_reply( struct thread *thread, unsigned int res, int pass_fd )
{
struct header *head = thread->buffer;
int len = head->len - sizeof(*head);
fprintf( stderr, "%08x: %s() = %d",
(unsigned int)thread, req_names[thread->last_req], head->type );
if (len)
(unsigned int)thread, req_names[thread->last_req], res );
if (reply_dumpers[thread->last_req])
{
const unsigned char *data = (unsigned char *)(head + 1);
int res = 0;
fprintf( stderr, " {" );
if (reply_dumpers[thread->last_req])
res = reply_dumpers[thread->last_req]( data, len );
len -= res;
data += res;
while (len--) fprintf( stderr, ", %02x", *data++ );
fprintf( stderr, " {" );
reply_dumpers[thread->last_req]( thread->buffer );
fprintf( stderr, " }" );
}
if (pass_fd != -1) fprintf( stderr, " fd=%d\n", pass_fd );
......
......@@ -14,9 +14,7 @@
"unsigned int" => "%08x",
"void*" => "%p",
"time_t" => "%ld",
"char[0]" => "dump_chars",
"int[0]" => "dump_ints",
"void*[0]" => "dump_ptrs"
"char[1]" => "\\\"%s\\\""
);
my @requests = ();
......@@ -31,7 +29,6 @@ my @trace_lines = ();
while (<SERVER>)
{
if (/^struct +(\w+)_request/) { &DO_REQUEST($1); }
if (/^struct +(\w+)_reply/) { &DO_REPLY($1); }
}
### Output the dumping function tables
......@@ -92,71 +89,56 @@ REPLACE_IN_FILE( "server/request.h", @request_lines );
sub DO_REQUEST
{
my $name = shift;
my @struct = ();
my @in_struct = ();
my @out_struct = ();
while (<SERVER>)
{
my ($dir, $type, $var);
last if /^};$/;
next if /^{$/;
s!/\*.*\*/!!g;
next if /^\s*$/;
/ *(\w+\**( +\w+\**)*) +(\w+)(\[0\])?;/ or die "Unrecognized syntax $_";
my $type = $1 . ($4 || "");
my $var = $3;
die "Unrecognized type $type" unless defined($formats{$type});
push @struct, $type, $var;
/^\s*(IN|OUT)\s*(\w+\**(\s+\w+\**)*)\s+(\w+)(\[[1]\])?;/ or die "Unrecognized syntax $_";
$dir = $1;
$type = $2 . ($5 || "");
$var = $4;
die "Unrecognized type $type" unless (defined($formats{$type}) || $5);
if ($dir =~ /IN/) { push @in_struct, $type, $var; }
if ($dir =~ /OUT/) { push @out_struct, $type, $var; }
}
push @requests, $name;
&DO_DUMP_FUNC( $name . "_request",@struct);
}
### Handle a reply structure definition
sub DO_REPLY
{
my $name = shift;
my @struct = ();
while (<SERVER>)
&DO_DUMP_FUNC( $name, "request", @in_struct);
if ($#out_struct >= 0)
{
last if /^};$/;
next if /^{$/;
s!/\*.*\*/!!g;
next if /^\s*$/;
/ *(\w+\**( +\w+\**)*) +(\w+)(\[0\])?;/ or die "Unrecognized syntax $_";
my $type = $1 . ($4 || "");
my $var = $3;
die "Unrecognized type $type" unless defined($formats{$type});
push @struct, $type, $var;
$replies{$name} = 1;
&DO_DUMP_FUNC( $name, "reply", @out_struct);
}
$replies{$name} = 1;
&DO_DUMP_FUNC( $name . "_reply" ,@struct);
}
### Generate a dumping function
sub DO_DUMP_FUNC
{
my $vararg = 0;
my $name = shift;
push @trace_lines, "static int dump_$name( struct $name *req, int len )\n{\n";
my $req = shift;
push @trace_lines, "static void dump_${name}_$req( struct ${name}_request *req )\n{\n";
while ($#_ >= 0)
{
my $type = shift;
my $var = shift;
if ($type =~ /\[0\]$/) # vararg type?
{
$vararg = 1;
push @trace_lines, " fprintf( stderr, \" $var=\" );\n";
push @trace_lines, " return $formats{$type}( req+1, len - (int)sizeof(*req) ) + sizeof(*req);\n";
}
else
if (defined($formats{$type}))
{
push @trace_lines, " fprintf( stderr, \" $var=$formats{$type}";
push @trace_lines, "," if ($#_ > 0);
push @trace_lines, "\", ";
push @trace_lines, "req->$var );\n";
}
else # must be some varargs format
{
push @trace_lines, " fprintf( stderr, \" $var=\" );\n";
push @trace_lines, " dump_varargs_${name}( req );\n";
}
}
push @trace_lines, " return (int)sizeof(*req);\n" unless $vararg;
push @trace_lines, "}\n\n";
}
......
......@@ -55,15 +55,14 @@ FILE *wine_openpty(int *master, int *slave, char *name,
struct termios *term, struct winsize *winsize);
/****************************************************************************
* CONSOLE_GetInfo
* CONSOLE_GetPid
*/
static BOOL CONSOLE_GetInfo( HANDLE handle, struct get_console_info_reply *reply )
static int CONSOLE_GetPid( HANDLE handle )
{
struct get_console_info_request req;
req.handle = handle;
CLIENT_SendRequest( REQ_GET_CONSOLE_INFO, -1, 1, &req, sizeof(req) );
return !CLIENT_WaitReply( NULL, NULL, 1, reply, sizeof(*reply) );
struct get_console_info_request *req = get_req_buffer();
req->handle = handle;
if (server_call( REQ_GET_CONSOLE_INFO )) return 0;
return req->pid;
}
/****************************************************************************
......@@ -428,9 +427,7 @@ DWORD WINAPI GetLargestConsoleWindowSize( HANDLE hConsoleOutput )
*/
BOOL WINAPI FreeConsole(VOID)
{
struct free_console_request req;
CLIENT_SendRequest( REQ_FREE_CONSOLE, -1, 1, &req, sizeof(req) );
return !CLIENT_WaitReply( NULL, NULL, 0 );
return !server_call( REQ_FREE_CONSOLE );
}
......@@ -441,16 +438,15 @@ BOOL WINAPI FreeConsole(VOID)
*/
HANDLE CONSOLE_OpenHandle( BOOL output, DWORD access, LPSECURITY_ATTRIBUTES sa )
{
struct open_console_request req;
struct open_console_reply reply;
int ret = -1;
struct open_console_request *req = get_req_buffer();
req.output = output;
req.access = access;
req.inherit = (sa && (sa->nLength>=sizeof(*sa)) && sa->bInheritHandle);
CLIENT_SendRequest( REQ_OPEN_CONSOLE, -1, 1, &req, sizeof(req) );
req->output = output;
req->access = access;
req->inherit = (sa && (sa->nLength>=sizeof(*sa)) && sa->bInheritHandle);
SetLastError(0);
if (!CLIENT_WaitSimpleReply( &reply, sizeof(reply), NULL )) return reply.handle;
return -1;
if (!server_call( REQ_OPEN_CONSOLE )) ret = req->handle;
return ret;
}
......@@ -470,17 +466,13 @@ HANDLE CONSOLE_OpenHandle( BOOL output, DWORD access, LPSECURITY_ATTRIBUTES sa )
*/
static BOOL CONSOLE_make_complex(HANDLE handle)
{
struct set_console_fd_request req;
struct get_console_info_reply info;
struct set_console_fd_request *req = get_req_buffer();
struct termios term;
char buf[256];
char c = '\0';
int status = 0;
int i,xpid,master,slave;
DWORD xlen;
int i,xpid,master,slave,pty_handle;
if (!CONSOLE_GetInfo( handle, &info )) return FALSE;
if (info.pid) return TRUE; /* already complex */
if (CONSOLE_GetPid( handle )) return TRUE; /* already complex */
MESSAGE("Console: Making console complex (creating an xterm)...\n");
......@@ -494,6 +486,7 @@ static BOOL CONSOLE_make_complex(HANDLE handle)
if ((xpid=fork()) == 0) {
tcsetattr(slave, TCSADRAIN, &term);
close( slave );
sprintf(buf, "-Sxx%d", master);
/* "-fn vga" for VGA font. Harmless if vga is not present:
* xterm: unable to open font "vga", trying "fixed"....
......@@ -502,35 +495,41 @@ static BOOL CONSOLE_make_complex(HANDLE handle)
ERR("error creating AllocConsole xterm\n");
exit(1);
}
req.handle = handle;
req.pid = xpid;
CLIENT_SendRequest( REQ_SET_CONSOLE_FD, dup(slave), 1, &req, sizeof(req) );
CLIENT_WaitReply( NULL, NULL, 0 );
pty_handle = FILE_DupUnixHandle( slave, GENERIC_READ | GENERIC_WRITE );
close( master );
close( slave );
if (pty_handle == -1) return FALSE;
/* most xterms like to print their window ID when used with -S;
* read it and continue before the user has a chance...
*/
for (i=0; c!='\n'; (status=read(slave, &c, 1)), i++) {
if (status == -1 && c == '\0') {
/* wait for xterm to be created */
usleep(100);
}
if (i > 10000) {
ERR("can't read xterm WID\n");
kill(xpid, SIGKILL);
return FALSE;
}
for (i = 0; i < 10000; i++)
{
BOOL ok = ReadFile( pty_handle, &c, 1, NULL, NULL );
if (!ok && !c) usleep(100); /* wait for xterm to be created */
else if (c == '\n') break;
}
if (i == 10000)
{
ERR("can't read xterm WID\n");
CloseHandle( pty_handle );
return FALSE;
}
req->handle = handle;
req->file_handle = pty_handle;
req->pid = xpid;
server_call( REQ_SET_CONSOLE_FD );
CloseHandle( pty_handle );
/* enable mouseclicks */
sprintf(buf,"%c[?1001s%c[?1000h",27,27);
WriteFile(handle,buf,strlen(buf),&xlen,NULL);
if (GetConsoleTitleA( buf, sizeof(buf) ))
strcpy( buf, "\033[?1001s\033[?1000h" );
WriteFile(handle,buf,strlen(buf),NULL,NULL);
strcpy( buf, "\033]2;" );
if (GetConsoleTitleA( buf + 4, sizeof(buf) - 5 ))
{
WriteFile(handle,"\033]2;",4,&xlen,NULL);
WriteFile(handle,buf,strlen(buf),&xlen,NULL);
WriteFile(handle,"\a",1,&xlen,NULL);
strcat( buf, "\a" );
WriteFile(handle,buf,strlen(buf),NULL,NULL);
}
return TRUE;
......@@ -544,29 +543,29 @@ static BOOL CONSOLE_make_complex(HANDLE handle)
*/
BOOL WINAPI AllocConsole(VOID)
{
struct alloc_console_request req;
struct alloc_console_reply reply;
struct alloc_console_request *req = get_req_buffer();
HANDLE hStderr;
int handle_in, handle_out;
TRACE("()\n");
req.access = GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE;
req.inherit = FALSE;
CLIENT_SendRequest( REQ_ALLOC_CONSOLE, -1, 1, &req, sizeof(req) );
if (CLIENT_WaitSimpleReply( &reply, sizeof(reply), NULL ) != ERROR_SUCCESS)
return FALSE;
req->access = GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE;
req->inherit = FALSE;
if (server_call( REQ_ALLOC_CONSOLE )) return FALSE;
handle_in = req->handle_in;
handle_out = req->handle_out;
if (!DuplicateHandle( GetCurrentProcess(), reply.handle_out, GetCurrentProcess(), &hStderr,
if (!DuplicateHandle( GetCurrentProcess(), req->handle_out, GetCurrentProcess(), &hStderr,
0, TRUE, DUPLICATE_SAME_ACCESS ))
{
CloseHandle( reply.handle_in );
CloseHandle( reply.handle_out );
CloseHandle( handle_in );
CloseHandle( handle_out );
FreeConsole();
return FALSE;
}
/* NT resets the STD_*_HANDLEs on console alloc */
SetStdHandle( STD_INPUT_HANDLE, reply.handle_in );
SetStdHandle( STD_OUTPUT_HANDLE, reply.handle_out );
SetStdHandle( STD_INPUT_HANDLE, handle_in );
SetStdHandle( STD_OUTPUT_HANDLE, handle_out );
SetStdHandle( STD_ERROR_HANDLE, hStderr );
SetLastError(ERROR_SUCCESS);
......@@ -600,14 +599,15 @@ UINT WINAPI GetConsoleOutputCP(VOID)
*/
BOOL WINAPI GetConsoleMode(HANDLE hcon,LPDWORD mode)
{
struct get_console_mode_request req;
struct get_console_mode_reply reply;
req.handle = hcon;
CLIENT_SendRequest( REQ_GET_CONSOLE_MODE, -1, 1, &req, sizeof(req));
if (CLIENT_WaitSimpleReply( &reply, sizeof(reply), NULL )) return FALSE;
*mode = reply.mode;
return TRUE;
BOOL ret = FALSE;
struct get_console_mode_request *req = get_req_buffer();
req->handle = hcon;
if (!server_call( REQ_GET_CONSOLE_MODE ))
{
if (mode) *mode = req->mode;
ret = TRUE;
}
return ret;
}
......@@ -624,12 +624,10 @@ BOOL WINAPI GetConsoleMode(HANDLE hcon,LPDWORD mode)
*/
BOOL WINAPI SetConsoleMode( HANDLE hcon, DWORD mode )
{
struct set_console_mode_request req;
req.handle = hcon;
req.mode = mode;
CLIENT_SendRequest( REQ_SET_CONSOLE_MODE, -1, 1, &req, sizeof(req));
return !CLIENT_WaitReply( NULL, NULL, 0 );
struct set_console_mode_request *req = get_req_buffer();
req->handle = hcon;
req->mode = mode;
return !server_call( REQ_SET_CONSOLE_MODE );
}
......@@ -638,21 +636,18 @@ BOOL WINAPI SetConsoleMode( HANDLE hcon, DWORD mode )
*/
DWORD WINAPI GetConsoleTitleA(LPSTR title,DWORD size)
{
struct get_console_info_request req;
struct get_console_info_reply reply;
int len;
struct get_console_info_request *req = get_req_buffer();
DWORD ret = 0;
HANDLE hcon;
if ((hcon = CreateFileA( "CONOUT$", GENERIC_READ, 0, NULL,
OPEN_EXISTING, 0, 0 )) == INVALID_HANDLE_VALUE)
return 0;
req.handle = hcon;
CLIENT_SendRequest( REQ_GET_CONSOLE_INFO, -1, 1, &req, sizeof(req) );
if (!CLIENT_WaitReply( &len, NULL, 2, &reply, sizeof(reply), title, size ))
req->handle = hcon;
if (!server_call( REQ_GET_CONSOLE_INFO ))
{
if (len > sizeof(reply)+size) title[size-1] = 0;
ret = strlen(title);
lstrcpynA( title, req->title, size );
ret = strlen(req->title);
}
CloseHandle( hcon );
return ret;
......@@ -722,7 +717,7 @@ BOOL WINAPI WriteConsoleOutputA( HANDLE hConsoleOutput,
1,5,3,7,
};
CONSOLE_make_complex(hConsoleOutput);
buffer = HeapAlloc(GetProcessHeap(),0,100);;
buffer = HeapAlloc(GetProcessHeap(),0,100);
curbufsize = 100;
TRACE("wr: top = %d, bottom=%d, left=%d,right=%d\n",
......@@ -790,8 +785,6 @@ BOOL WINAPI ReadConsoleA( HANDLE hConsoleInput,
{
int charsread = 0;
LPSTR xbuf = (LPSTR)lpBuffer;
struct read_console_input_request req;
struct read_console_input_reply reply;
INPUT_RECORD ir;
TRACE("(%d,%p,%ld,%p,%p)\n",
......@@ -801,21 +794,15 @@ BOOL WINAPI ReadConsoleA( HANDLE hConsoleInput,
CONSOLE_get_input(hConsoleInput,FALSE);
req.handle = hConsoleInput;
req.count = 1;
req.flush = 1;
/* FIXME: should we read at least 1 char? The SDK does not say */
while (charsread<nNumberOfCharsToRead)
{
int len;
CLIENT_SendRequest( REQ_READ_CONSOLE_INPUT, -1, 1, &req, sizeof(req) );
if (CLIENT_WaitReply( &len, NULL, 2, &reply, sizeof(reply), &ir, sizeof(ir) ))
return FALSE;
len -= sizeof(reply);
assert( !(len % sizeof(ir)) );
if (!len) break;
struct read_console_input_request *req = get_req_buffer();
req->handle = hConsoleInput;
req->count = 1;
req->flush = 1;
if (server_call( REQ_READ_CONSOLE_INPUT )) return FALSE;
if (!req->read) break;
if (!ir.Event.KeyEvent.bKeyDown)
continue;
if (ir.EventType != KEY_EVENT)
......@@ -867,33 +854,27 @@ BOOL WINAPI ReadConsoleW( HANDLE hConsoleInput,
* Success: TRUE
* Failure: FALSE
*/
BOOL WINAPI ReadConsoleInputA(HANDLE hConsoleInput,
LPINPUT_RECORD lpBuffer,
DWORD nLength, LPDWORD lpNumberOfEventsRead)
BOOL WINAPI ReadConsoleInputA(HANDLE hConsoleInput, LPINPUT_RECORD lpBuffer,
DWORD nLength, LPDWORD lpNumberOfEventsRead)
{
struct read_console_input_request req;
struct read_console_input_reply reply;
int len;
req.handle = hConsoleInput;
req.count = nLength;
req.flush = 1;
struct read_console_input_request *req = get_req_buffer();
/* loop until we get at least one event */
for (;;)
{
CLIENT_SendRequest( REQ_READ_CONSOLE_INPUT, -1, 1, &req, sizeof(req) );
if (CLIENT_WaitReply( &len, NULL, 2, &reply, sizeof(reply),
lpBuffer, nLength * sizeof(*lpBuffer) ))
return FALSE;
len -= sizeof(reply);
assert( !(len % sizeof(INPUT_RECORD)) );
if (len) break;
req->handle = hConsoleInput;
req->count = nLength;
req->flush = 1;
if (server_call( REQ_READ_CONSOLE_INPUT )) return FALSE;
if (req->read)
{
memcpy( lpBuffer, req + 1, req->read * sizeof(*lpBuffer) );
if (lpNumberOfEventsRead) *lpNumberOfEventsRead = req->read;
return TRUE;
}
CONSOLE_get_input(hConsoleInput,TRUE);
/*WaitForSingleObject( hConsoleInput, INFINITE32 );*/
}
if (lpNumberOfEventsRead) *lpNumberOfEventsRead = len / sizeof(INPUT_RECORD);
return TRUE;
}
......@@ -913,14 +894,11 @@ BOOL WINAPI ReadConsoleInputW( HANDLE handle, LPINPUT_RECORD buffer,
*/
BOOL WINAPI FlushConsoleInputBuffer( HANDLE handle )
{
struct read_console_input_request req;
int len;
req.handle = handle;
req.count = -1; /* get all records */
req.flush = 1;
CLIENT_SendRequest( REQ_READ_CONSOLE_INPUT, -1, 1, &req, sizeof(req) );
return !CLIENT_WaitReply( &len, NULL, 0 );
struct read_console_input_request *req = get_req_buffer();
req->handle = handle;
req->count = -1; /* get all records */
req->flush = 1;
return !server_call( REQ_READ_CONSOLE_INPUT );
}
......@@ -934,22 +912,16 @@ BOOL WINAPI FlushConsoleInputBuffer( HANDLE handle )
BOOL WINAPI PeekConsoleInputA( HANDLE handle, LPINPUT_RECORD buffer,
DWORD count, LPDWORD read )
{
struct read_console_input_request req;
struct read_console_input_reply reply;
int len;
struct read_console_input_request *req = get_req_buffer();
CONSOLE_get_input(handle,FALSE);
req.handle = handle;
req.count = count;
req.flush = 0;
CLIENT_SendRequest( REQ_READ_CONSOLE_INPUT, -1, 1, &req, sizeof(req) );
if (CLIENT_WaitReply( &len, NULL, 2, &reply, sizeof(reply),
buffer, count * sizeof(*buffer) ))
return FALSE;
len -= sizeof(reply);
assert( !(len % sizeof(INPUT_RECORD)) );
if (read) *read = len / sizeof(INPUT_RECORD);
req->handle = handle;
req->count = count;
req->flush = 0;
if (server_call( REQ_READ_CONSOLE_INPUT )) return FALSE;
if (req->read) memcpy( buffer, req + 1, req->read * sizeof(*buffer) );
if (read) *read = req->read;
return TRUE;
}
......@@ -972,17 +944,23 @@ BOOL WINAPI PeekConsoleInputW(HANDLE hConsoleInput,
*
*/
BOOL WINAPI WriteConsoleInputA( HANDLE handle, INPUT_RECORD *buffer,
DWORD count, LPDWORD written )
DWORD count, LPDWORD written )
{
struct write_console_input_request req;
struct write_console_input_reply reply;
req.handle = handle;
req.count = count;
CLIENT_SendRequest( REQ_WRITE_CONSOLE_INPUT, -1, 2, &req, sizeof(req),
buffer, count * sizeof(*buffer) );
if (CLIENT_WaitSimpleReply( &reply, sizeof(reply), NULL )) return FALSE;
if (written) *written = reply.written;
struct write_console_input_request *req = get_req_buffer();
const DWORD max = server_remaining( req + 1 ) / sizeof(INPUT_RECORD);
if (written) *written = 0;
while (count)
{
DWORD len = count < max ? count : max;
req->count = len;
req->handle = handle;
memcpy( req + 1, buffer, len * sizeof(*buffer) );
if (server_call( REQ_WRITE_CONSOLE_INPUT )) return FALSE;
if (written) *written += req->written;
count -= len;
buffer += len;
}
return TRUE;
}
......@@ -998,20 +976,18 @@ BOOL WINAPI WriteConsoleInputA( HANDLE handle, INPUT_RECORD *buffer,
*/
BOOL WINAPI SetConsoleTitleA(LPCSTR title)
{
struct set_console_info_request req;
struct get_console_info_reply info;
struct set_console_info_request *req = get_req_buffer();
HANDLE hcon;
DWORD written;
if ((hcon = CreateFileA( "CONOUT$", GENERIC_READ|GENERIC_WRITE, 0, NULL,
OPEN_EXISTING, 0, 0 )) == INVALID_HANDLE_VALUE)
return FALSE;
req.handle = hcon;
req.mask = SET_CONSOLE_INFO_TITLE;
CLIENT_SendRequest( REQ_SET_CONSOLE_INFO, -1, 2, &req, sizeof(req),
title, strlen(title)+1 );
if (CLIENT_WaitReply( NULL, NULL, 0 )) goto error;
if (CONSOLE_GetInfo( hcon, &info ) && info.pid)
req->handle = hcon;
req->mask = SET_CONSOLE_INFO_TITLE;
lstrcpynA( req->title, title, server_remaining(req->title) );
if (server_call( REQ_SET_CONSOLE_INFO )) goto error;
if (CONSOLE_GetPid( hcon ))
{
/* only set title for complex console (own xterm) */
WriteFile( hcon, "\033]2;", 4, &written, NULL );
......@@ -1112,16 +1088,15 @@ BOOL WINAPI GetNumberOfConsoleMouseButtons(LPDWORD nrofbuttons)
* Success: TRUE
* Failure: FALSE
*/
BOOL WINAPI GetConsoleCursorInfo( HANDLE hcon,
LPCONSOLE_CURSOR_INFO cinfo )
BOOL WINAPI GetConsoleCursorInfo( HANDLE hcon, LPCONSOLE_CURSOR_INFO cinfo )
{
struct get_console_info_reply reply;
if (!CONSOLE_GetInfo( hcon, &reply )) return FALSE;
struct get_console_info_request *req = get_req_buffer();
req->handle = hcon;
if (server_call( REQ_GET_CONSOLE_INFO )) return FALSE;
if (cinfo)
{
cinfo->dwSize = reply.cursor_size;
cinfo->bVisible = reply.cursor_visible;
cinfo->dwSize = req->cursor_size;
cinfo->bVisible = req->cursor_visible;
}
return TRUE;
}
......@@ -1138,20 +1113,19 @@ BOOL WINAPI SetConsoleCursorInfo(
HANDLE hcon, /* [in] Handle to console screen buffer */
LPCONSOLE_CURSOR_INFO cinfo) /* [in] Address of cursor information */
{
struct set_console_info_request req;
struct set_console_info_request *req = get_req_buffer();
char buf[8];
DWORD xlen;
req.handle = hcon;
CONSOLE_make_complex(hcon);
sprintf(buf,"\033[?25%c",cinfo->bVisible?'h':'l');
WriteFile(hcon,buf,strlen(buf),&xlen,NULL);
req.cursor_size = cinfo->dwSize;
req.cursor_visible = cinfo->bVisible;
req.mask = SET_CONSOLE_INFO_CURSOR;
CLIENT_SendRequest( REQ_SET_CONSOLE_INFO, -1, 1, &req, sizeof(req) );
return !CLIENT_WaitReply( NULL, NULL, 0 );
req->handle = hcon;
req->cursor_size = cinfo->dwSize;
req->cursor_visible = cinfo->bVisible;
req->mask = SET_CONSOLE_INFO_CURSOR;
return !server_call( REQ_SET_CONSOLE_INFO );
}
......
......@@ -285,20 +285,16 @@ HANDLE DEVICE_Open( LPCSTR filename, DWORD access,
static const struct VxDInfo *DEVICE_GetInfo( HANDLE handle )
{
struct get_file_info_request req;
struct get_file_info_reply reply;
req.handle = handle;
CLIENT_SendRequest( REQ_GET_FILE_INFO, -1, 1, &req, sizeof(req) );
if (!CLIENT_WaitSimpleReply( &reply, sizeof(reply), NULL ) &&
(reply.type == FILE_TYPE_UNKNOWN) &&
(reply.attr & 0x10000))
struct get_file_info_request *req = get_req_buffer();
req->handle = handle;
if (!server_call( REQ_GET_FILE_INFO ) &&
(req->type == FILE_TYPE_UNKNOWN) &&
(req->attr & 0x10000))
{
const struct VxDInfo *info;
for (info = VxDList; info->name; info++)
if (info->id == LOWORD(reply.attr)) break;
return info;
if (info->id == LOWORD(req->attr)) return info;
}
return NULL;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment