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
int ret;
SERVER_START_REQ
{
struct exception_event_request *req = server_alloc_req( sizeof(*req), 0 );
req->record = *rec;
struct exception_event_request *req = server_alloc_req( sizeof(*req),
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->context = *context;
if (!server_call_noerr( REQ_EXCEPTION_EVENT )) *context = req->context;
*rec_ptr = *rec;
*context_ptr = *context;
if (!server_call_noerr( REQ_EXCEPTION_EVENT )) *context = *context_ptr;
ret = req->status;
}
SERVER_END_REQ;
......
......@@ -86,6 +86,7 @@
#include "wine/port.h"
#include "services.h"
#include "server.h"
#include "file.h"
#include "debugtools.h"
......@@ -222,11 +223,7 @@ static char* _check_buffer(LPWSINFO pwsi, int size);
static int _get_sock_fd(SOCKET s)
{
struct get_read_fd_request *req = get_req_buffer();
int fd;
req->handle = s;
server_call_fd( REQ_GET_READ_FD, -1, &fd );
int fd = FILE_GetUnixHandle( s, GENERIC_READ );
if (fd == -1)
FIXME("handle %d is not a socket (GLE %ld)\n",s,GetLastError());
return fd;
......@@ -235,37 +232,53 @@ static int _get_sock_fd(SOCKET s)
static void _enable_event(SOCKET s, unsigned int event,
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->mask = event;
req->sstate = sstate;
req->cstate = cstate;
sock_server_call( REQ_ENABLE_SOCKET_EVENT );
}
SERVER_END_REQ;
}
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->service = FALSE;
req->s_event = 0;
req->c_event = 0;
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)
{
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->service = FALSE;
req->s_event = 0;
req->c_event = 0;
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)
......@@ -277,14 +290,20 @@ static void _sync_sock_state(SOCKET s)
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->service = FALSE;
req->s_event = 0;
req->c_event = 0;
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;
......@@ -803,12 +822,12 @@ SOCKET WINAPI WSOCK32_accept(SOCKET s, struct sockaddr *addr,
#ifdef HAVE_IPX
struct ws_sockaddr_ipx* addr2 = (struct ws_sockaddr_ipx *)addr;
#endif
struct accept_socket_request *req = get_req_buffer();
TRACE("(%08x): socket %04x\n",
(unsigned)pwsi, (UINT16)s );
if( _check_ws(pwsi, s) )
{
SOCKET as;
if (_is_blocking(s))
{
/* block here */
......@@ -820,13 +839,19 @@ SOCKET WINAPI WSOCK32_accept(SOCKET s, struct sockaddr *addr,
SetLastError(_get_sock_error(s, FD_ACCEPT_BIT));
/* FIXME: care about the error? */
}
SERVER_START_REQ
{
struct accept_socket_request *req = server_alloc_req( sizeof(*req), 0 );
req->lhandle = s;
req->access = GENERIC_READ|GENERIC_WRITE|SYNCHRONIZE;
req->inherit = TRUE;
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 );
int fd = _get_sock_fd( as );
if( getpeername(fd, addr, addrlen32) != -1 )
......@@ -2152,7 +2177,7 @@ INT16 WINAPI WINSOCK_shutdown16(SOCKET16 s, INT16 how)
SOCKET WINAPI WSOCK32_socket(INT af, INT type, INT protocol)
{
LPWSINFO pwsi = WINSOCK_GetIData();
struct create_socket_request *req = get_req_buffer();
SOCKET ret;
TRACE("(%08x): af=%d type=%d protocol=%d\n",
(unsigned)pwsi, af, type, protocol);
......@@ -2195,17 +2220,22 @@ SOCKET WINAPI WSOCK32_socket(INT af, INT type, INT protocol)
default: SetLastError(WSAEPROTOTYPE); return INVALID_SOCKET;
}
SERVER_START_REQ
{
struct create_socket_request *req = server_alloc_req( sizeof(*req), 0 );
req->family = af;
req->type = type;
req->protocol = protocol;
req->access = GENERIC_READ|GENERIC_WRITE|SYNCHRONIZE;
req->inherit = TRUE;
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);
return req->handle;
TRACE("\tcreated %04x\n", ret );
return ret;
}
if (GetLastError() == WSAEACCES) /* raw socket denied */
......@@ -2518,19 +2548,24 @@ INT16 WINAPI WINSOCK_gethostname16(char *name, INT16 namelen)
int WINAPI WSAEnumNetworkEvents(SOCKET s, WSAEVENT hEvent, LPWSANETWORKEVENTS lpEvent)
{
LPWSINFO pwsi = WINSOCK_GetIData();
struct get_socket_event_request *req = get_req_buffer();
TRACE("(%08x): %08x, hEvent %08x, lpEvent %08x\n",
(unsigned)pwsi, s, hEvent, (unsigned)lpEvent );
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->service = TRUE;
req->s_event = 0;
req->c_event = hEvent;
sock_server_call( REQ_GET_SOCKET_EVENT );
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;
}
else SetLastError(WSAEINVAL);
......@@ -2543,16 +2578,20 @@ int WINAPI WSAEnumNetworkEvents(SOCKET s, WSAEVENT hEvent, LPWSANETWORKEVENTS lp
int WINAPI WSAEventSelect(SOCKET s, WSAEVENT hEvent, LONG lEvent)
{
LPWSINFO pwsi = WINSOCK_GetIData();
struct set_socket_event_request *req = get_req_buffer();
TRACE("(%08x): %08x, hEvent %08x, event %08x\n",
(unsigned)pwsi, s, hEvent, (unsigned)lEvent );
if( _check_ws(pwsi, s) )
{
SERVER_START_REQ
{
struct set_socket_event_request *req = server_alloc_req( sizeof(*req), 0 );
req->handle = s;
req->mask = lEvent;
req->event = hEvent;
sock_server_call( REQ_SET_SOCKET_EVENT );
}
SERVER_END_REQ;
return 0;
}
else SetLastError(WSAEINVAL);
......@@ -2567,23 +2606,30 @@ VOID CALLBACK WINSOCK_DoAsyncEvent( ULONG_PTR ptr )
{
ws_select_info *info = (ws_select_info*)ptr;
LPWSINFO pwsi = info->pwsi;
struct get_socket_event_request *req = get_req_buffer();
unsigned int i, pmask, orphan = FALSE;
int errors[FD_MAX_EVENTS];
TRACE("socket %08x, event %08x\n", info->sock, info->event);
SetLastError(0);
SERVER_START_REQ
{
struct get_socket_event_request *req = server_alloc_req( sizeof(*req), sizeof(errors) );
req->handle = info->sock;
req->service = TRUE;
req->s_event = info->event; /* <== avoid race conditions */
req->c_event = info->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) )
{
/* orphaned event (socket closed or something) */
pmask = WS_FD_SERVEVENT;
orphan = TRUE;
} else
pmask = req->pmask;
}
/* check for accepted sockets that needs to inherit WSAAsyncSelect */
if (pmask & WS_FD_SERVEVENT) {
int q;
......@@ -2602,9 +2648,9 @@ VOID CALLBACK WINSOCK_DoAsyncEvent( ULONG_PTR ptr )
/* dispatch network events */
for (i=0; i<FD_MAX_EVENTS; 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,
WSAMAKESELECTREPLY(1<<i, req->errors[i]));
WSAMAKESELECTREPLY(1<<i, errors[i]));
}
/* cleanup */
if (orphan)
......
......@@ -621,16 +621,21 @@ const DOS_DEVICE *DOSFS_GetDevice( const char *name )
*/
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;
if (!server_call( REQ_GET_FILE_INFO ) && (req->type == FILE_TYPE_UNKNOWN))
{
if ((req->attr >= 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 )
/***********************************************************************
* 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
*
* Implementation of CreateFile. Takes a Unix path name.
......@@ -328,21 +353,35 @@ HANDLE FILE_CreateFile( LPCSTR filename, DWORD access, DWORD sharing,
DWORD attributes, HANDLE template, BOOL fail_read_only )
{
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:
SERVER_START_REQ
{
struct create_file_request *req = server_alloc_req( sizeof(*req), len );
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) );
memcpy( server_data_ptr(req), filename, len );
SetLastError(0);
err = server_call( REQ_CREATE_FILE );
ret = req->handle;
}
SERVER_END_REQ;
/* 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))
{
......@@ -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,
GetLastError());
return req->handle;
return ret;
}
......@@ -1140,7 +1179,6 @@ BOOL WINAPI GetOverlappedResult(HANDLE hFile,LPOVERLAPPED lpOverlapped,
BOOL WINAPI ReadFile( HANDLE hFile, LPVOID buffer, DWORD bytesToRead,
LPDWORD bytesRead, LPOVERLAPPED overlapped )
{
struct get_read_fd_request *req = get_req_buffer();
int unix_handle, result;
TRACE("%d %p %ld\n", hFile, buffer, bytesToRead );
......@@ -1153,8 +1191,7 @@ BOOL WINAPI ReadFile( HANDLE hFile, LPVOID buffer, DWORD bytesToRead,
return FALSE;
}
req->handle = hFile;
server_call_fd( REQ_GET_READ_FD, -1, &unix_handle );
unix_handle = FILE_GetUnixHandle( hFile, GENERIC_READ );
if (unix_handle == -1) return FALSE;
while ((result = read( unix_handle, buffer, bytesToRead )) == -1)
{
......@@ -1176,7 +1213,6 @@ 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 = get_req_buffer();
int unix_handle, result;
TRACE("%d %p %ld\n", hFile, buffer, bytesToWrite );
......@@ -1189,8 +1225,7 @@ BOOL WINAPI WriteFile( HANDLE hFile, LPCVOID buffer, DWORD bytesToWrite,
return FALSE;
}
req->handle = hFile;
server_call_fd( REQ_GET_WRITE_FD, -1, &unix_handle );
unix_handle = FILE_GetUnixHandle( hFile, GENERIC_WRITE );
if (unix_handle == -1) return FALSE;
while ((result = write( unix_handle, buffer, bytesToWrite )) == -1)
{
......
......@@ -33,6 +33,7 @@ typedef struct
/* files/file.c */
extern void FILE_SetDosError(void);
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 HFILE16 FILE_Dup2( HFILE16 hFile1, HFILE16 hFile2 );
extern HANDLE FILE_CreateFile( LPCSTR filename, DWORD access, DWORD sharing,
......
......@@ -41,6 +41,9 @@ struct request_max_size
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) */
typedef WCHAR path_t[MAX_PATH+1];
......@@ -131,7 +134,7 @@ struct new_process_request
IN int hstderr; /* handle for stderr */
IN int cmd_show; /* main window show mode */
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
OUT int hstdout; /* handle for stdout */
OUT int hstderr; /* handle for stderr */
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
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 */
IN VARARG(filename,string); /* file name */
};
......@@ -694,7 +697,7 @@ struct get_socket_event_request
OUT unsigned int mask; /* event mask */
OUT unsigned int pmask; /* pending events */
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
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 */
IN VARARG(title,string); /* console title */
};
#define SET_CONSOLE_INFO_CURSOR 0x01
#define SET_CONSOLE_INFO_TITLE 0x02
......@@ -787,7 +790,7 @@ struct get_console_info_request
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 */
OUT VARARG(title,string); /* console title */
};
......@@ -796,9 +799,8 @@ struct write_console_input_request
{
REQUEST_HEADER; /* request header */
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 */
IN VARARG(rec,input_records); /* input records */
};
/* Fetch input records from a console input queue */
......@@ -806,10 +808,9 @@ struct read_console_input_request
{
REQUEST_HEADER; /* request header */
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 */
OUT VARARG(rec,input_records); /* input records */
};
......@@ -947,10 +948,10 @@ struct wait_debug_event_request
struct exception_event_request
{
REQUEST_HEADER; /* request header */
IN EXCEPTION_RECORD record; /* exception record */
IN int first; /* first chance exception? */
IN CONTEXT context; /* thread context */
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
REQUEST_HEADER; /* request header */
IN int handle; /* thread handle */
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
REQUEST_HEADER; /* request header */
IN int handle; /* thread handle */
IN unsigned int flags; /* context flags */
IN CONTEXT context; /* thread context */
IN VARARG(context,context); /* thread context */
};
......@@ -1540,7 +1541,7 @@ union generic_request
struct wait_input_idle_request wait_input_idle;
};
#define SERVER_PROTOCOL_VERSION 19
#define SERVER_PROTOCOL_VERSION 20
/* ### make_requests end ### */
/* Everything above this line is generated automatically by tools/make_requests */
......
......@@ -33,10 +33,9 @@
#include "dosexe.h"
#include "dosmod.h"
#include "options.h"
#include "server.h"
#include "vga.h"
DEFAULT_DEBUG_CHANNEL(module)
DEFAULT_DEBUG_CHANNEL(module);
#ifdef MZ_SUPPORTED
......@@ -378,8 +377,6 @@ BOOL MZ_InitTask( LPDOSTASK lpDosTask )
int write_fd[2],x_fd;
pid_t child;
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;
/* create pipes */
......@@ -390,10 +387,8 @@ BOOL MZ_InitTask( LPDOSTASK lpDosTask )
return FALSE;
}
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 );
lpDosTask->read_pipe = FILE_GetUnixHandle( lpDosTask->hReadPipe, GENERIC_READ );
x_fd = FILE_GetUnixHandle( lpDosTask->hXPipe, GENERIC_WRITE );
TRACE("win32 pipe: read=%d, write=%d, unix pipe: read=%d, write=%d\n",
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,
if (shared_size)
{
struct get_read_fd_request *req = get_req_buffer();
req->handle = shared_file;
server_call_fd( REQ_GET_READ_FD, -1, &shared_fd );
if (shared_fd == -1) goto error;
if ((shared_fd = FILE_GetUnixHandle( shared_file, GENERIC_READ )) == -1) goto error;
CloseHandle( shared_file ); /* we no longer need it */
shared_file = INVALID_HANDLE_VALUE;
}
......
......@@ -1620,13 +1620,9 @@ BOOL WINAPI BuildCommDCBW(LPCWSTR devid,LPDCB lpdcb)
* Returns a file descriptor for reading.
* Make sure to close the handle afterwards!
*/
static int COMM_GetReadFd( HANDLE handle)
inline 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;
return FILE_GetUnixHandle( handle, GENERIC_READ );
}
/*****************************************************************************
......@@ -1634,13 +1630,9 @@ static int COMM_GetReadFd( HANDLE handle)
* Returns a file descriptor for writing.
* Make sure to close the handle afterwards!
*/
static int COMM_GetWriteFd( HANDLE handle)
inline static int COMM_GetWriteFd( HANDLE handle)
{
int fd = -1;
struct get_write_fd_request *req = get_req_buffer();
req->handle = handle;
server_call_fd( REQ_GET_WRITE_FD, -1, &fd );
return fd;
return FILE_GetUnixHandle( handle, GENERIC_WRITE );
}
/* FIXME: having these global for win32 for now */
......
......@@ -133,6 +133,7 @@ void *server_alloc_req( size_t fixed_size, size_t var_size )
size_t size = sizeof(*req) + var_size;
assert( fixed_size <= sizeof(*req) );
assert( var_size <= REQUEST_MAX_VAR_SIZE );
if ((char *)req + size > (char *)NtCurrentTeb()->buffer_info)
server_protocol_error( "buffer overflow %d bytes\n",
......
......@@ -39,7 +39,7 @@ DECLARE_DEBUG_CHANNEL(win32);
PDB current_process;
static char **main_exe_argv;
static char *main_exe_name;
static char main_exe_name[MAX_PATH];
static HFILE main_exe_file = -1;
......@@ -185,15 +185,18 @@ static BOOL process_init( char *argv[] )
/* Retrieve startup info from the server */
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_flags = ldt_flags_copy;
req->ppid = getppid();
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;
if (req->filename[0]) main_exe_name = strdup( req->filename );
current_startupinfo.dwFlags = req->start_flags;
current_startupinfo.wShowWindow = req->cmd_show;
current_envdb.hStdin = current_startupinfo.hStdInput = req->hstdin;
......@@ -367,17 +370,16 @@ static void start_process(void)
* PROCESS_Start
*
* 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, LPSTR filename )
static void PROCESS_Start( HMODULE main_module, HFILE hFile, LPCSTR filename ) WINE_NORETURN;
static void PROCESS_Start( HMODULE main_module, HFILE hFile, LPCSTR filename )
{
if (!filename)
{
/* if no explicit filename, use argv[0] */
if (!(filename = malloc( MAX_PATH ))) ExitProcess(1);
if (!GetLongPathNameA( full_argv0, filename, MAX_PATH ))
lstrcpynA( filename, full_argv0, MAX_PATH );
filename = main_exe_name;
if (!GetLongPathNameA( full_argv0, main_exe_name, sizeof(main_exe_name) ))
lstrcpynA( main_exe_name, full_argv0, sizeof(main_exe_name) );
}
/* load main module */
......@@ -387,7 +389,6 @@ static void PROCESS_Start( HMODULE main_module, HFILE hFile, LPSTR filename )
/* Create 32-bit MODREF */
if (!PE_CreateModule( main_module, filename, 0, hFile, FALSE ))
goto error;
free( filename );
/* allocate main thread stack */
if (!THREAD_InitStack( NtCurrentTeb(),
......@@ -416,23 +417,17 @@ void PROCESS_InitWine( int argc, char *argv[] )
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();
/* open the exe file */
if (!SearchPathA( NULL, argv[0], ".exe", sizeof(buffer), buffer, NULL ) &&
!SearchPathA( NULL, argv[0], NULL, sizeof(buffer), buffer, NULL ))
if (!SearchPathA( NULL, argv[0], ".exe", sizeof(main_exe_name), main_exe_name, NULL ) &&
!SearchPathA( NULL, argv[0], NULL, sizeof(main_exe_name), main_exe_name, NULL ))
{
MESSAGE( "%s: cannot find '%s'\n", argv0, argv[0] );
goto error;
}
if (!(main_exe_name = strdup(buffer)))
{
MESSAGE( "%s: out of memory\n", argv0 );
ExitProcess(1);
}
}
if (main_exe_file == INVALID_HANDLE_VALUE)
......@@ -723,12 +718,30 @@ BOOL PROCESS_Create( HFILE hFile, LPCSTR filename, LPSTR cmd_line, LPCSTR env,
const char *unixdir = NULL;
DOS_FULL_NAME full_name;
HANDLE load_done_evt = -1;
struct new_process_request *req = get_req_buffer();
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 */
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->create_flags = flags;
req->start_flags = startup->dwFlags;
......@@ -748,29 +761,21 @@ BOOL PROCESS_Create( HFILE hFile, LPCSTR filename, LPSTR cmd_line, LPCSTR env,
req->cmd_show = startup->wShowWindow;
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 */
{
unixfilename = filename;
if (DOSFS_GetFullName( filename, TRUE, &full_name )) unixfilename = full_name.long_name;
req->filename[0] = 0;
if (DOSFS_GetFullName( filename, TRUE, &full_name ))
unixfilename = full_name.long_name;
}
else /* new wine process */
{
if (!GetLongPathNameA( filename, req->filename, server_remaining(req->filename) ))
lstrcpynA( req->filename, filename, server_remaining(req->filename) );
if (!GetLongPathNameA( filename, server_data_ptr(req), MAX_PATH ))
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 */
......
......@@ -502,10 +502,11 @@ BOOL WINAPI SetThreadContext( HANDLE handle, /* [in] Handle to thread
BOOL ret;
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->flags = context->ContextFlags;
memcpy( &req->context, context, sizeof(*context) );
memcpy( server_data_ptr(req), context, sizeof(*context) );
ret = !server_call( REQ_SET_THREAD_CONTEXT );
}
SERVER_END_REQ;
......@@ -526,12 +527,13 @@ BOOL WINAPI GetThreadContext( HANDLE handle, /* [in] Handle to thread with
BOOL ret;
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->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 )))
memcpy( context, &req->context, sizeof(*context) );
memcpy( context, server_data_ptr(req), sizeof(*context) );
}
SERVER_END_REQ;
return ret;
......
......@@ -300,16 +300,25 @@ 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, 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;
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;
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) );
}
if (flush)
{
int i;
......@@ -440,24 +449,30 @@ DECL_HANDLER(open_console)
/* set info about a console (output only) */
DECL_HANDLER(set_console_info)
{
size_t len = get_req_strlen( req, req->title );
set_console_info( req->handle, req, req->title, len );
set_console_info( req->handle, req, get_req_data(req), get_req_data_size(req) );
}
/* get info about a console (output only) */
DECL_HANDLER(get_console_info)
{
struct screen_buffer *console;
req->title[0] = 0;
size_t len = 0;
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;
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 );
}
set_req_data_size( req, len );
}
/* set a console fd */
......@@ -498,17 +513,16 @@ DECL_HANDLER(set_console_mode)
/* add input records to a console input queue */
DECL_HANDLER(write_console_input)
{
int max = get_req_size( req, req + 1, sizeof(INPUT_RECORD) );
int count = req->count;
if (count > max) count = max;
req->written = write_console_input( req->handle, count, (INPUT_RECORD *)(req + 1) );
req->written = write_console_input( req->handle, get_req_data_size(req) / sizeof(INPUT_RECORD),
get_req_data(req) );
}
/* fetch input records from a console input queue */
DECL_HANDLER(read_console_input)
{
int max = get_req_size( req, req + 1, sizeof(INPUT_RECORD) );
req->read = read_console_input( req->handle, req->count, (INPUT_RECORD *)(req + 1),
max, req->flush );
size_t size = get_req_data_size(req) / sizeof(INPUT_RECORD);
int res = read_console_input( req->handle, size, get_req_data(req), 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)
struct thread *thread;
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->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;
}
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 );
}
release_object( thread );
......@@ -500,16 +505,21 @@ DECL_HANDLER(set_thread_context)
struct thread *thread;
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->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;
}
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 );
}
release_object( thread );
......
......@@ -159,16 +159,21 @@ DECL_HANDLER(get_thread_context)
struct thread *thread;
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->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;
}
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 );
}
release_object( thread );
......@@ -182,16 +187,21 @@ DECL_HANDLER(set_thread_context)
struct thread *thread;
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->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;
}
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 );
}
release_object( thread );
......
......@@ -593,13 +593,20 @@ DECL_HANDLER(exception_event)
{
struct debug_event_exception data;
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;
if ((event = queue_debug_event( current, EXCEPTION_DEBUG_EVENT, &data )))
{
struct object *obj = &event->obj;
current->context = &req->context;
current->context = context;
sleep_on( 1, &obj, 0, -1, build_exception_event_reply );
release_object( event );
}
......
......@@ -450,11 +450,10 @@ static int file_unlock( struct file *file, int offset_high, int offset_low,
/* create a file */
DECL_HANDLER(create_file)
{
size_t len = get_req_strlen( req, req->name );
struct file *file;
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->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 )
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->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->thread = (struct thread *)grab_object( current );
wake_up( &info->obj, 0 );
......@@ -270,7 +273,7 @@ static void init_process( int ppid, struct init_process_request *req )
{
req->start_flags = STARTF_USESTDHANDLES;
req->cmd_show = 0;
req->filename[0] = 0;
set_req_data_size( req, 0 );
}
error:
}
......@@ -711,7 +714,7 @@ struct module_snapshot *module_snap( struct process *process, int *count )
/* create a 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;
int sock[2];
......@@ -742,11 +745,12 @@ DECL_HANDLER(new_process)
return;
}
if (!(info->filename = memdup( req->filename, len+1 )))
if (!(info->filename = mem_alloc( len + 1 )))
{
release_object( info );
return;
}
memcpy( info->filename, get_req_data(req), len );
info->filename[len] = 0;
if (req->alloc_fd)
......
......@@ -486,6 +486,7 @@ DECL_HANDLER(set_socket_event)
DECL_HANDLER(get_socket_event)
{
struct sock *sock;
size_t size;
sock=(struct sock*)get_handle_obj(current->process,req->handle,GENERIC_READ|GENERIC_WRITE|SYNCHRONIZE,&sock_ops);
if (!sock)
......@@ -499,8 +500,10 @@ DECL_HANDLER(get_socket_event)
req->mask = sock->mask;
req->pmask = sock->pmask;
req->state = sock->state;
memcpy(req->errors, sock->errors, sizeof(sock->errors));
clear_error();
size = min( get_req_data_size(req), sizeof(sock->errors) );
memcpy( get_req_data(req), sock->errors, size );
set_req_data_size( req, size );
if (req->service)
{
if (req->s_event)
......
......@@ -15,9 +15,6 @@
"void*" => "%p",
"time_t" => "%ld",
"path_t" => "&dump_path_t",
"debug_event_t" => "&dump_debug_event_t",
"CONTEXT" => "&dump_context",
"EXCEPTION_RECORD" => "&dump_exc_record",
"char[1]" => "&dump_string",
"WCHAR[1]" => "&dump_unicode_string"
);
......
......@@ -68,20 +68,30 @@ void WINAPI RaiseException( DWORD code, DWORD flags, DWORD nbargs, const LPDWORD
*/
DWORD WINAPI UnhandledExceptionFilter(PEXCEPTION_POINTERS epointers)
{
struct exception_event_request *req = get_req_buffer();
PDB* pdb = PROCESS_Current();
char format[256];
char buffer[256];
HKEY hDbgConf;
DWORD bAuto = FALSE;
DWORD ret = EXCEPTION_EXECUTE_HANDLER;
int status;
/* 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->context = *epointers->ContextRecord;
if (!server_call_noerr( REQ_EXCEPTION_EVENT )) *epointers->ContextRecord = req->context;
switch (req->status)
*rec_ptr = *epointers->ExceptionRecord;
*context_ptr = *epointers->ContextRecord;
if (!server_call_noerr( REQ_EXCEPTION_EVENT )) *epointers->ContextRecord = *context_ptr;
status = req->status;
}
SERVER_END_REQ;
switch (status)
{
case DBG_CONTINUE:
return EXCEPTION_CONTINUE_EXECUTION;
......@@ -91,7 +101,7 @@ DWORD WINAPI UnhandledExceptionFilter(PEXCEPTION_POINTERS epointers)
case 0: /* no debugger is present */
break;
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)
......
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