Commit 9caa71ee authored by Alexandre Julliard's avatar Alexandre Julliard

Redesign of the server communication protocol to allow arbitrary sized

data to be exchanged. Split request and reply structures to make backwards compatibility easier. Moved many console functions to dlls/kernel, added code page support, changed a few requests to behave properly with the new protocol.
parent 8c2e573f
...@@ -1220,14 +1220,14 @@ LONG WINAPI RegLoadKeyW( HKEY hkey, LPCWSTR subkey, LPCWSTR filename ) ...@@ -1220,14 +1220,14 @@ LONG WINAPI RegLoadKeyW( HKEY hkey, LPCWSTR subkey, LPCWSTR filename )
goto done; goto done;
} }
SERVER_START_VAR_REQ( load_registry, len ) SERVER_START_REQ( load_registry )
{ {
req->hkey = hkey; req->hkey = hkey;
req->file = file; req->file = file;
memcpy( server_data_ptr(req), subkey, len ); wine_server_add_data( req, subkey, len );
ret = RtlNtStatusToDosError( SERVER_CALL() ); ret = RtlNtStatusToDosError( wine_server_call(req) );
} }
SERVER_END_VAR_REQ; SERVER_END_REQ;
CloseHandle( file ); CloseHandle( file );
done: done:
...@@ -1241,6 +1241,7 @@ LONG WINAPI RegLoadKeyW( HKEY hkey, LPCWSTR subkey, LPCWSTR filename ) ...@@ -1241,6 +1241,7 @@ LONG WINAPI RegLoadKeyW( HKEY hkey, LPCWSTR subkey, LPCWSTR filename )
*/ */
LONG WINAPI RegLoadKeyA( HKEY hkey, LPCSTR subkey, LPCSTR filename ) LONG WINAPI RegLoadKeyA( HKEY hkey, LPCSTR subkey, LPCSTR filename )
{ {
WCHAR buffer[MAX_PATH];
HANDLE file; HANDLE file;
DWORD ret, len, err = GetLastError(); DWORD ret, len, err = GetLastError();
...@@ -1249,8 +1250,8 @@ LONG WINAPI RegLoadKeyA( HKEY hkey, LPCSTR subkey, LPCSTR filename ) ...@@ -1249,8 +1250,8 @@ LONG WINAPI RegLoadKeyA( HKEY hkey, LPCSTR subkey, LPCSTR filename )
if (!filename || !*filename) return ERROR_INVALID_PARAMETER; if (!filename || !*filename) return ERROR_INVALID_PARAMETER;
if (!subkey || !*subkey) return ERROR_INVALID_PARAMETER; if (!subkey || !*subkey) return ERROR_INVALID_PARAMETER;
len = MultiByteToWideChar( CP_ACP, 0, subkey, strlen(subkey), NULL, 0 ) * sizeof(WCHAR); if (!(len = MultiByteToWideChar( CP_ACP, 0, subkey, strlen(subkey), buffer, MAX_PATH )))
if (len > MAX_PATH*sizeof(WCHAR)) return ERROR_INVALID_PARAMETER; return ERROR_INVALID_PARAMETER;
if ((file = CreateFileA( filename, GENERIC_READ, 0, NULL, OPEN_EXISTING, if ((file = CreateFileA( filename, GENERIC_READ, 0, NULL, OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL, 0 )) == INVALID_HANDLE_VALUE) FILE_ATTRIBUTE_NORMAL, 0 )) == INVALID_HANDLE_VALUE)
...@@ -1259,15 +1260,14 @@ LONG WINAPI RegLoadKeyA( HKEY hkey, LPCSTR subkey, LPCSTR filename ) ...@@ -1259,15 +1260,14 @@ LONG WINAPI RegLoadKeyA( HKEY hkey, LPCSTR subkey, LPCSTR filename )
goto done; goto done;
} }
SERVER_START_VAR_REQ( load_registry, len ) SERVER_START_REQ( load_registry )
{ {
req->hkey = hkey; req->hkey = hkey;
req->file = file; req->file = file;
MultiByteToWideChar( CP_ACP, 0, subkey, strlen(subkey), wine_server_add_data( req, buffer, len * sizeof(WCHAR) );
server_data_ptr(req), len/sizeof(WCHAR) ); ret = RtlNtStatusToDosError( wine_server_call(req) );
ret = RtlNtStatusToDosError( SERVER_CALL() );
} }
SERVER_END_VAR_REQ; SERVER_END_REQ;
CloseHandle( file ); CloseHandle( file );
done: done:
...@@ -1315,7 +1315,7 @@ LONG WINAPI RegSaveKeyA( HKEY hkey, LPCSTR file, LPSECURITY_ATTRIBUTES sa ) ...@@ -1315,7 +1315,7 @@ LONG WINAPI RegSaveKeyA( HKEY hkey, LPCSTR file, LPSECURITY_ATTRIBUTES sa )
{ {
req->hkey = hkey; req->hkey = hkey;
req->file = handle; req->file = handle;
ret = RtlNtStatusToDosError( SERVER_CALL() ); ret = RtlNtStatusToDosError( wine_server_call( req ) );
} }
SERVER_END_REQ; SERVER_END_REQ;
......
...@@ -9,6 +9,7 @@ IMPORTS = ntdll ...@@ -9,6 +9,7 @@ IMPORTS = ntdll
C_SRCS = \ C_SRCS = \
comm.c \ comm.c \
console.c \
debugger.c \ debugger.c \
format_msg.c \ format_msg.c \
kernel_main.c \ kernel_main.c \
......
...@@ -379,7 +379,7 @@ static BOOL COMM_SetCommError(HANDLE handle, DWORD error) ...@@ -379,7 +379,7 @@ static BOOL COMM_SetCommError(HANDLE handle, DWORD error)
req->handle = handle; req->handle = handle;
req->flags = SERIALINFO_SET_ERROR; req->flags = SERIALINFO_SET_ERROR;
req->commerror = error; req->commerror = error;
ret = !SERVER_CALL_ERR(); ret = !wine_server_call_err( req );
} }
SERVER_END_REQ; SERVER_END_REQ;
return ret; return ret;
...@@ -395,8 +395,8 @@ static BOOL COMM_GetCommError(HANDLE handle, LPDWORD lperror) ...@@ -395,8 +395,8 @@ static BOOL COMM_GetCommError(HANDLE handle, LPDWORD lperror)
SERVER_START_REQ( get_serial_info ) SERVER_START_REQ( get_serial_info )
{ {
req->handle = handle; req->handle = handle;
ret = !SERVER_CALL_ERR(); ret = !wine_server_call_err( req );
*lperror = req->commerror; *lperror = reply->commerror;
} }
SERVER_END_REQ; SERVER_END_REQ;
...@@ -748,9 +748,9 @@ BOOL WINAPI GetCommMask( ...@@ -748,9 +748,9 @@ BOOL WINAPI GetCommMask(
SERVER_START_REQ( get_serial_info ) SERVER_START_REQ( get_serial_info )
{ {
req->handle = handle; req->handle = handle;
if ((ret = !SERVER_CALL_ERR())) if ((ret = !wine_server_call_err( req )))
{ {
if (evtmask) *evtmask = req->eventmask; if (evtmask) *evtmask = reply->eventmask;
} }
} }
SERVER_END_REQ; SERVER_END_REQ;
...@@ -781,7 +781,7 @@ BOOL WINAPI SetCommMask( ...@@ -781,7 +781,7 @@ BOOL WINAPI SetCommMask(
req->handle = handle; req->handle = handle;
req->flags = SERIALINFO_SET_MASK; req->flags = SERIALINFO_SET_MASK;
req->eventmask = evtmask; req->eventmask = evtmask;
ret = !SERVER_CALL_ERR(); ret = !wine_server_call_err( req );
} }
SERVER_END_REQ; SERVER_END_REQ;
return ret; return ret;
...@@ -1347,13 +1347,13 @@ BOOL WINAPI GetCommTimeouts( ...@@ -1347,13 +1347,13 @@ BOOL WINAPI GetCommTimeouts(
SERVER_START_REQ( get_serial_info ) SERVER_START_REQ( get_serial_info )
{ {
req->handle = hComm; req->handle = hComm;
if ((ret = !SERVER_CALL_ERR())) if ((ret = !wine_server_call_err( req )))
{ {
lptimeouts->ReadIntervalTimeout = req->readinterval; lptimeouts->ReadIntervalTimeout = reply->readinterval;
lptimeouts->ReadTotalTimeoutMultiplier = req->readmult; lptimeouts->ReadTotalTimeoutMultiplier = reply->readmult;
lptimeouts->ReadTotalTimeoutConstant = req->readconst; lptimeouts->ReadTotalTimeoutConstant = reply->readconst;
lptimeouts->WriteTotalTimeoutMultiplier = req->writemult; lptimeouts->WriteTotalTimeoutMultiplier = reply->writemult;
lptimeouts->WriteTotalTimeoutConstant = req->writeconst; lptimeouts->WriteTotalTimeoutConstant = reply->writeconst;
} }
} }
SERVER_END_REQ; SERVER_END_REQ;
...@@ -1401,7 +1401,7 @@ BOOL WINAPI SetCommTimeouts( ...@@ -1401,7 +1401,7 @@ BOOL WINAPI SetCommTimeouts(
req->readconst = lptimeouts->ReadTotalTimeoutConstant ; req->readconst = lptimeouts->ReadTotalTimeoutConstant ;
req->writemult = lptimeouts->WriteTotalTimeoutMultiplier ; req->writemult = lptimeouts->WriteTotalTimeoutMultiplier ;
req->writeconst = lptimeouts->WriteTotalTimeoutConstant ; req->writeconst = lptimeouts->WriteTotalTimeoutConstant ;
ret = !SERVER_CALL_ERR(); ret = !wine_server_call_err( req );
} }
SERVER_END_REQ; SERVER_END_REQ;
if (!ret) return FALSE; if (!ret) return FALSE;
...@@ -1562,7 +1562,7 @@ static BOOL COMM_WaitCommEvent( ...@@ -1562,7 +1562,7 @@ static BOOL COMM_WaitCommEvent(
req->count = 0; req->count = 0;
req->type = ASYNC_TYPE_WAIT; req->type = ASYNC_TYPE_WAIT;
ret=SERVER_CALL_ERR(); ret=wine_server_call_err( req );
} }
SERVER_END_REQ; SERVER_END_REQ;
......
...@@ -36,78 +36,78 @@ BOOL WINAPI WaitForDebugEvent( ...@@ -36,78 +36,78 @@ BOOL WINAPI WaitForDebugEvent(
for (;;) for (;;)
{ {
HANDLE wait = 0; HANDLE wait = 0;
debug_event_t *data; debug_event_t data;
SERVER_START_VAR_REQ( wait_debug_event, sizeof(*data) ) SERVER_START_REQ( wait_debug_event )
{ {
req->get_handle = (timeout != 0); req->get_handle = (timeout != 0);
if (!(ret = !SERVER_CALL_ERR())) goto done; wine_server_set_reply( req, &data, sizeof(data) );
if (!(ret = !wine_server_call_err( req ))) goto done;
if (!server_data_size(req)) /* timeout */ if (!wine_server_reply_size(reply)) /* timeout */
{ {
wait = req->wait; wait = reply->wait;
ret = FALSE; ret = FALSE;
goto done; goto done;
} }
data = server_data_ptr(req); event->dwDebugEventCode = data.code;
event->dwDebugEventCode = data->code; event->dwProcessId = (DWORD)reply->pid;
event->dwProcessId = (DWORD)req->pid; event->dwThreadId = (DWORD)reply->tid;
event->dwThreadId = (DWORD)req->tid; switch(data.code)
switch(data->code)
{ {
case EXCEPTION_DEBUG_EVENT: case EXCEPTION_DEBUG_EVENT:
event->u.Exception.ExceptionRecord = data->info.exception.record; event->u.Exception.ExceptionRecord = data.info.exception.record;
event->u.Exception.dwFirstChance = data->info.exception.first; event->u.Exception.dwFirstChance = data.info.exception.first;
break; break;
case CREATE_THREAD_DEBUG_EVENT: case CREATE_THREAD_DEBUG_EVENT:
event->u.CreateThread.hThread = data->info.create_thread.handle; event->u.CreateThread.hThread = data.info.create_thread.handle;
event->u.CreateThread.lpThreadLocalBase = data->info.create_thread.teb; event->u.CreateThread.lpThreadLocalBase = data.info.create_thread.teb;
event->u.CreateThread.lpStartAddress = data->info.create_thread.start; event->u.CreateThread.lpStartAddress = data.info.create_thread.start;
break; break;
case CREATE_PROCESS_DEBUG_EVENT: case CREATE_PROCESS_DEBUG_EVENT:
event->u.CreateProcessInfo.hFile = data->info.create_process.file; event->u.CreateProcessInfo.hFile = data.info.create_process.file;
event->u.CreateProcessInfo.hProcess = data->info.create_process.process; event->u.CreateProcessInfo.hProcess = data.info.create_process.process;
event->u.CreateProcessInfo.hThread = data->info.create_process.thread; event->u.CreateProcessInfo.hThread = data.info.create_process.thread;
event->u.CreateProcessInfo.lpBaseOfImage = data->info.create_process.base; event->u.CreateProcessInfo.lpBaseOfImage = data.info.create_process.base;
event->u.CreateProcessInfo.dwDebugInfoFileOffset = data->info.create_process.dbg_offset; event->u.CreateProcessInfo.dwDebugInfoFileOffset = data.info.create_process.dbg_offset;
event->u.CreateProcessInfo.nDebugInfoSize = data->info.create_process.dbg_size; event->u.CreateProcessInfo.nDebugInfoSize = data.info.create_process.dbg_size;
event->u.CreateProcessInfo.lpThreadLocalBase = data->info.create_process.teb; event->u.CreateProcessInfo.lpThreadLocalBase = data.info.create_process.teb;
event->u.CreateProcessInfo.lpStartAddress = data->info.create_process.start; event->u.CreateProcessInfo.lpStartAddress = data.info.create_process.start;
event->u.CreateProcessInfo.lpImageName = data->info.create_process.name; event->u.CreateProcessInfo.lpImageName = data.info.create_process.name;
event->u.CreateProcessInfo.fUnicode = data->info.create_process.unicode; event->u.CreateProcessInfo.fUnicode = data.info.create_process.unicode;
if (data->info.create_process.file == -1) event->u.CreateProcessInfo.hFile = 0; if (data.info.create_process.file == -1) event->u.CreateProcessInfo.hFile = 0;
break; break;
case EXIT_THREAD_DEBUG_EVENT: case EXIT_THREAD_DEBUG_EVENT:
event->u.ExitThread.dwExitCode = data->info.exit.exit_code; event->u.ExitThread.dwExitCode = data.info.exit.exit_code;
break; break;
case EXIT_PROCESS_DEBUG_EVENT: case EXIT_PROCESS_DEBUG_EVENT:
event->u.ExitProcess.dwExitCode = data->info.exit.exit_code; event->u.ExitProcess.dwExitCode = data.info.exit.exit_code;
break; break;
case LOAD_DLL_DEBUG_EVENT: case LOAD_DLL_DEBUG_EVENT:
event->u.LoadDll.hFile = data->info.load_dll.handle; event->u.LoadDll.hFile = data.info.load_dll.handle;
event->u.LoadDll.lpBaseOfDll = data->info.load_dll.base; event->u.LoadDll.lpBaseOfDll = data.info.load_dll.base;
event->u.LoadDll.dwDebugInfoFileOffset = data->info.load_dll.dbg_offset; event->u.LoadDll.dwDebugInfoFileOffset = data.info.load_dll.dbg_offset;
event->u.LoadDll.nDebugInfoSize = data->info.load_dll.dbg_size; event->u.LoadDll.nDebugInfoSize = data.info.load_dll.dbg_size;
event->u.LoadDll.lpImageName = data->info.load_dll.name; event->u.LoadDll.lpImageName = data.info.load_dll.name;
event->u.LoadDll.fUnicode = data->info.load_dll.unicode; event->u.LoadDll.fUnicode = data.info.load_dll.unicode;
if (data->info.load_dll.handle == -1) event->u.LoadDll.hFile = 0; if (data.info.load_dll.handle == -1) event->u.LoadDll.hFile = 0;
break; break;
case UNLOAD_DLL_DEBUG_EVENT: case UNLOAD_DLL_DEBUG_EVENT:
event->u.UnloadDll.lpBaseOfDll = data->info.unload_dll.base; event->u.UnloadDll.lpBaseOfDll = data.info.unload_dll.base;
break; break;
case OUTPUT_DEBUG_STRING_EVENT: case OUTPUT_DEBUG_STRING_EVENT:
event->u.DebugString.lpDebugStringData = data->info.output_string.string; event->u.DebugString.lpDebugStringData = data.info.output_string.string;
event->u.DebugString.fUnicode = data->info.output_string.unicode; event->u.DebugString.fUnicode = data.info.output_string.unicode;
event->u.DebugString.nDebugStringLength = data->info.output_string.length; event->u.DebugString.nDebugStringLength = data.info.output_string.length;
break; break;
case RIP_EVENT: case RIP_EVENT:
event->u.RipInfo.dwError = data->info.rip_info.error; event->u.RipInfo.dwError = data.info.rip_info.error;
event->u.RipInfo.dwType = data->info.rip_info.type; event->u.RipInfo.dwType = data.info.rip_info.type;
break; break;
} }
done: done:
/* nothing */ ; /* nothing */ ;
} }
SERVER_END_VAR_REQ; SERVER_END_REQ;
if (ret) return TRUE; if (ret) return TRUE;
if (!wait) break; if (!wait) break;
res = WaitForSingleObject( wait, timeout ); res = WaitForSingleObject( wait, timeout );
...@@ -140,7 +140,7 @@ BOOL WINAPI ContinueDebugEvent( ...@@ -140,7 +140,7 @@ BOOL WINAPI ContinueDebugEvent(
req->pid = (void *)pid; req->pid = (void *)pid;
req->tid = (void *)tid; req->tid = (void *)tid;
req->status = status; req->status = status;
ret = !SERVER_CALL_ERR(); ret = !wine_server_call_err( req );
} }
SERVER_END_REQ; SERVER_END_REQ;
return ret; return ret;
...@@ -163,7 +163,7 @@ BOOL WINAPI DebugActiveProcess( ...@@ -163,7 +163,7 @@ BOOL WINAPI DebugActiveProcess(
SERVER_START_REQ( debug_process ) SERVER_START_REQ( debug_process )
{ {
req->pid = (void *)pid; req->pid = (void *)pid;
ret = !SERVER_CALL_ERR(); ret = !wine_server_call_err( req );
} }
SERVER_END_REQ; SERVER_END_REQ;
return ret; return ret;
...@@ -184,7 +184,7 @@ void WINAPI OutputDebugStringA( ...@@ -184,7 +184,7 @@ void WINAPI OutputDebugStringA(
req->string = (void *)str; req->string = (void *)str;
req->unicode = 0; req->unicode = 0;
req->length = strlen(str) + 1; req->length = strlen(str) + 1;
SERVER_CALL(); wine_server_call( req );
} }
SERVER_END_REQ; SERVER_END_REQ;
WARN("%s\n", str); WARN("%s\n", str);
...@@ -205,7 +205,7 @@ void WINAPI OutputDebugStringW( ...@@ -205,7 +205,7 @@ void WINAPI OutputDebugStringW(
req->string = (void *)str; req->string = (void *)str;
req->unicode = 1; req->unicode = 1;
req->length = (lstrlenW(str) + 1) * sizeof(WCHAR); req->length = (lstrlenW(str) + 1) * sizeof(WCHAR);
SERVER_CALL(); wine_server_call( req );
} }
SERVER_END_REQ; SERVER_END_REQ;
WARN("%s\n", debugstr_w(str)); WARN("%s\n", debugstr_w(str));
...@@ -278,7 +278,7 @@ BOOL WINAPI IsDebuggerPresent(void) ...@@ -278,7 +278,7 @@ BOOL WINAPI IsDebuggerPresent(void)
SERVER_START_REQ( get_process_info ) SERVER_START_REQ( get_process_info )
{ {
req->handle = GetCurrentProcess(); req->handle = GetCurrentProcess();
if (!SERVER_CALL_ERR()) ret = req->debugged; if (!wine_server_call_err( req )) ret = reply->debugged;
} }
SERVER_END_REQ; SERVER_END_REQ;
return ret; return ret;
......
...@@ -206,8 +206,8 @@ HANDLE WINAPI CreateToolhelp32Snapshot( DWORD flags, DWORD process ) ...@@ -206,8 +206,8 @@ HANDLE WINAPI CreateToolhelp32Snapshot( DWORD flags, DWORD process )
req->flags = flags & ~TH32CS_INHERIT; req->flags = flags & ~TH32CS_INHERIT;
req->inherit = (flags & TH32CS_INHERIT) != 0; req->inherit = (flags & TH32CS_INHERIT) != 0;
req->pid = (void *)process; req->pid = (void *)process;
SERVER_CALL_ERR(); wine_server_call_err( req );
ret = req->handle; ret = reply->handle;
} }
SERVER_END_REQ; SERVER_END_REQ;
if (!ret) ret = INVALID_HANDLE_VALUE; if (!ret) ret = INVALID_HANDLE_VALUE;
...@@ -234,13 +234,13 @@ static BOOL TOOLHELP_Thread32Next( HANDLE handle, LPTHREADENTRY32 lpte, BOOL fir ...@@ -234,13 +234,13 @@ static BOOL TOOLHELP_Thread32Next( HANDLE handle, LPTHREADENTRY32 lpte, BOOL fir
{ {
req->handle = handle; req->handle = handle;
req->reset = first; req->reset = first;
if ((ret = !SERVER_CALL_ERR())) if ((ret = !wine_server_call_err( req )))
{ {
lpte->cntUsage = req->count; lpte->cntUsage = reply->count;
lpte->th32ThreadID = (DWORD)req->tid; lpte->th32ThreadID = (DWORD)reply->tid;
lpte->th32OwnerProcessID = (DWORD)req->pid; lpte->th32OwnerProcessID = (DWORD)reply->pid;
lpte->tpBasePri = req->base_pri; lpte->tpBasePri = reply->base_pri;
lpte->tpDeltaPri = req->delta_pri; lpte->tpDeltaPri = reply->delta_pri;
lpte->dwFlags = 0; /* SDK: "reserved; do not use" */ lpte->dwFlags = 0; /* SDK: "reserved; do not use" */
} }
} }
...@@ -287,15 +287,15 @@ static BOOL TOOLHELP_Process32Next( HANDLE handle, LPPROCESSENTRY32 lppe, BOOL f ...@@ -287,15 +287,15 @@ static BOOL TOOLHELP_Process32Next( HANDLE handle, LPPROCESSENTRY32 lppe, BOOL f
{ {
req->handle = handle; req->handle = handle;
req->reset = first; req->reset = first;
if ((ret = !SERVER_CALL_ERR())) if ((ret = !wine_server_call_err( req )))
{ {
lppe->cntUsage = req->count; lppe->cntUsage = reply->count;
lppe->th32ProcessID = (DWORD)req->pid; lppe->th32ProcessID = (DWORD)reply->pid;
lppe->th32DefaultHeapID = 0; /* FIXME */ lppe->th32DefaultHeapID = 0; /* FIXME */
lppe->th32ModuleID = 0; /* FIXME */ lppe->th32ModuleID = 0; /* FIXME */
lppe->cntThreads = req->threads; lppe->cntThreads = reply->threads;
lppe->th32ParentProcessID = 0; /* FIXME */ lppe->th32ParentProcessID = 0; /* FIXME */
lppe->pcPriClassBase = req->priority; lppe->pcPriClassBase = reply->priority;
lppe->dwFlags = -1; /* FIXME */ lppe->dwFlags = -1; /* FIXME */
lppe->szExeFile[0] = 0; /* FIXME */ lppe->szExeFile[0] = 0; /* FIXME */
} }
...@@ -345,15 +345,15 @@ static BOOL TOOLHELP_Module32Next( HANDLE handle, LPMODULEENTRY32 lpme, BOOL fir ...@@ -345,15 +345,15 @@ static BOOL TOOLHELP_Module32Next( HANDLE handle, LPMODULEENTRY32 lpme, BOOL fir
{ {
req->handle = handle; req->handle = handle;
req->reset = first; req->reset = first;
if ((ret = !SERVER_CALL_ERR())) if ((ret = !wine_server_call_err( req )))
{ {
lpme->th32ModuleID = 0; /* toolhelp internal id, never used */ lpme->th32ModuleID = 0; /* toolhelp internal id, never used */
lpme->th32ProcessID = (DWORD)req->pid; lpme->th32ProcessID = (DWORD)reply->pid;
lpme->GlblcntUsage = 0; /* FIXME */ lpme->GlblcntUsage = 0; /* FIXME */
lpme->ProccntUsage = 0; /* FIXME */ lpme->ProccntUsage = 0; /* FIXME */
lpme->modBaseAddr = req->base; lpme->modBaseAddr = reply->base;
lpme->modBaseSize = 0; /* FIXME */ lpme->modBaseSize = 0; /* FIXME */
lpme->hModule = (DWORD)req->base; lpme->hModule = (DWORD)reply->base;
lpme->szModule[0] = 0; /* FIXME */ lpme->szModule[0] = 0; /* FIXME */
lpme->szExePath[0] = 0; /* FIXME */ lpme->szExePath[0] = 0; /* FIXME */
} }
......
...@@ -115,29 +115,28 @@ static int send_debug_event( EXCEPTION_RECORD *rec, int first_chance, CONTEXT *c ...@@ -115,29 +115,28 @@ static int send_debug_event( EXCEPTION_RECORD *rec, int first_chance, CONTEXT *c
int ret; int ret;
HANDLE handle = 0; HANDLE handle = 0;
SERVER_START_VAR_REQ( queue_exception_event, sizeof(*rec)+sizeof(*context) ) SERVER_START_REQ( queue_exception_event )
{ {
CONTEXT *context_ptr = server_data_ptr(req);
EXCEPTION_RECORD *rec_ptr = (EXCEPTION_RECORD *)(context_ptr + 1);
req->first = first_chance; req->first = first_chance;
*rec_ptr = *rec; wine_server_add_data( req, context, sizeof(*context) );
*context_ptr = *context; wine_server_add_data( req, rec, sizeof(*rec) );
if (!SERVER_CALL()) handle = req->handle; if (!wine_server_call( req )) handle = reply->handle;
} }
SERVER_END_VAR_REQ; SERVER_END_REQ;
if (!handle) return 0; /* no debugger present or other error */ if (!handle) return 0; /* no debugger present or other error */
/* No need to wait on the handle since the process gets suspended /* No need to wait on the handle since the process gets suspended
* once the event is passed to the debugger, so when we get back * once the event is passed to the debugger, so when we get back
* here the event has been continued already. * here the event has been continued already.
*/ */
SERVER_START_VAR_REQ( get_exception_status, sizeof(*context) ) SERVER_START_REQ( get_exception_status )
{ {
req->handle = handle; req->handle = handle;
if (!SERVER_CALL()) *context = *(CONTEXT *)server_data_ptr(req); wine_server_set_reply( req, context, sizeof(*context) );
ret = req->status; wine_server_call( req );
ret = reply->status;
} }
SERVER_END_VAR_REQ; SERVER_END_REQ;
NtClose( handle ); NtClose( handle );
return ret; return ret;
} }
......
...@@ -82,8 +82,8 @@ NTSTATUS WINAPI NtTerminateProcess( HANDLE handle, LONG exit_code ) ...@@ -82,8 +82,8 @@ NTSTATUS WINAPI NtTerminateProcess( HANDLE handle, LONG exit_code )
{ {
req->handle = handle; req->handle = handle;
req->exit_code = exit_code; req->exit_code = exit_code;
ret = SERVER_CALL(); ret = wine_server_call( req );
self = !ret && req->self; self = !ret && reply->self;
} }
SERVER_END_REQ; SERVER_END_REQ;
if (self) exit( exit_code ); if (self) exit( exit_code );
...@@ -159,9 +159,9 @@ NTSTATUS WINAPI NtTerminateThread( HANDLE handle, LONG exit_code ) ...@@ -159,9 +159,9 @@ NTSTATUS WINAPI NtTerminateThread( HANDLE handle, LONG exit_code )
{ {
req->handle = handle; req->handle = handle;
req->exit_code = exit_code; req->exit_code = exit_code;
ret = SERVER_CALL(); ret = wine_server_call( req );
self = !ret && req->self; self = !ret && reply->self;
last = req->last; last = reply->last;
} }
SERVER_END_REQ; SERVER_END_REQ;
......
...@@ -1033,6 +1033,4 @@ debug_channels (aspi atom cdrom console ddraw debug delayhlp dll dosfs dosmem ...@@ -1033,6 +1033,4 @@ debug_channels (aspi atom cdrom console ddraw debug delayhlp dll dosfs dosmem
@ cdecl __wine_get_wmain_args(ptr) __wine_get_wmain_args @ cdecl __wine_get_wmain_args(ptr) __wine_get_wmain_args
# Server interface # Server interface
@ cdecl -norelay wine_server_call(ptr long) wine_server_call @ cdecl -norelay wine_server_call(ptr) wine_server_call
@ cdecl -norelay wine_server_alloc_req(ptr long) wine_server_alloc_req
@ cdecl -norelay __wine_server_exception_handler(ptr ptr ptr ptr) __wine_server_exception_handler
...@@ -222,8 +222,8 @@ NTSTATUS WINAPI NtClose( HANDLE Handle ) ...@@ -222,8 +222,8 @@ NTSTATUS WINAPI NtClose( HANDLE Handle )
SERVER_START_REQ( close_handle ) SERVER_START_REQ( close_handle )
{ {
req->handle = Handle; req->handle = Handle;
ret = SERVER_CALL(); ret = wine_server_call( req );
if (!ret && req->fd != -1) close( req->fd ); if (!ret && reply->fd != -1) close( reply->fd );
} }
SERVER_END_REQ; SERVER_END_REQ;
return ret; return ret;
......
...@@ -36,16 +36,16 @@ NTSTATUS WINAPI NtCreateSemaphore( OUT PHANDLE SemaphoreHandle, ...@@ -36,16 +36,16 @@ NTSTATUS WINAPI NtCreateSemaphore( OUT PHANDLE SemaphoreHandle,
if ((MaximumCount <= 0) || (InitialCount > MaximumCount)) if ((MaximumCount <= 0) || (InitialCount > MaximumCount))
return STATUS_INVALID_PARAMETER; return STATUS_INVALID_PARAMETER;
SERVER_START_VAR_REQ( create_semaphore, len ) SERVER_START_REQ( create_semaphore )
{ {
req->initial = InitialCount; req->initial = InitialCount;
req->max = MaximumCount; req->max = MaximumCount;
req->inherit = attr && (attr->Attributes & OBJ_INHERIT); req->inherit = attr && (attr->Attributes & OBJ_INHERIT);
if (len) memcpy( server_data_ptr(req), attr->ObjectName->Buffer, len ); if (len) wine_server_add_data( req, attr->ObjectName->Buffer, len );
ret = SERVER_CALL(); ret = wine_server_call( req );
*SemaphoreHandle = req->handle; *SemaphoreHandle = reply->handle;
} }
SERVER_END_VAR_REQ; SERVER_END_REQ;
return ret; return ret;
} }
...@@ -59,15 +59,15 @@ NTSTATUS WINAPI NtOpenSemaphore( OUT PHANDLE SemaphoreHandle, ...@@ -59,15 +59,15 @@ NTSTATUS WINAPI NtOpenSemaphore( OUT PHANDLE SemaphoreHandle,
DWORD len = attr && attr->ObjectName ? attr->ObjectName->Length : 0; DWORD len = attr && attr->ObjectName ? attr->ObjectName->Length : 0;
NTSTATUS ret; NTSTATUS ret;
SERVER_START_VAR_REQ( open_semaphore, len ) SERVER_START_REQ( open_semaphore )
{ {
req->access = access; req->access = access;
req->inherit = attr && (attr->Attributes & OBJ_INHERIT); req->inherit = attr && (attr->Attributes & OBJ_INHERIT);
if (len) memcpy( server_data_ptr(req), attr->ObjectName->Buffer, len ); if (len) wine_server_add_data( req, attr->ObjectName->Buffer, len );
ret = SERVER_CALL(); ret = wine_server_call( req );
*SemaphoreHandle = req->handle; *SemaphoreHandle = reply->handle;
} }
SERVER_END_VAR_REQ; SERVER_END_REQ;
return ret; return ret;
} }
...@@ -96,9 +96,9 @@ NTSTATUS WINAPI NtReleaseSemaphore( HANDLE handle, ULONG count, PULONG previous ...@@ -96,9 +96,9 @@ NTSTATUS WINAPI NtReleaseSemaphore( HANDLE handle, ULONG count, PULONG previous
{ {
req->handle = handle; req->handle = handle;
req->count = count; req->count = count;
if (!(ret = SERVER_CALL())) if (!(ret = wine_server_call( req )))
{ {
if (previous) *previous = req->prev_count; if (previous) *previous = reply->prev_count;
} }
} }
SERVER_END_REQ; SERVER_END_REQ;
...@@ -123,16 +123,16 @@ NTSTATUS WINAPI NtCreateEvent( ...@@ -123,16 +123,16 @@ NTSTATUS WINAPI NtCreateEvent(
DWORD len = attr && attr->ObjectName ? attr->ObjectName->Length : 0; DWORD len = attr && attr->ObjectName ? attr->ObjectName->Length : 0;
NTSTATUS ret; NTSTATUS ret;
SERVER_START_VAR_REQ( create_event, len ) SERVER_START_REQ( create_event )
{ {
req->manual_reset = ManualReset; req->manual_reset = ManualReset;
req->initial_state = InitialState; req->initial_state = InitialState;
req->inherit = attr && (attr->Attributes & OBJ_INHERIT); req->inherit = attr && (attr->Attributes & OBJ_INHERIT);
if (len) memcpy( server_data_ptr(req), attr->ObjectName->Buffer, len ); if (len) wine_server_add_data( req, attr->ObjectName->Buffer, len );
ret = SERVER_CALL(); ret = wine_server_call( req );
*EventHandle = req->handle; *EventHandle = reply->handle;
} }
SERVER_END_VAR_REQ; SERVER_END_REQ;
return ret; return ret;
} }
...@@ -148,15 +148,15 @@ NTSTATUS WINAPI NtOpenEvent( ...@@ -148,15 +148,15 @@ NTSTATUS WINAPI NtOpenEvent(
DWORD len = attr && attr->ObjectName ? attr->ObjectName->Length : 0; DWORD len = attr && attr->ObjectName ? attr->ObjectName->Length : 0;
NTSTATUS ret; NTSTATUS ret;
SERVER_START_VAR_REQ( open_event, len ) SERVER_START_REQ( open_event )
{ {
req->access = DesiredAccess; req->access = DesiredAccess;
req->inherit = attr && (attr->Attributes & OBJ_INHERIT); req->inherit = attr && (attr->Attributes & OBJ_INHERIT);
if (len) memcpy( server_data_ptr(req), attr->ObjectName->Buffer, len ); if (len) wine_server_add_data( req, attr->ObjectName->Buffer, len );
ret = SERVER_CALL(); ret = wine_server_call( req );
*EventHandle = req->handle; *EventHandle = reply->handle;
} }
SERVER_END_VAR_REQ; SERVER_END_REQ;
return ret; return ret;
} }
...@@ -175,7 +175,7 @@ NTSTATUS WINAPI NtSetEvent( HANDLE handle, PULONG NumberOfThreadsReleased ) ...@@ -175,7 +175,7 @@ NTSTATUS WINAPI NtSetEvent( HANDLE handle, PULONG NumberOfThreadsReleased )
{ {
req->handle = handle; req->handle = handle;
req->op = SET_EVENT; req->op = SET_EVENT;
ret = SERVER_CALL(); ret = wine_server_call( req );
} }
SERVER_END_REQ; SERVER_END_REQ;
return ret; return ret;
...@@ -195,7 +195,7 @@ NTSTATUS WINAPI NtResetEvent( HANDLE handle, PULONG NumberOfThreadsReleased ) ...@@ -195,7 +195,7 @@ NTSTATUS WINAPI NtResetEvent( HANDLE handle, PULONG NumberOfThreadsReleased )
{ {
req->handle = handle; req->handle = handle;
req->op = RESET_EVENT; req->op = RESET_EVENT;
ret = SERVER_CALL(); ret = wine_server_call( req );
} }
SERVER_END_REQ; SERVER_END_REQ;
return ret; return ret;
...@@ -226,7 +226,7 @@ NTSTATUS WINAPI NtPulseEvent( HANDLE handle, PULONG PulseCount ) ...@@ -226,7 +226,7 @@ NTSTATUS WINAPI NtPulseEvent( HANDLE handle, PULONG PulseCount )
{ {
req->handle = handle; req->handle = handle;
req->op = PULSE_EVENT; req->op = PULSE_EVENT;
ret = SERVER_CALL(); ret = wine_server_call( req );
} }
SERVER_END_REQ; SERVER_END_REQ;
return ret; return ret;
......
...@@ -24,24 +24,30 @@ ...@@ -24,24 +24,30 @@
*/ */
static property_data_t *get_properties( HWND hwnd, int *count ) static property_data_t *get_properties( HWND hwnd, int *count )
{ {
property_data_t *ret = NULL; property_data_t *data;
int total = 32;
SERVER_START_VAR_REQ( get_window_properties, REQUEST_MAX_VAR_SIZE ) while (total)
{ {
req->window = hwnd; int res = 0;
if (!SERVER_CALL()) if (!(data = HeapAlloc( GetProcessHeap(), 0, total * sizeof(*data) ))) break;
*count = 0;
SERVER_START_REQ( get_window_properties )
{ {
size_t size = server_data_size(req); req->window = hwnd;
if (size) wine_server_add_data( req, data, total * sizeof(*data) );
{ if (!wine_server_call( req )) res = reply->total;
property_data_t *data = server_data_ptr(req);
if ((ret = HeapAlloc( GetProcessHeap(), 0, size ))) memcpy( ret, data, size );
*count = size / sizeof(*data);
}
} }
SERVER_END_REQ;
if (res && res <= total)
{
*count = res;
return data;
}
HeapFree( GetProcessHeap(), 0, data );
total = res; /* restart with larger buffer */
} }
SERVER_END_VAR_REQ; return NULL;
return ret;
} }
...@@ -102,7 +108,7 @@ HANDLE WINAPI GetPropA( HWND hwnd, LPCSTR str ) ...@@ -102,7 +108,7 @@ HANDLE WINAPI GetPropA( HWND hwnd, LPCSTR str )
{ {
req->window = hwnd; req->window = hwnd;
req->atom = atom; req->atom = atom;
if (!SERVER_CALL_ERR()) ret = req->handle; if (!wine_server_call_err( req )) ret = reply->handle;
} }
SERVER_END_REQ; SERVER_END_REQ;
return ret; return ret;
...@@ -124,7 +130,7 @@ HANDLE WINAPI GetPropW( HWND hwnd, LPCWSTR str ) ...@@ -124,7 +130,7 @@ HANDLE WINAPI GetPropW( HWND hwnd, LPCWSTR str )
{ {
req->window = hwnd; req->window = hwnd;
req->atom = atom; req->atom = atom;
if (!SERVER_CALL_ERR()) ret = req->handle; if (!wine_server_call_err( req )) ret = reply->handle;
} }
SERVER_END_REQ; SERVER_END_REQ;
return ret; return ret;
...@@ -148,7 +154,7 @@ BOOL WINAPI SetPropA( HWND hwnd, LPCSTR str, HANDLE handle ) ...@@ -148,7 +154,7 @@ BOOL WINAPI SetPropA( HWND hwnd, LPCSTR str, HANDLE handle )
req->atom = atom; req->atom = atom;
req->string = (HIWORD(str) != 0); req->string = (HIWORD(str) != 0);
req->handle = handle; req->handle = handle;
ret = !SERVER_CALL_ERR(); ret = !wine_server_call_err( req );
} }
SERVER_END_REQ; SERVER_END_REQ;
...@@ -174,7 +180,7 @@ BOOL WINAPI SetPropW( HWND hwnd, LPCWSTR str, HANDLE handle ) ...@@ -174,7 +180,7 @@ BOOL WINAPI SetPropW( HWND hwnd, LPCWSTR str, HANDLE handle )
req->atom = atom; req->atom = atom;
req->string = (HIWORD(str) != 0); req->string = (HIWORD(str) != 0);
req->handle = handle; req->handle = handle;
ret = !SERVER_CALL_ERR(); ret = !wine_server_call_err( req );
} }
SERVER_END_REQ; SERVER_END_REQ;
...@@ -217,7 +223,7 @@ HANDLE WINAPI RemovePropW( HWND hwnd, LPCWSTR str ) ...@@ -217,7 +223,7 @@ HANDLE WINAPI RemovePropW( HWND hwnd, LPCWSTR str )
{ {
req->window = hwnd; req->window = hwnd;
req->atom = atom; req->atom = atom;
if (!SERVER_CALL_ERR()) ret = req->handle; if (!wine_server_call_err( req )) ret = reply->handle;
} }
SERVER_END_REQ; SERVER_END_REQ;
......
...@@ -233,7 +233,7 @@ static void _enable_event(SOCKET s, unsigned int event, ...@@ -233,7 +233,7 @@ static void _enable_event(SOCKET s, unsigned int event,
req->mask = event; req->mask = event;
req->sstate = sstate; req->sstate = sstate;
req->cstate = cstate; req->cstate = cstate;
SERVER_CALL(); wine_server_call( req );
} }
SERVER_END_REQ; SERVER_END_REQ;
} }
...@@ -247,8 +247,8 @@ static int _is_blocking(SOCKET s) ...@@ -247,8 +247,8 @@ static int _is_blocking(SOCKET s)
req->service = FALSE; req->service = FALSE;
req->s_event = 0; req->s_event = 0;
req->c_event = 0; req->c_event = 0;
SERVER_CALL(); wine_server_call( req );
ret = (req->state & FD_WINE_NONBLOCKING) == 0; ret = (reply->state & FD_WINE_NONBLOCKING) == 0;
} }
SERVER_END_REQ; SERVER_END_REQ;
return ret; return ret;
...@@ -263,8 +263,8 @@ static unsigned int _get_sock_mask(SOCKET s) ...@@ -263,8 +263,8 @@ static unsigned int _get_sock_mask(SOCKET s)
req->service = FALSE; req->service = FALSE;
req->s_event = 0; req->s_event = 0;
req->c_event = 0; req->c_event = 0;
SERVER_CALL(); wine_server_call( req );
ret = req->mask; ret = reply->mask;
} }
SERVER_END_REQ; SERVER_END_REQ;
return ret; return ret;
...@@ -279,18 +279,19 @@ static void _sync_sock_state(SOCKET s) ...@@ -279,18 +279,19 @@ 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)
{ {
int ret; int events[FD_MAX_EVENTS];
SERVER_START_VAR_REQ( get_socket_event, FD_MAX_EVENTS*sizeof(int) )
SERVER_START_REQ( get_socket_event )
{ {
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;
SERVER_CALL(); wine_server_set_reply( req, events, sizeof(events) );
ret = *((int *)server_data_ptr(req) + bit); wine_server_call( req );
} }
SERVER_END_VAR_REQ; SERVER_END_REQ;
return ret; return events[bit];
} }
static void WINSOCK_DeleteIData(void) static void WINSOCK_DeleteIData(void)
...@@ -900,8 +901,8 @@ SOCKET WINAPI WS_accept(SOCKET s, struct WS_sockaddr *addr, ...@@ -900,8 +901,8 @@ SOCKET WINAPI WS_accept(SOCKET s, struct WS_sockaddr *addr,
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;
set_error( SERVER_CALL() ); set_error( wine_server_call( req ) );
as = (SOCKET)req->handle; as = (SOCKET)reply->handle;
} }
SERVER_END_REQ; SERVER_END_REQ;
if (as) if (as)
...@@ -2318,8 +2319,8 @@ SOCKET WINAPI WS_socket(int af, int type, int protocol) ...@@ -2318,8 +2319,8 @@ SOCKET WINAPI WS_socket(int af, int type, int protocol)
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;
set_error( SERVER_CALL() ); set_error( wine_server_call( req ) );
ret = (SOCKET)req->handle; ret = (SOCKET)reply->handle;
} }
SERVER_END_REQ; SERVER_END_REQ;
if (ret) if (ret)
...@@ -2718,19 +2719,16 @@ int WINAPI WSAEnumNetworkEvents(SOCKET s, WSAEVENT hEvent, LPWSANETWORKEVENTS lp ...@@ -2718,19 +2719,16 @@ int WINAPI WSAEnumNetworkEvents(SOCKET s, WSAEVENT hEvent, LPWSANETWORKEVENTS lp
TRACE("%08x, hEvent %08x, lpEvent %08x\n", s, hEvent, (unsigned)lpEvent ); TRACE("%08x, hEvent %08x, lpEvent %08x\n", s, hEvent, (unsigned)lpEvent );
SERVER_START_VAR_REQ( get_socket_event, sizeof(lpEvent->iErrorCode) ) SERVER_START_REQ( get_socket_event )
{ {
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;
if (!(ret = SERVER_CALL())) wine_server_set_reply( req, lpEvent->iErrorCode, sizeof(lpEvent->iErrorCode) );
{ if (!(ret = wine_server_call(req))) lpEvent->lNetworkEvents = reply->pmask & reply->mask;
lpEvent->lNetworkEvents = req->pmask & req->mask;
memcpy(lpEvent->iErrorCode, server_data_ptr(req), server_data_size(req) );
}
} }
SERVER_END_VAR_REQ; SERVER_END_REQ;
if (!ret) return 0; if (!ret) return 0;
SetLastError(WSAEINVAL); SetLastError(WSAEINVAL);
return SOCKET_ERROR; return SOCKET_ERROR;
...@@ -2750,7 +2748,7 @@ int WINAPI WSAEventSelect(SOCKET s, WSAEVENT hEvent, LONG lEvent) ...@@ -2750,7 +2748,7 @@ int WINAPI WSAEventSelect(SOCKET s, WSAEVENT hEvent, LONG lEvent)
req->handle = s; req->handle = s;
req->mask = lEvent; req->mask = lEvent;
req->event = hEvent; req->event = hEvent;
ret = SERVER_CALL(); ret = wine_server_call( req );
} }
SERVER_END_REQ; SERVER_END_REQ;
if (!ret) return 0; if (!ret) return 0;
...@@ -2769,17 +2767,17 @@ VOID CALLBACK WINSOCK_DoAsyncEvent( ULONG_PTR ptr ) ...@@ -2769,17 +2767,17 @@ VOID CALLBACK WINSOCK_DoAsyncEvent( ULONG_PTR ptr )
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_VAR_REQ( get_socket_event, sizeof(errors) ) SERVER_START_REQ( get_socket_event )
{ {
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;
set_error( SERVER_CALL() ); wine_server_set_reply( req, errors, sizeof(errors) );
pmask = req->pmask; set_error( wine_server_call(req) );
memcpy( errors, server_data_ptr(req), server_data_size(req) ); pmask = reply->pmask;
} }
SERVER_END_VAR_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) */
......
...@@ -36,7 +36,7 @@ HANDLE WINAPI FindFirstChangeNotificationA( LPCSTR lpPathName, BOOL bWatchSubtre ...@@ -36,7 +36,7 @@ HANDLE WINAPI FindFirstChangeNotificationA( LPCSTR lpPathName, BOOL bWatchSubtre
{ {
req->subtree = bWatchSubtree; req->subtree = bWatchSubtree;
req->filter = dwNotifyFilter; req->filter = dwNotifyFilter;
if (!SERVER_CALL_ERR()) ret = req->handle; if (!wine_server_call_err( req )) ret = reply->handle;
} }
SERVER_END_REQ; SERVER_END_REQ;
return ret; return ret;
......
...@@ -690,11 +690,11 @@ const DOS_DEVICE *DOSFS_GetDeviceByHandle( HFILE hFile ) ...@@ -690,11 +690,11 @@ const DOS_DEVICE *DOSFS_GetDeviceByHandle( HFILE hFile )
SERVER_START_REQ( get_file_info ) SERVER_START_REQ( get_file_info )
{ {
req->handle = hFile; req->handle = hFile;
if (!SERVER_CALL() && (req->type == FILE_TYPE_UNKNOWN)) if (!wine_server_call( req ) && (reply->type == FILE_TYPE_UNKNOWN))
{ {
if ((req->attr >= 0) && if ((reply->attr >= 0) &&
(req->attr < sizeof(DOSFS_Devices)/sizeof(DOSFS_Devices[0]))) (reply->attr < sizeof(DOSFS_Devices)/sizeof(DOSFS_Devices[0])))
ret = &DOSFS_Devices[req->attr]; ret = &DOSFS_Devices[reply->attr];
} }
} }
SERVER_END_REQ; SERVER_END_REQ;
...@@ -709,7 +709,6 @@ static HANDLE DOSFS_CreateCommPort(LPCSTR name, DWORD access, DWORD attributes, ...@@ -709,7 +709,6 @@ static HANDLE DOSFS_CreateCommPort(LPCSTR name, DWORD access, DWORD attributes,
{ {
HANDLE ret; HANDLE ret;
char devname[40]; char devname[40];
size_t len;
TRACE_(file)("%s %lx %lx\n", name, access, attributes); TRACE_(file)("%s %lx %lx\n", name, access, attributes);
...@@ -719,19 +718,18 @@ static HANDLE DOSFS_CreateCommPort(LPCSTR name, DWORD access, DWORD attributes, ...@@ -719,19 +718,18 @@ static HANDLE DOSFS_CreateCommPort(LPCSTR name, DWORD access, DWORD attributes,
TRACE("opening %s as %s\n", devname, name); TRACE("opening %s as %s\n", devname, name);
len = strlen(devname); SERVER_START_REQ( create_serial )
SERVER_START_VAR_REQ( create_serial, 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->attributes = attributes; req->attributes = attributes;
req->sharing = FILE_SHARE_READ|FILE_SHARE_WRITE; req->sharing = FILE_SHARE_READ|FILE_SHARE_WRITE;
memcpy( server_data_ptr(req), devname, len ); wine_server_add_data( req, devname, strlen(devname) );
SetLastError(0); SetLastError(0);
SERVER_CALL_ERR(); wine_server_call_err( req );
ret = req->handle; ret = reply->handle;
} }
SERVER_END_VAR_REQ; SERVER_END_REQ;
if(!ret) if(!ret)
ERR("Couldn't open device '%s' ! (check permissions)\n",devname); ERR("Couldn't open device '%s' ! (check permissions)\n",devname);
......
...@@ -90,9 +90,7 @@ typedef struct _TEB ...@@ -90,9 +90,7 @@ typedef struct _TEB
/* The following are Wine-specific fields (NT: GDI stuff) */ /* The following are Wine-specific fields (NT: GDI stuff) */
DWORD cleanup; /* --3 1fc Cleanup service handle */ DWORD cleanup; /* --3 1fc Cleanup service handle */
void *buffer; /* --3 200 Buffer shared with server */ DWORD unused[3]; /* --3 200 Was server buffer */
unsigned int buffer_pos; /* --3 204 Buffer current position */
unsigned int buffer_size; /* --3 208 Buffer size */
int request_fd; /* --3 20c fd for sending server requests */ int request_fd; /* --3 20c fd for sending server requests */
int reply_fd; /* --3 210 fd for receiving server replies */ int reply_fd; /* --3 210 fd for receiving server replies */
int wait_fd[2]; /* --3 214 fd for sleeping server requests */ int wait_fd[2]; /* --3 214 fd for sleeping server requests */
......
...@@ -1609,7 +1609,7 @@ BOOL WINAPI WriteProfileSectionW(LPCWSTR,LPCWSTR); ...@@ -1609,7 +1609,7 @@ BOOL WINAPI WriteProfileSectionW(LPCWSTR,LPCWSTR);
BOOL WINAPI WritePrivateProfileStructA(LPCSTR,LPCSTR,LPVOID,UINT,LPCSTR); BOOL WINAPI WritePrivateProfileStructA(LPCSTR,LPCSTR,LPVOID,UINT,LPCSTR);
BOOL WINAPI WritePrivateProfileStructW(LPCWSTR,LPCWSTR,LPVOID,UINT,LPCWSTR); BOOL WINAPI WritePrivateProfileStructW(LPCWSTR,LPCWSTR,LPVOID,UINT,LPCWSTR);
#define WritePrivateProfileStruct WINELIB_NAME_AW(WritePrivateProfileStruct) #define WritePrivateProfileStruct WINELIB_NAME_AW(WritePrivateProfileStruct)
BOOL WINAPI WriteProcessMemory(HANDLE, LPVOID, LPVOID, DWORD, LPDWORD); BOOL WINAPI WriteProcessMemory(HANDLE,LPVOID,LPCVOID,DWORD,LPDWORD);
BOOL WINAPI WriteProfileStringA(LPCSTR,LPCSTR,LPCSTR); BOOL WINAPI WriteProfileStringA(LPCSTR,LPCSTR,LPCSTR);
BOOL WINAPI WriteProfileStringW(LPCWSTR,LPCWSTR,LPCWSTR); BOOL WINAPI WriteProfileStringW(LPCWSTR,LPCWSTR,LPCWSTR);
#define WriteProfileString WINELIB_NAME_AW(WriteProfileString) #define WriteProfileString WINELIB_NAME_AW(WriteProfileString)
......
...@@ -177,10 +177,8 @@ HANDLE WINAPI CreateConsoleScreenBuffer( DWORD dwDesiredAccess, DWORD dwShareMod ...@@ -177,10 +177,8 @@ HANDLE WINAPI CreateConsoleScreenBuffer( DWORD dwDesiredAccess, DWORD dwShareMod
LPVOID lpScreenBufferData); LPVOID lpScreenBufferData);
BOOL WINAPI FillConsoleOutputAttribute( HANDLE hConsoleOutput, WORD wAttribute, DWORD nLength, BOOL WINAPI FillConsoleOutputAttribute( HANDLE hConsoleOutput, WORD wAttribute, DWORD nLength,
COORD dwCoord, LPDWORD lpNumAttrsWritten); COORD dwCoord, LPDWORD lpNumAttrsWritten);
BOOL WINAPI FillConsoleOutputCharacterA( HANDLE hConsoleOutput, BYTE cCharacter, DWORD nLength, BOOL WINAPI FillConsoleOutputCharacterA(HANDLE,CHAR,DWORD,COORD,LPDWORD);
COORD dwCoord, LPDWORD lpNumCharsWritten); BOOL WINAPI FillConsoleOutputCharacterW(HANDLE,WCHAR,DWORD,COORD,LPDWORD);
BOOL WINAPI FillConsoleOutputCharacterW( HANDLE hConsoleOutput, WCHAR cCharacter, DWORD nLength,
COORD dwCoord, LPDWORD lpNumCharsWritten);
#define FillConsoleOutputCharacter WINELIB_NAME_AW(FillConsoleOutputCharacter) #define FillConsoleOutputCharacter WINELIB_NAME_AW(FillConsoleOutputCharacter)
BOOL WINAPI FlushConsoleInputBuffer( HANDLE handle); BOOL WINAPI FlushConsoleInputBuffer( HANDLE handle);
BOOL WINAPI FreeConsole(VOID); BOOL WINAPI FreeConsole(VOID);
...@@ -242,13 +240,11 @@ BOOL WINAPI SetConsoleWindowInfo( HANDLE hcon, BOOL bAbsolute, LPSMALL_RECT wi ...@@ -242,13 +240,11 @@ BOOL WINAPI SetConsoleWindowInfo( HANDLE hcon, BOOL bAbsolute, LPSMALL_RECT wi
BOOL WINAPI WriteConsoleA(HANDLE,CONST VOID *,DWORD,LPDWORD,LPVOID); BOOL WINAPI WriteConsoleA(HANDLE,CONST VOID *,DWORD,LPDWORD,LPVOID);
BOOL WINAPI WriteConsoleW(HANDLE, CONST VOID *lpBuffer, DWORD,LPDWORD,LPVOID); BOOL WINAPI WriteConsoleW(HANDLE, CONST VOID *lpBuffer, DWORD,LPDWORD,LPVOID);
#define WriteConsole WINELIB_NAME_AW(WriteConsole) #define WriteConsole WINELIB_NAME_AW(WriteConsole)
BOOL WINAPI WriteConsoleInputA( HANDLE handle, INPUT_RECORD *buffer, DWORD, LPDWORD ); BOOL WINAPI WriteConsoleInputA(HANDLE,const INPUT_RECORD *,DWORD,LPDWORD);
BOOL WINAPI WriteConsoleInputW( HANDLE handle, INPUT_RECORD *buffer, DWORD, LPDWORD ); BOOL WINAPI WriteConsoleInputW(HANDLE,const INPUT_RECORD *,DWORD,LPDWORD);
#define WriteConsoleInput WINELIB_NAME_AW(WriteConsoleInput) #define WriteConsoleInput WINELIB_NAME_AW(WriteConsoleInput)
BOOL WINAPI WriteConsoleOutputA( HANDLE hConsoleOutput, LPCHAR_INFO lpBuffer, COORD dwBufferSize, BOOL WINAPI WriteConsoleOutputA(HANDLE,const CHAR_INFO*,COORD,COORD,LPSMALL_RECT);
COORD dwBufferCoord, LPSMALL_RECT lpWriteRegion); BOOL WINAPI WriteConsoleOutputW(HANDLE,const CHAR_INFO*,COORD,COORD,LPSMALL_RECT);
BOOL WINAPI WriteConsoleOutputW( HANDLE hConsoleOutput, LPCHAR_INFO lpBuffer, COORD dwBufferSize,
COORD dwBufferCoord, LPSMALL_RECT lpWriteRegion);
#define WriteConsoleOutput WINELIB_NAME_AW(WriteConsoleOutput) #define WriteConsoleOutput WINELIB_NAME_AW(WriteConsoleOutput)
BOOL WINAPI WriteConsoleOutputAttribute(HANDLE,CONST WORD *,DWORD,COORD,LPDWORD); BOOL WINAPI WriteConsoleOutputAttribute(HANDLE,CONST WORD *,DWORD,COORD,LPDWORD);
BOOL WINAPI WriteConsoleOutputCharacterA(HANDLE,LPCSTR,DWORD,COORD,LPDWORD); BOOL WINAPI WriteConsoleOutputCharacterA(HANDLE,LPCSTR,DWORD,COORD,LPDWORD);
......
...@@ -14,83 +14,90 @@ ...@@ -14,83 +14,90 @@
/* client communication functions */ /* client communication functions */
extern unsigned int wine_server_call( union generic_request *req, size_t size ); struct __server_iovec
extern void server_protocol_error( const char *err, ... ) WINE_NORETURN; {
extern void server_protocol_perror( const char *err ) WINE_NORETURN; const void *ptr;
extern void wine_server_alloc_req( union generic_request *req, size_t size ); unsigned int size;
};
#define __SERVER_MAX_DATA 4
struct __server_request_info
{
union
{
union generic_request req; /* request structure */
union generic_reply reply; /* reply structure */
} u;
size_t size; /* size of request structure */
unsigned int data_count; /* count of request data pointers */
void *reply_data; /* reply data pointer */
struct __server_iovec data[__SERVER_MAX_DATA]; /* request variable size data */
};
extern unsigned int wine_server_call( void *req_ptr );
extern void wine_server_send_fd( int fd ); extern void wine_server_send_fd( int fd );
extern int wine_server_recv_fd( handle_t handle ); extern int wine_server_recv_fd( handle_t handle );
extern const char *get_config_dir(void);
/* do a server call and set the last error code */ /* do a server call and set the last error code */
inline static unsigned int __server_call_err( union generic_request *req, size_t size ) inline static unsigned int wine_server_call_err( void *req_ptr )
{ {
unsigned int res = wine_server_call( req, size ); unsigned int res = wine_server_call( req_ptr );
if (res) SetLastError( RtlNtStatusToDosError(res) ); if (res) SetLastError( RtlNtStatusToDosError(res) );
return res; return res;
} }
/* get a pointer to the variable part of the request */ /* get the size of the variable part of the returned reply */
inline static void *server_data_ptr( const void *req ) inline static size_t wine_server_reply_size( const void *reply )
{ {
return (char *)NtCurrentTeb()->buffer + ((struct request_header *)req)->var_offset; return ((struct reply_header *)reply)->reply_size;
} }
/* get the size of the variable part of the request */ /* add some data to be sent along with the request */
inline static size_t server_data_size( const void *req ) inline static void wine_server_add_data( void *req_ptr, const void *ptr, unsigned int size )
{ {
return ((struct request_header *)req)->var_size; struct __server_request_info * const req = req_ptr;
if (size)
{
req->data[req->data_count].ptr = ptr;
req->data[req->data_count++].size = size;
req->u.req.request_header.request_size += size;
}
} }
/* set the pointer and max size for the reply var data */
/* exception support for server calls */ inline static void wine_server_set_reply( void *req_ptr, void *ptr, unsigned int max_size )
extern DWORD __wine_server_exception_handler( PEXCEPTION_RECORD record, EXCEPTION_FRAME *frame,
CONTEXT *context, EXCEPTION_FRAME **pdispatcher );
struct __server_exception_frame
{ {
EXCEPTION_FRAME frame; struct __server_request_info * const req = req_ptr;
unsigned int buffer_pos; /* saved buffer position */ req->reply_data = ptr;
}; req->u.req.request_header.reply_size = max_size;
}
/* macros for server requests */ /* macros for server requests */
#define SERVER_START_REQ(type) \ #define SERVER_START_REQ(type) \
do { \ do { \
union generic_request __req; \ struct __server_request_info __req; \
struct type##_request * const req = &__req.type; \ struct type##_request * const req = &__req.u.req.type##_request; \
__req.header.req = REQ_##type; \ const struct type##_reply * const reply = &__req.u.reply.type##_reply; \
__req.header.var_size = 0; \ __req.u.req.request_header.req = REQ_##type; \
__req.u.req.request_header.request_size = 0; \
__req.u.req.request_header.reply_size = 0; \
__req.size = sizeof(*req); \
__req.data_count = 0; \
(void)reply; \
do do
#define SERVER_END_REQ \ #define SERVER_END_REQ \
while(0); \ while(0); \
} while(0) } while(0)
#define SERVER_START_VAR_REQ(type,size) \
do { \
struct __server_exception_frame __f; \
union generic_request __req; \
struct type##_request * const req = &__req.type; \
__f.frame.Handler = __wine_server_exception_handler; \
__f.buffer_pos = NtCurrentTeb()->buffer_pos; \
__wine_push_frame( &__f.frame ); \
__req.header.req = REQ_##type; \
wine_server_alloc_req( &__req, (size) ); \
do
#define SERVER_END_VAR_REQ \
while(0); \
NtCurrentTeb()->buffer_pos = __f.buffer_pos; \
__wine_pop_frame( &__f.frame ); \
} while(0)
#define SERVER_CALL() (wine_server_call( &__req, sizeof(*req) ))
#define SERVER_CALL_ERR() (__server_call_err( &__req, sizeof(*req) ))
/* non-exported functions */
extern void server_protocol_error( const char *err, ... ) WINE_NORETURN;
extern void server_protocol_perror( const char *err ) WINE_NORETURN;
extern const char *get_config_dir(void);
extern void CLIENT_InitServer(void); extern void CLIENT_InitServer(void);
extern void CLIENT_InitThread(void); extern void CLIENT_InitThread(void);
extern void CLIENT_BootDone( int debug_level ); extern void CLIENT_BootDone( int debug_level );
......
...@@ -1693,7 +1693,7 @@ BOOL MODULE_FreeLibrary( WINE_MODREF *wm ) ...@@ -1693,7 +1693,7 @@ BOOL MODULE_FreeLibrary( WINE_MODREF *wm )
SERVER_START_REQ( unload_dll ) SERVER_START_REQ( unload_dll )
{ {
req->base = (void *)wm->module; req->base = (void *)wm->module;
SERVER_CALL(); wine_server_call( req );
} }
SERVER_END_REQ; SERVER_END_REQ;
MODULE_FlushModrefs(); MODULE_FlushModrefs();
......
...@@ -681,7 +681,7 @@ WINE_MODREF *PE_CreateModule( HMODULE hModule, LPCSTR filename, DWORD flags, ...@@ -681,7 +681,7 @@ WINE_MODREF *PE_CreateModule( HMODULE hModule, LPCSTR filename, DWORD flags,
req->dbg_offset = nt->FileHeader.PointerToSymbolTable; req->dbg_offset = nt->FileHeader.PointerToSymbolTable;
req->dbg_size = nt->FileHeader.NumberOfSymbols; req->dbg_size = nt->FileHeader.NumberOfSymbols;
req->name = &wm->filename; req->name = &wm->filename;
SERVER_CALL(); wine_server_call( req );
} }
SERVER_END_REQ; SERVER_END_REQ;
} }
......
...@@ -409,7 +409,7 @@ BOOL WINAPI InitAtomTable( DWORD entries ) ...@@ -409,7 +409,7 @@ BOOL WINAPI InitAtomTable( DWORD entries )
SERVER_START_REQ( init_atom_table ) SERVER_START_REQ( init_atom_table )
{ {
req->entries = entries; req->entries = entries;
ret = !SERVER_CALL_ERR(); ret = !wine_server_call_err( req );
} }
SERVER_END_REQ; SERVER_END_REQ;
return ret; return ret;
...@@ -421,19 +421,21 @@ static ATOM ATOM_AddAtomA( LPCSTR str, BOOL local ) ...@@ -421,19 +421,21 @@ static ATOM ATOM_AddAtomA( LPCSTR str, BOOL local )
ATOM atom = 0; ATOM atom = 0;
if (!ATOM_IsIntAtomA( str, &atom )) if (!ATOM_IsIntAtomA( str, &atom ))
{ {
DWORD len = MultiByteToWideChar( CP_ACP, 0, str, strlen(str), NULL, 0 ); WCHAR buffer[MAX_ATOM_LEN];
if (len > MAX_ATOM_LEN)
DWORD len = MultiByteToWideChar( CP_ACP, 0, str, strlen(str), buffer, MAX_ATOM_LEN );
if (!len)
{ {
SetLastError( ERROR_INVALID_PARAMETER ); SetLastError( ERROR_INVALID_PARAMETER );
return 0; return 0;
} }
SERVER_START_VAR_REQ( add_atom, len * sizeof(WCHAR) ) SERVER_START_REQ( add_atom )
{ {
MultiByteToWideChar( CP_ACP, 0, str, strlen(str), server_data_ptr(req), len ); wine_server_add_data( req, buffer, len * sizeof(WCHAR) );
req->local = local; req->local = local;
if (!SERVER_CALL_ERR()) atom = req->atom; if (!wine_server_call_err(req)) atom = reply->atom;
} }
SERVER_END_VAR_REQ; SERVER_END_REQ;
} }
TRACE( "(%s) %s -> %x\n", local ? "local" : "global", debugres_a(str), atom ); TRACE( "(%s) %s -> %x\n", local ? "local" : "global", debugres_a(str), atom );
return atom; return atom;
...@@ -482,13 +484,13 @@ static ATOM ATOM_AddAtomW( LPCWSTR str, BOOL local ) ...@@ -482,13 +484,13 @@ static ATOM ATOM_AddAtomW( LPCWSTR str, BOOL local )
SetLastError( ERROR_INVALID_PARAMETER ); SetLastError( ERROR_INVALID_PARAMETER );
return 0; return 0;
} }
SERVER_START_VAR_REQ( add_atom, len * sizeof(WCHAR) ) SERVER_START_REQ( add_atom )
{ {
memcpy( server_data_ptr(req), str, len * sizeof(WCHAR) );
req->local = local; req->local = local;
if (!SERVER_CALL_ERR()) atom = req->atom; wine_server_add_data( req, str, len * sizeof(WCHAR) );
if (!wine_server_call_err(req)) atom = reply->atom;
} }
SERVER_END_VAR_REQ; SERVER_END_REQ;
} }
TRACE( "(%s) %s -> %x\n", local ? "local" : "global", debugres_w(str), atom ); TRACE( "(%s) %s -> %x\n", local ? "local" : "global", debugres_w(str), atom );
return atom; return atom;
...@@ -523,7 +525,7 @@ static ATOM ATOM_DeleteAtom( ATOM atom, BOOL local) ...@@ -523,7 +525,7 @@ static ATOM ATOM_DeleteAtom( ATOM atom, BOOL local)
{ {
req->atom = atom; req->atom = atom;
req->local = local; req->local = local;
if (!SERVER_CALL_ERR()) atom = 0; if (!wine_server_call_err( req )) atom = 0;
} }
SERVER_END_REQ; SERVER_END_REQ;
} }
...@@ -566,19 +568,21 @@ static ATOM ATOM_FindAtomA( LPCSTR str, BOOL local ) ...@@ -566,19 +568,21 @@ static ATOM ATOM_FindAtomA( LPCSTR str, BOOL local )
ATOM atom = 0; ATOM atom = 0;
if (!ATOM_IsIntAtomA( str, &atom )) if (!ATOM_IsIntAtomA( str, &atom ))
{ {
DWORD len = MultiByteToWideChar( CP_ACP, 0, str, strlen(str), NULL, 0 ); WCHAR buffer[MAX_ATOM_LEN];
if (len > MAX_ATOM_LEN)
DWORD len = MultiByteToWideChar( CP_ACP, 0, str, strlen(str), buffer, MAX_ATOM_LEN );
if (!len)
{ {
SetLastError( ERROR_INVALID_PARAMETER ); SetLastError( ERROR_INVALID_PARAMETER );
return 0; return 0;
} }
SERVER_START_VAR_REQ( find_atom, len * sizeof(WCHAR) ) SERVER_START_REQ( find_atom )
{ {
MultiByteToWideChar( CP_ACP, 0, str, strlen(str), server_data_ptr(req), len );
req->local = local; req->local = local;
if (!SERVER_CALL_ERR()) atom = req->atom; wine_server_add_data( req, buffer, len * sizeof(WCHAR) );
if (!wine_server_call_err(req)) atom = reply->atom;
} }
SERVER_END_VAR_REQ; SERVER_END_REQ;
} }
TRACE( "(%s) %s -> %x\n", local ? "local" : "global", debugres_a(str), atom ); TRACE( "(%s) %s -> %x\n", local ? "local" : "global", debugres_a(str), atom );
return atom; return atom;
...@@ -626,13 +630,13 @@ static ATOM ATOM_FindAtomW( LPCWSTR str, BOOL local ) ...@@ -626,13 +630,13 @@ static ATOM ATOM_FindAtomW( LPCWSTR str, BOOL local )
SetLastError( ERROR_INVALID_PARAMETER ); SetLastError( ERROR_INVALID_PARAMETER );
return 0; return 0;
} }
SERVER_START_VAR_REQ( find_atom, len * sizeof(WCHAR) ) SERVER_START_REQ( find_atom )
{ {
memcpy( server_data_ptr(req), str, len * sizeof(WCHAR) ); wine_server_add_data( req, str, len * sizeof(WCHAR) );
req->local = local; req->local = local;
if (!SERVER_CALL_ERR()) atom = req->atom; if (!wine_server_call_err( req )) atom = reply->atom;
} }
SERVER_END_VAR_REQ; SERVER_END_REQ;
} }
TRACE( "(%s) %s -> %x\n", local ? "local" : "global", debugres_w(str), atom ); TRACE( "(%s) %s -> %x\n", local ? "local" : "global", debugres_w(str), atom );
return atom; return atom;
...@@ -679,21 +683,24 @@ static UINT ATOM_GetAtomNameA( ATOM atom, LPSTR buffer, INT count, BOOL local ) ...@@ -679,21 +683,24 @@ static UINT ATOM_GetAtomNameA( ATOM atom, LPSTR buffer, INT count, BOOL local )
} }
else else
{ {
WCHAR full_name[MAX_ATOM_LEN];
len = 0; len = 0;
SERVER_START_VAR_REQ( get_atom_name, MAX_ATOM_LEN * sizeof(WCHAR) ) SERVER_START_REQ( get_atom_name )
{ {
req->atom = atom; req->atom = atom;
req->local = local; req->local = local;
if (!SERVER_CALL_ERR()) wine_server_set_reply( req, full_name, sizeof(full_name) );
if (!wine_server_call_err( req ))
{ {
len = WideCharToMultiByte( CP_ACP, 0, server_data_ptr(req), len = WideCharToMultiByte( CP_ACP, 0, full_name,
server_data_size(req) / sizeof(WCHAR), wine_server_reply_size(reply) / sizeof(WCHAR),
buffer, count - 1, NULL, NULL ); buffer, count - 1, NULL, NULL );
if (!len) len = count; /* overflow */ if (!len) len = count; /* overflow */
else buffer[len] = 0; else buffer[len] = 0;
} }
} }
SERVER_END_VAR_REQ; SERVER_END_REQ;
} }
if (len && count <= len) if (len && count <= len)
...@@ -765,20 +772,23 @@ static UINT ATOM_GetAtomNameW( ATOM atom, LPWSTR buffer, INT count, BOOL local ) ...@@ -765,20 +772,23 @@ static UINT ATOM_GetAtomNameW( ATOM atom, LPWSTR buffer, INT count, BOOL local )
} }
else else
{ {
WCHAR full_name[MAX_ATOM_LEN];
len = 0; len = 0;
SERVER_START_VAR_REQ( get_atom_name, MAX_ATOM_LEN * sizeof(WCHAR) ) SERVER_START_REQ( get_atom_name )
{ {
req->atom = atom; req->atom = atom;
req->local = local; req->local = local;
if (!SERVER_CALL_ERR()) wine_server_set_reply( req, full_name, sizeof(full_name) );
if (!wine_server_call_err( req ))
{ {
len = server_data_size(req) / sizeof(WCHAR); len = wine_server_reply_size(reply) / sizeof(WCHAR);
if (count > len) count = len + 1; if (count > len) count = len + 1;
memcpy( buffer, server_data_ptr(req), (count-1) * sizeof(WCHAR) ); memcpy( buffer, full_name, (count-1) * sizeof(WCHAR) );
buffer[count-1] = 0; buffer[count-1] = 0;
} }
} }
SERVER_END_VAR_REQ; SERVER_END_REQ;
if (!len) return 0; if (!len) return 0;
} }
if (count <= len) if (count <= len)
......
...@@ -606,6 +606,7 @@ DWORD WINAPI RegDeleteValueA( HKEY hkey, LPCSTR name ) ...@@ -606,6 +606,7 @@ DWORD WINAPI RegDeleteValueA( HKEY hkey, LPCSTR name )
LONG WINAPI RegLoadKeyA( HKEY hkey, LPCSTR subkey, LPCSTR filename ) LONG WINAPI RegLoadKeyA( HKEY hkey, LPCSTR subkey, LPCSTR filename )
{ {
HANDLE file; HANDLE file;
WCHAR buffer[MAX_PATH];
DWORD ret, len, err = GetLastError(); DWORD ret, len, err = GetLastError();
TRACE( "(%x,%s,%s)\n", hkey, debugstr_a(subkey), debugstr_a(filename) ); TRACE( "(%x,%s,%s)\n", hkey, debugstr_a(subkey), debugstr_a(filename) );
...@@ -613,8 +614,8 @@ LONG WINAPI RegLoadKeyA( HKEY hkey, LPCSTR subkey, LPCSTR filename ) ...@@ -613,8 +614,8 @@ LONG WINAPI RegLoadKeyA( HKEY hkey, LPCSTR subkey, LPCSTR filename )
if (!filename || !*filename) return ERROR_INVALID_PARAMETER; if (!filename || !*filename) return ERROR_INVALID_PARAMETER;
if (!subkey || !*subkey) return ERROR_INVALID_PARAMETER; if (!subkey || !*subkey) return ERROR_INVALID_PARAMETER;
len = MultiByteToWideChar( CP_ACP, 0, subkey, strlen(subkey), NULL, 0 ) * sizeof(WCHAR); if (!(len = MultiByteToWideChar( CP_ACP, 0, subkey, strlen(subkey), buffer, MAX_PATH )))
if (len > MAX_PATH*sizeof(WCHAR)) return ERROR_INVALID_PARAMETER; return ERROR_INVALID_PARAMETER;
if ((file = CreateFileA( filename, GENERIC_READ, 0, NULL, OPEN_EXISTING, if ((file = CreateFileA( filename, GENERIC_READ, 0, NULL, OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL, 0 )) == INVALID_HANDLE_VALUE) FILE_ATTRIBUTE_NORMAL, 0 )) == INVALID_HANDLE_VALUE)
...@@ -623,15 +624,14 @@ LONG WINAPI RegLoadKeyA( HKEY hkey, LPCSTR subkey, LPCSTR filename ) ...@@ -623,15 +624,14 @@ LONG WINAPI RegLoadKeyA( HKEY hkey, LPCSTR subkey, LPCSTR filename )
goto done; goto done;
} }
SERVER_START_VAR_REQ( load_registry, len ) SERVER_START_REQ( load_registry )
{ {
req->hkey = hkey; req->hkey = hkey;
req->file = file; req->file = file;
MultiByteToWideChar( CP_ACP, 0, subkey, strlen(subkey), wine_server_add_data( req, buffer, len * sizeof(WCHAR) );
server_data_ptr(req), len/sizeof(WCHAR) ); ret = RtlNtStatusToDosError( wine_server_call(req) );
ret = RtlNtStatusToDosError( SERVER_CALL() );
} }
SERVER_END_VAR_REQ; SERVER_END_REQ;
CloseHandle( file ); CloseHandle( file );
done: done:
...@@ -679,7 +679,7 @@ LONG WINAPI RegSaveKeyA( HKEY hkey, LPCSTR file, LPSECURITY_ATTRIBUTES sa ) ...@@ -679,7 +679,7 @@ LONG WINAPI RegSaveKeyA( HKEY hkey, LPCSTR file, LPSECURITY_ATTRIBUTES sa )
{ {
req->hkey = hkey; req->hkey = hkey;
req->file = handle; req->file = handle;
ret = RtlNtStatusToDosError( SERVER_CALL() ); ret = RtlNtStatusToDosError( wine_server_call( req ) );
} }
SERVER_END_REQ; SERVER_END_REQ;
......
...@@ -594,18 +594,18 @@ BOOL WINAPI GetThreadSelectorEntry( HANDLE hthread, DWORD sel, LPLDT_ENTRY ldten ...@@ -594,18 +594,18 @@ BOOL WINAPI GetThreadSelectorEntry( HANDLE hthread, DWORD sel, LPLDT_ENTRY ldten
{ {
req->handle = hthread; req->handle = hthread;
req->entry = sel >> __AHSHIFT; req->entry = sel >> __AHSHIFT;
if ((ret = !SERVER_CALL_ERR())) if ((ret = !wine_server_call_err( req )))
{ {
if (!(req->flags & WINE_LDT_FLAGS_ALLOCATED)) if (!(reply->flags & WINE_LDT_FLAGS_ALLOCATED))
{ {
SetLastError( ERROR_MR_MID_NOT_FOUND ); /* sic */ SetLastError( ERROR_MR_MID_NOT_FOUND ); /* sic */
ret = FALSE; ret = FALSE;
} }
else else
{ {
wine_ldt_set_base( ldtent, (void *)req->base ); wine_ldt_set_base( ldtent, (void *)reply->base );
wine_ldt_set_limit( ldtent, req->limit ); wine_ldt_set_limit( ldtent, reply->limit );
wine_ldt_set_flags( ldtent, req->flags ); wine_ldt_set_flags( ldtent, reply->flags );
} }
} }
} }
......
...@@ -1360,50 +1360,16 @@ HANDLE WINAPI CreateFileMappingA( ...@@ -1360,50 +1360,16 @@ HANDLE WINAPI CreateFileMappingA(
DWORD size_low, /* [in] Low-order 32 bits of object size */ DWORD size_low, /* [in] Low-order 32 bits of object size */
LPCSTR name /* [in] Name of file-mapping object */ ) LPCSTR name /* [in] Name of file-mapping object */ )
{ {
HANDLE ret; WCHAR buffer[MAX_PATH];
BYTE vprot;
DWORD len = name ? MultiByteToWideChar( CP_ACP, 0, name, strlen(name), NULL, 0 ) : 0;
/* Check parameters */
TRACE("(%x,%p,%08lx,%08lx%08lx,%s)\n", if (!name) return CreateFileMappingW( hFile, sa, protect, size_high, size_low, NULL );
hFile, sa, protect, size_high, size_low, debugstr_a(name) );
if (len > MAX_PATH) if (!MultiByteToWideChar( CP_ACP, 0, name, -1, buffer, MAX_PATH ))
{ {
SetLastError( ERROR_FILENAME_EXCED_RANGE ); SetLastError( ERROR_FILENAME_EXCED_RANGE );
return 0; return 0;
} }
vprot = VIRTUAL_GetProt( protect ); return CreateFileMappingW( hFile, sa, protect, size_high, size_low, buffer );
if (protect & SEC_RESERVE)
{
if (hFile != INVALID_HANDLE_VALUE)
{
SetLastError( ERROR_INVALID_PARAMETER );
return 0;
}
}
else vprot |= VPROT_COMMITTED;
if (protect & SEC_NOCACHE) vprot |= VPROT_NOCACHE;
if (protect & SEC_IMAGE) vprot |= VPROT_IMAGE;
/* Create the server object */
if (hFile == INVALID_HANDLE_VALUE) hFile = 0;
SERVER_START_VAR_REQ( create_mapping, len * sizeof(WCHAR) )
{
req->file_handle = hFile;
req->size_high = size_high;
req->size_low = size_low;
req->protect = vprot;
req->inherit = (sa && (sa->nLength>=sizeof(*sa)) && sa->bInheritHandle);
if (len) MultiByteToWideChar( CP_ACP, 0, name, strlen(name), server_data_ptr(req), len );
SetLastError(0);
SERVER_CALL_ERR();
ret = req->handle;
}
SERVER_END_VAR_REQ;
return ret;
} }
...@@ -1446,19 +1412,19 @@ HANDLE WINAPI CreateFileMappingW( HANDLE hFile, LPSECURITY_ATTRIBUTES sa, ...@@ -1446,19 +1412,19 @@ HANDLE WINAPI CreateFileMappingW( HANDLE hFile, LPSECURITY_ATTRIBUTES sa,
/* Create the server object */ /* Create the server object */
if (hFile == INVALID_HANDLE_VALUE) hFile = 0; if (hFile == INVALID_HANDLE_VALUE) hFile = 0;
SERVER_START_VAR_REQ( create_mapping, len * sizeof(WCHAR) ) SERVER_START_REQ( create_mapping )
{ {
req->file_handle = hFile; req->file_handle = hFile;
req->size_high = size_high; req->size_high = size_high;
req->size_low = size_low; req->size_low = size_low;
req->protect = vprot; req->protect = vprot;
req->inherit = (sa && (sa->nLength>=sizeof(*sa)) && sa->bInheritHandle); req->inherit = (sa && (sa->nLength>=sizeof(*sa)) && sa->bInheritHandle);
memcpy( server_data_ptr(req), name, len * sizeof(WCHAR) ); wine_server_add_data( req, name, len * sizeof(WCHAR) );
SetLastError(0); SetLastError(0);
SERVER_CALL_ERR(); wine_server_call_err( req );
ret = req->handle; ret = reply->handle;
} }
SERVER_END_VAR_REQ; SERVER_END_REQ;
return ret; return ret;
} }
...@@ -1476,23 +1442,16 @@ HANDLE WINAPI OpenFileMappingA( ...@@ -1476,23 +1442,16 @@ HANDLE WINAPI OpenFileMappingA(
BOOL inherit, /* [in] Inherit flag */ BOOL inherit, /* [in] Inherit flag */
LPCSTR name ) /* [in] Name of file-mapping object */ LPCSTR name ) /* [in] Name of file-mapping object */
{ {
HANDLE ret; WCHAR buffer[MAX_PATH];
DWORD len = name ? MultiByteToWideChar( CP_ACP, 0, name, strlen(name), NULL, 0 ) : 0;
if (len > MAX_PATH) if (!name) return OpenFileMappingW( access, inherit, NULL );
if (!MultiByteToWideChar( CP_ACP, 0, name, -1, buffer, MAX_PATH ))
{ {
SetLastError( ERROR_FILENAME_EXCED_RANGE ); SetLastError( ERROR_FILENAME_EXCED_RANGE );
return 0; return 0;
} }
SERVER_START_VAR_REQ( open_mapping, len * sizeof(WCHAR) ) return OpenFileMappingW( access, inherit, buffer );
{
req->access = access;
req->inherit = inherit;
if (len) MultiByteToWideChar( CP_ACP, 0, name, strlen(name), server_data_ptr(req), len );
SERVER_CALL_ERR();
ret = req->handle;
}
SERVER_END_VAR_REQ;
return ret;
} }
...@@ -1504,20 +1463,20 @@ HANDLE WINAPI OpenFileMappingW( DWORD access, BOOL inherit, LPCWSTR name) ...@@ -1504,20 +1463,20 @@ HANDLE WINAPI OpenFileMappingW( DWORD access, BOOL inherit, LPCWSTR name)
{ {
HANDLE ret; HANDLE ret;
DWORD len = name ? strlenW(name) : 0; DWORD len = name ? strlenW(name) : 0;
if (len > MAX_PATH) if (len >= MAX_PATH)
{ {
SetLastError( ERROR_FILENAME_EXCED_RANGE ); SetLastError( ERROR_FILENAME_EXCED_RANGE );
return 0; return 0;
} }
SERVER_START_VAR_REQ( open_mapping, len * sizeof(WCHAR) ) SERVER_START_REQ( open_mapping )
{ {
req->access = access; req->access = access;
req->inherit = inherit; req->inherit = inherit;
memcpy( server_data_ptr(req), name, len * sizeof(WCHAR) ); wine_server_add_data( req, name, len * sizeof(WCHAR) );
SERVER_CALL_ERR(); wine_server_call_err( req );
ret = req->handle; ret = reply->handle;
} }
SERVER_END_VAR_REQ; SERVER_END_REQ;
return ret; return ret;
} }
...@@ -1580,16 +1539,16 @@ LPVOID WINAPI MapViewOfFileEx( ...@@ -1580,16 +1539,16 @@ LPVOID WINAPI MapViewOfFileEx(
SERVER_START_REQ( get_mapping_info ) SERVER_START_REQ( get_mapping_info )
{ {
req->handle = handle; req->handle = handle;
res = SERVER_CALL_ERR(); res = wine_server_call_err( req );
prot = req->protect; prot = reply->protect;
base = req->base; base = reply->base;
size_low = req->size_low; size_low = reply->size_low;
size_high = req->size_high; size_high = reply->size_high;
header_size = req->header_size; header_size = reply->header_size;
shared_file = req->shared_file; shared_file = reply->shared_file;
shared_size = req->shared_size; shared_size = reply->shared_size;
removable = (req->drive_type == DRIVE_REMOVABLE || removable = (reply->drive_type == DRIVE_REMOVABLE ||
req->drive_type == DRIVE_CDROM); reply->drive_type == DRIVE_CDROM);
} }
SERVER_END_REQ; SERVER_END_REQ;
if (res) goto error; if (res) goto error;
......
...@@ -38,10 +38,6 @@ const char *full_argv0; /* the full path of argv[0] (if known) */ ...@@ -38,10 +38,6 @@ const char *full_argv0; /* the full path of argv[0] (if known) */
static char *inherit_str; /* options to pass to child processes */ static char *inherit_str; /* options to pass to child processes */
static int app_argc; /* argc/argv to pass to application */
static char **app_argv;
static WCHAR **app_wargv;
static void out_of_memory(void) WINE_NORETURN; static void out_of_memory(void) WINE_NORETURN;
static void out_of_memory(void) static void out_of_memory(void)
{ {
...@@ -340,55 +336,4 @@ void OPTIONS_ParseOptions( char *argv[] ) ...@@ -340,55 +336,4 @@ void OPTIONS_ParseOptions( char *argv[] )
OPTIONS_Usage(); OPTIONS_Usage();
} }
} }
/* count the resulting arguments */
app_argv = argv;
app_argc = 0;
while (argv[app_argc]) app_argc++;
}
/***********************************************************************
* __wine_get_main_args (NTDLL.@)
*
* Return the argc/argv that the application should see.
* Used by the startup code generated in the .spec.c file.
*/
int __wine_get_main_args( char ***argv )
{
*argv = app_argv;
return app_argc;
}
/***********************************************************************
* __wine_get_wmain_args (NTDLL.@)
*
* Same as __wine_get_main_args but for Unicode.
*/
int __wine_get_wmain_args( WCHAR ***argv )
{
if (!app_wargv)
{
int i;
WCHAR *p;
DWORD total = 0;
for (i = 0; i < app_argc; i++)
total += MultiByteToWideChar( CP_ACP, 0, app_argv[i], -1, NULL, 0 );
app_wargv = HeapAlloc( GetProcessHeap(), 0,
total * sizeof(WCHAR) + (app_argc + 1) * sizeof(*app_wargv) );
p = (WCHAR *)(app_wargv + app_argc + 1);
for (i = 0; i < app_argc; i++)
{
DWORD len = MultiByteToWideChar( CP_ACP, 0, app_argv[i], -1, p, total );
app_wargv[i] = p;
p += len;
total -= len;
}
app_wargv[app_argc] = NULL;
}
*argv = app_wargv;
return app_argc;
} }
...@@ -1004,7 +1004,7 @@ static void _set_registry_levels(int level,int saving,int period) ...@@ -1004,7 +1004,7 @@ static void _set_registry_levels(int level,int saving,int period)
req->current = level; req->current = level;
req->saving = saving; req->saving = saving;
req->period = period; req->period = period;
SERVER_CALL(); wine_server_call( req );
} }
SERVER_END_REQ; SERVER_END_REQ;
} }
...@@ -1013,19 +1013,15 @@ static void _set_registry_levels(int level,int saving,int period) ...@@ -1013,19 +1013,15 @@ static void _set_registry_levels(int level,int saving,int period)
static void _save_at_exit(HKEY hkey,LPCSTR path) static void _save_at_exit(HKEY hkey,LPCSTR path)
{ {
LPCSTR confdir = get_config_dir(); LPCSTR confdir = get_config_dir();
size_t len = strlen(confdir) + strlen(path) + 2;
if (len > REQUEST_MAX_VAR_SIZE) { SERVER_START_REQ( save_registry_atexit )
ERR( "config dir '%s' too long\n", confdir );
return;
}
SERVER_START_VAR_REQ( save_registry_atexit, len )
{ {
sprintf( server_data_ptr(req), "%s/%s", confdir, path );
req->hkey = hkey; req->hkey = hkey;
SERVER_CALL(); wine_server_add_data( req, confdir, strlen(confdir) );
wine_server_add_data( req, path, strlen(path)+1 );
wine_server_call( req );
} }
SERVER_END_VAR_REQ; SERVER_END_REQ;
} }
/* configure save files and start the periodic saving timer [Internal] */ /* configure save files and start the periodic saving timer [Internal] */
...@@ -1042,9 +1038,9 @@ static void _init_registry_saving( HKEY hkey_users_default ) ...@@ -1042,9 +1038,9 @@ static void _init_registry_saving( HKEY hkey_users_default )
if (PROFILE_GetWineIniBool("registry","WritetoHomeRegistryFiles",1)) if (PROFILE_GetWineIniBool("registry","WritetoHomeRegistryFiles",1))
{ {
_save_at_exit(HKEY_CURRENT_USER,SAVE_LOCAL_REGBRANCH_CURRENT_USER ); _save_at_exit(HKEY_CURRENT_USER,"/" SAVE_LOCAL_REGBRANCH_CURRENT_USER );
_save_at_exit(HKEY_LOCAL_MACHINE,SAVE_LOCAL_REGBRANCH_LOCAL_MACHINE); _save_at_exit(HKEY_LOCAL_MACHINE,"/" SAVE_LOCAL_REGBRANCH_LOCAL_MACHINE);
_save_at_exit(hkey_users_default,SAVE_LOCAL_REGBRANCH_USER_DEFAULT); _save_at_exit(hkey_users_default,"/" SAVE_LOCAL_REGBRANCH_USER_DEFAULT);
} }
} }
...@@ -1190,7 +1186,7 @@ static void load_wine_registry(HKEY hkey,LPCSTR fn) ...@@ -1190,7 +1186,7 @@ static void load_wine_registry(HKEY hkey,LPCSTR fn)
{ {
req->hkey = hkey; req->hkey = hkey;
req->file = file; req->file = file;
SERVER_CALL(); wine_server_call( req );
} }
SERVER_END_REQ; SERVER_END_REQ;
CloseHandle( file ); CloseHandle( file );
......
...@@ -352,7 +352,8 @@ void CALLBACK VGA_Poll( ULONG_PTR arg ) ...@@ -352,7 +352,8 @@ void CALLBACK VGA_Poll( ULONG_PTR arg )
ch[X].Attributes = *dat++; ch[X].Attributes = *dat++;
} }
dest.Left=0; dest.Right=Width+1; dest.Left=0; dest.Right=Width+1;
WriteConsoleOutputA(con, ch, siz, off, &dest); FIXME("output commented out for now, should be moved to winedos.dll\n");
/*WriteConsoleOutputA(con, ch, siz, off, &dest);*/
} }
} }
vga_refresh=1; vga_refresh=1;
......
...@@ -5,7 +5,8 @@ ...@@ -5,7 +5,8 @@
*/ */
#include <stdio.h> #include <stdio.h>
#include <wine/server.h> #include "wine/server.h"
#include "wine/unicode.h"
#include "winecon_private.h" #include "winecon_private.h"
static int trace_level = 1; static int trace_level = 1;
...@@ -35,34 +36,20 @@ void XTracer(int level, const char* format, ...) ...@@ -35,34 +36,20 @@ void XTracer(int level, const char* format, ...)
* *
* updates the local copy of cells (band to update) * updates the local copy of cells (band to update)
*/ */
void WINECON_FetchCells(struct inner_data* data, int upd_tp, int upd_bm) void WINECON_FetchCells(struct inner_data* data, int upd_tp, int upd_bm)
{ {
int step; SERVER_START_REQ( read_console_output )
int j, nr;
step = REQUEST_MAX_VAR_SIZE / (data->sb_width * 4);
for (j = upd_tp; j <= upd_bm; j += step)
{ {
nr = min(step, upd_bm - j + 1); req->handle = (handle_t)data->hConOut;
SERVER_START_VAR_REQ( read_console_output, 4 * nr * data->sb_width ) req->x = 0;
{ req->y = upd_tp;
req->handle = (handle_t)data->hConOut; req->mode = CHAR_INFO_MODE_TEXTATTR;
req->x = 0; req->wrap = TRUE;
req->y = j; wine_server_set_reply( req, &data->cells[upd_tp * data->sb_width],
req->w = data->sb_width; (upd_bm-upd_tp+1) * data->sb_width * sizeof(CHAR_INFO) );
req->h = nr; wine_server_call( req );
if (!SERVER_CALL_ERR())
{
if (data->sb_width != req->eff_w || nr != req->eff_h)
Trace(0, "pb here... wrong eff_w %d/%d or eff_h %d/%d\n",
req->eff_w, data->sb_width, req->eff_h, nr);
memcpy(&data->cells[j * data->sb_width], server_data_ptr(req),
4 * nr * data->sb_width);
}
}
SERVER_END_VAR_REQ;
} }
SERVER_END_REQ;
data->fnRefresh(data, upd_tp, upd_bm); data->fnRefresh(data, upd_tp, upd_bm);
} }
...@@ -71,19 +58,17 @@ void WINECON_FetchCells(struct inner_data* data, int upd_tp, int upd_bm) ...@@ -71,19 +58,17 @@ void WINECON_FetchCells(struct inner_data* data, int upd_tp, int upd_bm)
* *
* Inform server that visible window on sb has changed * Inform server that visible window on sb has changed
*/ */
void WINECON_NotifyWindowChange(struct inner_data* data) void WINECON_NotifyWindowChange(struct inner_data* data)
{ {
SERVER_START_REQ( set_console_output_info ) SERVER_START_REQ( set_console_output_info )
{ {
req->handle = (handle_t)data->hConOut; req->handle = (handle_t)data->hConOut;
req->win_left = data->win_pos.X; req->win_left = data->win_pos.X;
req->win_top = data->win_pos.Y; req->win_top = data->win_pos.Y;
req->win_right = data->win_pos.X + data->win_width - 1; req->win_right = data->win_pos.X + data->win_width - 1;
req->win_bottom = data->win_pos.Y + data->win_height - 1; req->win_bottom = data->win_pos.Y + data->win_height - 1;
req->mask = SET_CONSOLE_OUTPUT_INFO_DISPLAY_WINDOW; req->mask = SET_CONSOLE_OUTPUT_INFO_DISPLAY_WINDOW;
if (!SERVER_CALL_ERR()) wine_server_call( req );
{
}
} }
SERVER_END_REQ; SERVER_END_REQ;
} }
...@@ -100,7 +85,7 @@ int WINECON_GetHistorySize(HANDLE hConIn) ...@@ -100,7 +85,7 @@ int WINECON_GetHistorySize(HANDLE hConIn)
SERVER_START_REQ(get_console_input_info) SERVER_START_REQ(get_console_input_info)
{ {
req->handle = (handle_t)hConIn; req->handle = (handle_t)hConIn;
if (!SERVER_CALL_ERR()) ret = req->history_size; if (!wine_server_call_err( req )) ret = reply->history_size;
} }
SERVER_END_REQ; SERVER_END_REQ;
return ret; return ret;
...@@ -120,7 +105,7 @@ BOOL WINECON_SetHistorySize(HANDLE hConIn, int size) ...@@ -120,7 +105,7 @@ BOOL WINECON_SetHistorySize(HANDLE hConIn, int size)
req->handle = (handle_t)hConIn; req->handle = (handle_t)hConIn;
req->mask = SET_CONSOLE_INPUT_INFO_HISTORY_SIZE; req->mask = SET_CONSOLE_INPUT_INFO_HISTORY_SIZE;
req->history_size = size; req->history_size = size;
ret = !SERVER_CALL_ERR(); ret = !wine_server_call_err( req );
} }
SERVER_END_REQ; SERVER_END_REQ;
return ret; return ret;
...@@ -139,7 +124,7 @@ int WINECON_GetHistoryMode(HANDLE hConIn) ...@@ -139,7 +124,7 @@ int WINECON_GetHistoryMode(HANDLE hConIn)
SERVER_START_REQ(get_console_input_info) SERVER_START_REQ(get_console_input_info)
{ {
req->handle = (handle_t)hConIn; req->handle = (handle_t)hConIn;
if (!SERVER_CALL_ERR()) ret = req->history_mode; if (!wine_server_call_err( req )) ret = reply->history_mode;
} }
SERVER_END_REQ; SERVER_END_REQ;
return ret; return ret;
...@@ -159,7 +144,7 @@ BOOL WINECON_SetHistoryMode(HANDLE hConIn, int mode) ...@@ -159,7 +144,7 @@ BOOL WINECON_SetHistoryMode(HANDLE hConIn, int mode)
req->handle = (handle_t)hConIn; req->handle = (handle_t)hConIn;
req->mask = SET_CONSOLE_INPUT_INFO_HISTORY_MODE; req->mask = SET_CONSOLE_INPUT_INFO_HISTORY_MODE;
req->history_mode = mode; req->history_mode = mode;
ret = !SERVER_CALL_ERR(); ret = !wine_server_call_err( req );
} }
SERVER_END_REQ; SERVER_END_REQ;
return ret; return ret;
...@@ -170,22 +155,23 @@ BOOL WINECON_SetHistoryMode(HANDLE hConIn, int mode) ...@@ -170,22 +155,23 @@ BOOL WINECON_SetHistoryMode(HANDLE hConIn, int mode)
* *
* *
*/ */
BOOL WINECON_GetConsoleTitle(HANDLE hConIn, WCHAR* buffer, size_t len) BOOL WINECON_GetConsoleTitle(HANDLE hConIn, WCHAR* buffer, size_t len)
{ {
BOOL ret; BOOL ret;
DWORD size = 0;
if (len < sizeof(WCHAR)) return FALSE;
SERVER_START_VAR_REQ(get_console_input_info, sizeof(buffer)) SERVER_START_REQ( get_console_input_info )
{ {
req->handle = (handle_t)hConIn; req->handle = (handle_t)hConIn;
if ((ret = !SERVER_CALL_ERR())) wine_server_set_reply( req, buffer, len - sizeof(WCHAR) );
if ((ret = !wine_server_call_err( req )))
{ {
size = min(len - sizeof(WCHAR), server_data_size(req)); len = wine_server_reply_size( reply );
memcpy(buffer, server_data_ptr(req), size); buffer[len / sizeof(WCHAR)] = 0;
buffer[size / sizeof(WCHAR)] = 0;
} }
} }
SERVER_END_VAR_REQ; SERVER_END_REQ;
return ret; return ret;
} }
...@@ -200,18 +186,14 @@ int WINECON_GrabChanges(struct inner_data* data) ...@@ -200,18 +186,14 @@ int WINECON_GrabChanges(struct inner_data* data)
int i, num; int i, num;
HANDLE h; HANDLE h;
SERVER_START_VAR_REQ( get_console_renderer_events, sizeof(evts) ) SERVER_START_REQ( get_console_renderer_events )
{ {
req->handle = (handle_t)data->hSynchro; wine_server_set_reply( req, evts, sizeof(evts) );
if (!SERVER_CALL_ERR()) req->handle = (handle_t)data->hSynchro;
{ if (!wine_server_call_err( req )) num = wine_server_reply_size(reply) / sizeof(evts[0]);
num = server_data_size(req); else num = 0;
memcpy(evts, server_data_ptr(req), num);
num /= sizeof(evts[0]);
}
else num = 0;
} }
SERVER_END_VAR_REQ; SERVER_END_REQ;
if (!num) {Trace(0, "hmm renderer signaled but no events available\n"); return 1;} if (!num) {Trace(0, "hmm renderer signaled but no events available\n"); return 1;}
/* FIXME: should do some event compression here (cursor pos, update) */ /* FIXME: should do some event compression here (cursor pos, update) */
...@@ -230,7 +212,7 @@ int WINECON_GrabChanges(struct inner_data* data) ...@@ -230,7 +212,7 @@ int WINECON_GrabChanges(struct inner_data* data)
req->access = GENERIC_READ | GENERIC_WRITE; req->access = GENERIC_READ | GENERIC_WRITE;
req->share = FILE_SHARE_READ | FILE_SHARE_WRITE; req->share = FILE_SHARE_READ | FILE_SHARE_WRITE;
req->inherit = FALSE; req->inherit = FALSE;
h = SERVER_CALL_ERR() ? 0 : (HANDLE)req->handle; h = wine_server_call_err( req ) ? 0 : (HANDLE)reply->handle;
} }
SERVER_END_REQ; SERVER_END_REQ;
Trace(1, " active(%d)", (int)h); Trace(1, " active(%d)", (int)h);
...@@ -340,7 +322,6 @@ static struct inner_data* WINECON_Init(HINSTANCE hInst, void* pid) ...@@ -340,7 +322,6 @@ static struct inner_data* WINECON_Init(HINSTANCE hInst, void* pid)
struct inner_data* data = NULL; struct inner_data* data = NULL;
DWORD ret; DWORD ret;
WCHAR szTitle[] = {'W','i','n','e',' ','c','o','n','s','o','l','e',0}; WCHAR szTitle[] = {'W','i','n','e',' ','c','o','n','s','o','l','e',0};
size_t len;
data = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*data)); data = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*data));
if (!data) return 0; if (!data) return 0;
...@@ -355,24 +336,21 @@ static struct inner_data* WINECON_Init(HINSTANCE hInst, void* pid) ...@@ -355,24 +336,21 @@ static struct inner_data* WINECON_Init(HINSTANCE hInst, void* pid)
req->access = GENERIC_READ | GENERIC_WRITE; req->access = GENERIC_READ | GENERIC_WRITE;
req->inherit = FALSE; req->inherit = FALSE;
req->pid = pid; req->pid = pid;
ret = !SERVER_CALL_ERR(); ret = !wine_server_call_err( req );
data->hConIn = (HANDLE)req->handle_in; data->hConIn = (HANDLE)reply->handle_in;
data->hSynchro = (HANDLE)req->event; data->hSynchro = (HANDLE)reply->event;
} }
SERVER_END_REQ; SERVER_END_REQ;
if (!ret) goto error; if (!ret) goto error;
len = lstrlenW(szTitle) * sizeof(WCHAR); SERVER_START_REQ( set_console_input_info )
len = min(len, REQUEST_MAX_VAR_SIZE);
SERVER_START_VAR_REQ(set_console_input_info, len)
{ {
req->handle = (handle_t)data->hConIn; req->handle = (handle_t)data->hConIn;
req->mask = SET_CONSOLE_INPUT_INFO_TITLE; req->mask = SET_CONSOLE_INPUT_INFO_TITLE;
memcpy(server_data_ptr(req), szTitle, len); wine_server_add_data( req, szTitle, strlenW(szTitle) * sizeof(WCHAR) );
ret = !SERVER_CALL_ERR(); ret = !wine_server_call_err( req );
} }
SERVER_END_VAR_REQ; SERVER_END_REQ;
if (ret) if (ret)
{ {
...@@ -382,7 +360,7 @@ static struct inner_data* WINECON_Init(HINSTANCE hInst, void* pid) ...@@ -382,7 +360,7 @@ static struct inner_data* WINECON_Init(HINSTANCE hInst, void* pid)
req->access = GENERIC_WRITE|GENERIC_READ; req->access = GENERIC_WRITE|GENERIC_READ;
req->share = FILE_SHARE_READ|FILE_SHARE_WRITE; req->share = FILE_SHARE_READ|FILE_SHARE_WRITE;
req->inherit = FALSE; req->inherit = FALSE;
data->hConOut = (HANDLE)(SERVER_CALL_ERR() ? 0 : req->handle_out); data->hConOut = (HANDLE)(wine_server_call_err( req ) ? 0 : reply->handle_out);
} }
SERVER_END_REQ; SERVER_END_REQ;
if (data->hConOut) return data; if (data->hConOut) return data;
......
...@@ -114,68 +114,59 @@ void server_protocol_perror( const char *err ) ...@@ -114,68 +114,59 @@ void server_protocol_perror( const char *err )
/*********************************************************************** /***********************************************************************
* __wine_server_exception_handler (NTDLL.@)
*/
DWORD __wine_server_exception_handler( PEXCEPTION_RECORD record, EXCEPTION_FRAME *frame,
CONTEXT *context, EXCEPTION_FRAME **pdispatcher )
{
struct __server_exception_frame *server_frame = (struct __server_exception_frame *)frame;
if ((record->ExceptionFlags & (EH_UNWINDING | EH_EXIT_UNWIND)))
NtCurrentTeb()->buffer_pos = server_frame->buffer_pos;
return ExceptionContinueSearch;
}
/***********************************************************************
* wine_server_alloc_req (NTDLL.@)
*/
void wine_server_alloc_req( union generic_request *req, size_t size )
{
unsigned int pos = NtCurrentTeb()->buffer_pos;
assert( size <= REQUEST_MAX_VAR_SIZE );
if (pos + size > NtCurrentTeb()->buffer_size)
server_protocol_error( "buffer overflow %d bytes\n",
pos + size - NtCurrentTeb()->buffer_pos );
NtCurrentTeb()->buffer_pos = pos + size;
req->header.var_offset = pos;
req->header.var_size = size;
}
/***********************************************************************
* send_request * send_request
* *
* Send a request to the server. * Send a request to the server.
*/ */
static void send_request( union generic_request *request ) static void send_request( const struct __server_request_info *req )
{ {
int ret; int i, ret;
if (!req->u.req.request_header.request_size)
{
if ((ret = write( NtCurrentTeb()->request_fd, &req->u.req,
sizeof(req->u.req) )) == sizeof(req->u.req)) return;
}
else
{
struct iovec vec[__SERVER_MAX_DATA+1];
vec[0].iov_base = (void *)&req->u.req;
vec[0].iov_len = sizeof(req->u.req);
for (i = 0; i < req->data_count; i++)
{
vec[i+1].iov_base = (void *)req->data[i].ptr;
vec[i+1].iov_len = req->data[i].size;
}
if ((ret = writev( NtCurrentTeb()->request_fd, vec, i+1 )) ==
req->u.req.request_header.request_size + sizeof(req->u.req)) return;
}
if ((ret = write( NtCurrentTeb()->request_fd, request, sizeof(*request) )) == sizeof(*request))
return;
if (ret >= 0) server_protocol_error( "partial write %d\n", ret ); if (ret >= 0) server_protocol_error( "partial write %d\n", ret );
if (errno == EPIPE) SYSDEPS_ExitThread(0); if (errno == EPIPE) SYSDEPS_ExitThread(0);
server_protocol_perror( "sendmsg" ); server_protocol_perror( "sendmsg" );
} }
/*********************************************************************** /***********************************************************************
* wait_reply * read_reply_data
* *
* Wait for a reply from the server. * Read data from the reply buffer; helper for wait_reply.
*/ */
static void wait_reply( union generic_request *req ) static void read_reply_data( void *buffer, size_t size )
{ {
int ret; int ret;
for (;;) for (;;)
{ {
if ((ret = read( NtCurrentTeb()->reply_fd, req, sizeof(*req) )) == sizeof(*req)) if ((ret = read( NtCurrentTeb()->reply_fd, buffer, size )) > 0)
return; {
if (!(size -= ret)) return;
buffer = (char *)buffer + ret;
continue;
}
if (!ret) break; if (!ret) break;
if (ret > 0) server_protocol_error( "partial read %d\n", ret );
if (errno == EINTR) continue; if (errno == EINTR) continue;
if (errno == EPIPE) break; if (errno == EPIPE) break;
server_protocol_perror("read"); server_protocol_perror("read");
...@@ -186,20 +177,34 @@ static void wait_reply( union generic_request *req ) ...@@ -186,20 +177,34 @@ static void wait_reply( union generic_request *req )
/*********************************************************************** /***********************************************************************
* wait_reply
*
* Wait for a reply from the server.
*/
inline static void wait_reply( struct __server_request_info *req )
{
read_reply_data( &req->u.reply, sizeof(req->u.reply) );
if (req->u.reply.reply_header.reply_size)
read_reply_data( req->reply_data, req->u.reply.reply_header.reply_size );
}
/***********************************************************************
* wine_server_call (NTDLL.@) * wine_server_call (NTDLL.@)
* *
* Perform a server call. * Perform a server call.
*/ */
unsigned int wine_server_call( union generic_request *req, size_t size ) unsigned int wine_server_call( void *req_ptr )
{ {
struct __server_request_info * const req = req_ptr;
sigset_t old_set; sigset_t old_set;
memset( (char *)req + size, 0, sizeof(*req) - size ); memset( (char *)&req->u.req + req->size, 0, sizeof(req->u.req) - req->size );
sigprocmask( SIG_BLOCK, &block_set, &old_set ); sigprocmask( SIG_BLOCK, &block_set, &old_set );
send_request( req ); send_request( req );
wait_reply( req ); wait_reply( req );
sigprocmask( SIG_SETMASK, &old_set, NULL ); sigprocmask( SIG_SETMASK, &old_set, NULL );
return req->header.error; return req->u.reply.reply_header.error;
} }
...@@ -331,13 +336,13 @@ int wine_server_recv_fd( handle_t handle ) ...@@ -331,13 +336,13 @@ int wine_server_recv_fd( handle_t handle )
req->flags = 0; req->flags = 0;
req->mask = 0; req->mask = 0;
req->fd = fd; req->fd = fd;
if (!SERVER_CALL()) if (!wine_server_call( req ))
{ {
if (req->cur_fd != fd) if (reply->cur_fd != fd)
{ {
/* someone was here before us */ /* someone was here before us */
close( fd ); close( fd );
fd = req->cur_fd; fd = reply->cur_fd;
} }
} }
else else
...@@ -597,47 +602,6 @@ void CLIENT_InitServer(void) ...@@ -597,47 +602,6 @@ void CLIENT_InitServer(void)
/*********************************************************************** /***********************************************************************
* set_request_buffer
*/
inline static void set_request_buffer(void)
{
char *name;
int fd, ret;
unsigned int offset, size;
/* create a temporary file */
do
{
if (!(name = tmpnam(NULL))) server_protocol_perror( "tmpnam" );
fd = open( name, O_CREAT | O_EXCL | O_RDWR, 0600 );
} while ((fd == -1) && (errno == EEXIST));
if (fd == -1) server_protocol_perror( "create" );
unlink( name );
wine_server_send_fd( fd );
SERVER_START_REQ( set_thread_buffer )
{
req->fd = fd;
ret = SERVER_CALL();
offset = req->offset;
size = req->size;
}
SERVER_END_REQ;
if (ret) server_protocol_error( "set_thread_buffer failed with status %x\n", ret );
if ((NtCurrentTeb()->buffer = mmap( 0, size, PROT_READ | PROT_WRITE,
MAP_SHARED, fd, offset )) == (void*)-1)
server_protocol_perror( "mmap" );
close( fd );
NtCurrentTeb()->buffer_pos = 0;
NtCurrentTeb()->buffer_size = size;
}
/***********************************************************************
* CLIENT_InitThread * CLIENT_InitThread
* *
* Send an init thread request. Return 0 if OK. * Send an init thread request. Return 0 if OK.
...@@ -670,11 +634,11 @@ void CLIENT_InitThread(void) ...@@ -670,11 +634,11 @@ void CLIENT_InitThread(void)
req->entry = teb->entry_point; req->entry = teb->entry_point;
req->reply_fd = reply_pipe[1]; req->reply_fd = reply_pipe[1];
req->wait_fd = teb->wait_fd[1]; req->wait_fd = teb->wait_fd[1];
ret = SERVER_CALL(); ret = wine_server_call( req );
teb->pid = req->pid; teb->pid = reply->pid;
teb->tid = req->tid; teb->tid = reply->tid;
version = req->version; version = reply->version;
if (req->boot) boot_thread_id = teb->tid; if (reply->boot) boot_thread_id = teb->tid;
else if (boot_thread_id == teb->tid) boot_thread_id = 0; else if (boot_thread_id == teb->tid) boot_thread_id = 0;
close( reply_pipe[1] ); close( reply_pipe[1] );
} }
...@@ -688,7 +652,6 @@ void CLIENT_InitThread(void) ...@@ -688,7 +652,6 @@ void CLIENT_InitThread(void)
"Or maybe the wrong wineserver is still running?\n", "Or maybe the wrong wineserver is still running?\n",
version, SERVER_PROTOCOL_VERSION, version, SERVER_PROTOCOL_VERSION,
(version > SERVER_PROTOCOL_VERSION) ? "wine" : "wineserver" ); (version > SERVER_PROTOCOL_VERSION) ? "wine" : "wineserver" );
set_request_buffer();
} }
...@@ -702,7 +665,7 @@ void CLIENT_BootDone( int debug_level ) ...@@ -702,7 +665,7 @@ void CLIENT_BootDone( int debug_level )
SERVER_START_REQ( boot_done ) SERVER_START_REQ( boot_done )
{ {
req->debug_level = debug_level; req->debug_level = debug_level;
SERVER_CALL(); wine_server_call( req );
} }
SERVER_END_REQ; SERVER_END_REQ;
} }
......
...@@ -46,8 +46,8 @@ BOOL WINAPI GetHandleInformation( HANDLE handle, LPDWORD flags ) ...@@ -46,8 +46,8 @@ BOOL WINAPI GetHandleInformation( HANDLE handle, LPDWORD flags )
req->flags = 0; req->flags = 0;
req->mask = 0; req->mask = 0;
req->fd = -1; req->fd = -1;
ret = !SERVER_CALL_ERR(); ret = !wine_server_call_err( req );
if (ret && flags) *flags = req->old_flags; if (ret && flags) *flags = reply->old_flags;
} }
SERVER_END_REQ; SERVER_END_REQ;
return ret; return ret;
...@@ -66,7 +66,7 @@ BOOL WINAPI SetHandleInformation( HANDLE handle, DWORD mask, DWORD flags ) ...@@ -66,7 +66,7 @@ BOOL WINAPI SetHandleInformation( HANDLE handle, DWORD mask, DWORD flags )
req->flags = flags; req->flags = flags;
req->mask = mask; req->mask = mask;
req->fd = -1; req->fd = -1;
ret = !SERVER_CALL_ERR(); ret = !wine_server_call_err( req );
} }
SERVER_END_REQ; SERVER_END_REQ;
return ret; return ret;
...@@ -90,11 +90,11 @@ BOOL WINAPI DuplicateHandle( HANDLE source_process, HANDLE source, ...@@ -90,11 +90,11 @@ BOOL WINAPI DuplicateHandle( HANDLE source_process, HANDLE source,
req->inherit = inherit; req->inherit = inherit;
req->options = options; req->options = options;
ret = !SERVER_CALL_ERR(); ret = !wine_server_call_err( req );
if (ret) if (ret)
{ {
if (dest) *dest = req->handle; if (dest) *dest = reply->handle;
if (req->fd != -1) close( req->fd ); if (reply->fd != -1) close( reply->fd );
} }
} }
SERVER_END_REQ; SERVER_END_REQ;
......
...@@ -20,10 +20,10 @@ BOOL WINAPI CreatePipe( PHANDLE hReadPipe, PHANDLE hWritePipe, ...@@ -20,10 +20,10 @@ BOOL WINAPI CreatePipe( PHANDLE hReadPipe, PHANDLE hWritePipe,
SERVER_START_REQ( create_pipe ) SERVER_START_REQ( create_pipe )
{ {
req->inherit = (sa && (sa->nLength>=sizeof(*sa)) && sa->bInheritHandle); req->inherit = (sa && (sa->nLength>=sizeof(*sa)) && sa->bInheritHandle);
if ((ret = !SERVER_CALL_ERR())) if ((ret = !wine_server_call_err( req )))
{ {
*hReadPipe = req->handle_read; *hReadPipe = reply->handle_read;
*hWritePipe = req->handle_write; *hWritePipe = reply->handle_write;
} }
} }
SERVER_END_REQ; SERVER_END_REQ;
......
...@@ -226,17 +226,17 @@ static void call_apcs( BOOL alertable ) ...@@ -226,17 +226,17 @@ static void call_apcs( BOOL alertable )
for (;;) for (;;)
{ {
int type = APC_NONE; int type = APC_NONE;
SERVER_START_VAR_REQ( get_apc, sizeof(args) ) SERVER_START_REQ( get_apc )
{ {
req->alertable = alertable; req->alertable = alertable;
if (!SERVER_CALL()) wine_server_set_reply( req, args, sizeof(args) );
if (!wine_server_call( req ))
{ {
type = req->type; type = reply->type;
proc = req->func; proc = reply->func;
memcpy( args, server_data_ptr(req), server_data_size(req) );
} }
} }
SERVER_END_VAR_REQ; SERVER_END_REQ;
switch(type) switch(type)
{ {
...@@ -315,7 +315,7 @@ DWORD WINAPI WaitForMultipleObjectsEx( DWORD count, const HANDLE *handles, ...@@ -315,7 +315,7 @@ DWORD WINAPI WaitForMultipleObjectsEx( DWORD count, const HANDLE *handles,
BOOL wait_all, DWORD timeout, BOOL wait_all, DWORD timeout,
BOOL alertable ) BOOL alertable )
{ {
int i, ret, cookie; int ret, cookie;
struct timeval tv; struct timeval tv;
if (count > MAXIMUM_WAIT_OBJECTS) if (count > MAXIMUM_WAIT_OBJECTS)
...@@ -329,23 +329,21 @@ DWORD WINAPI WaitForMultipleObjectsEx( DWORD count, const HANDLE *handles, ...@@ -329,23 +329,21 @@ DWORD WINAPI WaitForMultipleObjectsEx( DWORD count, const HANDLE *handles,
for (;;) for (;;)
{ {
SERVER_START_VAR_REQ( select, count * sizeof(int) ) SERVER_START_REQ( select )
{ {
int *data = server_data_ptr( req );
req->flags = SELECT_INTERRUPTIBLE; req->flags = SELECT_INTERRUPTIBLE;
req->cookie = &cookie; req->cookie = &cookie;
req->sec = tv.tv_sec; req->sec = tv.tv_sec;
req->usec = tv.tv_usec; req->usec = tv.tv_usec;
for (i = 0; i < count; i++) data[i] = handles[i]; wine_server_add_data( req, handles, count * sizeof(HANDLE) );
if (wait_all) req->flags |= SELECT_ALL; if (wait_all) req->flags |= SELECT_ALL;
if (alertable) req->flags |= SELECT_ALERTABLE; if (alertable) req->flags |= SELECT_ALERTABLE;
if (timeout != INFINITE) req->flags |= SELECT_TIMEOUT; if (timeout != INFINITE) req->flags |= SELECT_TIMEOUT;
ret = SERVER_CALL(); ret = wine_server_call( req );
} }
SERVER_END_VAR_REQ; SERVER_END_REQ;
if (ret == STATUS_PENDING) ret = wait_reply( &cookie ); if (ret == STATUS_PENDING) ret = wait_reply( &cookie );
if (ret != STATUS_USER_APC) break; if (ret != STATUS_USER_APC) break;
call_apcs( alertable ); call_apcs( alertable );
......
...@@ -51,7 +51,7 @@ TEB *THREAD_IdToTEB( DWORD id ) ...@@ -51,7 +51,7 @@ TEB *THREAD_IdToTEB( DWORD id )
{ {
req->handle = 0; req->handle = 0;
req->tid_in = (void *)id; req->tid_in = (void *)id;
if (!SERVER_CALL()) ret = req->teb; if (!wine_server_call( req )) ret = reply->teb;
} }
SERVER_END_REQ; SERVER_END_REQ;
...@@ -112,7 +112,6 @@ static void CALLBACK THREAD_FreeTEB( TEB *teb ) ...@@ -112,7 +112,6 @@ static void CALLBACK THREAD_FreeTEB( TEB *teb )
close( teb->wait_fd[1] ); close( teb->wait_fd[1] );
if (teb->stack_sel) FreeSelector16( teb->stack_sel ); if (teb->stack_sel) FreeSelector16( teb->stack_sel );
FreeSelector16( teb->teb_sel ); FreeSelector16( teb->teb_sel );
if (teb->buffer) munmap( (void *)teb->buffer, teb->buffer_size );
if (teb->debug_info) HeapFree( GetProcessHeap(), 0, teb->debug_info ); if (teb->debug_info) HeapFree( GetProcessHeap(), 0, teb->debug_info );
VirtualFree( teb->stack_base, 0, MEM_RELEASE ); VirtualFree( teb->stack_base, 0, MEM_RELEASE );
} }
...@@ -298,10 +297,10 @@ HANDLE WINAPI CreateThread( SECURITY_ATTRIBUTES *sa, DWORD stack, ...@@ -298,10 +297,10 @@ HANDLE WINAPI CreateThread( SECURITY_ATTRIBUTES *sa, DWORD stack,
req->suspend = ((flags & CREATE_SUSPENDED) != 0); req->suspend = ((flags & CREATE_SUSPENDED) != 0);
req->inherit = (sa && (sa->nLength>=sizeof(*sa)) && sa->bInheritHandle); req->inherit = (sa && (sa->nLength>=sizeof(*sa)) && sa->bInheritHandle);
req->request_fd = request_pipe[0]; req->request_fd = request_pipe[0];
if (!SERVER_CALL_ERR()) if (!wine_server_call_err( req ))
{ {
handle = req->handle; handle = reply->handle;
tid = req->tid; tid = reply->tid;
} }
close( request_pipe[0] ); close( request_pipe[0] );
} }
...@@ -370,8 +369,8 @@ void WINAPI ExitThread( DWORD code ) /* [in] Exit code for this thread */ ...@@ -370,8 +369,8 @@ void WINAPI ExitThread( DWORD code ) /* [in] Exit code for this thread */
/* send the exit code to the server */ /* send the exit code to the server */
req->handle = GetCurrentThread(); req->handle = GetCurrentThread();
req->exit_code = code; req->exit_code = code;
SERVER_CALL(); wine_server_call( req );
last = req->last; last = reply->last;
} }
SERVER_END_REQ; SERVER_END_REQ;
...@@ -400,14 +399,14 @@ BOOL WINAPI SetThreadContext( HANDLE handle, /* [in] Handle to thread ...@@ -400,14 +399,14 @@ BOOL WINAPI SetThreadContext( HANDLE handle, /* [in] Handle to thread
const CONTEXT *context ) /* [in] Address of context structure */ const CONTEXT *context ) /* [in] Address of context structure */
{ {
BOOL ret; BOOL ret;
SERVER_START_VAR_REQ( set_thread_context, sizeof(*context) ) SERVER_START_REQ( set_thread_context )
{ {
req->handle = handle; req->handle = handle;
req->flags = context->ContextFlags; req->flags = context->ContextFlags;
memcpy( server_data_ptr(req), context, sizeof(*context) ); wine_server_add_data( req, context, sizeof(*context) );
ret = !SERVER_CALL_ERR(); ret = !wine_server_call_err( req );
} }
SERVER_END_VAR_REQ; SERVER_END_REQ;
return ret; return ret;
} }
...@@ -423,15 +422,15 @@ BOOL WINAPI GetThreadContext( HANDLE handle, /* [in] Handle to thread with ...@@ -423,15 +422,15 @@ BOOL WINAPI GetThreadContext( HANDLE handle, /* [in] Handle to thread with
CONTEXT *context ) /* [out] Address of context structure */ CONTEXT *context ) /* [out] Address of context structure */
{ {
BOOL ret; BOOL ret;
SERVER_START_VAR_REQ( get_thread_context, sizeof(*context) ) SERVER_START_REQ( get_thread_context )
{ {
req->handle = handle; req->handle = handle;
req->flags = context->ContextFlags; req->flags = context->ContextFlags;
memcpy( server_data_ptr(req), context, sizeof(*context) ); wine_server_add_data( req, context, sizeof(*context) );
if ((ret = !SERVER_CALL_ERR())) wine_server_set_reply( req, context, sizeof(*context) );
memcpy( context, server_data_ptr(req), sizeof(*context) ); ret = !wine_server_call_err( req );
} }
SERVER_END_VAR_REQ; SERVER_END_REQ;
return ret; return ret;
} }
...@@ -451,7 +450,7 @@ INT WINAPI GetThreadPriority( ...@@ -451,7 +450,7 @@ INT WINAPI GetThreadPriority(
{ {
req->handle = hthread; req->handle = hthread;
req->tid_in = 0; req->tid_in = 0;
if (!SERVER_CALL_ERR()) ret = req->priority; if (!wine_server_call_err( req )) ret = reply->priority;
} }
SERVER_END_REQ; SERVER_END_REQ;
return ret; return ret;
...@@ -475,7 +474,7 @@ BOOL WINAPI SetThreadPriority( ...@@ -475,7 +474,7 @@ BOOL WINAPI SetThreadPriority(
req->handle = hthread; req->handle = hthread;
req->priority = priority; req->priority = priority;
req->mask = SET_THREAD_INFO_PRIORITY; req->mask = SET_THREAD_INFO_PRIORITY;
ret = !SERVER_CALL_ERR(); ret = !wine_server_call_err( req );
} }
SERVER_END_REQ; SERVER_END_REQ;
return ret; return ret;
...@@ -529,7 +528,7 @@ DWORD WINAPI SetThreadAffinityMask( HANDLE hThread, DWORD dwThreadAffinityMask ) ...@@ -529,7 +528,7 @@ DWORD WINAPI SetThreadAffinityMask( HANDLE hThread, DWORD dwThreadAffinityMask )
req->handle = hThread; req->handle = hThread;
req->affinity = dwThreadAffinityMask; req->affinity = dwThreadAffinityMask;
req->mask = SET_THREAD_INFO_AFFINITY; req->mask = SET_THREAD_INFO_AFFINITY;
ret = !SERVER_CALL_ERR(); ret = !wine_server_call_err( req );
/* FIXME: should return previous value */ /* FIXME: should return previous value */
} }
SERVER_END_REQ; SERVER_END_REQ;
...@@ -571,8 +570,8 @@ BOOL WINAPI GetExitCodeThread( ...@@ -571,8 +570,8 @@ BOOL WINAPI GetExitCodeThread(
{ {
req->handle = hthread; req->handle = hthread;
req->tid_in = 0; req->tid_in = 0;
ret = !SERVER_CALL_ERR(); ret = !wine_server_call_err( req );
if (ret && exitcode) *exitcode = req->exit_code; if (ret && exitcode) *exitcode = reply->exit_code;
} }
SERVER_END_REQ; SERVER_END_REQ;
return ret; return ret;
...@@ -597,7 +596,7 @@ DWORD WINAPI ResumeThread( ...@@ -597,7 +596,7 @@ DWORD WINAPI ResumeThread(
SERVER_START_REQ( resume_thread ) SERVER_START_REQ( resume_thread )
{ {
req->handle = hthread; req->handle = hthread;
if (!SERVER_CALL_ERR()) ret = req->count; if (!wine_server_call_err( req )) ret = reply->count;
} }
SERVER_END_REQ; SERVER_END_REQ;
return ret; return ret;
...@@ -618,7 +617,7 @@ DWORD WINAPI SuspendThread( ...@@ -618,7 +617,7 @@ DWORD WINAPI SuspendThread(
SERVER_START_REQ( suspend_thread ) SERVER_START_REQ( suspend_thread )
{ {
req->handle = hthread; req->handle = hthread;
if (!SERVER_CALL_ERR()) ret = req->count; if (!wine_server_call_err( req )) ret = reply->count;
} }
SERVER_END_REQ; SERVER_END_REQ;
return ret; return ret;
...@@ -637,7 +636,7 @@ DWORD WINAPI QueueUserAPC( PAPCFUNC func, HANDLE hthread, ULONG_PTR data ) ...@@ -637,7 +636,7 @@ DWORD WINAPI QueueUserAPC( PAPCFUNC func, HANDLE hthread, ULONG_PTR data )
req->user = 1; req->user = 1;
req->func = func; req->func = func;
req->param = (void *)data; req->param = (void *)data;
ret = !SERVER_CALL_ERR(); ret = !wine_server_call_err( req );
} }
SERVER_END_REQ; SERVER_END_REQ;
return ret; return ret;
......
...@@ -18,24 +18,16 @@ ...@@ -18,24 +18,16 @@
*/ */
HANDLE WINAPI CreateWaitableTimerA( SECURITY_ATTRIBUTES *sa, BOOL manual, LPCSTR name ) HANDLE WINAPI CreateWaitableTimerA( SECURITY_ATTRIBUTES *sa, BOOL manual, LPCSTR name )
{ {
HANDLE ret; WCHAR buffer[MAX_PATH];
DWORD len = name ? MultiByteToWideChar( CP_ACP, 0, name, strlen(name), NULL, 0 ) : 0;
if (len >= MAX_PATH) if (!name) return CreateWaitableTimerW( sa, manual, NULL );
if (!MultiByteToWideChar( CP_ACP, 0, name, -1, buffer, MAX_PATH ))
{ {
SetLastError( ERROR_FILENAME_EXCED_RANGE ); SetLastError( ERROR_FILENAME_EXCED_RANGE );
return 0; return 0;
} }
SERVER_START_VAR_REQ( create_timer, len * sizeof(WCHAR) ) return CreateWaitableTimerW( sa, manual, buffer );
{
req->manual = manual;
req->inherit = (sa && (sa->nLength>=sizeof(*sa)) && sa->bInheritHandle);
if (len) MultiByteToWideChar( CP_ACP, 0, name, strlen(name), server_data_ptr(req), len );
SetLastError(0);
SERVER_CALL_ERR();
ret = req->handle;
}
SERVER_END_VAR_REQ;
return ret;
} }
...@@ -51,16 +43,16 @@ HANDLE WINAPI CreateWaitableTimerW( SECURITY_ATTRIBUTES *sa, BOOL manual, LPCWST ...@@ -51,16 +43,16 @@ HANDLE WINAPI CreateWaitableTimerW( SECURITY_ATTRIBUTES *sa, BOOL manual, LPCWST
SetLastError( ERROR_FILENAME_EXCED_RANGE ); SetLastError( ERROR_FILENAME_EXCED_RANGE );
return 0; return 0;
} }
SERVER_START_VAR_REQ( create_timer, len * sizeof(WCHAR) ) SERVER_START_REQ( create_timer )
{ {
req->manual = manual; req->manual = manual;
req->inherit = (sa && (sa->nLength>=sizeof(*sa)) && sa->bInheritHandle); req->inherit = (sa && (sa->nLength>=sizeof(*sa)) && sa->bInheritHandle);
memcpy( server_data_ptr(req), name, len * sizeof(WCHAR) ); wine_server_add_data( req, name, len * sizeof(WCHAR) );
SetLastError(0); SetLastError(0);
SERVER_CALL_ERR(); wine_server_call_err( req );
ret = req->handle; ret = reply->handle;
} }
SERVER_END_VAR_REQ; SERVER_END_REQ;
return ret; return ret;
} }
...@@ -70,23 +62,16 @@ HANDLE WINAPI CreateWaitableTimerW( SECURITY_ATTRIBUTES *sa, BOOL manual, LPCWST ...@@ -70,23 +62,16 @@ HANDLE WINAPI CreateWaitableTimerW( SECURITY_ATTRIBUTES *sa, BOOL manual, LPCWST
*/ */
HANDLE WINAPI OpenWaitableTimerA( DWORD access, BOOL inherit, LPCSTR name ) HANDLE WINAPI OpenWaitableTimerA( DWORD access, BOOL inherit, LPCSTR name )
{ {
HANDLE ret; WCHAR buffer[MAX_PATH];
DWORD len = name ? MultiByteToWideChar( CP_ACP, 0, name, strlen(name), NULL, 0 ) : 0;
if (len >= MAX_PATH) if (!name) return OpenWaitableTimerW( access, inherit, NULL );
if (!MultiByteToWideChar( CP_ACP, 0, name, -1, buffer, MAX_PATH ))
{ {
SetLastError( ERROR_FILENAME_EXCED_RANGE ); SetLastError( ERROR_FILENAME_EXCED_RANGE );
return 0; return 0;
} }
SERVER_START_VAR_REQ( open_timer, len * sizeof(WCHAR) ) return OpenWaitableTimerW( access, inherit, buffer );
{
req->access = access;
req->inherit = inherit;
if (len) MultiByteToWideChar( CP_ACP, 0, name, strlen(name), server_data_ptr(req), len );
SERVER_CALL_ERR();
ret = req->handle;
}
SERVER_END_VAR_REQ;
return ret;
} }
...@@ -102,15 +87,15 @@ HANDLE WINAPI OpenWaitableTimerW( DWORD access, BOOL inherit, LPCWSTR name ) ...@@ -102,15 +87,15 @@ HANDLE WINAPI OpenWaitableTimerW( DWORD access, BOOL inherit, LPCWSTR name )
SetLastError( ERROR_FILENAME_EXCED_RANGE ); SetLastError( ERROR_FILENAME_EXCED_RANGE );
return 0; return 0;
} }
SERVER_START_VAR_REQ( open_timer, len * sizeof(WCHAR) ) SERVER_START_REQ( open_timer )
{ {
req->access = access; req->access = access;
req->inherit = inherit; req->inherit = inherit;
memcpy( server_data_ptr(req), name, len * sizeof(WCHAR) ); wine_server_add_data( req, name, len * sizeof(WCHAR) );
SERVER_CALL_ERR(); wine_server_call_err( req );
ret = req->handle; ret = reply->handle;
} }
SERVER_END_VAR_REQ; SERVER_END_REQ;
return ret; return ret;
} }
...@@ -150,7 +135,7 @@ BOOL WINAPI SetWaitableTimer( HANDLE handle, const LARGE_INTEGER *when, LONG per ...@@ -150,7 +135,7 @@ BOOL WINAPI SetWaitableTimer( HANDLE handle, const LARGE_INTEGER *when, LONG per
req->callback = callback; req->callback = callback;
req->arg = arg; req->arg = arg;
if (resume) SetLastError( ERROR_NOT_SUPPORTED ); /* set error but can still succeed */ if (resume) SetLastError( ERROR_NOT_SUPPORTED ); /* set error but can still succeed */
ret = !SERVER_CALL_ERR(); ret = !wine_server_call_err( req );
} }
SERVER_END_REQ; SERVER_END_REQ;
return ret; return ret;
...@@ -166,7 +151,7 @@ BOOL WINAPI CancelWaitableTimer( HANDLE handle ) ...@@ -166,7 +151,7 @@ BOOL WINAPI CancelWaitableTimer( HANDLE handle )
SERVER_START_REQ( cancel_timer ) SERVER_START_REQ( cancel_timer )
{ {
req->handle = handle; req->handle = handle;
ret = !SERVER_CALL_ERR(); ret = !wine_server_call_err( req );
} }
SERVER_END_REQ; SERVER_END_REQ;
return ret; return ret;
......
...@@ -28,7 +28,7 @@ DECL_HANDLER(create_async) ...@@ -28,7 +28,7 @@ DECL_HANDLER(create_async)
/* FIXME: check if this object is allowed to do overlapped I/O */ /* FIXME: check if this object is allowed to do overlapped I/O */
/* FIXME: this should be a function pointer */ /* FIXME: this should be a function pointer */
req->timeout = get_serial_async_timeout(obj,req->type,req->count); reply->timeout = get_serial_async_timeout(obj,req->type,req->count);
release_object(obj); release_object(obj);
} }
...@@ -65,11 +65,14 @@ static const struct object_ops atom_table_ops = ...@@ -65,11 +65,14 @@ static const struct object_ops atom_table_ops =
static struct atom_table *global_table; static struct atom_table *global_table;
/* copy an atom name to a temporary area */ /* copy an atom name from the request to a temporary area */
static const WCHAR *copy_name( const WCHAR *str, size_t len ) static const WCHAR *copy_request_name(void)
{ {
static WCHAR buffer[MAX_ATOM_LEN+1]; static WCHAR buffer[MAX_ATOM_LEN+1];
const WCHAR *str = get_req_data();
size_t len = get_req_data_size();
if (len > MAX_ATOM_LEN*sizeof(WCHAR)) if (len > MAX_ATOM_LEN*sizeof(WCHAR))
{ {
set_error( STATUS_INVALID_PARAMETER ); set_error( STATUS_INVALID_PARAMETER );
...@@ -267,27 +270,6 @@ static atom_t find_atom( struct atom_table *table, const WCHAR *str ) ...@@ -267,27 +270,6 @@ static atom_t find_atom( struct atom_table *table, const WCHAR *str )
return 0; return 0;
} }
/* get an atom name and refcount*/
static size_t get_atom_name( struct atom_table *table, atom_t atom,
WCHAR *str, size_t maxsize, int *count )
{
size_t len = 0;
struct atom_entry *entry = get_atom_entry( table, atom );
*count = -1;
if (entry)
{
*count = entry->count;
len = strlenW( entry->str ) * sizeof(WCHAR);
if (len <= maxsize) memcpy( str, entry->str, len );
else
{
set_error( STATUS_BUFFER_OVERFLOW );
len = 0;
}
}
return len;
}
/* increment the ref count of a global atom; used for window properties */ /* increment the ref count of a global atom; used for window properties */
int grab_global_atom( atom_t atom ) int grab_global_atom( atom_t atom )
{ {
...@@ -310,8 +292,8 @@ DECL_HANDLER(add_atom) ...@@ -310,8 +292,8 @@ DECL_HANDLER(add_atom)
if (!*table_ptr) *table_ptr = create_table(0); if (!*table_ptr) *table_ptr = create_table(0);
if (*table_ptr) if (*table_ptr)
{ {
const WCHAR *name = copy_name( get_req_data(req), get_req_data_size(req) ); const WCHAR *name = copy_request_name();
if (name) req->atom = add_atom( *table_ptr, name ); if (name) reply->atom = add_atom( *table_ptr, name );
} }
} }
...@@ -324,18 +306,26 @@ DECL_HANDLER(delete_atom) ...@@ -324,18 +306,26 @@ DECL_HANDLER(delete_atom)
/* find a global atom */ /* find a global atom */
DECL_HANDLER(find_atom) DECL_HANDLER(find_atom)
{ {
const WCHAR *name = copy_name( get_req_data(req), get_req_data_size(req) ); const WCHAR *name = copy_request_name();
if (name) if (name)
req->atom = find_atom( req->local ? current->process->atom_table : global_table, name ); reply->atom = find_atom( req->local ? current->process->atom_table : global_table, name );
} }
/* get global atom name */ /* get global atom name */
DECL_HANDLER(get_atom_name) DECL_HANDLER(get_atom_name)
{ {
WCHAR *name = get_req_data(req); struct atom_entry *entry;
size_t size = get_atom_name( req->local ? current->process->atom_table : global_table, size_t len = 0;
req->atom, name, get_req_data_size(req), &req->count );
set_req_data_size( req, size ); reply->count = -1;
if ((entry = get_atom_entry( req->local ? current->process->atom_table : global_table,
req->atom )))
{
reply->count = entry->count;
len = strlenW( entry->str ) * sizeof(WCHAR);
if (len <= get_reply_max_size()) set_reply_data( entry->str, len );
else set_error( STATUS_BUFFER_OVERFLOW );
}
} }
/* init the process atom table */ /* init the process atom table */
......
...@@ -72,11 +72,11 @@ DECL_HANDLER(create_change_notification) ...@@ -72,11 +72,11 @@ DECL_HANDLER(create_change_notification)
{ {
struct change *change; struct change *change;
req->handle = 0; reply->handle = 0;
if ((change = create_change_notification( req->subtree, req->filter ))) if ((change = create_change_notification( req->subtree, req->filter )))
{ {
req->handle = alloc_handle( current->process, change, reply->handle = alloc_handle( current->process, change,
STANDARD_RIGHTS_REQUIRED|SYNCHRONIZE, 0 ); STANDARD_RIGHTS_REQUIRED|SYNCHRONIZE, 0 );
release_object( change ); release_object( change );
} }
} }
...@@ -7,6 +7,8 @@ ...@@ -7,6 +7,8 @@
#ifndef __WINE_SERVER_CONSOLE_H #ifndef __WINE_SERVER_CONSOLE_H
#define __WINE_SERVER_CONSOLE_H #define __WINE_SERVER_CONSOLE_H
#include "wincon.h"
struct screen_buffer; struct screen_buffer;
struct console_input_events; struct console_input_events;
...@@ -18,7 +20,7 @@ struct console_input ...@@ -18,7 +20,7 @@ struct console_input
int mode; /* input mode */ int mode; /* input mode */
struct screen_buffer *active; /* active screen buffer */ struct screen_buffer *active; /* active screen buffer */
int recnum; /* number of input records */ int recnum; /* number of input records */
void *records; /* input records */ INPUT_RECORD *records; /* input records */
struct console_input_events *evt; /* synchronization event with renderer */ struct console_input_events *evt; /* synchronization event with renderer */
WCHAR *title; /* console title */ WCHAR *title; /* console title */
WCHAR **history; /* lines history */ WCHAR **history; /* lines history */
......
...@@ -144,7 +144,7 @@ static void get_thread_context( struct thread *thread, unsigned int flags, CONTE ...@@ -144,7 +144,7 @@ static void get_thread_context( struct thread *thread, unsigned int flags, CONTE
/* set a thread context */ /* set a thread context */
static void set_thread_context( struct thread *thread, unsigned int flags, CONTEXT *context ) static void set_thread_context( struct thread *thread, unsigned int flags, const CONTEXT *context )
{ {
int pid = thread->unix_pid; int pid = thread->unix_pid;
if (flags & CONTEXT_FULL) if (flags & CONTEXT_FULL)
...@@ -195,7 +195,6 @@ static void set_thread_context( struct thread *thread, unsigned int flags, CONTE ...@@ -195,7 +195,6 @@ static void set_thread_context( struct thread *thread, unsigned int flags, CONTE
/* we can use context->FloatSave directly as it is using the */ /* we can use context->FloatSave directly as it is using the */
/* correct structure (the same as fsave/frstor) */ /* correct structure (the same as fsave/frstor) */
if (ptrace( PTRACE_SETFPREGS, pid, 0, &context->FloatSave ) == -1) goto error; if (ptrace( PTRACE_SETFPREGS, pid, 0, &context->FloatSave ) == -1) goto error;
context->FloatSave.Cr0NpxState = 0; /* FIXME */
} }
return; return;
error: error:
...@@ -256,7 +255,7 @@ static void get_thread_context( struct thread *thread, unsigned int flags, CONTE ...@@ -256,7 +255,7 @@ static void get_thread_context( struct thread *thread, unsigned int flags, CONTE
/* set a thread context */ /* set a thread context */
static void set_thread_context( struct thread *thread, unsigned int flags, CONTEXT *context ) static void set_thread_context( struct thread *thread, unsigned int flags, const CONTEXT *context )
{ {
int pid = thread->unix_pid; int pid = thread->unix_pid;
if (flags & CONTEXT_FULL) if (flags & CONTEXT_FULL)
...@@ -303,7 +302,6 @@ static void set_thread_context( struct thread *thread, unsigned int flags, CONTE ...@@ -303,7 +302,6 @@ static void set_thread_context( struct thread *thread, unsigned int flags, CONTE
/* we can use context->FloatSave directly as it is using the */ /* we can use context->FloatSave directly as it is using the */
/* correct structure (the same as fsave/frstor) */ /* correct structure (the same as fsave/frstor) */
if (ptrace( PTRACE_SETFPREGS, pid, 0, (int) &context->FloatSave ) == -1) goto error; if (ptrace( PTRACE_SETFPREGS, pid, 0, (int) &context->FloatSave ) == -1) goto error;
context->FloatSave.Cr0NpxState = 0; /* FIXME */
} }
return; return;
error: error:
...@@ -365,7 +363,7 @@ static void get_thread_context( struct thread *thread, unsigned int flags, CONTE ...@@ -365,7 +363,7 @@ static void get_thread_context( struct thread *thread, unsigned int flags, CONTE
/* set a thread context */ /* set a thread context */
static void set_thread_context( struct thread *thread, unsigned int flags, CONTEXT *context ) static void set_thread_context( struct thread *thread, unsigned int flags, const CONTEXT *context )
{ {
int pid = thread->unix_pid; int pid = thread->unix_pid;
if (flags & CONTEXT_FULL) if (flags & CONTEXT_FULL)
...@@ -412,7 +410,6 @@ static void set_thread_context( struct thread *thread, unsigned int flags, CONTE ...@@ -412,7 +410,6 @@ static void set_thread_context( struct thread *thread, unsigned int flags, CONTE
/* we can use context->FloatSave directly as it is using the */ /* we can use context->FloatSave directly as it is using the */
/* correct structure (the same as fsave/frstor) */ /* correct structure (the same as fsave/frstor) */
if (ptrace( PTRACE_SETFPREGS, pid, 0, (int) &context->FloatSave ) == -1) goto error; if (ptrace( PTRACE_SETFPREGS, pid, 0, (int) &context->FloatSave ) == -1) goto error;
context->FloatSave.Cr0NpxState = 0; /* FIXME */
} }
return; return;
error: error:
...@@ -425,7 +422,7 @@ static void set_thread_context( struct thread *thread, unsigned int flags, CONTE ...@@ -425,7 +422,7 @@ static void set_thread_context( struct thread *thread, unsigned int flags, CONTE
/* copy a context structure according to the flags */ /* copy a context structure according to the flags */
static void copy_context( CONTEXT *to, CONTEXT *from, int flags ) static void copy_context( CONTEXT *to, const CONTEXT *from, int flags )
{ {
if (flags & CONTEXT_CONTROL) if (flags & CONTEXT_CONTROL)
{ {
...@@ -486,27 +483,34 @@ int get_thread_single_step( struct thread *thread ) ...@@ -486,27 +483,34 @@ int get_thread_single_step( struct thread *thread )
DECL_HANDLER(get_thread_context) DECL_HANDLER(get_thread_context)
{ {
struct thread *thread; struct thread *thread;
void *data;
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)) if (get_reply_max_size() < sizeof(CONTEXT))
{ {
set_error( STATUS_INVALID_PARAMETER ); set_error( STATUS_INVALID_PARAMETER );
return; return;
} }
if ((thread = get_thread_from_handle( req->handle, THREAD_GET_CONTEXT ))) if (!(thread = get_thread_from_handle( req->handle, THREAD_GET_CONTEXT ))) return;
if ((data = set_reply_data_size( sizeof(CONTEXT) )))
{ {
/* copy incoming context into reply */
memset( data, 0, sizeof(CONTEXT) );
memcpy( data, get_req_data(), min( get_req_data_size(), sizeof(CONTEXT) ));
if (thread->context) /* thread is inside an exception event */ if (thread->context) /* thread is inside an exception event */
{ {
copy_context( get_req_data(req), thread->context, flags ); copy_context( data, 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, get_req_data(req) ); get_thread_context( thread, flags, data );
resume_thread( thread ); resume_thread( thread );
} }
release_object( thread );
} }
release_object( thread );
} }
...@@ -516,7 +520,7 @@ DECL_HANDLER(set_thread_context) ...@@ -516,7 +520,7 @@ 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)) if (get_req_data_size() < sizeof(CONTEXT))
{ {
set_error( STATUS_INVALID_PARAMETER ); set_error( STATUS_INVALID_PARAMETER );
return; return;
...@@ -525,12 +529,12 @@ DECL_HANDLER(set_thread_context) ...@@ -525,12 +529,12 @@ DECL_HANDLER(set_thread_context)
{ {
if (thread->context) /* thread is inside an exception event */ if (thread->context) /* thread is inside an exception event */
{ {
copy_context( thread->context, get_req_data(req), flags ); copy_context( thread->context, get_req_data(), 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, get_req_data(req) ); set_thread_context( thread, flags, get_req_data() );
resume_thread( thread ); resume_thread( thread );
} }
release_object( thread ); release_object( thread );
......
...@@ -78,7 +78,7 @@ static void get_thread_context( struct thread *thread, unsigned int flags, CONTE ...@@ -78,7 +78,7 @@ static void get_thread_context( struct thread *thread, unsigned int flags, CONTE
/* set a thread context */ /* set a thread context */
static void set_thread_context( struct thread *thread, unsigned int flags, CONTEXT *context ) static void set_thread_context( struct thread *thread, unsigned int flags, const CONTEXT *context )
{ {
/* FIXME */ /* FIXME */
} }
...@@ -89,7 +89,7 @@ static void set_thread_context( struct thread *thread, unsigned int flags, CONTE ...@@ -89,7 +89,7 @@ static void set_thread_context( struct thread *thread, unsigned int flags, CONTE
/* copy a context structure according to the flags */ /* copy a context structure according to the flags */
static void copy_context( CONTEXT *to, CONTEXT *from, int flags ) static void copy_context( CONTEXT *to, const CONTEXT *from, int flags )
{ {
if (flags & CONTEXT_CONTROL) if (flags & CONTEXT_CONTROL)
{ {
...@@ -164,27 +164,30 @@ int get_thread_single_step( struct thread *thread ) ...@@ -164,27 +164,30 @@ int get_thread_single_step( struct thread *thread )
DECL_HANDLER(get_thread_context) DECL_HANDLER(get_thread_context)
{ {
struct thread *thread; struct thread *thread;
void *data;
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)) if (get_reply_max_size() < sizeof(CONTEXT))
{ {
set_error( STATUS_INVALID_PARAMETER ); set_error( STATUS_INVALID_PARAMETER );
return; return;
} }
if ((thread = get_thread_from_handle( req->handle, THREAD_GET_CONTEXT ))) if (!(thread = get_thread_from_handle( req->handle, THREAD_GET_CONTEXT ))) return;
if ((data = set_reply_data_size( sizeof(CONTEXT) )))
{ {
if (thread->context) /* thread is inside an exception event */ if (thread->context) /* thread is inside an exception event */
{ {
copy_context( get_req_data(req), thread->context, flags ); copy_context( data, thread->context, flags );
flags = 0; flags = 0;
} }
if (flags && suspend_for_ptrace( thread )) if (flags && suspend_for_ptrace( thread ))
{ {
get_thread_context( thread, flags, get_req_data(req) ); get_thread_context( thread, flags, data );
resume_thread( thread ); resume_thread( thread );
} }
release_object( thread );
} }
release_object( thread );
} }
...@@ -194,7 +197,7 @@ DECL_HANDLER(set_thread_context) ...@@ -194,7 +197,7 @@ 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)) if (get_req_data_size() < sizeof(CONTEXT))
{ {
set_error( STATUS_INVALID_PARAMETER ); set_error( STATUS_INVALID_PARAMETER );
return; return;
...@@ -203,12 +206,12 @@ DECL_HANDLER(set_thread_context) ...@@ -203,12 +206,12 @@ DECL_HANDLER(set_thread_context)
{ {
if (thread->context) /* thread is inside an exception event */ if (thread->context) /* thread is inside an exception event */
{ {
copy_context( thread->context, get_req_data(req), flags ); copy_context( thread->context, get_req_data(), flags );
flags = 0; flags = 0;
} }
if (flags && suspend_for_ptrace( thread )) if (flags && suspend_for_ptrace( thread ))
{ {
set_thread_context( thread, flags, get_req_data(req) ); set_thread_context( thread, flags, get_req_data() );
resume_thread( thread ); resume_thread( thread );
} }
release_object( thread ); release_object( thread );
......
...@@ -353,7 +353,7 @@ static int continue_debug_event( struct process *process, struct thread *thread, ...@@ -353,7 +353,7 @@ static int continue_debug_event( struct process *process, struct thread *thread,
/* alloc a debug event for a debugger */ /* alloc a debug event for a debugger */
static struct debug_event *alloc_debug_event( struct thread *thread, int code, static struct debug_event *alloc_debug_event( struct thread *thread, int code,
void *arg, CONTEXT *context ) void *arg, const CONTEXT *context )
{ {
struct thread *debugger = thread->process->debugger; struct thread *debugger = thread->process->debugger;
struct debug_event *event; struct debug_event *event;
...@@ -498,25 +498,23 @@ DECL_HANDLER(wait_debug_event) ...@@ -498,25 +498,23 @@ DECL_HANDLER(wait_debug_event)
set_error( STATUS_INVALID_HANDLE ); set_error( STATUS_INVALID_HANDLE );
return; return;
} }
req->wait = 0; reply->wait = 0;
if ((event = find_event_to_send( debug_ctx ))) if ((event = find_event_to_send( debug_ctx )))
{ {
size_t size = get_req_data_size(req); size_t size = get_reply_max_size();
event->state = EVENT_SENT; event->state = EVENT_SENT;
event->sender->debug_event = event; event->sender->debug_event = event;
req->pid = event->sender->process; reply->pid = event->sender->process;
req->tid = event->sender; reply->tid = event->sender;
if (size > sizeof(debug_event_t)) size = sizeof(debug_event_t); if (size > sizeof(debug_event_t)) size = sizeof(debug_event_t);
memcpy( get_req_data(req), &event->data, size ); set_reply_data( &event->data, size );
set_req_data_size( req, size );
} }
else /* no event ready */ else /* no event ready */
{ {
req->pid = 0; reply->pid = 0;
req->tid = 0; reply->tid = 0;
set_req_data_size( req, 0 );
if (req->get_handle) if (req->get_handle)
req->wait = alloc_handle( current->process, debug_ctx, SYNCHRONIZE, FALSE ); reply->wait = alloc_handle( current->process, debug_ctx, SYNCHRONIZE, FALSE );
} }
} }
...@@ -562,15 +560,15 @@ DECL_HANDLER(debug_process) ...@@ -562,15 +560,15 @@ DECL_HANDLER(debug_process)
/* queue an exception event */ /* queue an exception event */
DECL_HANDLER(queue_exception_event) DECL_HANDLER(queue_exception_event)
{ {
req->handle = 0; reply->handle = 0;
if (current->process->debugger) if (current->process->debugger)
{ {
struct debug_event_exception data; struct debug_event_exception data;
struct debug_event *event; struct debug_event *event;
CONTEXT *context = get_req_data( req ); const CONTEXT *context = get_req_data();
EXCEPTION_RECORD *rec = (EXCEPTION_RECORD *)(context + 1); EXCEPTION_RECORD *rec = (EXCEPTION_RECORD *)(context + 1);
if (get_req_data_size( req ) < sizeof(*rec) + sizeof(*context)) if (get_req_data_size() < sizeof(*rec) + sizeof(*context))
{ {
set_error( STATUS_INVALID_PARAMETER ); set_error( STATUS_INVALID_PARAMETER );
return; return;
...@@ -579,7 +577,7 @@ DECL_HANDLER(queue_exception_event) ...@@ -579,7 +577,7 @@ DECL_HANDLER(queue_exception_event)
data.first = req->first; data.first = req->first;
if ((event = alloc_debug_event( current, EXCEPTION_DEBUG_EVENT, &data, context ))) if ((event = alloc_debug_event( current, EXCEPTION_DEBUG_EVENT, &data, context )))
{ {
if ((req->handle = alloc_handle( current->process, event, SYNCHRONIZE, FALSE ))) if ((reply->handle = alloc_handle( current->process, event, SYNCHRONIZE, FALSE )))
{ {
link_event( event ); link_event( event );
suspend_process( current->process ); suspend_process( current->process );
...@@ -593,26 +591,24 @@ DECL_HANDLER(queue_exception_event) ...@@ -593,26 +591,24 @@ DECL_HANDLER(queue_exception_event)
DECL_HANDLER(get_exception_status) DECL_HANDLER(get_exception_status)
{ {
struct debug_event *event; struct debug_event *event;
size_t size = 0;
req->status = 0; reply->status = 0;
if ((event = (struct debug_event *)get_handle_obj( current->process, req->handle, if ((event = (struct debug_event *)get_handle_obj( current->process, req->handle,
0, &debug_event_ops ))) 0, &debug_event_ops )))
{ {
if (event->state == EVENT_CONTINUED) if (event->state == EVENT_CONTINUED)
{ {
req->status = event->status; reply->status = event->status;
if (current->context == &event->context) if (current->context == &event->context)
{ {
size = min( sizeof(CONTEXT), get_req_data_size(req) ); size_t size = min( sizeof(CONTEXT), get_reply_max_size() );
memcpy( get_req_data(req), &event->context, size ); set_reply_data( &event->context, size );
current->context = NULL; current->context = NULL;
} }
} }
else set_error( STATUS_PENDING ); else set_error( STATUS_PENDING );
release_object( event ); release_object( event );
} }
set_req_data_size( req, size );
} }
/* send an output string to the debugger */ /* send an output string to the debugger */
......
...@@ -29,7 +29,7 @@ struct device ...@@ -29,7 +29,7 @@ struct device
}; };
static void device_dump( struct object *obj, int verbose ); static void device_dump( struct object *obj, int verbose );
static int device_get_info( struct object *obj, struct get_file_info_request *req ); static int device_get_info( struct object *obj, struct get_file_info_reply *reply );
static const struct object_ops device_ops = static const struct object_ops device_ops =
{ {
...@@ -64,23 +64,23 @@ static void device_dump( struct object *obj, int verbose ) ...@@ -64,23 +64,23 @@ static void device_dump( struct object *obj, int verbose )
fprintf( stderr, "Device id=%08x\n", dev->id ); fprintf( stderr, "Device id=%08x\n", dev->id );
} }
static int device_get_info( struct object *obj, struct get_file_info_request *req ) static int device_get_info( struct object *obj, struct get_file_info_reply *reply )
{ {
struct device *dev = (struct device *)obj; struct device *dev = (struct device *)obj;
assert( obj->ops == &device_ops ); assert( obj->ops == &device_ops );
if (req) if (reply)
{ {
req->type = FILE_TYPE_UNKNOWN; reply->type = FILE_TYPE_UNKNOWN;
req->attr = dev->id; /* hack! */ reply->attr = dev->id; /* hack! */
req->access_time = 0; reply->access_time = 0;
req->write_time = 0; reply->write_time = 0;
req->size_high = 0; reply->size_high = 0;
req->size_low = 0; reply->size_low = 0;
req->links = 0; reply->links = 0;
req->index_high = 0; reply->index_high = 0;
req->index_low = 0; reply->index_low = 0;
req->serial = 0; reply->serial = 0;
} }
return FD_TYPE_DEFAULT; return FD_TYPE_DEFAULT;
} }
...@@ -90,10 +90,10 @@ DECL_HANDLER(create_device) ...@@ -90,10 +90,10 @@ DECL_HANDLER(create_device)
{ {
struct device *dev; struct device *dev;
req->handle = 0; reply->handle = 0;
if ((dev = create_device( req->id ))) if ((dev = create_device( req->id )))
{ {
req->handle = alloc_handle( current->process, dev, req->access, req->inherit ); reply->handle = alloc_handle( current->process, dev, req->access, req->inherit );
release_object( dev ); release_object( dev );
} }
} }
...@@ -115,11 +115,11 @@ DECL_HANDLER(create_event) ...@@ -115,11 +115,11 @@ DECL_HANDLER(create_event)
{ {
struct event *event; struct event *event;
req->handle = 0; reply->handle = 0;
if ((event = create_event( get_req_data(req), get_req_data_size(req), if ((event = create_event( get_req_data(), get_req_data_size(),
req->manual_reset, req->initial_state ))) req->manual_reset, req->initial_state )))
{ {
req->handle = alloc_handle( current->process, event, EVENT_ALL_ACCESS, req->inherit ); reply->handle = alloc_handle( current->process, event, EVENT_ALL_ACCESS, req->inherit );
release_object( event ); release_object( event );
} }
} }
...@@ -127,8 +127,8 @@ DECL_HANDLER(create_event) ...@@ -127,8 +127,8 @@ DECL_HANDLER(create_event)
/* open a handle to an event */ /* open a handle to an event */
DECL_HANDLER(open_event) DECL_HANDLER(open_event)
{ {
req->handle = open_object( get_req_data(req), get_req_data_size(req), reply->handle = open_object( get_req_data(), get_req_data_size(),
&event_ops, req->access, req->inherit ); &event_ops, req->access, req->inherit );
} }
/* do an event operation */ /* do an event operation */
......
...@@ -49,7 +49,7 @@ static void file_dump( struct object *obj, int verbose ); ...@@ -49,7 +49,7 @@ static void file_dump( struct object *obj, int verbose );
static int file_get_poll_events( struct object *obj ); static int file_get_poll_events( struct object *obj );
static int file_get_fd( struct object *obj ); static int file_get_fd( struct object *obj );
static int file_flush( struct object *obj ); static int file_flush( struct object *obj );
static int file_get_info( struct object *obj, struct get_file_info_request *req ); static int file_get_info( struct object *obj, struct get_file_info_reply *reply );
static void file_destroy( struct object *obj ); static void file_destroy( struct object *obj );
static const struct object_ops file_ops = static const struct object_ops file_ops =
...@@ -271,13 +271,13 @@ static int file_flush( struct object *obj ) ...@@ -271,13 +271,13 @@ static int file_flush( struct object *obj )
return ret; return ret;
} }
static int file_get_info( struct object *obj, struct get_file_info_request *req ) static int file_get_info( struct object *obj, struct get_file_info_reply *reply )
{ {
struct stat st; struct stat st;
struct file *file = (struct file *)obj; struct file *file = (struct file *)obj;
assert( obj->ops == &file_ops ); assert( obj->ops == &file_ops );
if (req) if (reply)
{ {
if (fstat( file->obj.fd, &st ) == -1) if (fstat( file->obj.fd, &st ) == -1)
{ {
...@@ -285,27 +285,27 @@ static int file_get_info( struct object *obj, struct get_file_info_request *req ...@@ -285,27 +285,27 @@ static int file_get_info( struct object *obj, struct get_file_info_request *req
return FD_TYPE_INVALID; return FD_TYPE_INVALID;
} }
if (S_ISCHR(st.st_mode) || S_ISFIFO(st.st_mode) || if (S_ISCHR(st.st_mode) || S_ISFIFO(st.st_mode) ||
S_ISSOCK(st.st_mode) || isatty(file->obj.fd)) req->type = FILE_TYPE_CHAR; S_ISSOCK(st.st_mode) || isatty(file->obj.fd)) reply->type = FILE_TYPE_CHAR;
else req->type = FILE_TYPE_DISK; else reply->type = FILE_TYPE_DISK;
if (S_ISDIR(st.st_mode)) req->attr = FILE_ATTRIBUTE_DIRECTORY; if (S_ISDIR(st.st_mode)) reply->attr = FILE_ATTRIBUTE_DIRECTORY;
else req->attr = FILE_ATTRIBUTE_ARCHIVE; else reply->attr = FILE_ATTRIBUTE_ARCHIVE;
if (!(st.st_mode & S_IWUSR)) req->attr |= FILE_ATTRIBUTE_READONLY; if (!(st.st_mode & S_IWUSR)) reply->attr |= FILE_ATTRIBUTE_READONLY;
req->access_time = st.st_atime; reply->access_time = st.st_atime;
req->write_time = st.st_mtime; reply->write_time = st.st_mtime;
if (S_ISDIR(st.st_mode)) if (S_ISDIR(st.st_mode))
{ {
req->size_high = 0; reply->size_high = 0;
req->size_low = 0; reply->size_low = 0;
} }
else else
{ {
req->size_high = st.st_size >> 32; reply->size_high = st.st_size >> 32;
req->size_low = st.st_size & 0xffffffff; reply->size_low = st.st_size & 0xffffffff;
} }
req->links = st.st_nlink; reply->links = st.st_nlink;
req->index_high = st.st_dev; reply->index_high = st.st_dev;
req->index_low = st.st_ino; reply->index_low = st.st_ino;
req->serial = 0; /* FIXME */ reply->serial = 0; /* FIXME */
} }
return FD_TYPE_DEFAULT; return FD_TYPE_DEFAULT;
} }
...@@ -470,11 +470,11 @@ DECL_HANDLER(create_file) ...@@ -470,11 +470,11 @@ DECL_HANDLER(create_file)
{ {
struct file *file; struct file *file;
req->handle = 0; reply->handle = 0;
if ((file = create_file( get_req_data(req), get_req_data_size(req), req->access, if ((file = create_file( get_req_data(), get_req_data_size(), req->access,
req->sharing, req->create, req->attrs, req->drive_type ))) req->sharing, req->create, req->attrs, req->drive_type )))
{ {
req->handle = alloc_handle( current->process, file, req->access, req->inherit ); reply->handle = alloc_handle( current->process, file, req->access, req->inherit );
release_object( file ); release_object( file );
} }
} }
...@@ -485,7 +485,7 @@ DECL_HANDLER(alloc_file_handle) ...@@ -485,7 +485,7 @@ DECL_HANDLER(alloc_file_handle)
struct file *file; struct file *file;
int fd; int fd;
req->handle = 0; reply->handle = 0;
if ((fd = thread_get_inflight_fd( current, req->fd )) == -1) if ((fd = thread_get_inflight_fd( current, req->fd )) == -1)
{ {
set_error( STATUS_INVALID_HANDLE ); set_error( STATUS_INVALID_HANDLE );
...@@ -494,7 +494,7 @@ DECL_HANDLER(alloc_file_handle) ...@@ -494,7 +494,7 @@ DECL_HANDLER(alloc_file_handle)
if ((file = create_file_for_fd( fd, req->access, FILE_SHARE_READ | FILE_SHARE_WRITE, if ((file = create_file_for_fd( fd, req->access, FILE_SHARE_READ | FILE_SHARE_WRITE,
0, DRIVE_UNKNOWN ))) 0, DRIVE_UNKNOWN )))
{ {
req->handle = alloc_handle( current->process, file, req->access, req->inherit ); reply->handle = alloc_handle( current->process, file, req->access, req->inherit );
release_object( file ); release_object( file );
} }
} }
...@@ -504,18 +504,18 @@ DECL_HANDLER(get_handle_fd) ...@@ -504,18 +504,18 @@ DECL_HANDLER(get_handle_fd)
{ {
struct object *obj; struct object *obj;
req->fd = -1; reply->fd = -1;
req->type = FD_TYPE_INVALID; reply->type = FD_TYPE_INVALID;
if ((obj = get_handle_obj( current->process, req->handle, req->access, NULL ))) if ((obj = get_handle_obj( current->process, req->handle, req->access, NULL )))
{ {
int fd = get_handle_fd( current->process, req->handle, req->access ); int fd = get_handle_fd( current->process, req->handle, req->access );
if (fd != -1) req->fd = fd; if (fd != -1) reply->fd = fd;
else if (!get_error()) else if (!get_error())
{ {
if ((fd = obj->ops->get_fd( obj )) != -1) if ((fd = obj->ops->get_fd( obj )) != -1)
send_client_fd( current->process, fd, req->handle ); send_client_fd( current->process, fd, req->handle );
} }
req->type = obj->ops->get_file_info( obj, NULL ); reply->type = obj->ops->get_file_info( obj, NULL );
release_object( obj ); release_object( obj );
} }
} }
...@@ -526,8 +526,8 @@ DECL_HANDLER(set_file_pointer) ...@@ -526,8 +526,8 @@ DECL_HANDLER(set_file_pointer)
int high = req->high; int high = req->high;
int low = req->low; int low = req->low;
set_file_pointer( req->handle, &low, &high, req->whence ); set_file_pointer( req->handle, &low, &high, req->whence );
req->new_low = low; reply->new_low = low;
req->new_high = high; reply->new_high = high;
} }
/* truncate (or extend) a file */ /* truncate (or extend) a file */
...@@ -561,7 +561,7 @@ DECL_HANDLER(get_file_info) ...@@ -561,7 +561,7 @@ DECL_HANDLER(get_file_info)
if ((obj = get_handle_obj( current->process, req->handle, 0, NULL ))) if ((obj = get_handle_obj( current->process, req->handle, 0, NULL )))
{ {
obj->ops->get_file_info( obj, req ); obj->ops->get_file_info( obj, reply );
release_object( obj ); release_object( obj );
} }
} }
......
...@@ -355,7 +355,6 @@ struct object *get_handle_obj( struct process *process, handle_t handle, ...@@ -355,7 +355,6 @@ struct object *get_handle_obj( struct process *process, handle_t handle,
if (!(entry = get_handle( process, handle ))) return NULL; if (!(entry = get_handle( process, handle ))) return NULL;
if ((entry->access & access) != access) if ((entry->access & access) != access)
{ {
fprintf( stderr, "handle %d access %08x denied (%08x)\n", handle, access, entry->access );
set_error( STATUS_ACCESS_DENIED ); set_error( STATUS_ACCESS_DENIED );
return NULL; return NULL;
} }
...@@ -377,7 +376,6 @@ int get_handle_fd( struct process *process, handle_t handle, unsigned int access ...@@ -377,7 +376,6 @@ int get_handle_fd( struct process *process, handle_t handle, unsigned int access
if (!(entry = get_handle( process, handle ))) return -1; if (!(entry = get_handle( process, handle ))) return -1;
if ((entry->access & access) != access) if ((entry->access & access) != access)
{ {
fprintf( stderr, "handle %d access %08x denied (%08x)\n", handle, access, entry->access );
set_error( STATUS_ACCESS_DENIED ); set_error( STATUS_ACCESS_DENIED );
return -1; return -1;
} }
...@@ -459,7 +457,7 @@ handle_t open_object( const WCHAR *name, size_t len, const struct object_ops *op ...@@ -459,7 +457,7 @@ handle_t open_object( const WCHAR *name, size_t len, const struct object_ops *op
/* close a handle */ /* close a handle */
DECL_HANDLER(close_handle) DECL_HANDLER(close_handle)
{ {
close_handle( current->process, req->handle, &req->fd ); close_handle( current->process, req->handle, &reply->fd );
} }
/* set a handle information */ /* set a handle information */
...@@ -468,8 +466,9 @@ DECL_HANDLER(set_handle_info) ...@@ -468,8 +466,9 @@ DECL_HANDLER(set_handle_info)
int fd = req->fd; int fd = req->fd;
if (handle_is_global(req->handle)) fd = -1; /* no fd cache for global handles */ if (handle_is_global(req->handle)) fd = -1; /* no fd cache for global handles */
req->old_flags = set_handle_info( current->process, req->handle, req->mask, req->flags, &fd ); reply->old_flags = set_handle_info( current->process, req->handle,
req->cur_fd = fd; req->mask, req->flags, &fd );
reply->cur_fd = fd;
} }
/* duplicate a handle */ /* duplicate a handle */
...@@ -477,25 +476,25 @@ DECL_HANDLER(dup_handle) ...@@ -477,25 +476,25 @@ DECL_HANDLER(dup_handle)
{ {
struct process *src, *dst; struct process *src, *dst;
req->handle = 0; reply->handle = 0;
req->fd = -1; reply->fd = -1;
if ((src = get_process_from_handle( req->src_process, PROCESS_DUP_HANDLE ))) if ((src = get_process_from_handle( req->src_process, PROCESS_DUP_HANDLE )))
{ {
if (req->options & DUP_HANDLE_MAKE_GLOBAL) if (req->options & DUP_HANDLE_MAKE_GLOBAL)
{ {
req->handle = duplicate_handle( src, req->src_handle, NULL, reply->handle = duplicate_handle( src, req->src_handle, NULL,
req->access, req->inherit, req->options ); req->access, req->inherit, req->options );
} }
else if ((dst = get_process_from_handle( req->dst_process, PROCESS_DUP_HANDLE ))) else if ((dst = get_process_from_handle( req->dst_process, PROCESS_DUP_HANDLE )))
{ {
req->handle = duplicate_handle( src, req->src_handle, dst, reply->handle = duplicate_handle( src, req->src_handle, dst,
req->access, req->inherit, req->options ); req->access, req->inherit, req->options );
release_object( dst ); release_object( dst );
} }
/* close the handle no matter what happened */ /* close the handle no matter what happened */
if (req->options & DUP_HANDLE_CLOSE_SOURCE) if (req->options & DUP_HANDLE_CLOSE_SOURCE)
{ {
if (src == current->process) close_handle( src, req->src_handle, &req->fd ); if (src == current->process) close_handle( src, req->src_handle, &reply->fd );
else close_handle( src, req->src_handle, NULL ); else close_handle( src, req->src_handle, NULL );
} }
release_object( src ); release_object( src );
......
...@@ -34,7 +34,7 @@ struct mapping ...@@ -34,7 +34,7 @@ struct mapping
}; };
static int mapping_get_fd( struct object *obj ); static int mapping_get_fd( struct object *obj );
static int mapping_get_info( struct object *obj, struct get_file_info_request *req ); static int mapping_get_info( struct object *obj, struct get_file_info_reply *reply );
static void mapping_dump( struct object *obj, int verbose ); static void mapping_dump( struct object *obj, int verbose );
static void mapping_destroy( struct object *obj ); static void mapping_destroy( struct object *obj );
...@@ -263,11 +263,11 @@ static struct object *create_mapping( int size_high, int size_low, int protect, ...@@ -263,11 +263,11 @@ static struct object *create_mapping( int size_high, int size_low, int protect,
} }
if (!size_high && !size_low) if (!size_high && !size_low)
{ {
struct get_file_info_request req; struct get_file_info_reply reply;
struct object *obj = (struct object *)mapping->file; struct object *obj = (struct object *)mapping->file;
obj->ops->get_file_info( obj, &req ); obj->ops->get_file_info( obj, &reply );
size_high = req.size_high; size_high = reply.size_high;
size_low = ROUND_SIZE( 0, req.size_low ); size_low = ROUND_SIZE( 0, reply.size_low );
} }
else if (!grow_file( mapping->file, size_high, size_low )) goto error; else if (!grow_file( mapping->file, size_high, size_low )) goto error;
} }
...@@ -311,14 +311,14 @@ static int mapping_get_fd( struct object *obj ) ...@@ -311,14 +311,14 @@ static int mapping_get_fd( struct object *obj )
return get_mmap_fd( mapping->file ); return get_mmap_fd( mapping->file );
} }
static int mapping_get_info( struct object *obj, struct get_file_info_request *req ) static int mapping_get_info( struct object *obj, struct get_file_info_reply *reply )
{ {
struct mapping *mapping = (struct mapping *)obj; struct mapping *mapping = (struct mapping *)obj;
struct object *file = (struct object *)mapping->file; struct object *file = (struct object *)mapping->file;
assert( obj->ops == &mapping_ops ); assert( obj->ops == &mapping_ops );
assert( file ); assert( file );
return file->ops->get_file_info( file, req ); return file->ops->get_file_info( file, reply );
} }
static void mapping_destroy( struct object *obj ) static void mapping_destroy( struct object *obj )
...@@ -346,14 +346,14 @@ DECL_HANDLER(create_mapping) ...@@ -346,14 +346,14 @@ DECL_HANDLER(create_mapping)
{ {
struct object *obj; struct object *obj;
req->handle = 0; reply->handle = 0;
if ((obj = create_mapping( req->size_high, req->size_low, if ((obj = create_mapping( req->size_high, req->size_low,
req->protect, req->file_handle, req->protect, req->file_handle,
get_req_data(req), get_req_data_size(req) ))) get_req_data(), get_req_data_size() )))
{ {
int access = FILE_MAP_ALL_ACCESS; int access = FILE_MAP_ALL_ACCESS;
if (!(req->protect & VPROT_WRITE)) access &= ~FILE_MAP_WRITE; if (!(req->protect & VPROT_WRITE)) access &= ~FILE_MAP_WRITE;
req->handle = alloc_handle( current->process, obj, access, req->inherit ); reply->handle = alloc_handle( current->process, obj, access, req->inherit );
release_object( obj ); release_object( obj );
} }
} }
...@@ -361,8 +361,8 @@ DECL_HANDLER(create_mapping) ...@@ -361,8 +361,8 @@ DECL_HANDLER(create_mapping)
/* open a handle to a mapping */ /* open a handle to a mapping */
DECL_HANDLER(open_mapping) DECL_HANDLER(open_mapping)
{ {
req->handle = open_object( get_req_data(req), get_req_data_size(req), reply->handle = open_object( get_req_data(), get_req_data_size(),
&mapping_ops, req->access, req->inherit ); &mapping_ops, req->access, req->inherit );
} }
/* get a mapping information */ /* get a mapping information */
...@@ -373,17 +373,17 @@ DECL_HANDLER(get_mapping_info) ...@@ -373,17 +373,17 @@ DECL_HANDLER(get_mapping_info)
if ((mapping = (struct mapping *)get_handle_obj( current->process, req->handle, if ((mapping = (struct mapping *)get_handle_obj( current->process, req->handle,
0, &mapping_ops ))) 0, &mapping_ops )))
{ {
req->size_high = mapping->size_high; reply->size_high = mapping->size_high;
req->size_low = mapping->size_low; reply->size_low = mapping->size_low;
req->protect = mapping->protect; reply->protect = mapping->protect;
req->header_size = mapping->header_size; reply->header_size = mapping->header_size;
req->base = mapping->base; reply->base = mapping->base;
req->shared_file = 0; reply->shared_file = 0;
req->shared_size = mapping->shared_size; reply->shared_size = mapping->shared_size;
req->drive_type = get_file_drive_type( mapping->file ); reply->drive_type = get_file_drive_type( mapping->file );
if (mapping->shared_file) if (mapping->shared_file)
req->shared_file = alloc_handle( current->process, mapping->shared_file, reply->shared_file = alloc_handle( current->process, mapping->shared_file,
GENERIC_READ|GENERIC_WRITE, 0 ); GENERIC_READ|GENERIC_WRITE, 0 );
release_object( mapping ); release_object( mapping );
} }
} }
...@@ -140,10 +140,10 @@ DECL_HANDLER(create_mutex) ...@@ -140,10 +140,10 @@ DECL_HANDLER(create_mutex)
{ {
struct mutex *mutex; struct mutex *mutex;
req->handle = 0; reply->handle = 0;
if ((mutex = create_mutex( get_req_data(req), get_req_data_size(req), req->owned ))) if ((mutex = create_mutex( get_req_data(), get_req_data_size(), req->owned )))
{ {
req->handle = alloc_handle( current->process, mutex, MUTEX_ALL_ACCESS, req->inherit ); reply->handle = alloc_handle( current->process, mutex, MUTEX_ALL_ACCESS, req->inherit );
release_object( mutex ); release_object( mutex );
} }
} }
...@@ -151,8 +151,8 @@ DECL_HANDLER(create_mutex) ...@@ -151,8 +151,8 @@ DECL_HANDLER(create_mutex)
/* open a handle to a mutex */ /* open a handle to a mutex */
DECL_HANDLER(open_mutex) DECL_HANDLER(open_mutex)
{ {
req->handle = open_object( get_req_data(req), get_req_data_size(req), reply->handle = open_object( get_req_data(), get_req_data_size(),
&mutex_ops, req->access, req->inherit ); &mutex_ops, req->access, req->inherit );
} }
/* release a mutex */ /* release a mutex */
......
...@@ -86,7 +86,7 @@ static const struct object_ops named_pipe_ops = ...@@ -86,7 +86,7 @@ static const struct object_ops named_pipe_ops =
static void pipe_user_dump( struct object *obj, int verbose ); static void pipe_user_dump( struct object *obj, int verbose );
static void pipe_user_destroy( struct object *obj); static void pipe_user_destroy( struct object *obj);
static int pipe_user_get_fd( struct object *obj ); static int pipe_user_get_fd( struct object *obj );
static int pipe_user_get_info( struct object *obj, struct get_file_info_request *req ); static int pipe_user_get_info( struct object *obj, struct get_file_info_reply *reply );
static const struct object_ops pipe_user_ops = static const struct object_ops pipe_user_ops =
{ {
...@@ -180,20 +180,20 @@ static int pipe_user_get_fd( struct object *obj ) ...@@ -180,20 +180,20 @@ static int pipe_user_get_fd( struct object *obj )
return user->obj.fd; return user->obj.fd;
} }
static int pipe_user_get_info( struct object *obj, struct get_file_info_request *req ) static int pipe_user_get_info( struct object *obj, struct get_file_info_reply *reply )
{ {
if (req) if (reply)
{ {
req->type = FILE_TYPE_PIPE; reply->type = FILE_TYPE_PIPE;
req->attr = 0; reply->attr = 0;
req->access_time = 0; reply->access_time = 0;
req->write_time = 0; reply->write_time = 0;
req->size_high = 0; reply->size_high = 0;
req->size_low = 0; reply->size_low = 0;
req->links = 0; reply->links = 0;
req->index_high = 0; reply->index_high = 0;
req->index_low = 0; reply->index_low = 0;
req->serial = 0; reply->serial = 0;
} }
return FD_TYPE_DEFAULT; return FD_TYPE_DEFAULT;
} }
...@@ -265,8 +265,8 @@ DECL_HANDLER(create_named_pipe) ...@@ -265,8 +265,8 @@ DECL_HANDLER(create_named_pipe)
struct named_pipe *pipe; struct named_pipe *pipe;
struct pipe_user *user; struct pipe_user *user;
req->handle = 0; reply->handle = 0;
pipe = create_named_pipe( get_req_data(req), get_req_data_size(req) ); pipe = create_named_pipe( get_req_data(), get_req_data_size() );
if(!pipe) if(!pipe)
return; return;
...@@ -284,7 +284,7 @@ DECL_HANDLER(create_named_pipe) ...@@ -284,7 +284,7 @@ DECL_HANDLER(create_named_pipe)
if(user) if(user)
{ {
user->state = ps_idle_server; user->state = ps_idle_server;
req->handle = alloc_handle( current->process, user, GENERIC_READ|GENERIC_WRITE, 0 ); reply->handle = alloc_handle( current->process, user, GENERIC_READ|GENERIC_WRITE, 0 );
release_object( user ); release_object( user );
} }
...@@ -295,8 +295,8 @@ DECL_HANDLER(open_named_pipe) ...@@ -295,8 +295,8 @@ DECL_HANDLER(open_named_pipe)
{ {
struct named_pipe *pipe; struct named_pipe *pipe;
req->handle = 0; reply->handle = 0;
pipe = create_named_pipe( get_req_data(req), get_req_data_size(req) ); pipe = create_named_pipe( get_req_data(), get_req_data_size() );
if(!pipe) if(!pipe)
return; return;
...@@ -320,7 +320,7 @@ DECL_HANDLER(open_named_pipe) ...@@ -320,7 +320,7 @@ DECL_HANDLER(open_named_pipe)
partner->other = user; partner->other = user;
user->state = ps_connected_client; user->state = ps_connected_client;
user->other = partner; user->other = partner;
req->handle = alloc_handle( current->process, user, req->access, 0 ); reply->handle = alloc_handle( current->process, user, req->access, 0 );
release_object(user); release_object(user);
} }
else else
...@@ -378,7 +378,7 @@ DECL_HANDLER(wait_named_pipe) ...@@ -378,7 +378,7 @@ DECL_HANDLER(wait_named_pipe)
{ {
struct named_pipe *pipe; struct named_pipe *pipe;
pipe = create_named_pipe( get_req_data(req), get_req_data_size(req) ); pipe = create_named_pipe( get_req_data(), get_req_data_size() );
if( pipe ) if( pipe )
{ {
/* only wait if the pipe already exists */ /* only wait if the pipe already exists */
...@@ -448,10 +448,10 @@ DECL_HANDLER(get_named_pipe_info) ...@@ -448,10 +448,10 @@ DECL_HANDLER(get_named_pipe_info)
if(!user) if(!user)
return; return;
req->flags = user->pipe->pipemode; reply->flags = user->pipe->pipemode;
req->maxinstances = user->pipe->maxinstances; reply->maxinstances = user->pipe->maxinstances;
req->insize = user->pipe->insize; reply->insize = user->pipe->insize;
req->outsize = user->pipe->outsize; reply->outsize = user->pipe->outsize;
release_object(user); release_object(user);
} }
......
...@@ -263,7 +263,7 @@ int no_flush( struct object *obj ) ...@@ -263,7 +263,7 @@ int no_flush( struct object *obj )
return 0; return 0;
} }
int no_get_file_info( struct object *obj, struct get_file_info_request *info ) int no_get_file_info( struct object *obj, struct get_file_info_reply *info )
{ {
set_error( STATUS_OBJECT_TYPE_MISMATCH ); set_error( STATUS_OBJECT_TYPE_MISMATCH );
return FD_TYPE_INVALID; return FD_TYPE_INVALID;
......
...@@ -47,7 +47,7 @@ struct object_ops ...@@ -47,7 +47,7 @@ struct object_ops
/* flush the object buffers */ /* flush the object buffers */
int (*flush)(struct object *); int (*flush)(struct object *);
/* get file information */ /* get file information */
int (*get_file_info)(struct object *,struct get_file_info_request *); int (*get_file_info)(struct object *,struct get_file_info_reply *);
/* destroy on refcount == 0 */ /* destroy on refcount == 0 */
void (*destroy)(struct object *); void (*destroy)(struct object *);
}; };
...@@ -89,7 +89,7 @@ extern int no_add_queue( struct object *obj, struct wait_queue_entry *entry ); ...@@ -89,7 +89,7 @@ extern int no_add_queue( struct object *obj, struct wait_queue_entry *entry );
extern int no_satisfied( struct object *obj, struct thread *thread ); extern int no_satisfied( struct object *obj, struct thread *thread );
extern int no_get_fd( struct object *obj ); extern int no_get_fd( struct object *obj );
extern int no_flush( struct object *obj ); extern int no_flush( struct object *obj );
extern int no_get_file_info( struct object *obj, struct get_file_info_request *info ); extern int no_get_file_info( struct object *obj, struct get_file_info_reply *info );
extern void no_destroy( struct object *obj ); extern void no_destroy( struct object *obj );
extern int default_poll_add_queue( struct object *obj, struct wait_queue_entry *entry ); extern int default_poll_add_queue( struct object *obj, struct wait_queue_entry *entry );
extern void default_poll_remove_queue( struct object *obj, struct wait_queue_entry *entry ); extern void default_poll_remove_queue( struct object *obj, struct wait_queue_entry *entry );
...@@ -103,7 +103,7 @@ extern void dump_objects(void); ...@@ -103,7 +103,7 @@ extern void dump_objects(void);
extern int add_select_user( struct object *obj ); extern int add_select_user( struct object *obj );
extern void remove_select_user( struct object *obj ); extern void remove_select_user( struct object *obj );
extern void change_select_fd( struct object *obj, int fd ); extern void change_select_fd( struct object *obj, int fd, int events );
extern void set_select_events( struct object *obj, int events ); extern void set_select_events( struct object *obj, int events );
extern int check_select_events( int fd, int events ); extern int check_select_events( int fd, int events );
extern void select_loop(void); extern void select_loop(void);
......
...@@ -37,7 +37,7 @@ struct pipe ...@@ -37,7 +37,7 @@ struct pipe
static void pipe_dump( struct object *obj, int verbose ); static void pipe_dump( struct object *obj, int verbose );
static int pipe_get_poll_events( struct object *obj ); static int pipe_get_poll_events( struct object *obj );
static int pipe_get_fd( struct object *obj ); static int pipe_get_fd( struct object *obj );
static int pipe_get_info( struct object *obj, struct get_file_info_request *req ); static int pipe_get_info( struct object *obj, struct get_file_info_reply *reply );
static void pipe_destroy( struct object *obj ); static void pipe_destroy( struct object *obj );
static const struct object_ops pipe_ops = static const struct object_ops pipe_ops =
...@@ -124,20 +124,20 @@ static int pipe_get_fd( struct object *obj ) ...@@ -124,20 +124,20 @@ static int pipe_get_fd( struct object *obj )
return pipe->obj.fd; return pipe->obj.fd;
} }
static int pipe_get_info( struct object *obj, struct get_file_info_request *req ) static int pipe_get_info( struct object *obj, struct get_file_info_reply *reply )
{ {
if (req) if (reply)
{ {
req->type = FILE_TYPE_PIPE; reply->type = FILE_TYPE_PIPE;
req->attr = 0; reply->attr = 0;
req->access_time = 0; reply->access_time = 0;
req->write_time = 0; reply->write_time = 0;
req->size_high = 0; reply->size_high = 0;
req->size_low = 0; reply->size_low = 0;
req->links = 0; reply->links = 0;
req->index_high = 0; reply->index_high = 0;
req->index_low = 0; reply->index_low = 0;
req->serial = 0; reply->serial = 0;
} }
return FD_TYPE_DEFAULT; return FD_TYPE_DEFAULT;
} }
...@@ -171,6 +171,6 @@ DECL_HANDLER(create_pipe) ...@@ -171,6 +171,6 @@ DECL_HANDLER(create_pipe)
release_object( obj[0] ); release_object( obj[0] );
release_object( obj[1] ); release_object( obj[1] );
} }
req->handle_read = hread; reply->handle_read = hread;
req->handle_write = hwrite; reply->handle_write = hwrite;
} }
...@@ -142,31 +142,105 @@ void fatal_perror( const char *err, ... ) ...@@ -142,31 +142,105 @@ void fatal_perror( const char *err, ... )
exit(1); exit(1);
} }
/* call a request handler */ /* allocate the reply data */
static inline void call_req_handler( struct thread *thread, union generic_request *request ) void *set_reply_data_size( size_t size )
{ {
enum request req = request->header.req; assert( size <= get_reply_max_size() );
if (size && !(current->reply_data = mem_alloc( size ))) size = 0;
current->reply_size = size;
return current->reply_data;
}
current = thread; /* write the remaining part of the reply */
clear_error(); void write_reply( struct thread *thread )
{
int ret;
if (debug_level) trace_request( thread, request ); if ((ret = write( thread->reply_fd,
(char *)thread->reply_data + thread->reply_size - thread->reply_towrite,
thread->reply_towrite )) >= 0)
{
if (!(thread->reply_towrite -= ret))
{
free( thread->reply_data );
thread->reply_data = NULL;
/* sent everything, can go back to waiting for requests */
change_select_fd( &thread->obj, thread->request_fd, POLLIN );
}
return;
}
if (errno == EPIPE)
kill_thread( thread, 0 ); /* normal death */
else if (errno != EWOULDBLOCK && errno != EAGAIN)
fatal_protocol_perror( thread, "reply write" );
}
if (request->header.var_size) /* send a reply to the current thread */
static void send_reply( union generic_reply *reply )
{
int ret;
if (!current->reply_size)
{
if ((ret = write( current->reply_fd, reply, sizeof(*reply) )) != sizeof(*reply)) goto error;
}
else
{ {
if ((unsigned int)request->header.var_offset + struct iovec vec[2];
request->header.var_size > MAX_REQUEST_LENGTH)
vec[0].iov_base = reply;
vec[0].iov_len = sizeof(*reply);
vec[1].iov_base = current->reply_data;
vec[1].iov_len = current->reply_size;
if ((ret = writev( current->reply_fd, vec, 2 )) < sizeof(*reply)) goto error;
if ((current->reply_towrite = current->reply_size - (ret - sizeof(*reply))))
{ {
fatal_protocol_error( current, "bad request offset/size %d/%d\n", /* couldn't write it all, wait for POLLOUT */
request->header.var_offset, request->header.var_size ); change_select_fd( &current->obj, current->reply_fd, POLLOUT );
return; return;
} }
} }
if (current->reply_data)
{
free( current->reply_data );
current->reply_data = NULL;
}
return;
error:
if (ret >= 0)
fatal_protocol_error( current, "partial write %d\n", ret );
else if (errno == EPIPE)
kill_thread( current, 0 ); /* normal death */
else
fatal_protocol_perror( current, "reply write" );
}
/* call a request handler */
static void call_req_handler( struct thread *thread )
{
union generic_reply reply;
enum request req = thread->req.request_header.req;
current = thread;
current->reply_size = 0;
clear_error();
memset( &reply, 0, sizeof(reply) );
if (debug_level) trace_request();
if (req < REQ_NB_REQUESTS) if (req < REQ_NB_REQUESTS)
{ {
req_handlers[req]( request ); req_handlers[req]( &current->req, &reply );
if (current) send_reply( current, request ); if (current)
{
reply.reply_header.error = current->error;
reply.reply_header.reply_size = current->reply_size;
if (debug_level) trace_reply( req, &reply );
send_reply( &reply );
}
current = NULL; current = NULL;
return; return;
} }
...@@ -176,14 +250,39 @@ static inline void call_req_handler( struct thread *thread, union generic_reques ...@@ -176,14 +250,39 @@ static inline void call_req_handler( struct thread *thread, union generic_reques
/* read a request from a thread */ /* read a request from a thread */
void read_request( struct thread *thread ) void read_request( struct thread *thread )
{ {
union generic_request req;
int ret; int ret;
if ((ret = read( thread->obj.fd, &req, sizeof(req) )) == sizeof(req)) if (!thread->req_toread) /* no pending request */
{ {
call_req_handler( thread, &req ); if ((ret = read( thread->obj.fd, &thread->req,
return; sizeof(thread->req) )) != sizeof(thread->req)) goto error;
if (!(thread->req_toread = thread->req.request_header.request_size))
{
/* no data, handle request at once */
call_req_handler( thread );
return;
}
if (!(thread->req_data = malloc( thread->req_toread )))
fatal_protocol_error( thread, "no memory for %d bytes request\n", thread->req_toread );
} }
/* read the variable sized data */
for (;;)
{
ret = read( thread->obj.fd, ((char *)thread->req_data +
thread->req.request_header.request_size - thread->req_toread),
thread->req_toread );
if (ret <= 0) break;
if (!(thread->req_toread -= ret))
{
call_req_handler( thread );
free( thread->req_data );
thread->req_data = NULL;
return;
}
}
error:
if (!ret) /* closed pipe */ if (!ret) /* closed pipe */
kill_thread( thread, 0 ); kill_thread( thread, 0 );
else if (ret > 0) else if (ret > 0)
...@@ -192,26 +291,6 @@ void read_request( struct thread *thread ) ...@@ -192,26 +291,6 @@ void read_request( struct thread *thread )
fatal_protocol_perror( thread, "read" ); fatal_protocol_perror( thread, "read" );
} }
/* send a reply to a thread */
void send_reply( struct thread *thread, union generic_request *request )
{
int ret;
if (debug_level) trace_reply( thread, request );
request->header.error = thread->error;
if ((ret = write( thread->reply_fd, request, sizeof(*request) )) != sizeof(*request))
{
if (ret >= 0)
fatal_protocol_error( thread, "partial write %d\n", ret );
else if (errno == EPIPE)
kill_thread( thread, 0 ); /* normal death */
else
fatal_protocol_perror( thread, "reply write" );
}
}
/* receive a file descriptor on the process socket */ /* receive a file descriptor on the process socket */
int receive_fd( struct process *process ) int receive_fd( struct process *process )
{ {
...@@ -439,6 +518,7 @@ void open_master_socket(void) ...@@ -439,6 +518,7 @@ void open_master_socket(void)
/* make sure no request is larger than the maximum size */ /* make sure no request is larger than the maximum size */
assert( sizeof(union generic_request) == sizeof(struct request_max_size) ); assert( sizeof(union generic_request) == sizeof(struct request_max_size) );
assert( sizeof(union generic_reply) == sizeof(struct request_max_size) );
create_server_dir(); create_server_dir();
if ((fd = socket( AF_UNIX, SOCK_STREAM, 0 )) == -1) fatal_perror( "socket" ); if ((fd = socket( AF_UNIX, SOCK_STREAM, 0 )) == -1) fatal_perror( "socket" );
......
...@@ -7,6 +7,8 @@ ...@@ -7,6 +7,8 @@
#ifndef __WINE_SERVER_REQUEST_H #ifndef __WINE_SERVER_REQUEST_H
#define __WINE_SERVER_REQUEST_H #define __WINE_SERVER_REQUEST_H
#include <assert.h>
#include "thread.h" #include "thread.h"
#include "wine/server_protocol.h" #include "wine/server_protocol.h"
...@@ -14,7 +16,8 @@ ...@@ -14,7 +16,8 @@
#define MAX_REQUEST_LENGTH 8192 #define MAX_REQUEST_LENGTH 8192
/* request handler definition */ /* request handler definition */
#define DECL_HANDLER(name) void req_##name( struct name##_request *req ) #define DECL_HANDLER(name) \
void req_##name( const struct name##_request *req, struct name##_reply *reply )
/* request functions */ /* request functions */
...@@ -33,36 +36,54 @@ extern void fatal_perror( const char *err, ... ); ...@@ -33,36 +36,54 @@ extern void fatal_perror( const char *err, ... );
#endif #endif
extern const char *get_config_dir(void); extern const char *get_config_dir(void);
extern void *set_reply_data_size( size_t size );
extern int receive_fd( struct process *process ); extern int receive_fd( struct process *process );
extern int send_client_fd( struct process *process, int fd, handle_t handle ); extern int send_client_fd( struct process *process, int fd, handle_t handle );
extern void read_request( struct thread *thread ); extern void read_request( struct thread *thread );
extern void send_reply( struct thread *thread, union generic_request *request ); extern void write_reply( struct thread *thread );
extern unsigned int get_tick_count(void); extern unsigned int get_tick_count(void);
extern void open_master_socket(void); extern void open_master_socket(void);
extern void close_master_socket(void); extern void close_master_socket(void);
extern void lock_master_socket( int locked ); extern void lock_master_socket( int locked );
extern void trace_request( struct thread *thread, const union generic_request *request ); extern void trace_request(void);
extern void trace_reply( struct thread *thread, const union generic_request *request ); extern void trace_reply( enum request req, const union generic_reply *reply );
/* get the request vararg data */ /* get the request vararg data */
inline static void *get_req_data( const void *req ) inline static const void *get_req_data(void)
{ {
return (char *)current->buffer + ((struct request_header *)req)->var_offset; return current->req_data;
} }
/* get the request vararg size */ /* get the request vararg size */
inline static size_t get_req_data_size( const void *req ) inline static size_t get_req_data_size(void)
{
return current->req.request_header.request_size;
}
/* get the reply maximum vararg size */
inline static size_t get_reply_max_size(void)
{ {
return ((struct request_header *)req)->var_size; return current->req.request_header.reply_size;
} }
/* set the request vararg size */ /* allocate and fill the reply data */
inline static void set_req_data_size( const void *req, size_t size ) inline static void *set_reply_data( const void *data, size_t size )
{ {
((struct request_header *)req)->var_size = size; void *ret = set_reply_data_size( size );
if (ret) memcpy( ret, data, size );
return ret;
} }
/* set the reply data pointer directly (will be freed by request code) */
inline static void set_reply_data_ptr( void *data, size_t size )
{
assert( size <= get_reply_max_size() );
current->reply_size = size;
current->reply_data = data;
}
/* Everything below this line is generated automatically by tools/make_requests */ /* Everything below this line is generated automatically by tools/make_requests */
/* ### make_requests begin ### */ /* ### make_requests begin ### */
...@@ -73,7 +94,6 @@ DECL_HANDLER(boot_done); ...@@ -73,7 +94,6 @@ DECL_HANDLER(boot_done);
DECL_HANDLER(init_process); DECL_HANDLER(init_process);
DECL_HANDLER(init_process_done); DECL_HANDLER(init_process_done);
DECL_HANDLER(init_thread); DECL_HANDLER(init_thread);
DECL_HANDLER(set_thread_buffer);
DECL_HANDLER(terminate_process); DECL_HANDLER(terminate_process);
DECL_HANDLER(terminate_thread); DECL_HANDLER(terminate_thread);
DECL_HANDLER(get_process_info); DECL_HANDLER(get_process_info);
...@@ -132,6 +152,7 @@ DECL_HANDLER(get_console_output_info); ...@@ -132,6 +152,7 @@ DECL_HANDLER(get_console_output_info);
DECL_HANDLER(write_console_input); DECL_HANDLER(write_console_input);
DECL_HANDLER(read_console_input); DECL_HANDLER(read_console_input);
DECL_HANDLER(write_console_output); DECL_HANDLER(write_console_output);
DECL_HANDLER(fill_console_output);
DECL_HANDLER(read_console_output); DECL_HANDLER(read_console_output);
DECL_HANDLER(move_console_output); DECL_HANDLER(move_console_output);
DECL_HANDLER(create_change_notification); DECL_HANDLER(create_change_notification);
...@@ -217,7 +238,7 @@ DECL_HANDLER(get_window_properties); ...@@ -217,7 +238,7 @@ DECL_HANDLER(get_window_properties);
#ifdef WANT_REQUEST_HANDLERS #ifdef WANT_REQUEST_HANDLERS
typedef void (*req_handler)( void *req ); typedef void (*req_handler)( const void *req, void *reply );
static const req_handler req_handlers[REQ_NB_REQUESTS] = static const req_handler req_handlers[REQ_NB_REQUESTS] =
{ {
(req_handler)req_new_process, (req_handler)req_new_process,
...@@ -227,7 +248,6 @@ static const req_handler req_handlers[REQ_NB_REQUESTS] = ...@@ -227,7 +248,6 @@ static const req_handler req_handlers[REQ_NB_REQUESTS] =
(req_handler)req_init_process, (req_handler)req_init_process,
(req_handler)req_init_process_done, (req_handler)req_init_process_done,
(req_handler)req_init_thread, (req_handler)req_init_thread,
(req_handler)req_set_thread_buffer,
(req_handler)req_terminate_process, (req_handler)req_terminate_process,
(req_handler)req_terminate_thread, (req_handler)req_terminate_thread,
(req_handler)req_get_process_info, (req_handler)req_get_process_info,
...@@ -286,6 +306,7 @@ static const req_handler req_handlers[REQ_NB_REQUESTS] = ...@@ -286,6 +306,7 @@ static const req_handler req_handlers[REQ_NB_REQUESTS] =
(req_handler)req_write_console_input, (req_handler)req_write_console_input,
(req_handler)req_read_console_input, (req_handler)req_read_console_input,
(req_handler)req_write_console_output, (req_handler)req_write_console_output,
(req_handler)req_fill_console_output,
(req_handler)req_read_console_output, (req_handler)req_read_console_output,
(req_handler)req_move_console_output, (req_handler)req_move_console_output,
(req_handler)req_create_change_notification, (req_handler)req_create_change_notification,
......
...@@ -97,13 +97,13 @@ void remove_select_user( struct object *obj ) ...@@ -97,13 +97,13 @@ void remove_select_user( struct object *obj )
active_users--; active_users--;
} }
/* change the fd of an object (the old fd is closed) */ /* change the fd and events of an object */
void change_select_fd( struct object *obj, int fd ) void change_select_fd( struct object *obj, int fd, int events )
{ {
int user = obj->select; int user = obj->select;
assert( poll_users[user] == obj ); assert( poll_users[user] == obj );
pollfd[user].fd = fd; pollfd[user].fd = fd;
close( obj->fd ); pollfd[user].events = events;
obj->fd = fd; obj->fd = fd;
} }
......
...@@ -123,11 +123,11 @@ DECL_HANDLER(create_semaphore) ...@@ -123,11 +123,11 @@ DECL_HANDLER(create_semaphore)
{ {
struct semaphore *sem; struct semaphore *sem;
req->handle = 0; reply->handle = 0;
if ((sem = create_semaphore( get_req_data(req), get_req_data_size(req), if ((sem = create_semaphore( get_req_data(), get_req_data_size(),
req->initial, req->max ))) req->initial, req->max )))
{ {
req->handle = alloc_handle( current->process, sem, SEMAPHORE_ALL_ACCESS, req->inherit ); reply->handle = alloc_handle( current->process, sem, SEMAPHORE_ALL_ACCESS, req->inherit );
release_object( sem ); release_object( sem );
} }
} }
...@@ -135,12 +135,12 @@ DECL_HANDLER(create_semaphore) ...@@ -135,12 +135,12 @@ DECL_HANDLER(create_semaphore)
/* open a handle to a semaphore */ /* open a handle to a semaphore */
DECL_HANDLER(open_semaphore) DECL_HANDLER(open_semaphore)
{ {
req->handle = open_object( get_req_data(req), get_req_data_size(req), reply->handle = open_object( get_req_data(), get_req_data_size(),
&semaphore_ops, req->access, req->inherit ); &semaphore_ops, req->access, req->inherit );
} }
/* release a semaphore */ /* release a semaphore */
DECL_HANDLER(release_semaphore) DECL_HANDLER(release_semaphore)
{ {
req->prev_count = release_semaphore( req->handle, req->count ); reply->prev_count = release_semaphore( req->handle, req->count );
} }
...@@ -37,7 +37,7 @@ ...@@ -37,7 +37,7 @@
static void serial_dump( struct object *obj, int verbose ); static void serial_dump( struct object *obj, int verbose );
static int serial_get_fd( struct object *obj ); static int serial_get_fd( struct object *obj );
static int serial_get_info( struct object *obj, struct get_file_info_request *req ); static int serial_get_info( struct object *obj, struct get_file_info_reply *reply );
static int serial_get_poll_events( struct object *obj ); static int serial_get_poll_events( struct object *obj );
struct serial struct serial
...@@ -165,23 +165,23 @@ static int serial_get_fd( struct object *obj ) ...@@ -165,23 +165,23 @@ static int serial_get_fd( struct object *obj )
return serial->obj.fd; return serial->obj.fd;
} }
static int serial_get_info( struct object *obj, struct get_file_info_request *req ) static int serial_get_info( struct object *obj, struct get_file_info_reply *reply )
{ {
struct serial *serial = (struct serial *) obj; struct serial *serial = (struct serial *) obj;
assert( obj->ops == &serial_ops ); assert( obj->ops == &serial_ops );
if (req) if (reply)
{ {
req->type = FILE_TYPE_CHAR; reply->type = FILE_TYPE_CHAR;
req->attr = 0; reply->attr = 0;
req->access_time = 0; reply->access_time = 0;
req->write_time = 0; reply->write_time = 0;
req->size_high = 0; reply->size_high = 0;
req->size_low = 0; reply->size_low = 0;
req->links = 0; reply->links = 0;
req->index_high = 0; reply->index_high = 0;
req->index_low = 0; reply->index_low = 0;
req->serial = 0; reply->serial = 0;
} }
if(serial->attrib & FILE_FLAG_OVERLAPPED) if(serial->attrib & FILE_FLAG_OVERLAPPED)
...@@ -215,10 +215,10 @@ DECL_HANDLER(create_serial) ...@@ -215,10 +215,10 @@ DECL_HANDLER(create_serial)
{ {
struct serial *serial; struct serial *serial;
req->handle = 0; reply->handle = 0;
if ((serial = create_serial( get_req_data(req), get_req_data_size(req), req->access, req->attributes ))) if ((serial = create_serial( get_req_data(), get_req_data_size(), req->access, req->attributes )))
{ {
req->handle = alloc_handle( current->process, serial, req->access, req->inherit ); reply->handle = alloc_handle( current->process, serial, req->access, req->inherit );
release_object( serial ); release_object( serial );
} }
} }
...@@ -230,17 +230,17 @@ DECL_HANDLER(get_serial_info) ...@@ -230,17 +230,17 @@ DECL_HANDLER(get_serial_info)
if ((serial = get_serial_obj( current->process, req->handle, 0 ))) if ((serial = get_serial_obj( current->process, req->handle, 0 )))
{ {
/* timeouts */ /* timeouts */
req->readinterval = serial->readinterval; reply->readinterval = serial->readinterval;
req->readconst = serial->readconst; reply->readconst = serial->readconst;
req->readmult = serial->readmult; reply->readmult = serial->readmult;
req->writeconst = serial->writeconst; reply->writeconst = serial->writeconst;
req->writemult = serial->writemult; reply->writemult = serial->writemult;
/* event mask */ /* event mask */
req->eventmask = serial->eventmask; reply->eventmask = serial->eventmask;
/* comm port error status */ /* comm port error status */
req->commerror = serial->commerror; reply->commerror = serial->commerror;
release_object( serial ); release_object( serial );
} }
......
...@@ -94,7 +94,7 @@ static struct snapshot *create_snapshot( void *pid, int flags ) ...@@ -94,7 +94,7 @@ static struct snapshot *create_snapshot( void *pid, int flags )
} }
/* get the next process in the snapshot */ /* get the next process in the snapshot */
static int snapshot_next_process( struct snapshot *snapshot, struct next_process_request *req ) static int snapshot_next_process( struct snapshot *snapshot, struct next_process_reply *reply )
{ {
struct process_snapshot *ptr; struct process_snapshot *ptr;
...@@ -103,22 +103,21 @@ static int snapshot_next_process( struct snapshot *snapshot, struct next_process ...@@ -103,22 +103,21 @@ static int snapshot_next_process( struct snapshot *snapshot, struct next_process
set_error( STATUS_INVALID_PARAMETER ); /* FIXME */ set_error( STATUS_INVALID_PARAMETER ); /* FIXME */
return 0; return 0;
} }
if (req->reset) snapshot->process_pos = 0; if (snapshot->process_pos >= snapshot->process_count)
else if (snapshot->process_pos >= snapshot->process_count)
{ {
set_error( STATUS_NO_MORE_FILES ); set_error( STATUS_NO_MORE_FILES );
return 0; return 0;
} }
ptr = &snapshot->processes[snapshot->process_pos++]; ptr = &snapshot->processes[snapshot->process_pos++];
req->count = ptr->count; reply->count = ptr->count;
req->pid = get_process_id( ptr->process ); reply->pid = get_process_id( ptr->process );
req->threads = ptr->threads; reply->threads = ptr->threads;
req->priority = ptr->priority; reply->priority = ptr->priority;
return 1; return 1;
} }
/* get the next thread in the snapshot */ /* get the next thread in the snapshot */
static int snapshot_next_thread( struct snapshot *snapshot, struct next_thread_request *req ) static int snapshot_next_thread( struct snapshot *snapshot, struct next_thread_reply *reply )
{ {
struct thread_snapshot *ptr; struct thread_snapshot *ptr;
...@@ -127,23 +126,22 @@ static int snapshot_next_thread( struct snapshot *snapshot, struct next_thread_r ...@@ -127,23 +126,22 @@ static int snapshot_next_thread( struct snapshot *snapshot, struct next_thread_r
set_error( STATUS_INVALID_PARAMETER ); /* FIXME */ set_error( STATUS_INVALID_PARAMETER ); /* FIXME */
return 0; return 0;
} }
if (req->reset) snapshot->thread_pos = 0; if (snapshot->thread_pos >= snapshot->thread_count)
else if (snapshot->thread_pos >= snapshot->thread_count)
{ {
set_error( STATUS_NO_MORE_FILES ); set_error( STATUS_NO_MORE_FILES );
return 0; return 0;
} }
ptr = &snapshot->threads[snapshot->thread_pos++]; ptr = &snapshot->threads[snapshot->thread_pos++];
req->count = ptr->count; reply->count = ptr->count;
req->pid = get_process_id( ptr->thread->process ); reply->pid = get_process_id( ptr->thread->process );
req->tid = get_thread_id( ptr->thread ); reply->tid = get_thread_id( ptr->thread );
req->base_pri = ptr->priority; reply->base_pri = ptr->priority;
req->delta_pri = 0; /* FIXME */ reply->delta_pri = 0; /* FIXME */
return 1; return 1;
} }
/* get the next module in the snapshot */ /* get the next module in the snapshot */
static int snapshot_next_module( struct snapshot *snapshot, struct next_module_request *req ) static int snapshot_next_module( struct snapshot *snapshot, struct next_module_reply *reply )
{ {
struct module_snapshot *ptr; struct module_snapshot *ptr;
...@@ -152,15 +150,14 @@ static int snapshot_next_module( struct snapshot *snapshot, struct next_module_r ...@@ -152,15 +150,14 @@ static int snapshot_next_module( struct snapshot *snapshot, struct next_module_r
set_error( STATUS_INVALID_PARAMETER ); /* FIXME */ set_error( STATUS_INVALID_PARAMETER ); /* FIXME */
return 0; return 0;
} }
if (req->reset) snapshot->module_pos = 0; if (snapshot->module_pos >= snapshot->module_count)
else if (snapshot->module_pos >= snapshot->module_count)
{ {
set_error( STATUS_NO_MORE_FILES ); set_error( STATUS_NO_MORE_FILES );
return 0; return 0;
} }
ptr = &snapshot->modules[snapshot->module_pos++]; ptr = &snapshot->modules[snapshot->module_pos++];
req->pid = get_process_id( snapshot->process ); reply->pid = get_process_id( snapshot->process );
req->base = ptr->base; reply->base = ptr->base;
return 1; return 1;
} }
...@@ -198,10 +195,10 @@ DECL_HANDLER(create_snapshot) ...@@ -198,10 +195,10 @@ DECL_HANDLER(create_snapshot)
{ {
struct snapshot *snapshot; struct snapshot *snapshot;
req->handle = 0; reply->handle = 0;
if ((snapshot = create_snapshot( req->pid, req->flags ))) if ((snapshot = create_snapshot( req->pid, req->flags )))
{ {
req->handle = alloc_handle( current->process, snapshot, 0, req->inherit ); reply->handle = alloc_handle( current->process, snapshot, 0, req->inherit );
release_object( snapshot ); release_object( snapshot );
} }
} }
...@@ -214,7 +211,8 @@ DECL_HANDLER(next_process) ...@@ -214,7 +211,8 @@ DECL_HANDLER(next_process)
if ((snapshot = (struct snapshot *)get_handle_obj( current->process, req->handle, if ((snapshot = (struct snapshot *)get_handle_obj( current->process, req->handle,
0, &snapshot_ops ))) 0, &snapshot_ops )))
{ {
snapshot_next_process( snapshot, req ); if (req->reset) snapshot->process_pos = 0;
snapshot_next_process( snapshot, reply );
release_object( snapshot ); release_object( snapshot );
} }
} }
...@@ -227,7 +225,8 @@ DECL_HANDLER(next_thread) ...@@ -227,7 +225,8 @@ DECL_HANDLER(next_thread)
if ((snapshot = (struct snapshot *)get_handle_obj( current->process, req->handle, if ((snapshot = (struct snapshot *)get_handle_obj( current->process, req->handle,
0, &snapshot_ops ))) 0, &snapshot_ops )))
{ {
snapshot_next_thread( snapshot, req ); if (req->reset) snapshot->thread_pos = 0;
snapshot_next_thread( snapshot, reply );
release_object( snapshot ); release_object( snapshot );
} }
} }
...@@ -240,7 +239,8 @@ DECL_HANDLER(next_module) ...@@ -240,7 +239,8 @@ DECL_HANDLER(next_module)
if ((snapshot = (struct snapshot *)get_handle_obj( current->process, req->handle, if ((snapshot = (struct snapshot *)get_handle_obj( current->process, req->handle,
0, &snapshot_ops ))) 0, &snapshot_ops )))
{ {
snapshot_next_module( snapshot, req ); if (req->reset) snapshot->module_pos = 0;
snapshot_next_module( snapshot, reply );
release_object( snapshot ); release_object( snapshot );
} }
} }
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