Commit 92643003 authored by Alexandre Julliard's avatar Alexandre Julliard

Converted a lot of server requests to the new exception handling

mechanism.
parent 94074bc2
...@@ -95,11 +95,14 @@ static inline int send_debug_event( EXCEPTION_RECORD *rec, int first_chance, CON ...@@ -95,11 +95,14 @@ static inline int send_debug_event( EXCEPTION_RECORD *rec, int first_chance, CON
int ret; int ret;
SERVER_START_REQ SERVER_START_REQ
{ {
struct exception_event_request *req = server_alloc_req( sizeof(*req), 0 ); struct exception_event_request *req = server_alloc_req( sizeof(*req),
req->record = *rec; sizeof(*rec)+sizeof(*context) );
CONTEXT *context_ptr = server_data_ptr(req);
EXCEPTION_RECORD *rec_ptr = (EXCEPTION_RECORD *)(context_ptr + 1);
req->first = first_chance; req->first = first_chance;
req->context = *context; *rec_ptr = *rec;
if (!server_call_noerr( REQ_EXCEPTION_EVENT )) *context = req->context; *context_ptr = *context;
if (!server_call_noerr( REQ_EXCEPTION_EVENT )) *context = *context_ptr;
ret = req->status; ret = req->status;
} }
SERVER_END_REQ; SERVER_END_REQ;
......
...@@ -86,6 +86,7 @@ ...@@ -86,6 +86,7 @@
#include "wine/port.h" #include "wine/port.h"
#include "services.h" #include "services.h"
#include "server.h" #include "server.h"
#include "file.h"
#include "debugtools.h" #include "debugtools.h"
...@@ -222,11 +223,7 @@ static char* _check_buffer(LPWSINFO pwsi, int size); ...@@ -222,11 +223,7 @@ static char* _check_buffer(LPWSINFO pwsi, int size);
static int _get_sock_fd(SOCKET s) static int _get_sock_fd(SOCKET s)
{ {
struct get_read_fd_request *req = get_req_buffer(); int fd = FILE_GetUnixHandle( s, GENERIC_READ );
int fd;
req->handle = s;
server_call_fd( REQ_GET_READ_FD, -1, &fd );
if (fd == -1) if (fd == -1)
FIXME("handle %d is not a socket (GLE %ld)\n",s,GetLastError()); FIXME("handle %d is not a socket (GLE %ld)\n",s,GetLastError());
return fd; return fd;
...@@ -235,37 +232,53 @@ static int _get_sock_fd(SOCKET s) ...@@ -235,37 +232,53 @@ static int _get_sock_fd(SOCKET s)
static void _enable_event(SOCKET s, unsigned int event, static void _enable_event(SOCKET s, unsigned int event,
unsigned int sstate, unsigned int cstate) unsigned int sstate, unsigned int cstate)
{ {
struct enable_socket_event_request *req = get_req_buffer(); SERVER_START_REQ
{
struct enable_socket_event_request *req = server_alloc_req( sizeof(*req), 0 );
req->handle = s; req->handle = s;
req->mask = event; req->mask = event;
req->sstate = sstate; req->sstate = sstate;
req->cstate = cstate; req->cstate = cstate;
sock_server_call( REQ_ENABLE_SOCKET_EVENT ); sock_server_call( REQ_ENABLE_SOCKET_EVENT );
}
SERVER_END_REQ;
} }
static int _is_blocking(SOCKET s) static int _is_blocking(SOCKET s)
{ {
struct get_socket_event_request *req = get_req_buffer(); int ret;
SERVER_START_REQ
{
struct get_socket_event_request *req = server_alloc_req( sizeof(*req), 0 );
req->handle = s; req->handle = s;
req->service = FALSE; req->service = FALSE;
req->s_event = 0; req->s_event = 0;
req->c_event = 0; req->c_event = 0;
sock_server_call( REQ_GET_SOCKET_EVENT ); sock_server_call( REQ_GET_SOCKET_EVENT );
return (req->state & WS_FD_NONBLOCKING) == 0; ret = (req->state & WS_FD_NONBLOCKING) == 0;
}
SERVER_END_REQ;
return ret;
} }
static unsigned int _get_sock_mask(SOCKET s) static unsigned int _get_sock_mask(SOCKET s)
{ {
struct get_socket_event_request *req = get_req_buffer(); unsigned int ret;
SERVER_START_REQ
{
struct get_socket_event_request *req = server_alloc_req( sizeof(*req), 0 );
req->handle = s; req->handle = s;
req->service = FALSE; req->service = FALSE;
req->s_event = 0; req->s_event = 0;
req->c_event = 0; req->c_event = 0;
sock_server_call( REQ_GET_SOCKET_EVENT ); sock_server_call( REQ_GET_SOCKET_EVENT );
return req->mask; ret = req->mask;
}
SERVER_END_REQ;
return ret;
} }
static void _sync_sock_state(SOCKET s) static void _sync_sock_state(SOCKET s)
...@@ -277,14 +290,20 @@ static void _sync_sock_state(SOCKET s) ...@@ -277,14 +290,20 @@ static void _sync_sock_state(SOCKET s)
static int _get_sock_error(SOCKET s, unsigned int bit) static int _get_sock_error(SOCKET s, unsigned int bit)
{ {
struct get_socket_event_request *req = get_req_buffer(); int ret;
SERVER_START_REQ
{
struct get_socket_event_request *req = server_alloc_req( sizeof(*req),
FD_MAX_EVENTS*sizeof(int) );
req->handle = s; req->handle = s;
req->service = FALSE; req->service = FALSE;
req->s_event = 0; req->s_event = 0;
req->c_event = 0; req->c_event = 0;
sock_server_call( REQ_GET_SOCKET_EVENT ); sock_server_call( REQ_GET_SOCKET_EVENT );
return req->errors[bit]; ret = *((int *)server_data_ptr(req) + bit);
}
SERVER_END_REQ;
return ret;
} }
static LPWSINFO lpFirstIData = NULL; static LPWSINFO lpFirstIData = NULL;
...@@ -803,12 +822,12 @@ SOCKET WINAPI WSOCK32_accept(SOCKET s, struct sockaddr *addr, ...@@ -803,12 +822,12 @@ SOCKET WINAPI WSOCK32_accept(SOCKET s, struct sockaddr *addr,
#ifdef HAVE_IPX #ifdef HAVE_IPX
struct ws_sockaddr_ipx* addr2 = (struct ws_sockaddr_ipx *)addr; struct ws_sockaddr_ipx* addr2 = (struct ws_sockaddr_ipx *)addr;
#endif #endif
struct accept_socket_request *req = get_req_buffer();
TRACE("(%08x): socket %04x\n", TRACE("(%08x): socket %04x\n",
(unsigned)pwsi, (UINT16)s ); (unsigned)pwsi, (UINT16)s );
if( _check_ws(pwsi, s) ) if( _check_ws(pwsi, s) )
{ {
SOCKET as;
if (_is_blocking(s)) if (_is_blocking(s))
{ {
/* block here */ /* block here */
...@@ -820,13 +839,19 @@ SOCKET WINAPI WSOCK32_accept(SOCKET s, struct sockaddr *addr, ...@@ -820,13 +839,19 @@ SOCKET WINAPI WSOCK32_accept(SOCKET s, struct sockaddr *addr,
SetLastError(_get_sock_error(s, FD_ACCEPT_BIT)); SetLastError(_get_sock_error(s, FD_ACCEPT_BIT));
/* FIXME: care about the error? */ /* FIXME: care about the error? */
} }
SERVER_START_REQ
{
struct accept_socket_request *req = server_alloc_req( sizeof(*req), 0 );
req->lhandle = s; req->lhandle = s;
req->access = GENERIC_READ|GENERIC_WRITE|SYNCHRONIZE; req->access = GENERIC_READ|GENERIC_WRITE|SYNCHRONIZE;
req->inherit = TRUE; req->inherit = TRUE;
sock_server_call( REQ_ACCEPT_SOCKET ); sock_server_call( REQ_ACCEPT_SOCKET );
if( req->handle >= 0 ) as = req->handle;
}
SERVER_END_REQ;
if( as >= 0 )
{ {
SOCKET as = req->handle;
unsigned omask = _get_sock_mask( s ); unsigned omask = _get_sock_mask( s );
int fd = _get_sock_fd( as ); int fd = _get_sock_fd( as );
if( getpeername(fd, addr, addrlen32) != -1 ) if( getpeername(fd, addr, addrlen32) != -1 )
...@@ -2152,7 +2177,7 @@ INT16 WINAPI WINSOCK_shutdown16(SOCKET16 s, INT16 how) ...@@ -2152,7 +2177,7 @@ INT16 WINAPI WINSOCK_shutdown16(SOCKET16 s, INT16 how)
SOCKET WINAPI WSOCK32_socket(INT af, INT type, INT protocol) SOCKET WINAPI WSOCK32_socket(INT af, INT type, INT protocol)
{ {
LPWSINFO pwsi = WINSOCK_GetIData(); LPWSINFO pwsi = WINSOCK_GetIData();
struct create_socket_request *req = get_req_buffer(); SOCKET ret;
TRACE("(%08x): af=%d type=%d protocol=%d\n", TRACE("(%08x): af=%d type=%d protocol=%d\n",
(unsigned)pwsi, af, type, protocol); (unsigned)pwsi, af, type, protocol);
...@@ -2195,17 +2220,22 @@ SOCKET WINAPI WSOCK32_socket(INT af, INT type, INT protocol) ...@@ -2195,17 +2220,22 @@ SOCKET WINAPI WSOCK32_socket(INT af, INT type, INT protocol)
default: SetLastError(WSAEPROTOTYPE); return INVALID_SOCKET; default: SetLastError(WSAEPROTOTYPE); return INVALID_SOCKET;
} }
SERVER_START_REQ
{
struct create_socket_request *req = server_alloc_req( sizeof(*req), 0 );
req->family = af; req->family = af;
req->type = type; req->type = type;
req->protocol = protocol; req->protocol = protocol;
req->access = GENERIC_READ|GENERIC_WRITE|SYNCHRONIZE; req->access = GENERIC_READ|GENERIC_WRITE|SYNCHRONIZE;
req->inherit = TRUE; req->inherit = TRUE;
sock_server_call( REQ_CREATE_SOCKET ); sock_server_call( REQ_CREATE_SOCKET );
if ( req->handle >= 0) ret = req->handle;
}
SERVER_END_REQ;
if ( ret >= 0)
{ {
TRACE("\tcreated %04x\n", req->handle); TRACE("\tcreated %04x\n", ret );
return ret;
return req->handle;
} }
if (GetLastError() == WSAEACCES) /* raw socket denied */ if (GetLastError() == WSAEACCES) /* raw socket denied */
...@@ -2518,19 +2548,24 @@ INT16 WINAPI WINSOCK_gethostname16(char *name, INT16 namelen) ...@@ -2518,19 +2548,24 @@ INT16 WINAPI WINSOCK_gethostname16(char *name, INT16 namelen)
int WINAPI WSAEnumNetworkEvents(SOCKET s, WSAEVENT hEvent, LPWSANETWORKEVENTS lpEvent) int WINAPI WSAEnumNetworkEvents(SOCKET s, WSAEVENT hEvent, LPWSANETWORKEVENTS lpEvent)
{ {
LPWSINFO pwsi = WINSOCK_GetIData(); LPWSINFO pwsi = WINSOCK_GetIData();
struct get_socket_event_request *req = get_req_buffer();
TRACE("(%08x): %08x, hEvent %08x, lpEvent %08x\n", TRACE("(%08x): %08x, hEvent %08x, lpEvent %08x\n",
(unsigned)pwsi, s, hEvent, (unsigned)lpEvent ); (unsigned)pwsi, s, hEvent, (unsigned)lpEvent );
if( _check_ws(pwsi, s) ) if( _check_ws(pwsi, s) )
{ {
SERVER_START_REQ
{
struct get_socket_event_request *req = server_alloc_req( sizeof(*req),
sizeof(lpEvent->iErrorCode) );
req->handle = s; req->handle = s;
req->service = TRUE; req->service = TRUE;
req->s_event = 0; req->s_event = 0;
req->c_event = hEvent; req->c_event = hEvent;
sock_server_call( REQ_GET_SOCKET_EVENT ); sock_server_call( REQ_GET_SOCKET_EVENT );
lpEvent->lNetworkEvents = req->pmask; lpEvent->lNetworkEvents = req->pmask;
memcpy(lpEvent->iErrorCode, req->errors, sizeof(lpEvent->iErrorCode)); memcpy(lpEvent->iErrorCode, server_data_ptr(req), server_data_size(req) );
}
SERVER_END_REQ;
return 0; return 0;
} }
else SetLastError(WSAEINVAL); else SetLastError(WSAEINVAL);
...@@ -2543,16 +2578,20 @@ int WINAPI WSAEnumNetworkEvents(SOCKET s, WSAEVENT hEvent, LPWSANETWORKEVENTS lp ...@@ -2543,16 +2578,20 @@ int WINAPI WSAEnumNetworkEvents(SOCKET s, WSAEVENT hEvent, LPWSANETWORKEVENTS lp
int WINAPI WSAEventSelect(SOCKET s, WSAEVENT hEvent, LONG lEvent) int WINAPI WSAEventSelect(SOCKET s, WSAEVENT hEvent, LONG lEvent)
{ {
LPWSINFO pwsi = WINSOCK_GetIData(); LPWSINFO pwsi = WINSOCK_GetIData();
struct set_socket_event_request *req = get_req_buffer();
TRACE("(%08x): %08x, hEvent %08x, event %08x\n", TRACE("(%08x): %08x, hEvent %08x, event %08x\n",
(unsigned)pwsi, s, hEvent, (unsigned)lEvent ); (unsigned)pwsi, s, hEvent, (unsigned)lEvent );
if( _check_ws(pwsi, s) ) if( _check_ws(pwsi, s) )
{ {
SERVER_START_REQ
{
struct set_socket_event_request *req = server_alloc_req( sizeof(*req), 0 );
req->handle = s; req->handle = s;
req->mask = lEvent; req->mask = lEvent;
req->event = hEvent; req->event = hEvent;
sock_server_call( REQ_SET_SOCKET_EVENT ); sock_server_call( REQ_SET_SOCKET_EVENT );
}
SERVER_END_REQ;
return 0; return 0;
} }
else SetLastError(WSAEINVAL); else SetLastError(WSAEINVAL);
...@@ -2567,23 +2606,30 @@ VOID CALLBACK WINSOCK_DoAsyncEvent( ULONG_PTR ptr ) ...@@ -2567,23 +2606,30 @@ VOID CALLBACK WINSOCK_DoAsyncEvent( ULONG_PTR ptr )
{ {
ws_select_info *info = (ws_select_info*)ptr; ws_select_info *info = (ws_select_info*)ptr;
LPWSINFO pwsi = info->pwsi; LPWSINFO pwsi = info->pwsi;
struct get_socket_event_request *req = get_req_buffer();
unsigned int i, pmask, orphan = FALSE; unsigned int i, pmask, orphan = FALSE;
int errors[FD_MAX_EVENTS];
TRACE("socket %08x, event %08x\n", info->sock, info->event); TRACE("socket %08x, event %08x\n", info->sock, info->event);
SetLastError(0); SetLastError(0);
SERVER_START_REQ
{
struct get_socket_event_request *req = server_alloc_req( sizeof(*req), sizeof(errors) );
req->handle = info->sock; req->handle = info->sock;
req->service = TRUE; req->service = TRUE;
req->s_event = info->event; /* <== avoid race conditions */ req->s_event = info->event; /* <== avoid race conditions */
req->c_event = info->event; req->c_event = info->event;
sock_server_call( REQ_GET_SOCKET_EVENT ); sock_server_call( REQ_GET_SOCKET_EVENT );
pmask = req->pmask;
memcpy( errors, server_data_ptr(req), server_data_size(req) );
}
SERVER_END_REQ;
if ( (GetLastError() == WSAENOTSOCK) || (GetLastError() == WSAEINVAL) ) if ( (GetLastError() == WSAENOTSOCK) || (GetLastError() == WSAEINVAL) )
{ {
/* orphaned event (socket closed or something) */ /* orphaned event (socket closed or something) */
pmask = WS_FD_SERVEVENT; pmask = WS_FD_SERVEVENT;
orphan = TRUE; orphan = TRUE;
} else }
pmask = req->pmask;
/* check for accepted sockets that needs to inherit WSAAsyncSelect */ /* check for accepted sockets that needs to inherit WSAAsyncSelect */
if (pmask & WS_FD_SERVEVENT) { if (pmask & WS_FD_SERVEVENT) {
int q; int q;
...@@ -2602,9 +2648,9 @@ VOID CALLBACK WINSOCK_DoAsyncEvent( ULONG_PTR ptr ) ...@@ -2602,9 +2648,9 @@ VOID CALLBACK WINSOCK_DoAsyncEvent( ULONG_PTR ptr )
/* dispatch network events */ /* dispatch network events */
for (i=0; i<FD_MAX_EVENTS; i++) for (i=0; i<FD_MAX_EVENTS; i++)
if (pmask & (1<<i)) { if (pmask & (1<<i)) {
TRACE("post: event bit %d, error %d\n", i, req->errors[i]); TRACE("post: event bit %d, error %d\n", i, errors[i]);
PostMessageA(info->hWnd, info->uMsg, info->sock, PostMessageA(info->hWnd, info->uMsg, info->sock,
WSAMAKESELECTREPLY(1<<i, req->errors[i])); WSAMAKESELECTREPLY(1<<i, errors[i]));
} }
/* cleanup */ /* cleanup */
if (orphan) if (orphan)
......
...@@ -621,16 +621,21 @@ const DOS_DEVICE *DOSFS_GetDevice( const char *name ) ...@@ -621,16 +621,21 @@ const DOS_DEVICE *DOSFS_GetDevice( const char *name )
*/ */
const DOS_DEVICE *DOSFS_GetDeviceByHandle( HFILE hFile ) const DOS_DEVICE *DOSFS_GetDeviceByHandle( HFILE hFile )
{ {
struct get_file_info_request *req = get_req_buffer(); const DOS_DEVICE *ret = NULL;
SERVER_START_REQ
{
struct get_file_info_request *req = server_alloc_req( sizeof(*req), 0 );
req->handle = hFile; req->handle = hFile;
if (!server_call( REQ_GET_FILE_INFO ) && (req->type == FILE_TYPE_UNKNOWN)) if (!server_call( REQ_GET_FILE_INFO ) && (req->type == FILE_TYPE_UNKNOWN))
{ {
if ((req->attr >= 0) && if ((req->attr >= 0) &&
(req->attr < sizeof(DOSFS_Devices)/sizeof(DOSFS_Devices[0]))) (req->attr < sizeof(DOSFS_Devices)/sizeof(DOSFS_Devices[0])))
return &DOSFS_Devices[req->attr]; ret = &DOSFS_Devices[req->attr];
} }
return NULL; }
SERVER_END_REQ;
return ret;
} }
......
...@@ -319,6 +319,31 @@ HFILE FILE_DupUnixHandle( int fd, DWORD access ) ...@@ -319,6 +319,31 @@ HFILE FILE_DupUnixHandle( int fd, DWORD access )
/*********************************************************************** /***********************************************************************
* FILE_GetUnixHandle
*
* Retrieve the Unix handle corresponding to a file handle.
*/
int FILE_GetUnixHandle( HANDLE handle, DWORD access )
{
int unix_handle = -1;
if (access == GENERIC_READ)
{
struct get_read_fd_request *req = get_req_buffer();
req->handle = handle;
server_call_fd( REQ_GET_READ_FD, -1, &unix_handle );
}
else if (access == GENERIC_WRITE)
{
struct get_write_fd_request *req = get_req_buffer();
req->handle = handle;
server_call_fd( REQ_GET_WRITE_FD, -1, &unix_handle );
}
else ERR( "bad access %08lx\n", access );
return unix_handle;
}
/***********************************************************************
* FILE_CreateFile * FILE_CreateFile
* *
* Implementation of CreateFile. Takes a Unix path name. * Implementation of CreateFile. Takes a Unix path name.
...@@ -328,21 +353,35 @@ HANDLE FILE_CreateFile( LPCSTR filename, DWORD access, DWORD sharing, ...@@ -328,21 +353,35 @@ HANDLE FILE_CreateFile( LPCSTR filename, DWORD access, DWORD sharing,
DWORD attributes, HANDLE template, BOOL fail_read_only ) DWORD attributes, HANDLE template, BOOL fail_read_only )
{ {
DWORD err; DWORD err;
struct create_file_request *req = get_req_buffer(); HANDLE ret;
size_t len = strlen(filename);
if (len > REQUEST_MAX_VAR_SIZE)
{
FIXME("filename '%s' too long\n", filename );
SetLastError( ERROR_INVALID_PARAMETER );
return -1;
}
restart: restart:
SERVER_START_REQ
{
struct create_file_request *req = server_alloc_req( sizeof(*req), len );
req->access = access; req->access = access;
req->inherit = (sa && (sa->nLength>=sizeof(*sa)) && sa->bInheritHandle); req->inherit = (sa && (sa->nLength>=sizeof(*sa)) && sa->bInheritHandle);
req->sharing = sharing; req->sharing = sharing;
req->create = creation; req->create = creation;
req->attrs = attributes; req->attrs = attributes;
lstrcpynA( req->name, filename, server_remaining(req->name) ); memcpy( server_data_ptr(req), filename, len );
SetLastError(0); SetLastError(0);
err = server_call( REQ_CREATE_FILE ); err = server_call( REQ_CREATE_FILE );
ret = req->handle;
}
SERVER_END_REQ;
/* If write access failed, retry without GENERIC_WRITE */ /* If write access failed, retry without GENERIC_WRITE */
if ((req->handle == -1) && !fail_read_only && (access & GENERIC_WRITE)) if ((ret == -1) && !fail_read_only && (access & GENERIC_WRITE))
{ {
if ((err == STATUS_MEDIA_WRITE_PROTECTED) || (err == STATUS_ACCESS_DENIED)) if ((err == STATUS_MEDIA_WRITE_PROTECTED) || (err == STATUS_ACCESS_DENIED))
{ {
...@@ -353,11 +392,11 @@ HANDLE FILE_CreateFile( LPCSTR filename, DWORD access, DWORD sharing, ...@@ -353,11 +392,11 @@ HANDLE FILE_CreateFile( LPCSTR filename, DWORD access, DWORD sharing,
} }
} }
if (req->handle == -1) if (ret == -1)
WARN("Unable to create file '%s' (GLE %ld)\n", filename, WARN("Unable to create file '%s' (GLE %ld)\n", filename,
GetLastError()); GetLastError());
return req->handle; return ret;
} }
...@@ -1140,7 +1179,6 @@ BOOL WINAPI GetOverlappedResult(HANDLE hFile,LPOVERLAPPED lpOverlapped, ...@@ -1140,7 +1179,6 @@ BOOL WINAPI GetOverlappedResult(HANDLE hFile,LPOVERLAPPED lpOverlapped,
BOOL WINAPI ReadFile( HANDLE hFile, LPVOID buffer, DWORD bytesToRead, BOOL WINAPI ReadFile( HANDLE hFile, LPVOID buffer, DWORD bytesToRead,
LPDWORD bytesRead, LPOVERLAPPED overlapped ) LPDWORD bytesRead, LPOVERLAPPED overlapped )
{ {
struct get_read_fd_request *req = get_req_buffer();
int unix_handle, result; int unix_handle, result;
TRACE("%d %p %ld\n", hFile, buffer, bytesToRead ); TRACE("%d %p %ld\n", hFile, buffer, bytesToRead );
...@@ -1153,8 +1191,7 @@ BOOL WINAPI ReadFile( HANDLE hFile, LPVOID buffer, DWORD bytesToRead, ...@@ -1153,8 +1191,7 @@ BOOL WINAPI ReadFile( HANDLE hFile, LPVOID buffer, DWORD bytesToRead,
return FALSE; return FALSE;
} }
req->handle = hFile; unix_handle = FILE_GetUnixHandle( hFile, GENERIC_READ );
server_call_fd( REQ_GET_READ_FD, -1, &unix_handle );
if (unix_handle == -1) return FALSE; if (unix_handle == -1) return FALSE;
while ((result = read( unix_handle, buffer, bytesToRead )) == -1) while ((result = read( unix_handle, buffer, bytesToRead )) == -1)
{ {
...@@ -1176,7 +1213,6 @@ BOOL WINAPI ReadFile( HANDLE hFile, LPVOID buffer, DWORD bytesToRead, ...@@ -1176,7 +1213,6 @@ BOOL WINAPI ReadFile( HANDLE hFile, LPVOID buffer, DWORD bytesToRead,
BOOL WINAPI WriteFile( HANDLE hFile, LPCVOID buffer, DWORD bytesToWrite, BOOL WINAPI WriteFile( HANDLE hFile, LPCVOID buffer, DWORD bytesToWrite,
LPDWORD bytesWritten, LPOVERLAPPED overlapped ) LPDWORD bytesWritten, LPOVERLAPPED overlapped )
{ {
struct get_write_fd_request *req = get_req_buffer();
int unix_handle, result; int unix_handle, result;
TRACE("%d %p %ld\n", hFile, buffer, bytesToWrite ); TRACE("%d %p %ld\n", hFile, buffer, bytesToWrite );
...@@ -1189,8 +1225,7 @@ BOOL WINAPI WriteFile( HANDLE hFile, LPCVOID buffer, DWORD bytesToWrite, ...@@ -1189,8 +1225,7 @@ BOOL WINAPI WriteFile( HANDLE hFile, LPCVOID buffer, DWORD bytesToWrite,
return FALSE; return FALSE;
} }
req->handle = hFile; unix_handle = FILE_GetUnixHandle( hFile, GENERIC_WRITE );
server_call_fd( REQ_GET_WRITE_FD, -1, &unix_handle );
if (unix_handle == -1) return FALSE; if (unix_handle == -1) return FALSE;
while ((result = write( unix_handle, buffer, bytesToWrite )) == -1) while ((result = write( unix_handle, buffer, bytesToWrite )) == -1)
{ {
......
...@@ -33,6 +33,7 @@ typedef struct ...@@ -33,6 +33,7 @@ typedef struct
/* files/file.c */ /* files/file.c */
extern void FILE_SetDosError(void); extern void FILE_SetDosError(void);
extern HFILE FILE_DupUnixHandle( int fd, DWORD access ); extern HFILE FILE_DupUnixHandle( int fd, DWORD access );
extern int FILE_GetUnixHandle( HANDLE handle, DWORD access );
extern BOOL FILE_Stat( LPCSTR unixName, BY_HANDLE_FILE_INFORMATION *info ); extern BOOL FILE_Stat( LPCSTR unixName, BY_HANDLE_FILE_INFORMATION *info );
extern HFILE16 FILE_Dup2( HFILE16 hFile1, HFILE16 hFile2 ); extern HFILE16 FILE_Dup2( HFILE16 hFile1, HFILE16 hFile2 );
extern HANDLE FILE_CreateFile( LPCSTR filename, DWORD access, DWORD sharing, extern HANDLE FILE_CreateFile( LPCSTR filename, DWORD access, DWORD sharing,
......
...@@ -41,6 +41,9 @@ struct request_max_size ...@@ -41,6 +41,9 @@ struct request_max_size
int pad[16]; /* the max request size is 16 ints */ int pad[16]; /* the max request size is 16 ints */
}; };
/* max size of the variable part of a request */
#define REQUEST_MAX_VAR_SIZE 1024
/* a path name for server requests (Unicode) */ /* a path name for server requests (Unicode) */
typedef WCHAR path_t[MAX_PATH+1]; typedef WCHAR path_t[MAX_PATH+1];
...@@ -131,7 +134,7 @@ struct new_process_request ...@@ -131,7 +134,7 @@ struct new_process_request
IN int hstderr; /* handle for stderr */ IN int hstderr; /* handle for stderr */
IN int cmd_show; /* main window show mode */ IN int cmd_show; /* main window show mode */
IN int alloc_fd; /* create the fd pair right now? */ IN int alloc_fd; /* create the fd pair right now? */
IN char filename[1]; /* file name of main exe */ IN VARARG(filename,string); /* file name of main exe */
}; };
...@@ -183,7 +186,7 @@ struct init_process_request ...@@ -183,7 +186,7 @@ struct init_process_request
OUT int hstdout; /* handle for stdout */ OUT int hstdout; /* handle for stdout */
OUT int hstderr; /* handle for stderr */ OUT int hstderr; /* handle for stderr */
OUT int cmd_show; /* main window show mode */ OUT int cmd_show; /* main window show mode */
OUT char filename[1]; /* file name of main exe */ OUT VARARG(filename,string); /* file name of main exe */
}; };
...@@ -529,7 +532,7 @@ struct create_file_request ...@@ -529,7 +532,7 @@ struct create_file_request
IN int create; /* file create action */ IN int create; /* file create action */
IN unsigned int attrs; /* file attributes for creation */ IN unsigned int attrs; /* file attributes for creation */
OUT int handle; /* handle to the file */ OUT int handle; /* handle to the file */
IN char name[1]; /* file name */ IN VARARG(filename,string); /* file name */
}; };
...@@ -694,7 +697,7 @@ struct get_socket_event_request ...@@ -694,7 +697,7 @@ struct get_socket_event_request
OUT unsigned int mask; /* event mask */ OUT unsigned int mask; /* event mask */
OUT unsigned int pmask; /* pending events */ OUT unsigned int pmask; /* pending events */
OUT unsigned int state; /* status bits */ OUT unsigned int state; /* status bits */
OUT int errors[1]; /* event errors */ OUT VARARG(errors,ints); /* event errors */
}; };
...@@ -774,7 +777,7 @@ struct set_console_info_request ...@@ -774,7 +777,7 @@ struct set_console_info_request
IN int mask; /* setting mask (see below) */ IN int mask; /* setting mask (see below) */
IN int cursor_size; /* size of cursor (percentage filled) */ IN int cursor_size; /* size of cursor (percentage filled) */
IN int cursor_visible;/* cursor visibility flag */ IN int cursor_visible;/* cursor visibility flag */
IN char title[1]; /* console title */ IN VARARG(title,string); /* console title */
}; };
#define SET_CONSOLE_INFO_CURSOR 0x01 #define SET_CONSOLE_INFO_CURSOR 0x01
#define SET_CONSOLE_INFO_TITLE 0x02 #define SET_CONSOLE_INFO_TITLE 0x02
...@@ -787,7 +790,7 @@ struct get_console_info_request ...@@ -787,7 +790,7 @@ struct get_console_info_request
OUT int cursor_size; /* size of cursor (percentage filled) */ OUT int cursor_size; /* size of cursor (percentage filled) */
OUT int cursor_visible;/* cursor visibility flag */ OUT int cursor_visible;/* cursor visibility flag */
OUT int pid; /* pid of xterm (hack) */ OUT int pid; /* pid of xterm (hack) */
OUT char title[1]; /* console title */ OUT VARARG(title,string); /* console title */
}; };
...@@ -796,9 +799,8 @@ struct write_console_input_request ...@@ -796,9 +799,8 @@ struct write_console_input_request
{ {
REQUEST_HEADER; /* request header */ REQUEST_HEADER; /* request header */
IN int handle; /* handle to the console input */ IN int handle; /* handle to the console input */
IN int count; /* number of input records */
OUT int written; /* number of records written */ OUT int written; /* number of records written */
/* INPUT_RECORD records[0]; */ /* input records */ IN VARARG(rec,input_records); /* input records */
}; };
/* Fetch input records from a console input queue */ /* Fetch input records from a console input queue */
...@@ -806,10 +808,9 @@ struct read_console_input_request ...@@ -806,10 +808,9 @@ struct read_console_input_request
{ {
REQUEST_HEADER; /* request header */ REQUEST_HEADER; /* request header */
IN int handle; /* handle to the console input */ 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? */ IN int flush; /* flush the retrieved records from the queue? */
OUT int read; /* number of records read */ OUT int read; /* number of records read */
/* INPUT_RECORD records[0]; */ /* input records */ OUT VARARG(rec,input_records); /* input records */
}; };
...@@ -947,10 +948,10 @@ struct wait_debug_event_request ...@@ -947,10 +948,10 @@ struct wait_debug_event_request
struct exception_event_request struct exception_event_request
{ {
REQUEST_HEADER; /* request header */ REQUEST_HEADER; /* request header */
IN EXCEPTION_RECORD record; /* exception record */
IN int first; /* first chance exception? */ IN int first; /* first chance exception? */
IN CONTEXT context; /* thread context */
OUT int status; /* event continuation status */ OUT int status; /* event continuation status */
IN VARARG(record,exc_event); /* thread context followed by exception record */
OUT VARARG(context,context); /* modified thread context */
}; };
...@@ -1213,7 +1214,7 @@ struct get_thread_context_request ...@@ -1213,7 +1214,7 @@ struct get_thread_context_request
REQUEST_HEADER; /* request header */ REQUEST_HEADER; /* request header */
IN int handle; /* thread handle */ IN int handle; /* thread handle */
IN unsigned int flags; /* context flags */ IN unsigned int flags; /* context flags */
OUT CONTEXT context; /* thread context */ OUT VARARG(context,context); /* thread context */
}; };
...@@ -1223,7 +1224,7 @@ struct set_thread_context_request ...@@ -1223,7 +1224,7 @@ struct set_thread_context_request
REQUEST_HEADER; /* request header */ REQUEST_HEADER; /* request header */
IN int handle; /* thread handle */ IN int handle; /* thread handle */
IN unsigned int flags; /* context flags */ IN unsigned int flags; /* context flags */
IN CONTEXT context; /* thread context */ IN VARARG(context,context); /* thread context */
}; };
...@@ -1540,7 +1541,7 @@ union generic_request ...@@ -1540,7 +1541,7 @@ union generic_request
struct wait_input_idle_request wait_input_idle; struct wait_input_idle_request wait_input_idle;
}; };
#define SERVER_PROTOCOL_VERSION 19 #define SERVER_PROTOCOL_VERSION 20
/* ### make_requests end ### */ /* ### make_requests end ### */
/* Everything above this line is generated automatically by tools/make_requests */ /* Everything above this line is generated automatically by tools/make_requests */
......
...@@ -33,10 +33,9 @@ ...@@ -33,10 +33,9 @@
#include "dosexe.h" #include "dosexe.h"
#include "dosmod.h" #include "dosmod.h"
#include "options.h" #include "options.h"
#include "server.h"
#include "vga.h" #include "vga.h"
DEFAULT_DEBUG_CHANNEL(module) DEFAULT_DEBUG_CHANNEL(module);
#ifdef MZ_SUPPORTED #ifdef MZ_SUPPORTED
...@@ -378,8 +377,6 @@ BOOL MZ_InitTask( LPDOSTASK lpDosTask ) ...@@ -378,8 +377,6 @@ BOOL MZ_InitTask( LPDOSTASK lpDosTask )
int write_fd[2],x_fd; int write_fd[2],x_fd;
pid_t child; pid_t child;
char *fname,*farg,arg[16],fproc[64],path[256],*fpath; char *fname,*farg,arg[16],fproc[64],path[256],*fpath;
struct get_read_fd_request *r_req = get_req_buffer();
struct get_write_fd_request *w_req = get_req_buffer();
if (!lpDosTask) return FALSE; if (!lpDosTask) return FALSE;
/* create pipes */ /* create pipes */
...@@ -390,10 +387,8 @@ BOOL MZ_InitTask( LPDOSTASK lpDosTask ) ...@@ -390,10 +387,8 @@ BOOL MZ_InitTask( LPDOSTASK lpDosTask )
return FALSE; return FALSE;
} }
r_req->handle = lpDosTask->hReadPipe; lpDosTask->read_pipe = FILE_GetUnixHandle( lpDosTask->hReadPipe, GENERIC_READ );
server_call_fd( REQ_GET_READ_FD, -1, &lpDosTask->read_pipe ); x_fd = FILE_GetUnixHandle( lpDosTask->hXPipe, GENERIC_WRITE );
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", TRACE("win32 pipe: read=%d, write=%d, unix pipe: read=%d, write=%d\n",
lpDosTask->hReadPipe,lpDosTask->hXPipe,lpDosTask->read_pipe,x_fd); lpDosTask->hReadPipe,lpDosTask->hXPipe,lpDosTask->read_pipe,x_fd);
......
...@@ -471,10 +471,7 @@ static LPVOID map_image( HANDLE hmapping, int fd, char *base, DWORD total_size, ...@@ -471,10 +471,7 @@ static LPVOID map_image( HANDLE hmapping, int fd, char *base, DWORD total_size,
if (shared_size) if (shared_size)
{ {
struct get_read_fd_request *req = get_req_buffer(); if ((shared_fd = FILE_GetUnixHandle( shared_file, GENERIC_READ )) == -1) goto error;
req->handle = shared_file;
server_call_fd( REQ_GET_READ_FD, -1, &shared_fd );
if (shared_fd == -1) goto error;
CloseHandle( shared_file ); /* we no longer need it */ CloseHandle( shared_file ); /* we no longer need it */
shared_file = INVALID_HANDLE_VALUE; shared_file = INVALID_HANDLE_VALUE;
} }
......
...@@ -1620,13 +1620,9 @@ BOOL WINAPI BuildCommDCBW(LPCWSTR devid,LPDCB lpdcb) ...@@ -1620,13 +1620,9 @@ BOOL WINAPI BuildCommDCBW(LPCWSTR devid,LPDCB lpdcb)
* Returns a file descriptor for reading. * Returns a file descriptor for reading.
* Make sure to close the handle afterwards! * Make sure to close the handle afterwards!
*/ */
static int COMM_GetReadFd( HANDLE handle) inline static int COMM_GetReadFd( HANDLE handle)
{ {
int fd; return FILE_GetUnixHandle( handle, GENERIC_READ );
struct get_read_fd_request *req = get_req_buffer();
req->handle = handle;
server_call_fd( REQ_GET_READ_FD, -1, &fd );
return fd;
} }
/***************************************************************************** /*****************************************************************************
...@@ -1634,13 +1630,9 @@ static int COMM_GetReadFd( HANDLE handle) ...@@ -1634,13 +1630,9 @@ static int COMM_GetReadFd( HANDLE handle)
* Returns a file descriptor for writing. * Returns a file descriptor for writing.
* Make sure to close the handle afterwards! * Make sure to close the handle afterwards!
*/ */
static int COMM_GetWriteFd( HANDLE handle) inline static int COMM_GetWriteFd( HANDLE handle)
{ {
int fd = -1; return FILE_GetUnixHandle( handle, GENERIC_WRITE );
struct get_write_fd_request *req = get_req_buffer();
req->handle = handle;
server_call_fd( REQ_GET_WRITE_FD, -1, &fd );
return fd;
} }
/* FIXME: having these global for win32 for now */ /* FIXME: having these global for win32 for now */
......
...@@ -133,6 +133,7 @@ void *server_alloc_req( size_t fixed_size, size_t var_size ) ...@@ -133,6 +133,7 @@ void *server_alloc_req( size_t fixed_size, size_t var_size )
size_t size = sizeof(*req) + var_size; size_t size = sizeof(*req) + var_size;
assert( fixed_size <= sizeof(*req) ); assert( fixed_size <= sizeof(*req) );
assert( var_size <= REQUEST_MAX_VAR_SIZE );
if ((char *)req + size > (char *)NtCurrentTeb()->buffer_info) if ((char *)req + size > (char *)NtCurrentTeb()->buffer_info)
server_protocol_error( "buffer overflow %d bytes\n", server_protocol_error( "buffer overflow %d bytes\n",
......
...@@ -39,7 +39,7 @@ DECLARE_DEBUG_CHANNEL(win32); ...@@ -39,7 +39,7 @@ DECLARE_DEBUG_CHANNEL(win32);
PDB current_process; PDB current_process;
static char **main_exe_argv; static char **main_exe_argv;
static char *main_exe_name; static char main_exe_name[MAX_PATH];
static HFILE main_exe_file = -1; static HFILE main_exe_file = -1;
...@@ -185,15 +185,18 @@ static BOOL process_init( char *argv[] ) ...@@ -185,15 +185,18 @@ static BOOL process_init( char *argv[] )
/* Retrieve startup info from the server */ /* Retrieve startup info from the server */
SERVER_START_REQ SERVER_START_REQ
{ {
struct init_process_request *req = server_alloc_req( sizeof(*req), 0 ); struct init_process_request *req = server_alloc_req( sizeof(*req),
sizeof(main_exe_name)-1 );
req->ldt_copy = ldt_copy; req->ldt_copy = ldt_copy;
req->ldt_flags = ldt_flags_copy; req->ldt_flags = ldt_flags_copy;
req->ppid = getppid(); req->ppid = getppid();
if ((ret = !server_call( REQ_INIT_PROCESS ))) if ((ret = !server_call( REQ_INIT_PROCESS )))
{ {
size_t len = server_data_size( req );
memcpy( main_exe_name, server_data_ptr(req), len );
main_exe_name[len] = 0;
main_exe_file = req->exe_file; main_exe_file = req->exe_file;
if (req->filename[0]) main_exe_name = strdup( req->filename );
current_startupinfo.dwFlags = req->start_flags; current_startupinfo.dwFlags = req->start_flags;
current_startupinfo.wShowWindow = req->cmd_show; current_startupinfo.wShowWindow = req->cmd_show;
current_envdb.hStdin = current_startupinfo.hStdInput = req->hstdin; current_envdb.hStdin = current_startupinfo.hStdInput = req->hstdin;
...@@ -367,17 +370,16 @@ static void start_process(void) ...@@ -367,17 +370,16 @@ static void start_process(void)
* PROCESS_Start * PROCESS_Start
* *
* Startup routine of a new Win32 process once the main module has been loaded. * Startup routine of a new Win32 process once the main module has been loaded.
* The filename is free'd by this routine.
*/ */
static void PROCESS_Start( HMODULE main_module, HFILE hFile, LPSTR filename ) WINE_NORETURN; static void PROCESS_Start( HMODULE main_module, HFILE hFile, LPCSTR filename ) WINE_NORETURN;
static void PROCESS_Start( HMODULE main_module, HFILE hFile, LPSTR filename ) static void PROCESS_Start( HMODULE main_module, HFILE hFile, LPCSTR filename )
{ {
if (!filename) if (!filename)
{ {
/* if no explicit filename, use argv[0] */ /* if no explicit filename, use argv[0] */
if (!(filename = malloc( MAX_PATH ))) ExitProcess(1); filename = main_exe_name;
if (!GetLongPathNameA( full_argv0, filename, MAX_PATH )) if (!GetLongPathNameA( full_argv0, main_exe_name, sizeof(main_exe_name) ))
lstrcpynA( filename, full_argv0, MAX_PATH ); lstrcpynA( main_exe_name, full_argv0, sizeof(main_exe_name) );
} }
/* load main module */ /* load main module */
...@@ -387,7 +389,6 @@ static void PROCESS_Start( HMODULE main_module, HFILE hFile, LPSTR filename ) ...@@ -387,7 +389,6 @@ static void PROCESS_Start( HMODULE main_module, HFILE hFile, LPSTR filename )
/* Create 32-bit MODREF */ /* Create 32-bit MODREF */
if (!PE_CreateModule( main_module, filename, 0, hFile, FALSE )) if (!PE_CreateModule( main_module, filename, 0, hFile, FALSE ))
goto error; goto error;
free( filename );
/* allocate main thread stack */ /* allocate main thread stack */
if (!THREAD_InitStack( NtCurrentTeb(), if (!THREAD_InitStack( NtCurrentTeb(),
...@@ -416,23 +417,17 @@ void PROCESS_InitWine( int argc, char *argv[] ) ...@@ -416,23 +417,17 @@ void PROCESS_InitWine( int argc, char *argv[] )
main_exe_argv = ++argv; /* remove argv[0] (wine itself) */ main_exe_argv = ++argv; /* remove argv[0] (wine itself) */
if (!main_exe_name) if (!main_exe_name[0])
{ {
char buffer[MAX_PATH];
if (!argv[0]) OPTIONS_Usage(); if (!argv[0]) OPTIONS_Usage();
/* open the exe file */ /* open the exe file */
if (!SearchPathA( NULL, argv[0], ".exe", sizeof(buffer), buffer, NULL ) && if (!SearchPathA( NULL, argv[0], ".exe", sizeof(main_exe_name), main_exe_name, NULL ) &&
!SearchPathA( NULL, argv[0], NULL, sizeof(buffer), buffer, NULL )) !SearchPathA( NULL, argv[0], NULL, sizeof(main_exe_name), main_exe_name, NULL ))
{ {
MESSAGE( "%s: cannot find '%s'\n", argv0, argv[0] ); MESSAGE( "%s: cannot find '%s'\n", argv0, argv[0] );
goto error; goto error;
} }
if (!(main_exe_name = strdup(buffer)))
{
MESSAGE( "%s: out of memory\n", argv0 );
ExitProcess(1);
}
} }
if (main_exe_file == INVALID_HANDLE_VALUE) if (main_exe_file == INVALID_HANDLE_VALUE)
...@@ -723,12 +718,30 @@ BOOL PROCESS_Create( HFILE hFile, LPCSTR filename, LPSTR cmd_line, LPCSTR env, ...@@ -723,12 +718,30 @@ BOOL PROCESS_Create( HFILE hFile, LPCSTR filename, LPSTR cmd_line, LPCSTR env,
const char *unixdir = NULL; const char *unixdir = NULL;
DOS_FULL_NAME full_name; DOS_FULL_NAME full_name;
HANDLE load_done_evt = -1; HANDLE load_done_evt = -1;
struct new_process_request *req = get_req_buffer();
info->hThread = info->hProcess = INVALID_HANDLE_VALUE; info->hThread = info->hProcess = INVALID_HANDLE_VALUE;
if (lpCurrentDirectory)
{
if (DOSFS_GetFullName( lpCurrentDirectory, TRUE, &full_name ))
unixdir = full_name.long_name;
}
else
{
char buf[MAX_PATH];
if (GetCurrentDirectoryA(sizeof(buf),buf))
{
if (DOSFS_GetFullName( buf, TRUE, &full_name ))
unixdir = full_name.long_name;
}
}
/* create the process on the server side */ /* create the process on the server side */
SERVER_START_REQ
{
size_t len = (hFile == -1) ? 0 : MAX_PATH;
struct new_process_request *req = server_alloc_req( sizeof(*req), len );
req->inherit_all = inherit; req->inherit_all = inherit;
req->create_flags = flags; req->create_flags = flags;
req->start_flags = startup->dwFlags; req->start_flags = startup->dwFlags;
...@@ -748,29 +761,21 @@ BOOL PROCESS_Create( HFILE hFile, LPCSTR filename, LPSTR cmd_line, LPCSTR env, ...@@ -748,29 +761,21 @@ BOOL PROCESS_Create( HFILE hFile, LPCSTR filename, LPSTR cmd_line, LPCSTR env,
req->cmd_show = startup->wShowWindow; req->cmd_show = startup->wShowWindow;
req->alloc_fd = 0; req->alloc_fd = 0;
if (lpCurrentDirectory) {
if (DOSFS_GetFullName( lpCurrentDirectory, TRUE, &full_name ))
unixdir = full_name.long_name;
} else {
CHAR buf[260];
if (GetCurrentDirectoryA(sizeof(buf),buf)) {
if (DOSFS_GetFullName( buf, TRUE, &full_name ))
unixdir = full_name.long_name;
}
}
if (hFile == -1) /* unix process */ if (hFile == -1) /* unix process */
{ {
unixfilename = filename; unixfilename = filename;
if (DOSFS_GetFullName( filename, TRUE, &full_name )) unixfilename = full_name.long_name; if (DOSFS_GetFullName( filename, TRUE, &full_name ))
req->filename[0] = 0; unixfilename = full_name.long_name;
} }
else /* new wine process */ else /* new wine process */
{ {
if (!GetLongPathNameA( filename, req->filename, server_remaining(req->filename) )) if (!GetLongPathNameA( filename, server_data_ptr(req), MAX_PATH ))
lstrcpynA( req->filename, filename, server_remaining(req->filename) ); lstrcpynA( server_data_ptr(req), filename, MAX_PATH );
} }
if (server_call( REQ_NEW_PROCESS )) return FALSE; ret = !server_call( REQ_NEW_PROCESS );
}
SERVER_END_REQ;
if (!ret) return FALSE;
/* fork and execute */ /* fork and execute */
......
...@@ -502,10 +502,11 @@ BOOL WINAPI SetThreadContext( HANDLE handle, /* [in] Handle to thread ...@@ -502,10 +502,11 @@ BOOL WINAPI SetThreadContext( HANDLE handle, /* [in] Handle to thread
BOOL ret; BOOL ret;
SERVER_START_REQ SERVER_START_REQ
{ {
struct set_thread_context_request *req = server_alloc_req( sizeof(*req), 0 ); struct set_thread_context_request *req = server_alloc_req( sizeof(*req),
sizeof(*context) );
req->handle = handle; req->handle = handle;
req->flags = context->ContextFlags; req->flags = context->ContextFlags;
memcpy( &req->context, context, sizeof(*context) ); memcpy( server_data_ptr(req), context, sizeof(*context) );
ret = !server_call( REQ_SET_THREAD_CONTEXT ); ret = !server_call( REQ_SET_THREAD_CONTEXT );
} }
SERVER_END_REQ; SERVER_END_REQ;
...@@ -526,12 +527,13 @@ BOOL WINAPI GetThreadContext( HANDLE handle, /* [in] Handle to thread with ...@@ -526,12 +527,13 @@ BOOL WINAPI GetThreadContext( HANDLE handle, /* [in] Handle to thread with
BOOL ret; BOOL ret;
SERVER_START_REQ SERVER_START_REQ
{ {
struct get_thread_context_request *req = server_alloc_req( sizeof(*req), 0 ); struct get_thread_context_request *req = server_alloc_req( sizeof(*req),
sizeof(*context) );
req->handle = handle; req->handle = handle;
req->flags = context->ContextFlags; req->flags = context->ContextFlags;
memcpy( &req->context, context, sizeof(*context) ); memcpy( server_data_ptr(req), context, sizeof(*context) );
if ((ret = !server_call( REQ_GET_THREAD_CONTEXT ))) if ((ret = !server_call( REQ_GET_THREAD_CONTEXT )))
memcpy( context, &req->context, sizeof(*context) ); memcpy( context, server_data_ptr(req), sizeof(*context) );
} }
SERVER_END_REQ; SERVER_END_REQ;
return ret; return ret;
......
...@@ -300,16 +300,25 @@ static int write_console_input( int handle, int count, INPUT_RECORD *records ) ...@@ -300,16 +300,25 @@ static int write_console_input( int handle, int count, INPUT_RECORD *records )
} }
/* retrieve a pointer to the console input records */ /* retrieve a pointer to the console input records */
static int read_console_input( int handle, int count, INPUT_RECORD *rec, int max, int flush ) static int read_console_input( int handle, int count, INPUT_RECORD *rec, int flush )
{ {
struct console_input *console; struct console_input *console;
if (!(console = (struct console_input *)get_handle_obj( current->process, handle, if (!(console = (struct console_input *)get_handle_obj( current->process, handle,
GENERIC_READ, &console_input_ops ))) GENERIC_READ, &console_input_ops )))
return -1; return -1;
if ((count < 0) || (count > console->recnum)) count = console->recnum;
if (count > max) count = max; if (!count)
{
/* special case: do not retrieve anything, but return
* the total number of records available */
count = console->recnum;
}
else
{
if (count > console->recnum) count = console->recnum;
memcpy( rec, console->records, count * sizeof(INPUT_RECORD) ); memcpy( rec, console->records, count * sizeof(INPUT_RECORD) );
}
if (flush) if (flush)
{ {
int i; int i;
...@@ -440,24 +449,30 @@ DECL_HANDLER(open_console) ...@@ -440,24 +449,30 @@ DECL_HANDLER(open_console)
/* set info about a console (output only) */ /* set info about a console (output only) */
DECL_HANDLER(set_console_info) DECL_HANDLER(set_console_info)
{ {
size_t len = get_req_strlen( req, req->title ); set_console_info( req->handle, req, get_req_data(req), get_req_data_size(req) );
set_console_info( req->handle, req, req->title, len );
} }
/* get info about a console (output only) */ /* get info about a console (output only) */
DECL_HANDLER(get_console_info) DECL_HANDLER(get_console_info)
{ {
struct screen_buffer *console; struct screen_buffer *console;
req->title[0] = 0; size_t len = 0;
if ((console = (struct screen_buffer *)get_handle_obj( current->process, req->handle, if ((console = (struct screen_buffer *)get_handle_obj( current->process, req->handle,
GENERIC_READ, &screen_buffer_ops ))) GENERIC_READ, &screen_buffer_ops )))
{ {
req->cursor_size = console->cursor_size; req->cursor_size = console->cursor_size;
req->cursor_visible = console->cursor_visible; req->cursor_visible = console->cursor_visible;
req->pid = console->pid; req->pid = console->pid;
if (console->title) strcpy( req->title, console->title ); if (console->title)
{
len = strlen( console->title );
if (len > get_req_data_size(req)) len = get_req_data_size(req);
memcpy( get_req_data(req), console->title, len );
}
release_object( console ); release_object( console );
} }
set_req_data_size( req, len );
} }
/* set a console fd */ /* set a console fd */
...@@ -498,17 +513,16 @@ DECL_HANDLER(set_console_mode) ...@@ -498,17 +513,16 @@ DECL_HANDLER(set_console_mode)
/* add input records to a console input queue */ /* add input records to a console input queue */
DECL_HANDLER(write_console_input) DECL_HANDLER(write_console_input)
{ {
int max = get_req_size( req, req + 1, sizeof(INPUT_RECORD) ); req->written = write_console_input( req->handle, get_req_data_size(req) / sizeof(INPUT_RECORD),
int count = req->count; get_req_data(req) );
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 */ /* fetch input records from a console input queue */
DECL_HANDLER(read_console_input) DECL_HANDLER(read_console_input)
{ {
int max = get_req_size( req, req + 1, sizeof(INPUT_RECORD) ); size_t size = get_req_data_size(req) / sizeof(INPUT_RECORD);
req->read = read_console_input( req->handle, req->count, (INPUT_RECORD *)(req + 1), int res = read_console_input( req->handle, size, get_req_data(req), req->flush );
max, req->flush ); /* if size was 0 we didn't fetch anything */
if (size) set_req_data_size( req, res * sizeof(INPUT_RECORD) );
req->read = res;
} }
...@@ -477,16 +477,21 @@ DECL_HANDLER(get_thread_context) ...@@ -477,16 +477,21 @@ DECL_HANDLER(get_thread_context)
struct thread *thread; struct thread *thread;
int flags = req->flags & ~CONTEXT_i386; /* get rid of CPU id */ int flags = req->flags & ~CONTEXT_i386; /* get rid of CPU id */
if (get_req_data_size(req) < sizeof(CONTEXT))
{
set_error( STATUS_INVALID_PARAMETER );
return;
}
if ((thread = get_thread_from_handle( req->handle, THREAD_GET_CONTEXT ))) if ((thread = get_thread_from_handle( req->handle, THREAD_GET_CONTEXT )))
{ {
if (thread->context) /* thread is inside an exception event */ if (thread->context) /* thread is inside an exception event */
{ {
copy_context( &req->context, thread->context, flags ); copy_context( get_req_data(req), thread->context, flags );
flags &= CONTEXT_DEBUG_REGISTERS; flags &= CONTEXT_DEBUG_REGISTERS;
} }
if (flags && suspend_for_ptrace( thread )) if (flags && suspend_for_ptrace( thread ))
{ {
get_thread_context( thread, flags, &req->context ); get_thread_context( thread, flags, get_req_data(req) );
resume_thread( thread ); resume_thread( thread );
} }
release_object( thread ); release_object( thread );
...@@ -500,16 +505,21 @@ DECL_HANDLER(set_thread_context) ...@@ -500,16 +505,21 @@ DECL_HANDLER(set_thread_context)
struct thread *thread; struct thread *thread;
int flags = req->flags & ~CONTEXT_i386; /* get rid of CPU id */ int flags = req->flags & ~CONTEXT_i386; /* get rid of CPU id */
if (get_req_data_size(req) < sizeof(CONTEXT))
{
set_error( STATUS_INVALID_PARAMETER );
return;
}
if ((thread = get_thread_from_handle( req->handle, THREAD_SET_CONTEXT ))) if ((thread = get_thread_from_handle( req->handle, THREAD_SET_CONTEXT )))
{ {
if (thread->context) /* thread is inside an exception event */ if (thread->context) /* thread is inside an exception event */
{ {
copy_context( thread->context, &req->context, flags ); copy_context( thread->context, get_req_data(req), flags );
flags &= CONTEXT_DEBUG_REGISTERS; flags &= CONTEXT_DEBUG_REGISTERS;
} }
if (flags && suspend_for_ptrace( thread )) if (flags && suspend_for_ptrace( thread ))
{ {
set_thread_context( thread, flags, &req->context ); set_thread_context( thread, flags, get_req_data(req) );
resume_thread( thread ); resume_thread( thread );
} }
release_object( thread ); release_object( thread );
......
...@@ -159,16 +159,21 @@ DECL_HANDLER(get_thread_context) ...@@ -159,16 +159,21 @@ DECL_HANDLER(get_thread_context)
struct thread *thread; struct thread *thread;
int flags = req->flags & ~CONTEXT_SPARC; /* get rid of CPU id */ int flags = req->flags & ~CONTEXT_SPARC; /* get rid of CPU id */
if (get_req_data_size(req) < sizeof(CONTEXT))
{
set_error( STATUS_INVALID_PARAMETER );
return;
}
if ((thread = get_thread_from_handle( req->handle, THREAD_GET_CONTEXT ))) if ((thread = get_thread_from_handle( req->handle, THREAD_GET_CONTEXT )))
{ {
if (thread->context) /* thread is inside an exception event */ if (thread->context) /* thread is inside an exception event */
{ {
copy_context( &req->context, thread->context, flags ); copy_context( get_req_data(req), thread->context, flags );
flags = 0; flags = 0;
} }
if (flags && suspend_for_ptrace( thread )) if (flags && suspend_for_ptrace( thread ))
{ {
get_thread_context( thread, flags, &req->context ); get_thread_context( thread, flags, get_req_data(req) );
resume_thread( thread ); resume_thread( thread );
} }
release_object( thread ); release_object( thread );
...@@ -182,16 +187,21 @@ DECL_HANDLER(set_thread_context) ...@@ -182,16 +187,21 @@ DECL_HANDLER(set_thread_context)
struct thread *thread; struct thread *thread;
int flags = req->flags & ~CONTEXT_SPARC; /* get rid of CPU id */ int flags = req->flags & ~CONTEXT_SPARC; /* get rid of CPU id */
if (get_req_data_size(req) < sizeof(CONTEXT))
{
set_error( STATUS_INVALID_PARAMETER );
return;
}
if ((thread = get_thread_from_handle( req->handle, THREAD_SET_CONTEXT ))) if ((thread = get_thread_from_handle( req->handle, THREAD_SET_CONTEXT )))
{ {
if (thread->context) /* thread is inside an exception event */ if (thread->context) /* thread is inside an exception event */
{ {
copy_context( thread->context, &req->context, flags ); copy_context( thread->context, get_req_data(req), flags );
flags = 0; flags = 0;
} }
if (flags && suspend_for_ptrace( thread )) if (flags && suspend_for_ptrace( thread ))
{ {
set_thread_context( thread, flags, &req->context ); set_thread_context( thread, flags, get_req_data(req) );
resume_thread( thread ); resume_thread( thread );
} }
release_object( thread ); release_object( thread );
......
...@@ -593,13 +593,20 @@ DECL_HANDLER(exception_event) ...@@ -593,13 +593,20 @@ DECL_HANDLER(exception_event)
{ {
struct debug_event_exception data; struct debug_event_exception data;
struct debug_event *event; struct debug_event *event;
CONTEXT *context = get_req_data( req );
EXCEPTION_RECORD *rec = (EXCEPTION_RECORD *)(context + 1);
data.record = req->record; if (get_req_data_size( req ) < sizeof(*rec) + sizeof(*context))
{
set_error( STATUS_INVALID_PARAMETER );
return;
}
data.record = *rec;
data.first = req->first; data.first = req->first;
if ((event = queue_debug_event( current, EXCEPTION_DEBUG_EVENT, &data ))) if ((event = queue_debug_event( current, EXCEPTION_DEBUG_EVENT, &data )))
{ {
struct object *obj = &event->obj; struct object *obj = &event->obj;
current->context = &req->context; current->context = context;
sleep_on( 1, &obj, 0, -1, build_exception_event_reply ); sleep_on( 1, &obj, 0, -1, build_exception_event_reply );
release_object( event ); release_object( event );
} }
......
...@@ -450,11 +450,10 @@ static int file_unlock( struct file *file, int offset_high, int offset_low, ...@@ -450,11 +450,10 @@ static int file_unlock( struct file *file, int offset_high, int offset_low,
/* create a file */ /* create a file */
DECL_HANDLER(create_file) DECL_HANDLER(create_file)
{ {
size_t len = get_req_strlen( req, req->name );
struct file *file; struct file *file;
req->handle = -1; req->handle = -1;
if ((file = create_file( req->name, len, req->access, if ((file = create_file( get_req_data(req), get_req_data_size(req), req->access,
req->sharing, req->create, req->attrs ))) req->sharing, req->create, req->attrs )))
{ {
req->handle = alloc_handle( current->process, file, req->access, req->inherit ); req->handle = alloc_handle( current->process, file, req->access, req->inherit );
......
...@@ -259,9 +259,12 @@ static void init_process( int ppid, struct init_process_request *req ) ...@@ -259,9 +259,12 @@ static void init_process( int ppid, struct init_process_request *req )
if (info) if (info)
{ {
size_t size = strlen(info->filename);
if (size > get_req_data_size(req)) size = get_req_data_size(req);
req->start_flags = info->start_flags; req->start_flags = info->start_flags;
req->cmd_show = info->cmd_show; req->cmd_show = info->cmd_show;
strcpy( req->filename, info->filename ); memcpy( get_req_data(req), info->filename, size );
set_req_data_size( req, size );
info->process = (struct process *)grab_object( process ); info->process = (struct process *)grab_object( process );
info->thread = (struct thread *)grab_object( current ); info->thread = (struct thread *)grab_object( current );
wake_up( &info->obj, 0 ); wake_up( &info->obj, 0 );
...@@ -270,7 +273,7 @@ static void init_process( int ppid, struct init_process_request *req ) ...@@ -270,7 +273,7 @@ static void init_process( int ppid, struct init_process_request *req )
{ {
req->start_flags = STARTF_USESTDHANDLES; req->start_flags = STARTF_USESTDHANDLES;
req->cmd_show = 0; req->cmd_show = 0;
req->filename[0] = 0; set_req_data_size( req, 0 );
} }
error: error:
} }
...@@ -711,7 +714,7 @@ struct module_snapshot *module_snap( struct process *process, int *count ) ...@@ -711,7 +714,7 @@ struct module_snapshot *module_snap( struct process *process, int *count )
/* create a new process */ /* create a new process */
DECL_HANDLER(new_process) DECL_HANDLER(new_process)
{ {
size_t len = get_req_strlen( req, req->filename ); size_t len = get_req_data_size( req );
struct startup_info *info; struct startup_info *info;
int sock[2]; int sock[2];
...@@ -742,11 +745,12 @@ DECL_HANDLER(new_process) ...@@ -742,11 +745,12 @@ DECL_HANDLER(new_process)
return; return;
} }
if (!(info->filename = memdup( req->filename, len+1 ))) if (!(info->filename = mem_alloc( len + 1 )))
{ {
release_object( info ); release_object( info );
return; return;
} }
memcpy( info->filename, get_req_data(req), len );
info->filename[len] = 0; info->filename[len] = 0;
if (req->alloc_fd) if (req->alloc_fd)
......
...@@ -486,6 +486,7 @@ DECL_HANDLER(set_socket_event) ...@@ -486,6 +486,7 @@ DECL_HANDLER(set_socket_event)
DECL_HANDLER(get_socket_event) DECL_HANDLER(get_socket_event)
{ {
struct sock *sock; struct sock *sock;
size_t size;
sock=(struct sock*)get_handle_obj(current->process,req->handle,GENERIC_READ|GENERIC_WRITE|SYNCHRONIZE,&sock_ops); sock=(struct sock*)get_handle_obj(current->process,req->handle,GENERIC_READ|GENERIC_WRITE|SYNCHRONIZE,&sock_ops);
if (!sock) if (!sock)
...@@ -499,8 +500,10 @@ DECL_HANDLER(get_socket_event) ...@@ -499,8 +500,10 @@ DECL_HANDLER(get_socket_event)
req->mask = sock->mask; req->mask = sock->mask;
req->pmask = sock->pmask; req->pmask = sock->pmask;
req->state = sock->state; req->state = sock->state;
memcpy(req->errors, sock->errors, sizeof(sock->errors)); size = min( get_req_data_size(req), sizeof(sock->errors) );
clear_error(); memcpy( get_req_data(req), sock->errors, size );
set_req_data_size( req, size );
if (req->service) if (req->service)
{ {
if (req->s_event) if (req->s_event)
......
...@@ -15,9 +15,6 @@ ...@@ -15,9 +15,6 @@
"void*" => "%p", "void*" => "%p",
"time_t" => "%ld", "time_t" => "%ld",
"path_t" => "&dump_path_t", "path_t" => "&dump_path_t",
"debug_event_t" => "&dump_debug_event_t",
"CONTEXT" => "&dump_context",
"EXCEPTION_RECORD" => "&dump_exc_record",
"char[1]" => "&dump_string", "char[1]" => "&dump_string",
"WCHAR[1]" => "&dump_unicode_string" "WCHAR[1]" => "&dump_unicode_string"
); );
......
...@@ -68,20 +68,30 @@ void WINAPI RaiseException( DWORD code, DWORD flags, DWORD nbargs, const LPDWORD ...@@ -68,20 +68,30 @@ void WINAPI RaiseException( DWORD code, DWORD flags, DWORD nbargs, const LPDWORD
*/ */
DWORD WINAPI UnhandledExceptionFilter(PEXCEPTION_POINTERS epointers) DWORD WINAPI UnhandledExceptionFilter(PEXCEPTION_POINTERS epointers)
{ {
struct exception_event_request *req = get_req_buffer();
PDB* pdb = PROCESS_Current(); PDB* pdb = PROCESS_Current();
char format[256]; char format[256];
char buffer[256]; char buffer[256];
HKEY hDbgConf; HKEY hDbgConf;
DWORD bAuto = FALSE; DWORD bAuto = FALSE;
DWORD ret = EXCEPTION_EXECUTE_HANDLER; DWORD ret = EXCEPTION_EXECUTE_HANDLER;
int status;
/* send a last chance event to the debugger */ /* send a last chance event to the debugger */
req->record = *epointers->ExceptionRecord; SERVER_START_REQ
{
struct exception_event_request *req = server_alloc_req( sizeof(*req),
sizeof(EXCEPTION_RECORD)+sizeof(CONTEXT) );
CONTEXT *context_ptr = server_data_ptr(req);
EXCEPTION_RECORD *rec_ptr = (EXCEPTION_RECORD *)(context_ptr + 1);
req->first = 0; req->first = 0;
req->context = *epointers->ContextRecord; *rec_ptr = *epointers->ExceptionRecord;
if (!server_call_noerr( REQ_EXCEPTION_EVENT )) *epointers->ContextRecord = req->context; *context_ptr = *epointers->ContextRecord;
switch (req->status) if (!server_call_noerr( REQ_EXCEPTION_EVENT )) *epointers->ContextRecord = *context_ptr;
status = req->status;
}
SERVER_END_REQ;
switch (status)
{ {
case DBG_CONTINUE: case DBG_CONTINUE:
return EXCEPTION_CONTINUE_EXECUTION; return EXCEPTION_CONTINUE_EXECUTION;
...@@ -91,7 +101,7 @@ DWORD WINAPI UnhandledExceptionFilter(PEXCEPTION_POINTERS epointers) ...@@ -91,7 +101,7 @@ DWORD WINAPI UnhandledExceptionFilter(PEXCEPTION_POINTERS epointers)
case 0: /* no debugger is present */ case 0: /* no debugger is present */
break; break;
default: default:
FIXME("Unsupported yet debug continue value %d (please report)\n", req->status); FIXME("Unsupported yet debug continue value %d (please report)\n", status);
} }
if (pdb->top_filter) if (pdb->top_filter)
......
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