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 )
goto done;
}
SERVER_START_VAR_REQ( load_registry, len )
SERVER_START_REQ( load_registry )
{
req->hkey = hkey;
req->file = file;
memcpy( server_data_ptr(req), subkey, len );
ret = RtlNtStatusToDosError( SERVER_CALL() );
wine_server_add_data( req, subkey, len );
ret = RtlNtStatusToDosError( wine_server_call(req) );
}
SERVER_END_VAR_REQ;
SERVER_END_REQ;
CloseHandle( file );
done:
......@@ -1241,6 +1241,7 @@ LONG WINAPI RegLoadKeyW( HKEY hkey, LPCWSTR subkey, LPCWSTR filename )
*/
LONG WINAPI RegLoadKeyA( HKEY hkey, LPCSTR subkey, LPCSTR filename )
{
WCHAR buffer[MAX_PATH];
HANDLE file;
DWORD ret, len, err = GetLastError();
......@@ -1249,8 +1250,8 @@ LONG WINAPI RegLoadKeyA( HKEY hkey, LPCSTR subkey, LPCSTR filename )
if (!filename || !*filename) 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 > MAX_PATH*sizeof(WCHAR)) return ERROR_INVALID_PARAMETER;
if (!(len = MultiByteToWideChar( CP_ACP, 0, subkey, strlen(subkey), buffer, MAX_PATH )))
return ERROR_INVALID_PARAMETER;
if ((file = CreateFileA( filename, GENERIC_READ, 0, NULL, OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL, 0 )) == INVALID_HANDLE_VALUE)
......@@ -1259,15 +1260,14 @@ LONG WINAPI RegLoadKeyA( HKEY hkey, LPCSTR subkey, LPCSTR filename )
goto done;
}
SERVER_START_VAR_REQ( load_registry, len )
SERVER_START_REQ( load_registry )
{
req->hkey = hkey;
req->file = file;
MultiByteToWideChar( CP_ACP, 0, subkey, strlen(subkey),
server_data_ptr(req), len/sizeof(WCHAR) );
ret = RtlNtStatusToDosError( SERVER_CALL() );
wine_server_add_data( req, buffer, len * sizeof(WCHAR) );
ret = RtlNtStatusToDosError( wine_server_call(req) );
}
SERVER_END_VAR_REQ;
SERVER_END_REQ;
CloseHandle( file );
done:
......@@ -1315,7 +1315,7 @@ LONG WINAPI RegSaveKeyA( HKEY hkey, LPCSTR file, LPSECURITY_ATTRIBUTES sa )
{
req->hkey = hkey;
req->file = handle;
ret = RtlNtStatusToDosError( SERVER_CALL() );
ret = RtlNtStatusToDosError( wine_server_call( req ) );
}
SERVER_END_REQ;
......
......@@ -9,6 +9,7 @@ IMPORTS = ntdll
C_SRCS = \
comm.c \
console.c \
debugger.c \
format_msg.c \
kernel_main.c \
......
......@@ -379,7 +379,7 @@ static BOOL COMM_SetCommError(HANDLE handle, DWORD error)
req->handle = handle;
req->flags = SERIALINFO_SET_ERROR;
req->commerror = error;
ret = !SERVER_CALL_ERR();
ret = !wine_server_call_err( req );
}
SERVER_END_REQ;
return ret;
......@@ -395,8 +395,8 @@ static BOOL COMM_GetCommError(HANDLE handle, LPDWORD lperror)
SERVER_START_REQ( get_serial_info )
{
req->handle = handle;
ret = !SERVER_CALL_ERR();
*lperror = req->commerror;
ret = !wine_server_call_err( req );
*lperror = reply->commerror;
}
SERVER_END_REQ;
......@@ -748,9 +748,9 @@ BOOL WINAPI GetCommMask(
SERVER_START_REQ( get_serial_info )
{
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;
......@@ -781,7 +781,7 @@ BOOL WINAPI SetCommMask(
req->handle = handle;
req->flags = SERIALINFO_SET_MASK;
req->eventmask = evtmask;
ret = !SERVER_CALL_ERR();
ret = !wine_server_call_err( req );
}
SERVER_END_REQ;
return ret;
......@@ -1347,13 +1347,13 @@ BOOL WINAPI GetCommTimeouts(
SERVER_START_REQ( get_serial_info )
{
req->handle = hComm;
if ((ret = !SERVER_CALL_ERR()))
if ((ret = !wine_server_call_err( req )))
{
lptimeouts->ReadIntervalTimeout = req->readinterval;
lptimeouts->ReadTotalTimeoutMultiplier = req->readmult;
lptimeouts->ReadTotalTimeoutConstant = req->readconst;
lptimeouts->WriteTotalTimeoutMultiplier = req->writemult;
lptimeouts->WriteTotalTimeoutConstant = req->writeconst;
lptimeouts->ReadIntervalTimeout = reply->readinterval;
lptimeouts->ReadTotalTimeoutMultiplier = reply->readmult;
lptimeouts->ReadTotalTimeoutConstant = reply->readconst;
lptimeouts->WriteTotalTimeoutMultiplier = reply->writemult;
lptimeouts->WriteTotalTimeoutConstant = reply->writeconst;
}
}
SERVER_END_REQ;
......@@ -1401,7 +1401,7 @@ BOOL WINAPI SetCommTimeouts(
req->readconst = lptimeouts->ReadTotalTimeoutConstant ;
req->writemult = lptimeouts->WriteTotalTimeoutMultiplier ;
req->writeconst = lptimeouts->WriteTotalTimeoutConstant ;
ret = !SERVER_CALL_ERR();
ret = !wine_server_call_err( req );
}
SERVER_END_REQ;
if (!ret) return FALSE;
......@@ -1562,7 +1562,7 @@ static BOOL COMM_WaitCommEvent(
req->count = 0;
req->type = ASYNC_TYPE_WAIT;
ret=SERVER_CALL_ERR();
ret=wine_server_call_err( req );
}
SERVER_END_REQ;
......
......@@ -36,78 +36,78 @@ BOOL WINAPI WaitForDebugEvent(
for (;;)
{
HANDLE wait = 0;
debug_event_t *data;
SERVER_START_VAR_REQ( wait_debug_event, sizeof(*data) )
debug_event_t data;
SERVER_START_REQ( wait_debug_event )
{
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;
goto done;
}
data = server_data_ptr(req);
event->dwDebugEventCode = data->code;
event->dwProcessId = (DWORD)req->pid;
event->dwThreadId = (DWORD)req->tid;
switch(data->code)
event->dwDebugEventCode = data.code;
event->dwProcessId = (DWORD)reply->pid;
event->dwThreadId = (DWORD)reply->tid;
switch(data.code)
{
case EXCEPTION_DEBUG_EVENT:
event->u.Exception.ExceptionRecord = data->info.exception.record;
event->u.Exception.dwFirstChance = data->info.exception.first;
event->u.Exception.ExceptionRecord = data.info.exception.record;
event->u.Exception.dwFirstChance = data.info.exception.first;
break;
case CREATE_THREAD_DEBUG_EVENT:
event->u.CreateThread.hThread = data->info.create_thread.handle;
event->u.CreateThread.lpThreadLocalBase = data->info.create_thread.teb;
event->u.CreateThread.lpStartAddress = data->info.create_thread.start;
event->u.CreateThread.hThread = data.info.create_thread.handle;
event->u.CreateThread.lpThreadLocalBase = data.info.create_thread.teb;
event->u.CreateThread.lpStartAddress = data.info.create_thread.start;
break;
case CREATE_PROCESS_DEBUG_EVENT:
event->u.CreateProcessInfo.hFile = data->info.create_process.file;
event->u.CreateProcessInfo.hProcess = data->info.create_process.process;
event->u.CreateProcessInfo.hThread = data->info.create_process.thread;
event->u.CreateProcessInfo.lpBaseOfImage = data->info.create_process.base;
event->u.CreateProcessInfo.dwDebugInfoFileOffset = data->info.create_process.dbg_offset;
event->u.CreateProcessInfo.nDebugInfoSize = data->info.create_process.dbg_size;
event->u.CreateProcessInfo.lpThreadLocalBase = data->info.create_process.teb;
event->u.CreateProcessInfo.lpStartAddress = data->info.create_process.start;
event->u.CreateProcessInfo.lpImageName = data->info.create_process.name;
event->u.CreateProcessInfo.fUnicode = data->info.create_process.unicode;
if (data->info.create_process.file == -1) event->u.CreateProcessInfo.hFile = 0;
event->u.CreateProcessInfo.hFile = data.info.create_process.file;
event->u.CreateProcessInfo.hProcess = data.info.create_process.process;
event->u.CreateProcessInfo.hThread = data.info.create_process.thread;
event->u.CreateProcessInfo.lpBaseOfImage = data.info.create_process.base;
event->u.CreateProcessInfo.dwDebugInfoFileOffset = data.info.create_process.dbg_offset;
event->u.CreateProcessInfo.nDebugInfoSize = data.info.create_process.dbg_size;
event->u.CreateProcessInfo.lpThreadLocalBase = data.info.create_process.teb;
event->u.CreateProcessInfo.lpStartAddress = data.info.create_process.start;
event->u.CreateProcessInfo.lpImageName = data.info.create_process.name;
event->u.CreateProcessInfo.fUnicode = data.info.create_process.unicode;
if (data.info.create_process.file == -1) event->u.CreateProcessInfo.hFile = 0;
break;
case EXIT_THREAD_DEBUG_EVENT:
event->u.ExitThread.dwExitCode = data->info.exit.exit_code;
event->u.ExitThread.dwExitCode = data.info.exit.exit_code;
break;
case EXIT_PROCESS_DEBUG_EVENT:
event->u.ExitProcess.dwExitCode = data->info.exit.exit_code;
event->u.ExitProcess.dwExitCode = data.info.exit.exit_code;
break;
case LOAD_DLL_DEBUG_EVENT:
event->u.LoadDll.hFile = data->info.load_dll.handle;
event->u.LoadDll.lpBaseOfDll = data->info.load_dll.base;
event->u.LoadDll.dwDebugInfoFileOffset = data->info.load_dll.dbg_offset;
event->u.LoadDll.nDebugInfoSize = data->info.load_dll.dbg_size;
event->u.LoadDll.lpImageName = data->info.load_dll.name;
event->u.LoadDll.fUnicode = data->info.load_dll.unicode;
if (data->info.load_dll.handle == -1) event->u.LoadDll.hFile = 0;
event->u.LoadDll.hFile = data.info.load_dll.handle;
event->u.LoadDll.lpBaseOfDll = data.info.load_dll.base;
event->u.LoadDll.dwDebugInfoFileOffset = data.info.load_dll.dbg_offset;
event->u.LoadDll.nDebugInfoSize = data.info.load_dll.dbg_size;
event->u.LoadDll.lpImageName = data.info.load_dll.name;
event->u.LoadDll.fUnicode = data.info.load_dll.unicode;
if (data.info.load_dll.handle == -1) event->u.LoadDll.hFile = 0;
break;
case UNLOAD_DLL_DEBUG_EVENT:
event->u.UnloadDll.lpBaseOfDll = data->info.unload_dll.base;
event->u.UnloadDll.lpBaseOfDll = data.info.unload_dll.base;
break;
case OUTPUT_DEBUG_STRING_EVENT:
event->u.DebugString.lpDebugStringData = data->info.output_string.string;
event->u.DebugString.fUnicode = data->info.output_string.unicode;
event->u.DebugString.nDebugStringLength = data->info.output_string.length;
event->u.DebugString.lpDebugStringData = data.info.output_string.string;
event->u.DebugString.fUnicode = data.info.output_string.unicode;
event->u.DebugString.nDebugStringLength = data.info.output_string.length;
break;
case RIP_EVENT:
event->u.RipInfo.dwError = data->info.rip_info.error;
event->u.RipInfo.dwType = data->info.rip_info.type;
event->u.RipInfo.dwError = data.info.rip_info.error;
event->u.RipInfo.dwType = data.info.rip_info.type;
break;
}
done:
/* nothing */ ;
}
SERVER_END_VAR_REQ;
SERVER_END_REQ;
if (ret) return TRUE;
if (!wait) break;
res = WaitForSingleObject( wait, timeout );
......@@ -140,7 +140,7 @@ BOOL WINAPI ContinueDebugEvent(
req->pid = (void *)pid;
req->tid = (void *)tid;
req->status = status;
ret = !SERVER_CALL_ERR();
ret = !wine_server_call_err( req );
}
SERVER_END_REQ;
return ret;
......@@ -163,7 +163,7 @@ BOOL WINAPI DebugActiveProcess(
SERVER_START_REQ( debug_process )
{
req->pid = (void *)pid;
ret = !SERVER_CALL_ERR();
ret = !wine_server_call_err( req );
}
SERVER_END_REQ;
return ret;
......@@ -184,7 +184,7 @@ void WINAPI OutputDebugStringA(
req->string = (void *)str;
req->unicode = 0;
req->length = strlen(str) + 1;
SERVER_CALL();
wine_server_call( req );
}
SERVER_END_REQ;
WARN("%s\n", str);
......@@ -205,7 +205,7 @@ void WINAPI OutputDebugStringW(
req->string = (void *)str;
req->unicode = 1;
req->length = (lstrlenW(str) + 1) * sizeof(WCHAR);
SERVER_CALL();
wine_server_call( req );
}
SERVER_END_REQ;
WARN("%s\n", debugstr_w(str));
......@@ -278,7 +278,7 @@ BOOL WINAPI IsDebuggerPresent(void)
SERVER_START_REQ( get_process_info )
{
req->handle = GetCurrentProcess();
if (!SERVER_CALL_ERR()) ret = req->debugged;
if (!wine_server_call_err( req )) ret = reply->debugged;
}
SERVER_END_REQ;
return ret;
......
......@@ -206,8 +206,8 @@ HANDLE WINAPI CreateToolhelp32Snapshot( DWORD flags, DWORD process )
req->flags = flags & ~TH32CS_INHERIT;
req->inherit = (flags & TH32CS_INHERIT) != 0;
req->pid = (void *)process;
SERVER_CALL_ERR();
ret = req->handle;
wine_server_call_err( req );
ret = reply->handle;
}
SERVER_END_REQ;
if (!ret) ret = INVALID_HANDLE_VALUE;
......@@ -234,13 +234,13 @@ static BOOL TOOLHELP_Thread32Next( HANDLE handle, LPTHREADENTRY32 lpte, BOOL fir
{
req->handle = handle;
req->reset = first;
if ((ret = !SERVER_CALL_ERR()))
if ((ret = !wine_server_call_err( req )))
{
lpte->cntUsage = req->count;
lpte->th32ThreadID = (DWORD)req->tid;
lpte->th32OwnerProcessID = (DWORD)req->pid;
lpte->tpBasePri = req->base_pri;
lpte->tpDeltaPri = req->delta_pri;
lpte->cntUsage = reply->count;
lpte->th32ThreadID = (DWORD)reply->tid;
lpte->th32OwnerProcessID = (DWORD)reply->pid;
lpte->tpBasePri = reply->base_pri;
lpte->tpDeltaPri = reply->delta_pri;
lpte->dwFlags = 0; /* SDK: "reserved; do not use" */
}
}
......@@ -287,15 +287,15 @@ static BOOL TOOLHELP_Process32Next( HANDLE handle, LPPROCESSENTRY32 lppe, BOOL f
{
req->handle = handle;
req->reset = first;
if ((ret = !SERVER_CALL_ERR()))
if ((ret = !wine_server_call_err( req )))
{
lppe->cntUsage = req->count;
lppe->th32ProcessID = (DWORD)req->pid;
lppe->cntUsage = reply->count;
lppe->th32ProcessID = (DWORD)reply->pid;
lppe->th32DefaultHeapID = 0; /* FIXME */
lppe->th32ModuleID = 0; /* FIXME */
lppe->cntThreads = req->threads;
lppe->cntThreads = reply->threads;
lppe->th32ParentProcessID = 0; /* FIXME */
lppe->pcPriClassBase = req->priority;
lppe->pcPriClassBase = reply->priority;
lppe->dwFlags = -1; /* FIXME */
lppe->szExeFile[0] = 0; /* FIXME */
}
......@@ -345,15 +345,15 @@ static BOOL TOOLHELP_Module32Next( HANDLE handle, LPMODULEENTRY32 lpme, BOOL fir
{
req->handle = handle;
req->reset = first;
if ((ret = !SERVER_CALL_ERR()))
if ((ret = !wine_server_call_err( req )))
{
lpme->th32ModuleID = 0; /* toolhelp internal id, never used */
lpme->th32ProcessID = (DWORD)req->pid;
lpme->th32ProcessID = (DWORD)reply->pid;
lpme->GlblcntUsage = 0; /* FIXME */
lpme->ProccntUsage = 0; /* FIXME */
lpme->modBaseAddr = req->base;
lpme->ProccntUsage = 0; /* FIXME */
lpme->modBaseAddr = reply->base;
lpme->modBaseSize = 0; /* FIXME */
lpme->hModule = (DWORD)req->base;
lpme->hModule = (DWORD)reply->base;
lpme->szModule[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
int ret;
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;
*rec_ptr = *rec;
*context_ptr = *context;
if (!SERVER_CALL()) handle = req->handle;
wine_server_add_data( req, context, sizeof(*context) );
wine_server_add_data( req, rec, sizeof(*rec) );
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 */
/* 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
* 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;
if (!SERVER_CALL()) *context = *(CONTEXT *)server_data_ptr(req);
ret = req->status;
wine_server_set_reply( req, context, sizeof(*context) );
wine_server_call( req );
ret = reply->status;
}
SERVER_END_VAR_REQ;
SERVER_END_REQ;
NtClose( handle );
return ret;
}
......
......@@ -82,8 +82,8 @@ NTSTATUS WINAPI NtTerminateProcess( HANDLE handle, LONG exit_code )
{
req->handle = handle;
req->exit_code = exit_code;
ret = SERVER_CALL();
self = !ret && req->self;
ret = wine_server_call( req );
self = !ret && reply->self;
}
SERVER_END_REQ;
if (self) exit( exit_code );
......@@ -159,9 +159,9 @@ NTSTATUS WINAPI NtTerminateThread( HANDLE handle, LONG exit_code )
{
req->handle = handle;
req->exit_code = exit_code;
ret = SERVER_CALL();
self = !ret && req->self;
last = req->last;
ret = wine_server_call( req );
self = !ret && reply->self;
last = reply->last;
}
SERVER_END_REQ;
......
......@@ -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
# Server interface
@ cdecl -norelay wine_server_call(ptr long) 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
@ cdecl -norelay wine_server_call(ptr) wine_server_call
......@@ -222,8 +222,8 @@ NTSTATUS WINAPI NtClose( HANDLE Handle )
SERVER_START_REQ( close_handle )
{
req->handle = Handle;
ret = SERVER_CALL();
if (!ret && req->fd != -1) close( req->fd );
ret = wine_server_call( req );
if (!ret && reply->fd != -1) close( reply->fd );
}
SERVER_END_REQ;
return ret;
......
......@@ -36,16 +36,16 @@ NTSTATUS WINAPI NtCreateSemaphore( OUT PHANDLE SemaphoreHandle,
if ((MaximumCount <= 0) || (InitialCount > MaximumCount))
return STATUS_INVALID_PARAMETER;
SERVER_START_VAR_REQ( create_semaphore, len )
SERVER_START_REQ( create_semaphore )
{
req->initial = InitialCount;
req->max = MaximumCount;
req->inherit = attr && (attr->Attributes & OBJ_INHERIT);
if (len) memcpy( server_data_ptr(req), attr->ObjectName->Buffer, len );
ret = SERVER_CALL();
*SemaphoreHandle = req->handle;
if (len) wine_server_add_data( req, attr->ObjectName->Buffer, len );
ret = wine_server_call( req );
*SemaphoreHandle = reply->handle;
}
SERVER_END_VAR_REQ;
SERVER_END_REQ;
return ret;
}
......@@ -59,15 +59,15 @@ NTSTATUS WINAPI NtOpenSemaphore( OUT PHANDLE SemaphoreHandle,
DWORD len = attr && attr->ObjectName ? attr->ObjectName->Length : 0;
NTSTATUS ret;
SERVER_START_VAR_REQ( open_semaphore, len )
SERVER_START_REQ( open_semaphore )
{
req->access = access;
req->inherit = attr && (attr->Attributes & OBJ_INHERIT);
if (len) memcpy( server_data_ptr(req), attr->ObjectName->Buffer, len );
ret = SERVER_CALL();
*SemaphoreHandle = req->handle;
if (len) wine_server_add_data( req, attr->ObjectName->Buffer, len );
ret = wine_server_call( req );
*SemaphoreHandle = reply->handle;
}
SERVER_END_VAR_REQ;
SERVER_END_REQ;
return ret;
}
......@@ -96,9 +96,9 @@ NTSTATUS WINAPI NtReleaseSemaphore( HANDLE handle, ULONG count, PULONG previous
{
req->handle = handle;
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;
......@@ -123,16 +123,16 @@ NTSTATUS WINAPI NtCreateEvent(
DWORD len = attr && attr->ObjectName ? attr->ObjectName->Length : 0;
NTSTATUS ret;
SERVER_START_VAR_REQ( create_event, len )
SERVER_START_REQ( create_event )
{
req->manual_reset = ManualReset;
req->initial_state = InitialState;
req->inherit = attr && (attr->Attributes & OBJ_INHERIT);
if (len) memcpy( server_data_ptr(req), attr->ObjectName->Buffer, len );
ret = SERVER_CALL();
*EventHandle = req->handle;
if (len) wine_server_add_data( req, attr->ObjectName->Buffer, len );
ret = wine_server_call( req );
*EventHandle = reply->handle;
}
SERVER_END_VAR_REQ;
SERVER_END_REQ;
return ret;
}
......@@ -148,15 +148,15 @@ NTSTATUS WINAPI NtOpenEvent(
DWORD len = attr && attr->ObjectName ? attr->ObjectName->Length : 0;
NTSTATUS ret;
SERVER_START_VAR_REQ( open_event, len )
SERVER_START_REQ( open_event )
{
req->access = DesiredAccess;
req->inherit = attr && (attr->Attributes & OBJ_INHERIT);
if (len) memcpy( server_data_ptr(req), attr->ObjectName->Buffer, len );
ret = SERVER_CALL();
*EventHandle = req->handle;
if (len) wine_server_add_data( req, attr->ObjectName->Buffer, len );
ret = wine_server_call( req );
*EventHandle = reply->handle;
}
SERVER_END_VAR_REQ;
SERVER_END_REQ;
return ret;
}
......@@ -175,7 +175,7 @@ NTSTATUS WINAPI NtSetEvent( HANDLE handle, PULONG NumberOfThreadsReleased )
{
req->handle = handle;
req->op = SET_EVENT;
ret = SERVER_CALL();
ret = wine_server_call( req );
}
SERVER_END_REQ;
return ret;
......@@ -195,7 +195,7 @@ NTSTATUS WINAPI NtResetEvent( HANDLE handle, PULONG NumberOfThreadsReleased )
{
req->handle = handle;
req->op = RESET_EVENT;
ret = SERVER_CALL();
ret = wine_server_call( req );
}
SERVER_END_REQ;
return ret;
......@@ -226,7 +226,7 @@ NTSTATUS WINAPI NtPulseEvent( HANDLE handle, PULONG PulseCount )
{
req->handle = handle;
req->op = PULSE_EVENT;
ret = SERVER_CALL();
ret = wine_server_call( req );
}
SERVER_END_REQ;
return ret;
......
......@@ -24,24 +24,30 @@
*/
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;
if (!SERVER_CALL())
int res = 0;
if (!(data = HeapAlloc( GetProcessHeap(), 0, total * sizeof(*data) ))) break;
*count = 0;
SERVER_START_REQ( get_window_properties )
{
size_t size = server_data_size(req);
if (size)
{
property_data_t *data = server_data_ptr(req);
if ((ret = HeapAlloc( GetProcessHeap(), 0, size ))) memcpy( ret, data, size );
*count = size / sizeof(*data);
}
req->window = hwnd;
wine_server_add_data( req, data, total * sizeof(*data) );
if (!wine_server_call( req )) res = reply->total;
}
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 ret;
return NULL;
}
......@@ -102,7 +108,7 @@ HANDLE WINAPI GetPropA( HWND hwnd, LPCSTR str )
{
req->window = hwnd;
req->atom = atom;
if (!SERVER_CALL_ERR()) ret = req->handle;
if (!wine_server_call_err( req )) ret = reply->handle;
}
SERVER_END_REQ;
return ret;
......@@ -124,7 +130,7 @@ HANDLE WINAPI GetPropW( HWND hwnd, LPCWSTR str )
{
req->window = hwnd;
req->atom = atom;
if (!SERVER_CALL_ERR()) ret = req->handle;
if (!wine_server_call_err( req )) ret = reply->handle;
}
SERVER_END_REQ;
return ret;
......@@ -148,7 +154,7 @@ BOOL WINAPI SetPropA( HWND hwnd, LPCSTR str, HANDLE handle )
req->atom = atom;
req->string = (HIWORD(str) != 0);
req->handle = handle;
ret = !SERVER_CALL_ERR();
ret = !wine_server_call_err( req );
}
SERVER_END_REQ;
......@@ -174,7 +180,7 @@ BOOL WINAPI SetPropW( HWND hwnd, LPCWSTR str, HANDLE handle )
req->atom = atom;
req->string = (HIWORD(str) != 0);
req->handle = handle;
ret = !SERVER_CALL_ERR();
ret = !wine_server_call_err( req );
}
SERVER_END_REQ;
......@@ -217,7 +223,7 @@ HANDLE WINAPI RemovePropW( HWND hwnd, LPCWSTR str )
{
req->window = hwnd;
req->atom = atom;
if (!SERVER_CALL_ERR()) ret = req->handle;
if (!wine_server_call_err( req )) ret = reply->handle;
}
SERVER_END_REQ;
......
......@@ -233,7 +233,7 @@ static void _enable_event(SOCKET s, unsigned int event,
req->mask = event;
req->sstate = sstate;
req->cstate = cstate;
SERVER_CALL();
wine_server_call( req );
}
SERVER_END_REQ;
}
......@@ -247,8 +247,8 @@ static int _is_blocking(SOCKET s)
req->service = FALSE;
req->s_event = 0;
req->c_event = 0;
SERVER_CALL();
ret = (req->state & FD_WINE_NONBLOCKING) == 0;
wine_server_call( req );
ret = (reply->state & FD_WINE_NONBLOCKING) == 0;
}
SERVER_END_REQ;
return ret;
......@@ -263,8 +263,8 @@ static unsigned int _get_sock_mask(SOCKET s)
req->service = FALSE;
req->s_event = 0;
req->c_event = 0;
SERVER_CALL();
ret = req->mask;
wine_server_call( req );
ret = reply->mask;
}
SERVER_END_REQ;
return ret;
......@@ -279,18 +279,19 @@ static void _sync_sock_state(SOCKET s)
static int _get_sock_error(SOCKET s, unsigned int bit)
{
int ret;
SERVER_START_VAR_REQ( get_socket_event, FD_MAX_EVENTS*sizeof(int) )
int events[FD_MAX_EVENTS];
SERVER_START_REQ( get_socket_event )
{
req->handle = s;
req->service = FALSE;
req->s_event = 0;
req->c_event = 0;
SERVER_CALL();
ret = *((int *)server_data_ptr(req) + bit);
wine_server_set_reply( req, events, sizeof(events) );
wine_server_call( req );
}
SERVER_END_VAR_REQ;
return ret;
SERVER_END_REQ;
return events[bit];
}
static void WINSOCK_DeleteIData(void)
......@@ -900,8 +901,8 @@ SOCKET WINAPI WS_accept(SOCKET s, struct WS_sockaddr *addr,
req->lhandle = s;
req->access = GENERIC_READ|GENERIC_WRITE|SYNCHRONIZE;
req->inherit = TRUE;
set_error( SERVER_CALL() );
as = (SOCKET)req->handle;
set_error( wine_server_call( req ) );
as = (SOCKET)reply->handle;
}
SERVER_END_REQ;
if (as)
......@@ -2318,8 +2319,8 @@ SOCKET WINAPI WS_socket(int af, int type, int protocol)
req->protocol = protocol;
req->access = GENERIC_READ|GENERIC_WRITE|SYNCHRONIZE;
req->inherit = TRUE;
set_error( SERVER_CALL() );
ret = (SOCKET)req->handle;
set_error( wine_server_call( req ) );
ret = (SOCKET)reply->handle;
}
SERVER_END_REQ;
if (ret)
......@@ -2718,19 +2719,16 @@ int WINAPI WSAEnumNetworkEvents(SOCKET s, WSAEVENT hEvent, LPWSANETWORKEVENTS lp
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->service = TRUE;
req->s_event = 0;
req->c_event = hEvent;
if (!(ret = SERVER_CALL()))
{
lpEvent->lNetworkEvents = req->pmask & req->mask;
memcpy(lpEvent->iErrorCode, server_data_ptr(req), server_data_size(req) );
}
wine_server_set_reply( req, lpEvent->iErrorCode, sizeof(lpEvent->iErrorCode) );
if (!(ret = wine_server_call(req))) lpEvent->lNetworkEvents = reply->pmask & reply->mask;
}
SERVER_END_VAR_REQ;
SERVER_END_REQ;
if (!ret) return 0;
SetLastError(WSAEINVAL);
return SOCKET_ERROR;
......@@ -2750,7 +2748,7 @@ int WINAPI WSAEventSelect(SOCKET s, WSAEVENT hEvent, LONG lEvent)
req->handle = s;
req->mask = lEvent;
req->event = hEvent;
ret = SERVER_CALL();
ret = wine_server_call( req );
}
SERVER_END_REQ;
if (!ret) return 0;
......@@ -2769,17 +2767,17 @@ VOID CALLBACK WINSOCK_DoAsyncEvent( ULONG_PTR ptr )
TRACE("socket %08x, event %08x\n", info->sock, info->event);
SetLastError(0);
SERVER_START_VAR_REQ( get_socket_event, sizeof(errors) )
SERVER_START_REQ( get_socket_event )
{
req->handle = info->sock;
req->service = TRUE;
req->s_event = info->event; /* <== avoid race conditions */
req->c_event = info->event;
set_error( SERVER_CALL() );
pmask = req->pmask;
memcpy( errors, server_data_ptr(req), server_data_size(req) );
wine_server_set_reply( req, errors, sizeof(errors) );
set_error( wine_server_call(req) );
pmask = reply->pmask;
}
SERVER_END_VAR_REQ;
SERVER_END_REQ;
if ( (GetLastError() == WSAENOTSOCK) || (GetLastError() == WSAEINVAL) )
{
/* orphaned event (socket closed or something) */
......
......@@ -36,7 +36,7 @@ HANDLE WINAPI FindFirstChangeNotificationA( LPCSTR lpPathName, BOOL bWatchSubtre
{
req->subtree = bWatchSubtree;
req->filter = dwNotifyFilter;
if (!SERVER_CALL_ERR()) ret = req->handle;
if (!wine_server_call_err( req )) ret = reply->handle;
}
SERVER_END_REQ;
return ret;
......
......@@ -690,11 +690,11 @@ const DOS_DEVICE *DOSFS_GetDeviceByHandle( HFILE hFile )
SERVER_START_REQ( get_file_info )
{
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) &&
(req->attr < sizeof(DOSFS_Devices)/sizeof(DOSFS_Devices[0])))
ret = &DOSFS_Devices[req->attr];
if ((reply->attr >= 0) &&
(reply->attr < sizeof(DOSFS_Devices)/sizeof(DOSFS_Devices[0])))
ret = &DOSFS_Devices[reply->attr];
}
}
SERVER_END_REQ;
......@@ -709,7 +709,6 @@ static HANDLE DOSFS_CreateCommPort(LPCSTR name, DWORD access, DWORD attributes,
{
HANDLE ret;
char devname[40];
size_t len;
TRACE_(file)("%s %lx %lx\n", name, access, attributes);
......@@ -719,19 +718,18 @@ static HANDLE DOSFS_CreateCommPort(LPCSTR name, DWORD access, DWORD attributes,
TRACE("opening %s as %s\n", devname, name);
len = strlen(devname);
SERVER_START_VAR_REQ( create_serial, len )
SERVER_START_REQ( create_serial )
{
req->access = access;
req->inherit = (sa && (sa->nLength>=sizeof(*sa)) && sa->bInheritHandle);
req->attributes = attributes;
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);
SERVER_CALL_ERR();
ret = req->handle;
wine_server_call_err( req );
ret = reply->handle;
}
SERVER_END_VAR_REQ;
SERVER_END_REQ;
if(!ret)
ERR("Couldn't open device '%s' ! (check permissions)\n",devname);
......
......@@ -90,9 +90,7 @@ typedef struct _TEB
/* The following are Wine-specific fields (NT: GDI stuff) */
DWORD cleanup; /* --3 1fc Cleanup service handle */
void *buffer; /* --3 200 Buffer shared with server */
unsigned int buffer_pos; /* --3 204 Buffer current position */
unsigned int buffer_size; /* --3 208 Buffer size */
DWORD unused[3]; /* --3 200 Was server buffer */
int request_fd; /* --3 20c fd for sending server requests */
int reply_fd; /* --3 210 fd for receiving server replies */
int wait_fd[2]; /* --3 214 fd for sleeping server requests */
......
......@@ -1609,7 +1609,7 @@ BOOL WINAPI WriteProfileSectionW(LPCWSTR,LPCWSTR);
BOOL WINAPI WritePrivateProfileStructA(LPCSTR,LPCSTR,LPVOID,UINT,LPCSTR);
BOOL WINAPI WritePrivateProfileStructW(LPCWSTR,LPCWSTR,LPVOID,UINT,LPCWSTR);
#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 WriteProfileStringW(LPCWSTR,LPCWSTR,LPCWSTR);
#define WriteProfileString WINELIB_NAME_AW(WriteProfileString)
......
......@@ -177,10 +177,8 @@ HANDLE WINAPI CreateConsoleScreenBuffer( DWORD dwDesiredAccess, DWORD dwShareMod
LPVOID lpScreenBufferData);
BOOL WINAPI FillConsoleOutputAttribute( HANDLE hConsoleOutput, WORD wAttribute, DWORD nLength,
COORD dwCoord, LPDWORD lpNumAttrsWritten);
BOOL WINAPI FillConsoleOutputCharacterA( HANDLE hConsoleOutput, BYTE cCharacter, DWORD nLength,
COORD dwCoord, LPDWORD lpNumCharsWritten);
BOOL WINAPI FillConsoleOutputCharacterW( HANDLE hConsoleOutput, WCHAR cCharacter, DWORD nLength,
COORD dwCoord, LPDWORD lpNumCharsWritten);
BOOL WINAPI FillConsoleOutputCharacterA(HANDLE,CHAR,DWORD,COORD,LPDWORD);
BOOL WINAPI FillConsoleOutputCharacterW(HANDLE,WCHAR,DWORD,COORD,LPDWORD);
#define FillConsoleOutputCharacter WINELIB_NAME_AW(FillConsoleOutputCharacter)
BOOL WINAPI FlushConsoleInputBuffer( HANDLE handle);
BOOL WINAPI FreeConsole(VOID);
......@@ -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 WriteConsoleW(HANDLE, CONST VOID *lpBuffer, DWORD,LPDWORD,LPVOID);
#define WriteConsole WINELIB_NAME_AW(WriteConsole)
BOOL WINAPI WriteConsoleInputA( HANDLE handle, INPUT_RECORD *buffer, DWORD, LPDWORD );
BOOL WINAPI WriteConsoleInputW( HANDLE handle, INPUT_RECORD *buffer, DWORD, LPDWORD );
BOOL WINAPI WriteConsoleInputA(HANDLE,const INPUT_RECORD *,DWORD,LPDWORD);
BOOL WINAPI WriteConsoleInputW(HANDLE,const INPUT_RECORD *,DWORD,LPDWORD);
#define WriteConsoleInput WINELIB_NAME_AW(WriteConsoleInput)
BOOL WINAPI WriteConsoleOutputA( HANDLE hConsoleOutput, LPCHAR_INFO lpBuffer, COORD dwBufferSize,
COORD dwBufferCoord, LPSMALL_RECT lpWriteRegion);
BOOL WINAPI WriteConsoleOutputW( HANDLE hConsoleOutput, LPCHAR_INFO lpBuffer, COORD dwBufferSize,
COORD dwBufferCoord, LPSMALL_RECT lpWriteRegion);
BOOL WINAPI WriteConsoleOutputA(HANDLE,const CHAR_INFO*,COORD,COORD,LPSMALL_RECT);
BOOL WINAPI WriteConsoleOutputW(HANDLE,const CHAR_INFO*,COORD,COORD,LPSMALL_RECT);
#define WriteConsoleOutput WINELIB_NAME_AW(WriteConsoleOutput)
BOOL WINAPI WriteConsoleOutputAttribute(HANDLE,CONST WORD *,DWORD,COORD,LPDWORD);
BOOL WINAPI WriteConsoleOutputCharacterA(HANDLE,LPCSTR,DWORD,COORD,LPDWORD);
......
......@@ -14,83 +14,90 @@
/* client communication functions */
extern unsigned int wine_server_call( union generic_request *req, size_t size );
extern void server_protocol_error( const char *err, ... ) WINE_NORETURN;
extern void server_protocol_perror( const char *err ) WINE_NORETURN;
extern void wine_server_alloc_req( union generic_request *req, size_t size );
struct __server_iovec
{
const void *ptr;
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 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 */
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) );
return res;
}
/* get a pointer to the variable part of the request */
inline static void *server_data_ptr( const void *req )
/* get the size of the variable part of the returned reply */
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 */
inline static size_t server_data_size( const void *req )
/* add some data to be sent along with the request */
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;
}
}
/* exception support for server calls */
extern DWORD __wine_server_exception_handler( PEXCEPTION_RECORD record, EXCEPTION_FRAME *frame,
CONTEXT *context, EXCEPTION_FRAME **pdispatcher );
struct __server_exception_frame
/* set the pointer and max size for the reply var data */
inline static void wine_server_set_reply( void *req_ptr, void *ptr, unsigned int max_size )
{
EXCEPTION_FRAME frame;
unsigned int buffer_pos; /* saved buffer position */
};
struct __server_request_info * const req = req_ptr;
req->reply_data = ptr;
req->u.req.request_header.reply_size = max_size;
}
/* macros for server requests */
#define SERVER_START_REQ(type) \
do { \
union generic_request __req; \
struct type##_request * const req = &__req.type; \
__req.header.req = REQ_##type; \
__req.header.var_size = 0; \
struct __server_request_info __req; \
struct type##_request * const req = &__req.u.req.type##_request; \
const struct type##_reply * const reply = &__req.u.reply.type##_reply; \
__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
#define SERVER_END_REQ \
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_InitThread(void);
extern void CLIENT_BootDone( int debug_level );
......
......@@ -1693,7 +1693,7 @@ BOOL MODULE_FreeLibrary( WINE_MODREF *wm )
SERVER_START_REQ( unload_dll )
{
req->base = (void *)wm->module;
SERVER_CALL();
wine_server_call( req );
}
SERVER_END_REQ;
MODULE_FlushModrefs();
......
......@@ -681,7 +681,7 @@ WINE_MODREF *PE_CreateModule( HMODULE hModule, LPCSTR filename, DWORD flags,
req->dbg_offset = nt->FileHeader.PointerToSymbolTable;
req->dbg_size = nt->FileHeader.NumberOfSymbols;
req->name = &wm->filename;
SERVER_CALL();
wine_server_call( req );
}
SERVER_END_REQ;
}
......
......@@ -409,7 +409,7 @@ BOOL WINAPI InitAtomTable( DWORD entries )
SERVER_START_REQ( init_atom_table )
{
req->entries = entries;
ret = !SERVER_CALL_ERR();
ret = !wine_server_call_err( req );
}
SERVER_END_REQ;
return ret;
......@@ -421,19 +421,21 @@ static ATOM ATOM_AddAtomA( LPCSTR str, BOOL local )
ATOM atom = 0;
if (!ATOM_IsIntAtomA( str, &atom ))
{
DWORD len = MultiByteToWideChar( CP_ACP, 0, str, strlen(str), NULL, 0 );
if (len > MAX_ATOM_LEN)
WCHAR buffer[MAX_ATOM_LEN];
DWORD len = MultiByteToWideChar( CP_ACP, 0, str, strlen(str), buffer, MAX_ATOM_LEN );
if (!len)
{
SetLastError( ERROR_INVALID_PARAMETER );
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;
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 );
return atom;
......@@ -482,13 +484,13 @@ static ATOM ATOM_AddAtomW( LPCWSTR str, BOOL local )
SetLastError( ERROR_INVALID_PARAMETER );
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;
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 );
return atom;
......@@ -523,7 +525,7 @@ static ATOM ATOM_DeleteAtom( ATOM atom, BOOL local)
{
req->atom = atom;
req->local = local;
if (!SERVER_CALL_ERR()) atom = 0;
if (!wine_server_call_err( req )) atom = 0;
}
SERVER_END_REQ;
}
......@@ -566,19 +568,21 @@ static ATOM ATOM_FindAtomA( LPCSTR str, BOOL local )
ATOM atom = 0;
if (!ATOM_IsIntAtomA( str, &atom ))
{
DWORD len = MultiByteToWideChar( CP_ACP, 0, str, strlen(str), NULL, 0 );
if (len > MAX_ATOM_LEN)
WCHAR buffer[MAX_ATOM_LEN];
DWORD len = MultiByteToWideChar( CP_ACP, 0, str, strlen(str), buffer, MAX_ATOM_LEN );
if (!len)
{
SetLastError( ERROR_INVALID_PARAMETER );
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;
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 );
return atom;
......@@ -626,13 +630,13 @@ static ATOM ATOM_FindAtomW( LPCWSTR str, BOOL local )
SetLastError( ERROR_INVALID_PARAMETER );
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;
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 );
return atom;
......@@ -679,21 +683,24 @@ static UINT ATOM_GetAtomNameA( ATOM atom, LPSTR buffer, INT count, BOOL local )
}
else
{
WCHAR full_name[MAX_ATOM_LEN];
len = 0;
SERVER_START_VAR_REQ( get_atom_name, MAX_ATOM_LEN * sizeof(WCHAR) )
SERVER_START_REQ( get_atom_name )
{
req->atom = atom;
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),
server_data_size(req) / sizeof(WCHAR),
len = WideCharToMultiByte( CP_ACP, 0, full_name,
wine_server_reply_size(reply) / sizeof(WCHAR),
buffer, count - 1, NULL, NULL );
if (!len) len = count; /* overflow */
else buffer[len] = 0;
}
}
SERVER_END_VAR_REQ;
SERVER_END_REQ;
}
if (len && count <= len)
......@@ -765,20 +772,23 @@ static UINT ATOM_GetAtomNameW( ATOM atom, LPWSTR buffer, INT count, BOOL local )
}
else
{
WCHAR full_name[MAX_ATOM_LEN];
len = 0;
SERVER_START_VAR_REQ( get_atom_name, MAX_ATOM_LEN * sizeof(WCHAR) )
SERVER_START_REQ( get_atom_name )
{
req->atom = atom;
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;
memcpy( buffer, server_data_ptr(req), (count-1) * sizeof(WCHAR) );
memcpy( buffer, full_name, (count-1) * sizeof(WCHAR) );
buffer[count-1] = 0;
}
}
SERVER_END_VAR_REQ;
SERVER_END_REQ;
if (!len) return 0;
}
if (count <= len)
......
......@@ -606,6 +606,7 @@ DWORD WINAPI RegDeleteValueA( HKEY hkey, LPCSTR name )
LONG WINAPI RegLoadKeyA( HKEY hkey, LPCSTR subkey, LPCSTR filename )
{
HANDLE file;
WCHAR buffer[MAX_PATH];
DWORD ret, len, err = GetLastError();
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 )
if (!filename || !*filename) 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 > MAX_PATH*sizeof(WCHAR)) return ERROR_INVALID_PARAMETER;
if (!(len = MultiByteToWideChar( CP_ACP, 0, subkey, strlen(subkey), buffer, MAX_PATH )))
return ERROR_INVALID_PARAMETER;
if ((file = CreateFileA( filename, GENERIC_READ, 0, NULL, OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL, 0 )) == INVALID_HANDLE_VALUE)
......@@ -623,15 +624,14 @@ LONG WINAPI RegLoadKeyA( HKEY hkey, LPCSTR subkey, LPCSTR filename )
goto done;
}
SERVER_START_VAR_REQ( load_registry, len )
SERVER_START_REQ( load_registry )
{
req->hkey = hkey;
req->file = file;
MultiByteToWideChar( CP_ACP, 0, subkey, strlen(subkey),
server_data_ptr(req), len/sizeof(WCHAR) );
ret = RtlNtStatusToDosError( SERVER_CALL() );
wine_server_add_data( req, buffer, len * sizeof(WCHAR) );
ret = RtlNtStatusToDosError( wine_server_call(req) );
}
SERVER_END_VAR_REQ;
SERVER_END_REQ;
CloseHandle( file );
done:
......@@ -679,7 +679,7 @@ LONG WINAPI RegSaveKeyA( HKEY hkey, LPCSTR file, LPSECURITY_ATTRIBUTES sa )
{
req->hkey = hkey;
req->file = handle;
ret = RtlNtStatusToDosError( SERVER_CALL() );
ret = RtlNtStatusToDosError( wine_server_call( req ) );
}
SERVER_END_REQ;
......
......@@ -594,18 +594,18 @@ BOOL WINAPI GetThreadSelectorEntry( HANDLE hthread, DWORD sel, LPLDT_ENTRY ldten
{
req->handle = hthread;
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 */
ret = FALSE;
}
else
{
wine_ldt_set_base( ldtent, (void *)req->base );
wine_ldt_set_limit( ldtent, req->limit );
wine_ldt_set_flags( ldtent, req->flags );
wine_ldt_set_base( ldtent, (void *)reply->base );
wine_ldt_set_limit( ldtent, reply->limit );
wine_ldt_set_flags( ldtent, reply->flags );
}
}
}
......
......@@ -1360,50 +1360,16 @@ HANDLE WINAPI CreateFileMappingA(
DWORD size_low, /* [in] Low-order 32 bits of object size */
LPCSTR name /* [in] Name of file-mapping object */ )
{
HANDLE ret;
BYTE vprot;
DWORD len = name ? MultiByteToWideChar( CP_ACP, 0, name, strlen(name), NULL, 0 ) : 0;
/* Check parameters */
WCHAR buffer[MAX_PATH];
TRACE("(%x,%p,%08lx,%08lx%08lx,%s)\n",
hFile, sa, protect, size_high, size_low, debugstr_a(name) );
if (!name) return CreateFileMappingW( hFile, sa, protect, size_high, size_low, NULL );
if (len > MAX_PATH)
if (!MultiByteToWideChar( CP_ACP, 0, name, -1, buffer, MAX_PATH ))
{
SetLastError( ERROR_FILENAME_EXCED_RANGE );
return 0;
}
vprot = VIRTUAL_GetProt( protect );
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;
return CreateFileMappingW( hFile, sa, protect, size_high, size_low, buffer );
}
......@@ -1446,19 +1412,19 @@ HANDLE WINAPI CreateFileMappingW( HANDLE hFile, LPSECURITY_ATTRIBUTES sa,
/* Create the server object */
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->size_high = size_high;
req->size_low = size_low;
req->protect = vprot;
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);
SERVER_CALL_ERR();
ret = req->handle;
wine_server_call_err( req );
ret = reply->handle;
}
SERVER_END_VAR_REQ;
SERVER_END_REQ;
return ret;
}
......@@ -1476,23 +1442,16 @@ HANDLE WINAPI OpenFileMappingA(
BOOL inherit, /* [in] Inherit flag */
LPCSTR name ) /* [in] Name of file-mapping object */
{
HANDLE ret;
DWORD len = name ? MultiByteToWideChar( CP_ACP, 0, name, strlen(name), NULL, 0 ) : 0;
if (len > MAX_PATH)
WCHAR buffer[MAX_PATH];
if (!name) return OpenFileMappingW( access, inherit, NULL );
if (!MultiByteToWideChar( CP_ACP, 0, name, -1, buffer, MAX_PATH ))
{
SetLastError( ERROR_FILENAME_EXCED_RANGE );
return 0;
}
SERVER_START_VAR_REQ( open_mapping, len * sizeof(WCHAR) )
{
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;
return OpenFileMappingW( access, inherit, buffer );
}
......@@ -1504,20 +1463,20 @@ HANDLE WINAPI OpenFileMappingW( DWORD access, BOOL inherit, LPCWSTR name)
{
HANDLE ret;
DWORD len = name ? strlenW(name) : 0;
if (len > MAX_PATH)
if (len >= MAX_PATH)
{
SetLastError( ERROR_FILENAME_EXCED_RANGE );
return 0;
}
SERVER_START_VAR_REQ( open_mapping, len * sizeof(WCHAR) )
SERVER_START_REQ( open_mapping )
{
req->access = access;
req->inherit = inherit;
memcpy( server_data_ptr(req), name, len * sizeof(WCHAR) );
SERVER_CALL_ERR();
ret = req->handle;
wine_server_add_data( req, name, len * sizeof(WCHAR) );
wine_server_call_err( req );
ret = reply->handle;
}
SERVER_END_VAR_REQ;
SERVER_END_REQ;
return ret;
}
......@@ -1580,16 +1539,16 @@ LPVOID WINAPI MapViewOfFileEx(
SERVER_START_REQ( get_mapping_info )
{
req->handle = handle;
res = SERVER_CALL_ERR();
prot = req->protect;
base = req->base;
size_low = req->size_low;
size_high = req->size_high;
header_size = req->header_size;
shared_file = req->shared_file;
shared_size = req->shared_size;
removable = (req->drive_type == DRIVE_REMOVABLE ||
req->drive_type == DRIVE_CDROM);
res = wine_server_call_err( req );
prot = reply->protect;
base = reply->base;
size_low = reply->size_low;
size_high = reply->size_high;
header_size = reply->header_size;
shared_file = reply->shared_file;
shared_size = reply->shared_size;
removable = (reply->drive_type == DRIVE_REMOVABLE ||
reply->drive_type == DRIVE_CDROM);
}
SERVER_END_REQ;
if (res) goto error;
......
......@@ -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 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)
{
......@@ -340,55 +336,4 @@ void OPTIONS_ParseOptions( char *argv[] )
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)
req->current = level;
req->saving = saving;
req->period = period;
SERVER_CALL();
wine_server_call( req );
}
SERVER_END_REQ;
}
......@@ -1013,19 +1013,15 @@ static void _set_registry_levels(int level,int saving,int period)
static void _save_at_exit(HKEY hkey,LPCSTR path)
{
LPCSTR confdir = get_config_dir();
size_t len = strlen(confdir) + strlen(path) + 2;
if (len > REQUEST_MAX_VAR_SIZE) {
ERR( "config dir '%s' too long\n", confdir );
return;
}
SERVER_START_VAR_REQ( save_registry_atexit, len )
SERVER_START_REQ( save_registry_atexit )
{
sprintf( server_data_ptr(req), "%s/%s", confdir, path );
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] */
......@@ -1042,9 +1038,9 @@ static void _init_registry_saving( HKEY hkey_users_default )
if (PROFILE_GetWineIniBool("registry","WritetoHomeRegistryFiles",1))
{
_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_users_default,SAVE_LOCAL_REGBRANCH_USER_DEFAULT);
_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_users_default,"/" SAVE_LOCAL_REGBRANCH_USER_DEFAULT);
}
}
......@@ -1190,7 +1186,7 @@ static void load_wine_registry(HKEY hkey,LPCSTR fn)
{
req->hkey = hkey;
req->file = file;
SERVER_CALL();
wine_server_call( req );
}
SERVER_END_REQ;
CloseHandle( file );
......
......@@ -352,7 +352,8 @@ void CALLBACK VGA_Poll( ULONG_PTR arg )
ch[X].Attributes = *dat++;
}
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;
......
......@@ -5,7 +5,8 @@
*/
#include <stdio.h>
#include <wine/server.h>
#include "wine/server.h"
#include "wine/unicode.h"
#include "winecon_private.h"
static int trace_level = 1;
......@@ -35,34 +36,20 @@ void XTracer(int level, const char* format, ...)
*
* 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;
int j, nr;
step = REQUEST_MAX_VAR_SIZE / (data->sb_width * 4);
for (j = upd_tp; j <= upd_bm; j += step)
SERVER_START_REQ( read_console_output )
{
nr = min(step, upd_bm - j + 1);
SERVER_START_VAR_REQ( read_console_output, 4 * nr * data->sb_width )
{
req->handle = (handle_t)data->hConOut;
req->x = 0;
req->y = j;
req->w = data->sb_width;
req->h = nr;
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;
req->handle = (handle_t)data->hConOut;
req->x = 0;
req->y = upd_tp;
req->mode = CHAR_INFO_MODE_TEXTATTR;
req->wrap = TRUE;
wine_server_set_reply( req, &data->cells[upd_tp * data->sb_width],
(upd_bm-upd_tp+1) * data->sb_width * sizeof(CHAR_INFO) );
wine_server_call( req );
}
SERVER_END_REQ;
data->fnRefresh(data, upd_tp, 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
*/
void WINECON_NotifyWindowChange(struct inner_data* data)
void WINECON_NotifyWindowChange(struct inner_data* data)
{
SERVER_START_REQ( set_console_output_info )
{
req->handle = (handle_t)data->hConOut;
req->win_left = data->win_pos.X;
req->win_top = data->win_pos.Y;
req->win_right = data->win_pos.X + data->win_width - 1;
req->win_bottom = data->win_pos.Y + data->win_height - 1;
req->mask = SET_CONSOLE_OUTPUT_INFO_DISPLAY_WINDOW;
if (!SERVER_CALL_ERR())
{
}
req->handle = (handle_t)data->hConOut;
req->win_left = data->win_pos.X;
req->win_top = data->win_pos.Y;
req->win_right = data->win_pos.X + data->win_width - 1;
req->win_bottom = data->win_pos.Y + data->win_height - 1;
req->mask = SET_CONSOLE_OUTPUT_INFO_DISPLAY_WINDOW;
wine_server_call( req );
}
SERVER_END_REQ;
}
......@@ -100,7 +85,7 @@ int WINECON_GetHistorySize(HANDLE hConIn)
SERVER_START_REQ(get_console_input_info)
{
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;
return ret;
......@@ -120,7 +105,7 @@ BOOL WINECON_SetHistorySize(HANDLE hConIn, int size)
req->handle = (handle_t)hConIn;
req->mask = SET_CONSOLE_INPUT_INFO_HISTORY_SIZE;
req->history_size = size;
ret = !SERVER_CALL_ERR();
ret = !wine_server_call_err( req );
}
SERVER_END_REQ;
return ret;
......@@ -139,7 +124,7 @@ int WINECON_GetHistoryMode(HANDLE hConIn)
SERVER_START_REQ(get_console_input_info)
{
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;
return ret;
......@@ -159,7 +144,7 @@ BOOL WINECON_SetHistoryMode(HANDLE hConIn, int mode)
req->handle = (handle_t)hConIn;
req->mask = SET_CONSOLE_INPUT_INFO_HISTORY_MODE;
req->history_mode = mode;
ret = !SERVER_CALL_ERR();
ret = !wine_server_call_err( req );
}
SERVER_END_REQ;
return ret;
......@@ -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;
DWORD size = 0;
BOOL ret;
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;
if ((ret = !SERVER_CALL_ERR()))
req->handle = (handle_t)hConIn;
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));
memcpy(buffer, server_data_ptr(req), size);
buffer[size / sizeof(WCHAR)] = 0;
len = wine_server_reply_size( reply );
buffer[len / sizeof(WCHAR)] = 0;
}
}
SERVER_END_VAR_REQ;
SERVER_END_REQ;
return ret;
}
......@@ -200,18 +186,14 @@ int WINECON_GrabChanges(struct inner_data* data)
int i, num;
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;
if (!SERVER_CALL_ERR())
{
num = server_data_size(req);
memcpy(evts, server_data_ptr(req), num);
num /= sizeof(evts[0]);
}
else num = 0;
wine_server_set_reply( req, evts, sizeof(evts) );
req->handle = (handle_t)data->hSynchro;
if (!wine_server_call_err( req )) num = wine_server_reply_size(reply) / 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;}
/* FIXME: should do some event compression here (cursor pos, update) */
......@@ -230,7 +212,7 @@ int WINECON_GrabChanges(struct inner_data* data)
req->access = GENERIC_READ | GENERIC_WRITE;
req->share = FILE_SHARE_READ | FILE_SHARE_WRITE;
req->inherit = FALSE;
h = SERVER_CALL_ERR() ? 0 : (HANDLE)req->handle;
h = wine_server_call_err( req ) ? 0 : (HANDLE)reply->handle;
}
SERVER_END_REQ;
Trace(1, " active(%d)", (int)h);
......@@ -340,7 +322,6 @@ static struct inner_data* WINECON_Init(HINSTANCE hInst, void* pid)
struct inner_data* data = NULL;
DWORD ret;
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));
if (!data) return 0;
......@@ -355,24 +336,21 @@ static struct inner_data* WINECON_Init(HINSTANCE hInst, void* pid)
req->access = GENERIC_READ | GENERIC_WRITE;
req->inherit = FALSE;
req->pid = pid;
ret = !SERVER_CALL_ERR();
data->hConIn = (HANDLE)req->handle_in;
data->hSynchro = (HANDLE)req->event;
ret = !wine_server_call_err( req );
data->hConIn = (HANDLE)reply->handle_in;
data->hSynchro = (HANDLE)reply->event;
}
SERVER_END_REQ;
if (!ret) goto error;
len = lstrlenW(szTitle) * sizeof(WCHAR);
len = min(len, REQUEST_MAX_VAR_SIZE);
SERVER_START_VAR_REQ(set_console_input_info, len)
SERVER_START_REQ( set_console_input_info )
{
req->handle = (handle_t)data->hConIn;
req->handle = (handle_t)data->hConIn;
req->mask = SET_CONSOLE_INPUT_INFO_TITLE;
memcpy(server_data_ptr(req), szTitle, len);
ret = !SERVER_CALL_ERR();
wine_server_add_data( req, szTitle, strlenW(szTitle) * sizeof(WCHAR) );
ret = !wine_server_call_err( req );
}
SERVER_END_VAR_REQ;
SERVER_END_REQ;
if (ret)
{
......@@ -382,7 +360,7 @@ static struct inner_data* WINECON_Init(HINSTANCE hInst, void* pid)
req->access = GENERIC_WRITE|GENERIC_READ;
req->share = FILE_SHARE_READ|FILE_SHARE_WRITE;
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;
if (data->hConOut) return data;
......
......@@ -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 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 (errno == EPIPE) SYSDEPS_ExitThread(0);
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;
for (;;)
{
if ((ret = read( NtCurrentTeb()->reply_fd, req, sizeof(*req) )) == sizeof(*req))
return;
if ((ret = read( NtCurrentTeb()->reply_fd, buffer, size )) > 0)
{
if (!(size -= ret)) return;
buffer = (char *)buffer + ret;
continue;
}
if (!ret) break;
if (ret > 0) server_protocol_error( "partial read %d\n", ret );
if (errno == EINTR) continue;
if (errno == EPIPE) break;
server_protocol_perror("read");
......@@ -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.@)
*
* 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;
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 );
send_request( req );
wait_reply( req );
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 )
req->flags = 0;
req->mask = 0;
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 */
close( fd );
fd = req->cur_fd;
fd = reply->cur_fd;
}
}
else
......@@ -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
*
* Send an init thread request. Return 0 if OK.
......@@ -670,11 +634,11 @@ void CLIENT_InitThread(void)
req->entry = teb->entry_point;
req->reply_fd = reply_pipe[1];
req->wait_fd = teb->wait_fd[1];
ret = SERVER_CALL();
teb->pid = req->pid;
teb->tid = req->tid;
version = req->version;
if (req->boot) boot_thread_id = teb->tid;
ret = wine_server_call( req );
teb->pid = reply->pid;
teb->tid = reply->tid;
version = reply->version;
if (reply->boot) boot_thread_id = teb->tid;
else if (boot_thread_id == teb->tid) boot_thread_id = 0;
close( reply_pipe[1] );
}
......@@ -688,7 +652,6 @@ void CLIENT_InitThread(void)
"Or maybe the wrong wineserver is still running?\n",
version, SERVER_PROTOCOL_VERSION,
(version > SERVER_PROTOCOL_VERSION) ? "wine" : "wineserver" );
set_request_buffer();
}
......@@ -702,7 +665,7 @@ void CLIENT_BootDone( int debug_level )
SERVER_START_REQ( boot_done )
{
req->debug_level = debug_level;
SERVER_CALL();
wine_server_call( req );
}
SERVER_END_REQ;
}
......
......@@ -46,8 +46,8 @@ BOOL WINAPI GetHandleInformation( HANDLE handle, LPDWORD flags )
req->flags = 0;
req->mask = 0;
req->fd = -1;
ret = !SERVER_CALL_ERR();
if (ret && flags) *flags = req->old_flags;
ret = !wine_server_call_err( req );
if (ret && flags) *flags = reply->old_flags;
}
SERVER_END_REQ;
return ret;
......@@ -66,7 +66,7 @@ BOOL WINAPI SetHandleInformation( HANDLE handle, DWORD mask, DWORD flags )
req->flags = flags;
req->mask = mask;
req->fd = -1;
ret = !SERVER_CALL_ERR();
ret = !wine_server_call_err( req );
}
SERVER_END_REQ;
return ret;
......@@ -90,11 +90,11 @@ BOOL WINAPI DuplicateHandle( HANDLE source_process, HANDLE source,
req->inherit = inherit;
req->options = options;
ret = !SERVER_CALL_ERR();
ret = !wine_server_call_err( req );
if (ret)
{
if (dest) *dest = req->handle;
if (req->fd != -1) close( req->fd );
if (dest) *dest = reply->handle;
if (reply->fd != -1) close( reply->fd );
}
}
SERVER_END_REQ;
......
......@@ -20,10 +20,10 @@ BOOL WINAPI CreatePipe( PHANDLE hReadPipe, PHANDLE hWritePipe,
SERVER_START_REQ( create_pipe )
{
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;
*hWritePipe = req->handle_write;
*hReadPipe = reply->handle_read;
*hWritePipe = reply->handle_write;
}
}
SERVER_END_REQ;
......
......@@ -226,17 +226,17 @@ static void call_apcs( BOOL alertable )
for (;;)
{
int type = APC_NONE;
SERVER_START_VAR_REQ( get_apc, sizeof(args) )
SERVER_START_REQ( get_apc )
{
req->alertable = alertable;
if (!SERVER_CALL())
wine_server_set_reply( req, args, sizeof(args) );
if (!wine_server_call( req ))
{
type = req->type;
proc = req->func;
memcpy( args, server_data_ptr(req), server_data_size(req) );
type = reply->type;
proc = reply->func;
}
}
SERVER_END_VAR_REQ;
SERVER_END_REQ;
switch(type)
{
......@@ -315,7 +315,7 @@ DWORD WINAPI WaitForMultipleObjectsEx( DWORD count, const HANDLE *handles,
BOOL wait_all, DWORD timeout,
BOOL alertable )
{
int i, ret, cookie;
int ret, cookie;
struct timeval tv;
if (count > MAXIMUM_WAIT_OBJECTS)
......@@ -329,23 +329,21 @@ DWORD WINAPI WaitForMultipleObjectsEx( DWORD count, const HANDLE *handles,
for (;;)
{
SERVER_START_VAR_REQ( select, count * sizeof(int) )
SERVER_START_REQ( select )
{
int *data = server_data_ptr( req );
req->flags = SELECT_INTERRUPTIBLE;
req->cookie = &cookie;
req->sec = tv.tv_sec;
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 (alertable) req->flags |= SELECT_ALERTABLE;
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_USER_APC) break;
call_apcs( alertable );
......
......@@ -51,7 +51,7 @@ TEB *THREAD_IdToTEB( DWORD id )
{
req->handle = 0;
req->tid_in = (void *)id;
if (!SERVER_CALL()) ret = req->teb;
if (!wine_server_call( req )) ret = reply->teb;
}
SERVER_END_REQ;
......@@ -112,7 +112,6 @@ static void CALLBACK THREAD_FreeTEB( TEB *teb )
close( teb->wait_fd[1] );
if (teb->stack_sel) FreeSelector16( teb->stack_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 );
VirtualFree( teb->stack_base, 0, MEM_RELEASE );
}
......@@ -298,10 +297,10 @@ HANDLE WINAPI CreateThread( SECURITY_ATTRIBUTES *sa, DWORD stack,
req->suspend = ((flags & CREATE_SUSPENDED) != 0);
req->inherit = (sa && (sa->nLength>=sizeof(*sa)) && sa->bInheritHandle);
req->request_fd = request_pipe[0];
if (!SERVER_CALL_ERR())
if (!wine_server_call_err( req ))
{
handle = req->handle;
tid = req->tid;
handle = reply->handle;
tid = reply->tid;
}
close( request_pipe[0] );
}
......@@ -370,8 +369,8 @@ void WINAPI ExitThread( DWORD code ) /* [in] Exit code for this thread */
/* send the exit code to the server */
req->handle = GetCurrentThread();
req->exit_code = code;
SERVER_CALL();
last = req->last;
wine_server_call( req );
last = reply->last;
}
SERVER_END_REQ;
......@@ -400,14 +399,14 @@ BOOL WINAPI SetThreadContext( HANDLE handle, /* [in] Handle to thread
const CONTEXT *context ) /* [in] Address of context structure */
{
BOOL ret;
SERVER_START_VAR_REQ( set_thread_context, sizeof(*context) )
SERVER_START_REQ( set_thread_context )
{
req->handle = handle;
req->flags = context->ContextFlags;
memcpy( server_data_ptr(req), context, sizeof(*context) );
ret = !SERVER_CALL_ERR();
wine_server_add_data( req, context, sizeof(*context) );
ret = !wine_server_call_err( req );
}
SERVER_END_VAR_REQ;
SERVER_END_REQ;
return ret;
}
......@@ -423,15 +422,15 @@ BOOL WINAPI GetThreadContext( HANDLE handle, /* [in] Handle to thread with
CONTEXT *context ) /* [out] Address of context structure */
{
BOOL ret;
SERVER_START_VAR_REQ( get_thread_context, sizeof(*context) )
SERVER_START_REQ( get_thread_context )
{
req->handle = handle;
req->flags = context->ContextFlags;
memcpy( server_data_ptr(req), context, sizeof(*context) );
if ((ret = !SERVER_CALL_ERR()))
memcpy( context, server_data_ptr(req), sizeof(*context) );
wine_server_add_data( req, context, sizeof(*context) );
wine_server_set_reply( req, context, sizeof(*context) );
ret = !wine_server_call_err( req );
}
SERVER_END_VAR_REQ;
SERVER_END_REQ;
return ret;
}
......@@ -451,7 +450,7 @@ INT WINAPI GetThreadPriority(
{
req->handle = hthread;
req->tid_in = 0;
if (!SERVER_CALL_ERR()) ret = req->priority;
if (!wine_server_call_err( req )) ret = reply->priority;
}
SERVER_END_REQ;
return ret;
......@@ -475,7 +474,7 @@ BOOL WINAPI SetThreadPriority(
req->handle = hthread;
req->priority = priority;
req->mask = SET_THREAD_INFO_PRIORITY;
ret = !SERVER_CALL_ERR();
ret = !wine_server_call_err( req );
}
SERVER_END_REQ;
return ret;
......@@ -529,7 +528,7 @@ DWORD WINAPI SetThreadAffinityMask( HANDLE hThread, DWORD dwThreadAffinityMask )
req->handle = hThread;
req->affinity = dwThreadAffinityMask;
req->mask = SET_THREAD_INFO_AFFINITY;
ret = !SERVER_CALL_ERR();
ret = !wine_server_call_err( req );
/* FIXME: should return previous value */
}
SERVER_END_REQ;
......@@ -571,8 +570,8 @@ BOOL WINAPI GetExitCodeThread(
{
req->handle = hthread;
req->tid_in = 0;
ret = !SERVER_CALL_ERR();
if (ret && exitcode) *exitcode = req->exit_code;
ret = !wine_server_call_err( req );
if (ret && exitcode) *exitcode = reply->exit_code;
}
SERVER_END_REQ;
return ret;
......@@ -597,7 +596,7 @@ DWORD WINAPI ResumeThread(
SERVER_START_REQ( resume_thread )
{
req->handle = hthread;
if (!SERVER_CALL_ERR()) ret = req->count;
if (!wine_server_call_err( req )) ret = reply->count;
}
SERVER_END_REQ;
return ret;
......@@ -618,7 +617,7 @@ DWORD WINAPI SuspendThread(
SERVER_START_REQ( suspend_thread )
{
req->handle = hthread;
if (!SERVER_CALL_ERR()) ret = req->count;
if (!wine_server_call_err( req )) ret = reply->count;
}
SERVER_END_REQ;
return ret;
......@@ -637,7 +636,7 @@ DWORD WINAPI QueueUserAPC( PAPCFUNC func, HANDLE hthread, ULONG_PTR data )
req->user = 1;
req->func = func;
req->param = (void *)data;
ret = !SERVER_CALL_ERR();
ret = !wine_server_call_err( req );
}
SERVER_END_REQ;
return ret;
......
......@@ -18,24 +18,16 @@
*/
HANDLE WINAPI CreateWaitableTimerA( SECURITY_ATTRIBUTES *sa, BOOL manual, LPCSTR name )
{
HANDLE ret;
DWORD len = name ? MultiByteToWideChar( CP_ACP, 0, name, strlen(name), NULL, 0 ) : 0;
if (len >= MAX_PATH)
WCHAR buffer[MAX_PATH];
if (!name) return CreateWaitableTimerW( sa, manual, NULL );
if (!MultiByteToWideChar( CP_ACP, 0, name, -1, buffer, MAX_PATH ))
{
SetLastError( ERROR_FILENAME_EXCED_RANGE );
return 0;
}
SERVER_START_VAR_REQ( create_timer, len * sizeof(WCHAR) )
{
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;
return CreateWaitableTimerW( sa, manual, buffer );
}
......@@ -51,16 +43,16 @@ HANDLE WINAPI CreateWaitableTimerW( SECURITY_ATTRIBUTES *sa, BOOL manual, LPCWST
SetLastError( ERROR_FILENAME_EXCED_RANGE );
return 0;
}
SERVER_START_VAR_REQ( create_timer, len * sizeof(WCHAR) )
SERVER_START_REQ( create_timer )
{
req->manual = manual;
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);
SERVER_CALL_ERR();
ret = req->handle;
wine_server_call_err( req );
ret = reply->handle;
}
SERVER_END_VAR_REQ;
SERVER_END_REQ;
return ret;
}
......@@ -70,23 +62,16 @@ HANDLE WINAPI CreateWaitableTimerW( SECURITY_ATTRIBUTES *sa, BOOL manual, LPCWST
*/
HANDLE WINAPI OpenWaitableTimerA( DWORD access, BOOL inherit, LPCSTR name )
{
HANDLE ret;
DWORD len = name ? MultiByteToWideChar( CP_ACP, 0, name, strlen(name), NULL, 0 ) : 0;
if (len >= MAX_PATH)
WCHAR buffer[MAX_PATH];
if (!name) return OpenWaitableTimerW( access, inherit, NULL );
if (!MultiByteToWideChar( CP_ACP, 0, name, -1, buffer, MAX_PATH ))
{
SetLastError( ERROR_FILENAME_EXCED_RANGE );
return 0;
}
SERVER_START_VAR_REQ( open_timer, len * sizeof(WCHAR) )
{
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;
return OpenWaitableTimerW( access, inherit, buffer );
}
......@@ -102,15 +87,15 @@ HANDLE WINAPI OpenWaitableTimerW( DWORD access, BOOL inherit, LPCWSTR name )
SetLastError( ERROR_FILENAME_EXCED_RANGE );
return 0;
}
SERVER_START_VAR_REQ( open_timer, len * sizeof(WCHAR) )
SERVER_START_REQ( open_timer )
{
req->access = access;
req->inherit = inherit;
memcpy( server_data_ptr(req), name, len * sizeof(WCHAR) );
SERVER_CALL_ERR();
ret = req->handle;
wine_server_add_data( req, name, len * sizeof(WCHAR) );
wine_server_call_err( req );
ret = reply->handle;
}
SERVER_END_VAR_REQ;
SERVER_END_REQ;
return ret;
}
......@@ -150,7 +135,7 @@ BOOL WINAPI SetWaitableTimer( HANDLE handle, const LARGE_INTEGER *when, LONG per
req->callback = callback;
req->arg = arg;
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;
return ret;
......@@ -166,7 +151,7 @@ BOOL WINAPI CancelWaitableTimer( HANDLE handle )
SERVER_START_REQ( cancel_timer )
{
req->handle = handle;
ret = !SERVER_CALL_ERR();
ret = !wine_server_call_err( req );
}
SERVER_END_REQ;
return ret;
......
......@@ -28,7 +28,7 @@ DECL_HANDLER(create_async)
/* FIXME: check if this object is allowed to do overlapped I/O */
/* 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);
}
......@@ -65,11 +65,14 @@ static const struct object_ops atom_table_ops =
static struct atom_table *global_table;
/* copy an atom name to a temporary area */
static const WCHAR *copy_name( const WCHAR *str, size_t len )
/* copy an atom name from the request to a temporary area */
static const WCHAR *copy_request_name(void)
{
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))
{
set_error( STATUS_INVALID_PARAMETER );
......@@ -267,27 +270,6 @@ static atom_t find_atom( struct atom_table *table, const WCHAR *str )
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 */
int grab_global_atom( atom_t atom )
{
......@@ -310,8 +292,8 @@ DECL_HANDLER(add_atom)
if (!*table_ptr) *table_ptr = create_table(0);
if (*table_ptr)
{
const WCHAR *name = copy_name( get_req_data(req), get_req_data_size(req) );
if (name) req->atom = add_atom( *table_ptr, name );
const WCHAR *name = copy_request_name();
if (name) reply->atom = add_atom( *table_ptr, name );
}
}
......@@ -324,18 +306,26 @@ DECL_HANDLER(delete_atom)
/* find a global 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)
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 */
DECL_HANDLER(get_atom_name)
{
WCHAR *name = get_req_data(req);
size_t size = get_atom_name( req->local ? current->process->atom_table : global_table,
req->atom, name, get_req_data_size(req), &req->count );
set_req_data_size( req, size );
struct atom_entry *entry;
size_t len = 0;
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 */
......
......@@ -72,11 +72,11 @@ DECL_HANDLER(create_change_notification)
{
struct change *change;
req->handle = 0;
reply->handle = 0;
if ((change = create_change_notification( req->subtree, req->filter )))
{
req->handle = alloc_handle( current->process, change,
STANDARD_RIGHTS_REQUIRED|SYNCHRONIZE, 0 );
reply->handle = alloc_handle( current->process, change,
STANDARD_RIGHTS_REQUIRED|SYNCHRONIZE, 0 );
release_object( change );
}
}
......@@ -7,6 +7,8 @@
#ifndef __WINE_SERVER_CONSOLE_H
#define __WINE_SERVER_CONSOLE_H
#include "wincon.h"
struct screen_buffer;
struct console_input_events;
......@@ -18,7 +20,7 @@ struct console_input
int mode; /* input mode */
struct screen_buffer *active; /* active screen buffer */
int recnum; /* number of input records */
void *records; /* input records */
INPUT_RECORD *records; /* input records */
struct console_input_events *evt; /* synchronization event with renderer */
WCHAR *title; /* console title */
WCHAR **history; /* lines history */
......
......@@ -144,7 +144,7 @@ static void get_thread_context( struct thread *thread, unsigned int flags, CONTE
/* 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;
if (flags & CONTEXT_FULL)
......@@ -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 */
/* correct structure (the same as fsave/frstor) */
if (ptrace( PTRACE_SETFPREGS, pid, 0, &context->FloatSave ) == -1) goto error;
context->FloatSave.Cr0NpxState = 0; /* FIXME */
}
return;
error:
......@@ -256,7 +255,7 @@ static void get_thread_context( struct thread *thread, unsigned int flags, CONTE
/* 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;
if (flags & CONTEXT_FULL)
......@@ -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 */
/* correct structure (the same as fsave/frstor) */
if (ptrace( PTRACE_SETFPREGS, pid, 0, (int) &context->FloatSave ) == -1) goto error;
context->FloatSave.Cr0NpxState = 0; /* FIXME */
}
return;
error:
......@@ -365,7 +363,7 @@ static void get_thread_context( struct thread *thread, unsigned int flags, CONTE
/* 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;
if (flags & CONTEXT_FULL)
......@@ -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 */
/* correct structure (the same as fsave/frstor) */
if (ptrace( PTRACE_SETFPREGS, pid, 0, (int) &context->FloatSave ) == -1) goto error;
context->FloatSave.Cr0NpxState = 0; /* FIXME */
}
return;
error:
......@@ -425,7 +422,7 @@ static void set_thread_context( struct thread *thread, unsigned int flags, CONTE
/* 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)
{
......@@ -486,27 +483,34 @@ int get_thread_single_step( struct thread *thread )
DECL_HANDLER(get_thread_context)
{
struct thread *thread;
void *data;
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 );
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 */
{
copy_context( get_req_data(req), thread->context, flags );
copy_context( data, thread->context, flags );
flags &= CONTEXT_DEBUG_REGISTERS;
}
if (flags && suspend_for_ptrace( thread ))
{
get_thread_context( thread, flags, get_req_data(req) );
get_thread_context( thread, flags, data );
resume_thread( thread );
}
release_object( thread );
}
release_object( thread );
}
......@@ -516,7 +520,7 @@ DECL_HANDLER(set_thread_context)
struct thread *thread;
int flags = req->flags & ~CONTEXT_i386; /* get rid of CPU id */
if (get_req_data_size(req) < sizeof(CONTEXT))
if (get_req_data_size() < sizeof(CONTEXT))
{
set_error( STATUS_INVALID_PARAMETER );
return;
......@@ -525,12 +529,12 @@ DECL_HANDLER(set_thread_context)
{
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;
}
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 );
}
release_object( thread );
......
......@@ -78,7 +78,7 @@ static void get_thread_context( struct thread *thread, unsigned int flags, CONTE
/* 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 */
}
......@@ -89,7 +89,7 @@ static void set_thread_context( struct thread *thread, unsigned int flags, CONTE
/* 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)
{
......@@ -164,27 +164,30 @@ int get_thread_single_step( struct thread *thread )
DECL_HANDLER(get_thread_context)
{
struct thread *thread;
void *data;
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 );
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 */
{
copy_context( get_req_data(req), thread->context, flags );
copy_context( data, thread->context, flags );
flags = 0;
}
if (flags && suspend_for_ptrace( thread ))
{
get_thread_context( thread, flags, get_req_data(req) );
get_thread_context( thread, flags, data );
resume_thread( thread );
}
release_object( thread );
}
release_object( thread );
}
......@@ -194,7 +197,7 @@ DECL_HANDLER(set_thread_context)
struct thread *thread;
int flags = req->flags & ~CONTEXT_SPARC; /* get rid of CPU id */
if (get_req_data_size(req) < sizeof(CONTEXT))
if (get_req_data_size() < sizeof(CONTEXT))
{
set_error( STATUS_INVALID_PARAMETER );
return;
......@@ -203,12 +206,12 @@ DECL_HANDLER(set_thread_context)
{
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;
}
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 );
}
release_object( thread );
......
......@@ -353,7 +353,7 @@ static int continue_debug_event( struct process *process, struct thread *thread,
/* alloc a debug event for a debugger */
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 debug_event *event;
......@@ -498,25 +498,23 @@ DECL_HANDLER(wait_debug_event)
set_error( STATUS_INVALID_HANDLE );
return;
}
req->wait = 0;
reply->wait = 0;
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->sender->debug_event = event;
req->pid = event->sender->process;
req->tid = event->sender;
reply->pid = event->sender->process;
reply->tid = event->sender;
if (size > sizeof(debug_event_t)) size = sizeof(debug_event_t);
memcpy( get_req_data(req), &event->data, size );
set_req_data_size( req, size );
set_reply_data( &event->data, size );
}
else /* no event ready */
{
req->pid = 0;
req->tid = 0;
set_req_data_size( req, 0 );
reply->pid = 0;
reply->tid = 0;
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)
/* queue an exception event */
DECL_HANDLER(queue_exception_event)
{
req->handle = 0;
reply->handle = 0;
if (current->process->debugger)
{
struct debug_event_exception data;
struct debug_event *event;
CONTEXT *context = get_req_data( req );
const CONTEXT *context = get_req_data();
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 );
return;
......@@ -579,7 +577,7 @@ DECL_HANDLER(queue_exception_event)
data.first = req->first;
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 );
suspend_process( current->process );
......@@ -593,26 +591,24 @@ DECL_HANDLER(queue_exception_event)
DECL_HANDLER(get_exception_status)
{
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,
0, &debug_event_ops )))
{
if (event->state == EVENT_CONTINUED)
{
req->status = event->status;
reply->status = event->status;
if (current->context == &event->context)
{
size = min( sizeof(CONTEXT), get_req_data_size(req) );
memcpy( get_req_data(req), &event->context, size );
size_t size = min( sizeof(CONTEXT), get_reply_max_size() );
set_reply_data( &event->context, size );
current->context = NULL;
}
}
else set_error( STATUS_PENDING );
release_object( event );
}
set_req_data_size( req, size );
}
/* send an output string to the debugger */
......
......@@ -29,7 +29,7 @@ struct device
};
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 =
{
......@@ -64,23 +64,23 @@ static void device_dump( struct object *obj, int verbose )
fprintf( stderr, "Device id=%08x\n", dev->id );
}
static int device_get_info( struct object *obj, struct get_file_info_request *req )
static int device_get_info( struct object *obj, struct get_file_info_reply *reply )
{
struct device *dev = (struct device *)obj;
assert( obj->ops == &device_ops );
if (req)
if (reply)
{
req->type = FILE_TYPE_UNKNOWN;
req->attr = dev->id; /* hack! */
req->access_time = 0;
req->write_time = 0;
req->size_high = 0;
req->size_low = 0;
req->links = 0;
req->index_high = 0;
req->index_low = 0;
req->serial = 0;
reply->type = FILE_TYPE_UNKNOWN;
reply->attr = dev->id; /* hack! */
reply->access_time = 0;
reply->write_time = 0;
reply->size_high = 0;
reply->size_low = 0;
reply->links = 0;
reply->index_high = 0;
reply->index_low = 0;
reply->serial = 0;
}
return FD_TYPE_DEFAULT;
}
......@@ -90,10 +90,10 @@ DECL_HANDLER(create_device)
{
struct device *dev;
req->handle = 0;
reply->handle = 0;
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 );
}
}
......@@ -115,11 +115,11 @@ DECL_HANDLER(create_event)
{
struct event *event;
req->handle = 0;
if ((event = create_event( get_req_data(req), get_req_data_size(req),
reply->handle = 0;
if ((event = create_event( get_req_data(), get_req_data_size(),
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 );
}
}
......@@ -127,8 +127,8 @@ DECL_HANDLER(create_event)
/* open a handle to an event */
DECL_HANDLER(open_event)
{
req->handle = open_object( get_req_data(req), get_req_data_size(req),
&event_ops, req->access, req->inherit );
reply->handle = open_object( get_req_data(), get_req_data_size(),
&event_ops, req->access, req->inherit );
}
/* do an event operation */
......
......@@ -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_fd( 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 const struct object_ops file_ops =
......@@ -271,13 +271,13 @@ static int file_flush( struct object *obj )
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 file *file = (struct file *)obj;
assert( obj->ops == &file_ops );
if (req)
if (reply)
{
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
return FD_TYPE_INVALID;
}
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;
else req->type = FILE_TYPE_DISK;
if (S_ISDIR(st.st_mode)) req->attr = FILE_ATTRIBUTE_DIRECTORY;
else req->attr = FILE_ATTRIBUTE_ARCHIVE;
if (!(st.st_mode & S_IWUSR)) req->attr |= FILE_ATTRIBUTE_READONLY;
req->access_time = st.st_atime;
req->write_time = st.st_mtime;
S_ISSOCK(st.st_mode) || isatty(file->obj.fd)) reply->type = FILE_TYPE_CHAR;
else reply->type = FILE_TYPE_DISK;
if (S_ISDIR(st.st_mode)) reply->attr = FILE_ATTRIBUTE_DIRECTORY;
else reply->attr = FILE_ATTRIBUTE_ARCHIVE;
if (!(st.st_mode & S_IWUSR)) reply->attr |= FILE_ATTRIBUTE_READONLY;
reply->access_time = st.st_atime;
reply->write_time = st.st_mtime;
if (S_ISDIR(st.st_mode))
{
req->size_high = 0;
req->size_low = 0;
reply->size_high = 0;
reply->size_low = 0;
}
else
{
req->size_high = st.st_size >> 32;
req->size_low = st.st_size & 0xffffffff;
reply->size_high = st.st_size >> 32;
reply->size_low = st.st_size & 0xffffffff;
}
req->links = st.st_nlink;
req->index_high = st.st_dev;
req->index_low = st.st_ino;
req->serial = 0; /* FIXME */
reply->links = st.st_nlink;
reply->index_high = st.st_dev;
reply->index_low = st.st_ino;
reply->serial = 0; /* FIXME */
}
return FD_TYPE_DEFAULT;
}
......@@ -470,11 +470,11 @@ DECL_HANDLER(create_file)
{
struct file *file;
req->handle = 0;
if ((file = create_file( get_req_data(req), get_req_data_size(req), req->access,
reply->handle = 0;
if ((file = create_file( get_req_data(), get_req_data_size(), req->access,
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 );
}
}
......@@ -485,7 +485,7 @@ DECL_HANDLER(alloc_file_handle)
struct file *file;
int fd;
req->handle = 0;
reply->handle = 0;
if ((fd = thread_get_inflight_fd( current, req->fd )) == -1)
{
set_error( STATUS_INVALID_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,
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 );
}
}
......@@ -504,18 +504,18 @@ DECL_HANDLER(get_handle_fd)
{
struct object *obj;
req->fd = -1;
req->type = FD_TYPE_INVALID;
reply->fd = -1;
reply->type = FD_TYPE_INVALID;
if ((obj = get_handle_obj( current->process, req->handle, req->access, NULL )))
{
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())
{
if ((fd = obj->ops->get_fd( obj )) != -1)
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 );
}
}
......@@ -526,8 +526,8 @@ DECL_HANDLER(set_file_pointer)
int high = req->high;
int low = req->low;
set_file_pointer( req->handle, &low, &high, req->whence );
req->new_low = low;
req->new_high = high;
reply->new_low = low;
reply->new_high = high;
}
/* truncate (or extend) a file */
......@@ -561,7 +561,7 @@ DECL_HANDLER(get_file_info)
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 );
}
}
......
......@@ -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->access & access) != access)
{
fprintf( stderr, "handle %d access %08x denied (%08x)\n", handle, access, entry->access );
set_error( STATUS_ACCESS_DENIED );
return NULL;
}
......@@ -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->access & access) != access)
{
fprintf( stderr, "handle %d access %08x denied (%08x)\n", handle, access, entry->access );
set_error( STATUS_ACCESS_DENIED );
return -1;
}
......@@ -459,7 +457,7 @@ handle_t open_object( const WCHAR *name, size_t len, const struct object_ops *op
/* close a 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 */
......@@ -468,8 +466,9 @@ DECL_HANDLER(set_handle_info)
int fd = req->fd;
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 );
req->cur_fd = fd;
reply->old_flags = set_handle_info( current->process, req->handle,
req->mask, req->flags, &fd );
reply->cur_fd = fd;
}
/* duplicate a handle */
......@@ -477,25 +476,25 @@ DECL_HANDLER(dup_handle)
{
struct process *src, *dst;
req->handle = 0;
req->fd = -1;
reply->handle = 0;
reply->fd = -1;
if ((src = get_process_from_handle( req->src_process, PROCESS_DUP_HANDLE )))
{
if (req->options & DUP_HANDLE_MAKE_GLOBAL)
{
req->handle = duplicate_handle( src, req->src_handle, NULL,
req->access, req->inherit, req->options );
reply->handle = duplicate_handle( src, req->src_handle, NULL,
req->access, req->inherit, req->options );
}
else if ((dst = get_process_from_handle( req->dst_process, PROCESS_DUP_HANDLE )))
{
req->handle = duplicate_handle( src, req->src_handle, dst,
req->access, req->inherit, req->options );
reply->handle = duplicate_handle( src, req->src_handle, dst,
req->access, req->inherit, req->options );
release_object( dst );
}
/* close the handle no matter what happened */
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 );
}
release_object( src );
......
......@@ -34,7 +34,7 @@ struct mapping
};
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_destroy( struct object *obj );
......@@ -263,11 +263,11 @@ static struct object *create_mapping( int size_high, int size_low, int protect,
}
if (!size_high && !size_low)
{
struct get_file_info_request req;
struct get_file_info_reply reply;
struct object *obj = (struct object *)mapping->file;
obj->ops->get_file_info( obj, &req );
size_high = req.size_high;
size_low = ROUND_SIZE( 0, req.size_low );
obj->ops->get_file_info( obj, &reply );
size_high = reply.size_high;
size_low = ROUND_SIZE( 0, reply.size_low );
}
else if (!grow_file( mapping->file, size_high, size_low )) goto error;
}
......@@ -311,14 +311,14 @@ static int mapping_get_fd( struct object *obj )
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 object *file = (struct object *)mapping->file;
assert( obj->ops == &mapping_ops );
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 )
......@@ -346,14 +346,14 @@ DECL_HANDLER(create_mapping)
{
struct object *obj;
req->handle = 0;
reply->handle = 0;
if ((obj = create_mapping( req->size_high, req->size_low,
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;
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 );
}
}
......@@ -361,8 +361,8 @@ DECL_HANDLER(create_mapping)
/* open a handle to a mapping */
DECL_HANDLER(open_mapping)
{
req->handle = open_object( get_req_data(req), get_req_data_size(req),
&mapping_ops, req->access, req->inherit );
reply->handle = open_object( get_req_data(), get_req_data_size(),
&mapping_ops, req->access, req->inherit );
}
/* get a mapping information */
......@@ -373,17 +373,17 @@ DECL_HANDLER(get_mapping_info)
if ((mapping = (struct mapping *)get_handle_obj( current->process, req->handle,
0, &mapping_ops )))
{
req->size_high = mapping->size_high;
req->size_low = mapping->size_low;
req->protect = mapping->protect;
req->header_size = mapping->header_size;
req->base = mapping->base;
req->shared_file = 0;
req->shared_size = mapping->shared_size;
req->drive_type = get_file_drive_type( mapping->file );
reply->size_high = mapping->size_high;
reply->size_low = mapping->size_low;
reply->protect = mapping->protect;
reply->header_size = mapping->header_size;
reply->base = mapping->base;
reply->shared_file = 0;
reply->shared_size = mapping->shared_size;
reply->drive_type = get_file_drive_type( mapping->file );
if (mapping->shared_file)
req->shared_file = alloc_handle( current->process, mapping->shared_file,
GENERIC_READ|GENERIC_WRITE, 0 );
reply->shared_file = alloc_handle( current->process, mapping->shared_file,
GENERIC_READ|GENERIC_WRITE, 0 );
release_object( mapping );
}
}
......@@ -140,10 +140,10 @@ DECL_HANDLER(create_mutex)
{
struct mutex *mutex;
req->handle = 0;
if ((mutex = create_mutex( get_req_data(req), get_req_data_size(req), req->owned )))
reply->handle = 0;
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 );
}
}
......@@ -151,8 +151,8 @@ DECL_HANDLER(create_mutex)
/* open a handle to a mutex */
DECL_HANDLER(open_mutex)
{
req->handle = open_object( get_req_data(req), get_req_data_size(req),
&mutex_ops, req->access, req->inherit );
reply->handle = open_object( get_req_data(), get_req_data_size(),
&mutex_ops, req->access, req->inherit );
}
/* release a mutex */
......
......@@ -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_destroy( 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 =
{
......@@ -180,20 +180,20 @@ static int pipe_user_get_fd( struct object *obj )
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;
req->attr = 0;
req->access_time = 0;
req->write_time = 0;
req->size_high = 0;
req->size_low = 0;
req->links = 0;
req->index_high = 0;
req->index_low = 0;
req->serial = 0;
reply->type = FILE_TYPE_PIPE;
reply->attr = 0;
reply->access_time = 0;
reply->write_time = 0;
reply->size_high = 0;
reply->size_low = 0;
reply->links = 0;
reply->index_high = 0;
reply->index_low = 0;
reply->serial = 0;
}
return FD_TYPE_DEFAULT;
}
......@@ -265,8 +265,8 @@ DECL_HANDLER(create_named_pipe)
struct named_pipe *pipe;
struct pipe_user *user;
req->handle = 0;
pipe = create_named_pipe( get_req_data(req), get_req_data_size(req) );
reply->handle = 0;
pipe = create_named_pipe( get_req_data(), get_req_data_size() );
if(!pipe)
return;
......@@ -284,7 +284,7 @@ DECL_HANDLER(create_named_pipe)
if(user)
{
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 );
}
......@@ -295,8 +295,8 @@ DECL_HANDLER(open_named_pipe)
{
struct named_pipe *pipe;
req->handle = 0;
pipe = create_named_pipe( get_req_data(req), get_req_data_size(req) );
reply->handle = 0;
pipe = create_named_pipe( get_req_data(), get_req_data_size() );
if(!pipe)
return;
......@@ -320,7 +320,7 @@ DECL_HANDLER(open_named_pipe)
partner->other = user;
user->state = ps_connected_client;
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);
}
else
......@@ -378,7 +378,7 @@ DECL_HANDLER(wait_named_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 )
{
/* only wait if the pipe already exists */
......@@ -448,10 +448,10 @@ DECL_HANDLER(get_named_pipe_info)
if(!user)
return;
req->flags = user->pipe->pipemode;
req->maxinstances = user->pipe->maxinstances;
req->insize = user->pipe->insize;
req->outsize = user->pipe->outsize;
reply->flags = user->pipe->pipemode;
reply->maxinstances = user->pipe->maxinstances;
reply->insize = user->pipe->insize;
reply->outsize = user->pipe->outsize;
release_object(user);
}
......
......@@ -263,7 +263,7 @@ int no_flush( struct object *obj )
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 );
return FD_TYPE_INVALID;
......
......@@ -47,7 +47,7 @@ struct object_ops
/* flush the object buffers */
int (*flush)(struct object *);
/* get file information */
int (*get_file_info)(struct object *,struct get_file_info_request *);
int (*get_file_info)(struct object *,struct get_file_info_reply *);
/* destroy on refcount == 0 */
void (*destroy)(struct object *);
};
......@@ -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_get_fd( 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 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 );
......@@ -103,7 +103,7 @@ extern void dump_objects(void);
extern int add_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 int check_select_events( int fd, int events );
extern void select_loop(void);
......
......@@ -37,7 +37,7 @@ struct pipe
static void pipe_dump( struct object *obj, int verbose );
static int pipe_get_poll_events( 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 const struct object_ops pipe_ops =
......@@ -124,20 +124,20 @@ static int pipe_get_fd( struct object *obj )
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;
req->attr = 0;
req->access_time = 0;
req->write_time = 0;
req->size_high = 0;
req->size_low = 0;
req->links = 0;
req->index_high = 0;
req->index_low = 0;
req->serial = 0;
reply->type = FILE_TYPE_PIPE;
reply->attr = 0;
reply->access_time = 0;
reply->write_time = 0;
reply->size_high = 0;
reply->size_low = 0;
reply->links = 0;
reply->index_high = 0;
reply->index_low = 0;
reply->serial = 0;
}
return FD_TYPE_DEFAULT;
}
......@@ -171,6 +171,6 @@ DECL_HANDLER(create_pipe)
release_object( obj[0] );
release_object( obj[1] );
}
req->handle_read = hread;
req->handle_write = hwrite;
reply->handle_read = hread;
reply->handle_write = hwrite;
}
......@@ -142,31 +142,105 @@ void fatal_perror( const char *err, ... )
exit(1);
}
/* call a request handler */
static inline void call_req_handler( struct thread *thread, union generic_request *request )
/* allocate the reply data */
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;
clear_error();
/* write the remaining part of the reply */
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 +
request->header.var_size > MAX_REQUEST_LENGTH)
struct iovec vec[2];
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",
request->header.var_offset, request->header.var_size );
/* couldn't write it all, wait for POLLOUT */
change_select_fd( &current->obj, current->reply_fd, POLLOUT );
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)
{
req_handlers[req]( request );
if (current) send_reply( current, request );
req_handlers[req]( &current->req, &reply );
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;
return;
}
......@@ -176,14 +250,39 @@ static inline void call_req_handler( struct thread *thread, union generic_reques
/* read a request from a thread */
void read_request( struct thread *thread )
{
union generic_request req;
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 );
return;
if ((ret = read( thread->obj.fd, &thread->req,
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 */
kill_thread( thread, 0 );
else if (ret > 0)
......@@ -192,26 +291,6 @@ void read_request( struct thread *thread )
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 */
int receive_fd( struct process *process )
{
......@@ -439,6 +518,7 @@ void open_master_socket(void)
/* make sure no request is larger than the maximum size */
assert( sizeof(union generic_request) == sizeof(struct request_max_size) );
assert( sizeof(union generic_reply) == sizeof(struct request_max_size) );
create_server_dir();
if ((fd = socket( AF_UNIX, SOCK_STREAM, 0 )) == -1) fatal_perror( "socket" );
......
......@@ -7,6 +7,8 @@
#ifndef __WINE_SERVER_REQUEST_H
#define __WINE_SERVER_REQUEST_H
#include <assert.h>
#include "thread.h"
#include "wine/server_protocol.h"
......@@ -14,7 +16,8 @@
#define MAX_REQUEST_LENGTH 8192
/* 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 */
......@@ -33,36 +36,54 @@ extern void fatal_perror( const char *err, ... );
#endif
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 send_client_fd( struct process *process, int fd, handle_t handle );
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 void open_master_socket(void);
extern void close_master_socket(void);
extern void lock_master_socket( int locked );
extern void trace_request( struct thread *thread, const union generic_request *request );
extern void trace_reply( struct thread *thread, const union generic_request *request );
extern void trace_request(void);
extern void trace_reply( enum request req, const union generic_reply *reply );
/* 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 */
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 */
inline static void set_req_data_size( const void *req, size_t size )
/* allocate and fill the reply data */
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 */
/* ### make_requests begin ### */
......@@ -73,7 +94,6 @@ DECL_HANDLER(boot_done);
DECL_HANDLER(init_process);
DECL_HANDLER(init_process_done);
DECL_HANDLER(init_thread);
DECL_HANDLER(set_thread_buffer);
DECL_HANDLER(terminate_process);
DECL_HANDLER(terminate_thread);
DECL_HANDLER(get_process_info);
......@@ -132,6 +152,7 @@ DECL_HANDLER(get_console_output_info);
DECL_HANDLER(write_console_input);
DECL_HANDLER(read_console_input);
DECL_HANDLER(write_console_output);
DECL_HANDLER(fill_console_output);
DECL_HANDLER(read_console_output);
DECL_HANDLER(move_console_output);
DECL_HANDLER(create_change_notification);
......@@ -217,7 +238,7 @@ DECL_HANDLER(get_window_properties);
#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] =
{
(req_handler)req_new_process,
......@@ -227,7 +248,6 @@ static const req_handler req_handlers[REQ_NB_REQUESTS] =
(req_handler)req_init_process,
(req_handler)req_init_process_done,
(req_handler)req_init_thread,
(req_handler)req_set_thread_buffer,
(req_handler)req_terminate_process,
(req_handler)req_terminate_thread,
(req_handler)req_get_process_info,
......@@ -286,6 +306,7 @@ static const req_handler req_handlers[REQ_NB_REQUESTS] =
(req_handler)req_write_console_input,
(req_handler)req_read_console_input,
(req_handler)req_write_console_output,
(req_handler)req_fill_console_output,
(req_handler)req_read_console_output,
(req_handler)req_move_console_output,
(req_handler)req_create_change_notification,
......
......@@ -97,13 +97,13 @@ void remove_select_user( struct object *obj )
active_users--;
}
/* change the fd of an object (the old fd is closed) */
void change_select_fd( struct object *obj, int fd )
/* change the fd and events of an object */
void change_select_fd( struct object *obj, int fd, int events )
{
int user = obj->select;
assert( poll_users[user] == obj );
pollfd[user].fd = fd;
close( obj->fd );
pollfd[user].events = events;
obj->fd = fd;
}
......
......@@ -123,11 +123,11 @@ DECL_HANDLER(create_semaphore)
{
struct semaphore *sem;
req->handle = 0;
if ((sem = create_semaphore( get_req_data(req), get_req_data_size(req),
reply->handle = 0;
if ((sem = create_semaphore( get_req_data(), get_req_data_size(),
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 );
}
}
......@@ -135,12 +135,12 @@ DECL_HANDLER(create_semaphore)
/* open a handle to a semaphore */
DECL_HANDLER(open_semaphore)
{
req->handle = open_object( get_req_data(req), get_req_data_size(req),
&semaphore_ops, req->access, req->inherit );
reply->handle = open_object( get_req_data(), get_req_data_size(),
&semaphore_ops, req->access, req->inherit );
}
/* release a 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 @@
static void serial_dump( struct object *obj, int verbose );
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 );
struct serial
......@@ -165,23 +165,23 @@ static int serial_get_fd( struct object *obj )
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;
assert( obj->ops == &serial_ops );
if (req)
if (reply)
{
req->type = FILE_TYPE_CHAR;
req->attr = 0;
req->access_time = 0;
req->write_time = 0;
req->size_high = 0;
req->size_low = 0;
req->links = 0;
req->index_high = 0;
req->index_low = 0;
req->serial = 0;
reply->type = FILE_TYPE_CHAR;
reply->attr = 0;
reply->access_time = 0;
reply->write_time = 0;
reply->size_high = 0;
reply->size_low = 0;
reply->links = 0;
reply->index_high = 0;
reply->index_low = 0;
reply->serial = 0;
}
if(serial->attrib & FILE_FLAG_OVERLAPPED)
......@@ -215,10 +215,10 @@ DECL_HANDLER(create_serial)
{
struct serial *serial;
req->handle = 0;
if ((serial = create_serial( get_req_data(req), get_req_data_size(req), req->access, req->attributes )))
reply->handle = 0;
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 );
}
}
......@@ -230,17 +230,17 @@ DECL_HANDLER(get_serial_info)
if ((serial = get_serial_obj( current->process, req->handle, 0 )))
{
/* timeouts */
req->readinterval = serial->readinterval;
req->readconst = serial->readconst;
req->readmult = serial->readmult;
req->writeconst = serial->writeconst;
req->writemult = serial->writemult;
reply->readinterval = serial->readinterval;
reply->readconst = serial->readconst;
reply->readmult = serial->readmult;
reply->writeconst = serial->writeconst;
reply->writemult = serial->writemult;
/* event mask */
req->eventmask = serial->eventmask;
reply->eventmask = serial->eventmask;
/* comm port error status */
req->commerror = serial->commerror;
reply->commerror = serial->commerror;
release_object( serial );
}
......
......@@ -94,7 +94,7 @@ static struct snapshot *create_snapshot( void *pid, int flags )
}
/* 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;
......@@ -103,22 +103,21 @@ static int snapshot_next_process( struct snapshot *snapshot, struct next_process
set_error( STATUS_INVALID_PARAMETER ); /* FIXME */
return 0;
}
if (req->reset) snapshot->process_pos = 0;
else if (snapshot->process_pos >= snapshot->process_count)
if (snapshot->process_pos >= snapshot->process_count)
{
set_error( STATUS_NO_MORE_FILES );
return 0;
}
ptr = &snapshot->processes[snapshot->process_pos++];
req->count = ptr->count;
req->pid = get_process_id( ptr->process );
req->threads = ptr->threads;
req->priority = ptr->priority;
reply->count = ptr->count;
reply->pid = get_process_id( ptr->process );
reply->threads = ptr->threads;
reply->priority = ptr->priority;
return 1;
}
/* 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;
......@@ -127,23 +126,22 @@ static int snapshot_next_thread( struct snapshot *snapshot, struct next_thread_r
set_error( STATUS_INVALID_PARAMETER ); /* FIXME */
return 0;
}
if (req->reset) snapshot->thread_pos = 0;
else if (snapshot->thread_pos >= snapshot->thread_count)
if (snapshot->thread_pos >= snapshot->thread_count)
{
set_error( STATUS_NO_MORE_FILES );
return 0;
}
ptr = &snapshot->threads[snapshot->thread_pos++];
req->count = ptr->count;
req->pid = get_process_id( ptr->thread->process );
req->tid = get_thread_id( ptr->thread );
req->base_pri = ptr->priority;
req->delta_pri = 0; /* FIXME */
reply->count = ptr->count;
reply->pid = get_process_id( ptr->thread->process );
reply->tid = get_thread_id( ptr->thread );
reply->base_pri = ptr->priority;
reply->delta_pri = 0; /* FIXME */
return 1;
}
/* 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;
......@@ -152,15 +150,14 @@ static int snapshot_next_module( struct snapshot *snapshot, struct next_module_r
set_error( STATUS_INVALID_PARAMETER ); /* FIXME */
return 0;
}
if (req->reset) snapshot->module_pos = 0;
else if (snapshot->module_pos >= snapshot->module_count)
if (snapshot->module_pos >= snapshot->module_count)
{
set_error( STATUS_NO_MORE_FILES );
return 0;
}
ptr = &snapshot->modules[snapshot->module_pos++];
req->pid = get_process_id( snapshot->process );
req->base = ptr->base;
reply->pid = get_process_id( snapshot->process );
reply->base = ptr->base;
return 1;
}
......@@ -198,10 +195,10 @@ DECL_HANDLER(create_snapshot)
{
struct snapshot *snapshot;
req->handle = 0;
reply->handle = 0;
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 );
}
}
......@@ -214,7 +211,8 @@ DECL_HANDLER(next_process)
if ((snapshot = (struct snapshot *)get_handle_obj( current->process, req->handle,
0, &snapshot_ops )))
{
snapshot_next_process( snapshot, req );
if (req->reset) snapshot->process_pos = 0;
snapshot_next_process( snapshot, reply );
release_object( snapshot );
}
}
......@@ -227,7 +225,8 @@ DECL_HANDLER(next_thread)
if ((snapshot = (struct snapshot *)get_handle_obj( current->process, req->handle,
0, &snapshot_ops )))
{
snapshot_next_thread( snapshot, req );
if (req->reset) snapshot->thread_pos = 0;
snapshot_next_thread( snapshot, reply );
release_object( snapshot );
}
}
......@@ -240,7 +239,8 @@ DECL_HANDLER(next_module)
if ((snapshot = (struct snapshot *)get_handle_obj( current->process, req->handle,
0, &snapshot_ops )))
{
snapshot_next_module( snapshot, req );
if (req->reset) snapshot->module_pos = 0;
snapshot_next_module( snapshot, reply );
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