diff --git a/files/change.c b/files/change.c
index 5b99ca5eb8ef3ef8b7f5c437b6d37657d20884cf..331700c43fdc0581607b15e8db666fed5c754202 100644
--- a/files/change.c
+++ b/files/change.c
@@ -15,22 +15,13 @@
 #include "process.h"
 #include "thread.h"
 #include "heap.h"
+#include "server.h"
 #include "debug.h"
 
-static BOOL32 CHANGE_Signaled( K32OBJ *obj, DWORD thread_id );
-static BOOL32 CHANGE_Satisfied( K32OBJ *obj, DWORD thread_id );
-static void CHANGE_AddWait( K32OBJ *obj, DWORD thread_id );
-static void CHANGE_RemoveWait( K32OBJ *obj, DWORD thread_id );
 static void CHANGE_Destroy( K32OBJ *obj );
 
 const K32OBJ_OPS CHANGE_Ops =
 {
-    CHANGE_Signaled,    /* signaled */
-    CHANGE_Satisfied,   /* satisfied */
-    CHANGE_AddWait,     /* add_wait */
-    CHANGE_RemoveWait,  /* remove_wait */
-    NULL,               /* read */
-    NULL,               /* write */
     CHANGE_Destroy      /* destroy */
 };
 
@@ -48,51 +39,6 @@ typedef struct
 
 } CHANGE_OBJECT;
 
-/***********************************************************************
- *           CHANGE_Signaled
- */
-static BOOL32 CHANGE_Signaled( K32OBJ *obj, DWORD thread_id )
-{
-    CHANGE_OBJECT *change = (CHANGE_OBJECT *)obj;
-    assert( obj->type == K32OBJ_CHANGE );
-    return change->notify;
-}
-
-/***********************************************************************
- *           CHANGE_Satisfied
- *
- * Wait on this object has been satisfied.
- */
-static BOOL32 CHANGE_Satisfied( K32OBJ *obj, DWORD thread_id )
-{
-    assert( obj->type == K32OBJ_CHANGE );
-    return FALSE;  /* Not abandoned */
-}
-
-/***********************************************************************
- *           CHANGE_AddWait
- *
- * Add thread to object wait queue.
- */
-static void CHANGE_AddWait( K32OBJ *obj, DWORD thread_id )
-{
-    CHANGE_OBJECT *change = (CHANGE_OBJECT *)obj;
-    assert( obj->type == K32OBJ_CHANGE );
-    THREAD_AddQueue( &change->wait_queue, THREAD_ID_TO_THDB(thread_id) );
-}
-
-/***********************************************************************
- *           CHANGE_RemoveWait
- *
- * Remove thread from object wait queue.
- */
-static void CHANGE_RemoveWait( K32OBJ *obj, DWORD thread_id )
-{
-    CHANGE_OBJECT *change = (CHANGE_OBJECT *)obj;
-    assert( obj->type == K32OBJ_CHANGE );
-    THREAD_RemoveQueue( &change->wait_queue, THREAD_ID_TO_THDB(thread_id) );
-}
-
 /****************************************************************************
  *		CHANGE_Destroy
  */
@@ -118,11 +64,24 @@ HANDLE32 WINAPI FindFirstChangeNotification32A( LPCSTR lpPathName,
                                                 BOOL32 bWatchSubtree,
                                                 DWORD dwNotifyFilter ) 
 {
-    HANDLE32 handle;
     CHANGE_OBJECT *change;
+    struct create_change_notification_request req;
+    struct create_change_notification_reply reply;
+    int len;
+
+    req.subtree = bWatchSubtree;
+    req.filter  = dwNotifyFilter;
+    CLIENT_SendRequest( REQ_CREATE_CHANGE_NOTIFICATION, -1, 1, &req, sizeof(req) );
+    CLIENT_WaitReply( &len, NULL, 1, &reply, sizeof(reply) );
+    CHECK_LEN( len, sizeof(reply) );
+    if (reply.handle == -1) return INVALID_HANDLE_VALUE32;
 
     change = HeapAlloc( SystemHeap, 0, sizeof(CHANGE_OBJECT) );
-    if (!change) return INVALID_HANDLE_VALUE32;
+    if (!change)
+    {
+        CLIENT_CloseHandle( reply.handle );
+        return INVALID_HANDLE_VALUE32;
+    }
 
     change->header.type = K32OBJ_CHANGE;
     change->header.refcount = 1;
@@ -134,11 +93,9 @@ HANDLE32 WINAPI FindFirstChangeNotification32A( LPCSTR lpPathName,
     change->wait_queue = NULL;
     change->notify = FALSE;
 
-    handle = HANDLE_Alloc( PROCESS_Current(), &change->header, 
-                           FILE_ALL_ACCESS /*FIXME*/, TRUE, -1 );
-    /* If the allocation failed, the object is already destroyed */
-    if (handle == INVALID_HANDLE_VALUE32) change = NULL;
-    return handle;
+    return HANDLE_Alloc( PROCESS_Current(), &change->header, 
+                         STANDARD_RIGHTS_REQUIRED|SYNCHRONIZE /*FIXME*/,
+                         FALSE, reply.handle );
 }
 
 /****************************************************************************
diff --git a/files/file.c b/files/file.c
index 585b461b632daa545166492eacc5e354ac603a0a..5b000cf4274c6b0425b744f22e082c1f21f514a8 100644
--- a/files/file.c
+++ b/files/file.c
@@ -45,29 +45,10 @@
 #define MAP_ANON MAP_ANONYMOUS
 #endif
 
-#if 0
-static BOOL32 FILE_Signaled(K32OBJ *ptr, DWORD tid);
-static BOOL32 FILE_Satisfied(K32OBJ *ptr, DWORD thread_id);
-static void FILE_AddWait(K32OBJ *ptr, DWORD tid);
-static void FILE_RemoveWait(K32OBJ *ptr, DWORD thread_id);
-#endif
 static void FILE_Destroy( K32OBJ *obj );
 
 const K32OBJ_OPS FILE_Ops =
 {
-#if 0
-    FILE_Signaled,     /* signaled */
-    FILE_Satisfied,    /* satisfied */
-    FILE_AddWait,      /* add_wait */
-    FILE_RemoveWait,   /* remove_wait */
-#else
-    NULL,              /* signaled */
-    NULL,              /* satisfied */
-    NULL,              /* add_wait */
-    NULL,              /* remove_wait */
-#endif
-    NULL,              /* read */
-    NULL,              /* write */
     FILE_Destroy       /* destroy */
 };
 
@@ -126,58 +107,6 @@ HFILE32 FILE_Alloc( FILE_OBJECT **file, int unix_handle )
     return handle;
 }
 
-/***********************************************************************
- *		FILE_async_handler			[internal]
- */
-#if 0
-static void
-FILE_async_handler(int unixfd,void *private) {
-	FILE_OBJECT *file = (FILE_OBJECT*)private;
-
-	SYNC_WakeUp(&file->wait_queue,INFINITE32);
-}
-
-static BOOL32 FILE_Signaled(K32OBJ *ptr, DWORD thread_id)
-{
-	fd_set	fds,*readfds = NULL,*writefds = NULL;
-	struct timeval tv;
-	FILE_OBJECT *file = (FILE_OBJECT *)ptr;
-
-	FD_ZERO(&fds);
-	FD_SET(file->unix_handle,&fds);
-	if (file->mode == OF_READ) readfds = &fds;
-	if (file->mode == OF_WRITE) writefds = &fds;
-	if (file->mode == OF_READWRITE) {writefds = &fds; readfds = &fds;}
-	tv.tv_sec = 0;
-	tv.tv_usec = 0;
-	assert(readfds || writefds);
-	if (select(file->unix_handle+1,readfds,writefds,NULL,&tv)>0)
-		return TRUE; /* we triggered one fd. Whereever. */
-	return FALSE;
-}
-
-static void FILE_AddWait(K32OBJ *ptr, DWORD thread_id)
-{
-	FILE_OBJECT *file = (FILE_OBJECT*)ptr;
-	if (!file->wait_queue)
-		ASYNC_RegisterFD(file->unix_handle,FILE_async_handler,file);
-	THREAD_AddQueue(&file->wait_queue,thread_id);
-}
-
-static void FILE_RemoveWait(K32OBJ *ptr, DWORD thread_id)
-{
-	FILE_OBJECT *file = (FILE_OBJECT*)ptr;
-	THREAD_RemoveQueue(&file->wait_queue,thread_id);
-	if (!file->wait_queue)
-		ASYNC_UnregisterFD(file->unix_handle,FILE_async_handler);
-}
-
-static BOOL32 FILE_Satisfied(K32OBJ *ptr, DWORD thread_id)
-{
-	return FALSE; /* not abandoned. Hmm? */
-}
-#endif
-
 
 /***********************************************************************
  *           FILE_Destroy
@@ -1248,6 +1177,7 @@ BOOL32 WINAPI ReadFile( HANDLE32 hFile, LPVOID buffer, DWORD bytesToRead,
 {
     K32OBJ *ptr;
     struct get_read_fd_request req;
+    int unix_handle, result;
 
     TRACE(file, "%d %p %ld\n", hFile, buffer, bytesToRead );
 
@@ -1258,29 +1188,25 @@ BOOL32 WINAPI ReadFile( HANDLE32 hFile, LPVOID buffer, DWORD bytesToRead,
                                   K32OBJ_UNKNOWN, GENERIC_READ, &req.handle )))
         return FALSE;
 
-    if (req.handle != -1)  /* We have a server handle */
+    if (req.handle == -1)  /* We need a server handle */
     {
-        int unix_handle, result;
-
-        CLIENT_SendRequest( REQ_GET_READ_FD, -1, 1, &req, sizeof(req) );
-        CLIENT_WaitReply( NULL, &unix_handle, 0 );
-        if (unix_handle == -1) return FALSE;
-        if ((result = read( unix_handle, buffer, bytesToRead )) == -1)
-            FILE_SetDosError();
-        close( unix_handle );
         K32OBJ_DecCount( ptr );
-        if (result == -1) return FALSE;
-        if (bytesRead) *bytesRead = result;
-        return TRUE;
+        return FALSE;
     }
-    else
+    CLIENT_SendRequest( REQ_GET_READ_FD, -1, 1, &req, sizeof(req) );
+    CLIENT_WaitReply( NULL, &unix_handle, 0 );
+    K32OBJ_DecCount( ptr );
+    if (unix_handle == -1) return FALSE;
+    while ((result = read( unix_handle, buffer, bytesToRead )) == -1)
     {
-        BOOL32 status = FALSE;
-        if (K32OBJ_OPS(ptr)->read)
-            status = K32OBJ_OPS(ptr)->read(ptr, buffer, bytesToRead, bytesRead, overlapped );
-        K32OBJ_DecCount( ptr );
-        return status;
+        if ((errno == EAGAIN) || (errno == EINTR)) continue;
+        FILE_SetDosError();
+        break;
     }
+    close( unix_handle );
+    if (result == -1) return FALSE;
+    if (bytesRead) *bytesRead = result;
+    return TRUE;
 }
 
 
@@ -1292,6 +1218,7 @@ BOOL32 WINAPI WriteFile( HANDLE32 hFile, LPCVOID buffer, DWORD bytesToWrite,
 {
     K32OBJ *ptr;
     struct get_write_fd_request req;
+    int unix_handle, result;
 
     TRACE(file, "%d %p %ld\n", hFile, buffer, bytesToWrite );
 
@@ -1302,31 +1229,25 @@ BOOL32 WINAPI WriteFile( HANDLE32 hFile, LPCVOID buffer, DWORD bytesToWrite,
                                   K32OBJ_UNKNOWN, GENERIC_WRITE, &req.handle )))
         return FALSE;
 
-    if (req.handle != -1)  /* We have a server handle */
+    if (req.handle == -1)  /* We need a server handle */
     {
-        int unix_handle, result;
-
-        CLIENT_SendRequest( REQ_GET_WRITE_FD, -1, 1, &req, sizeof(req) );
-        CLIENT_WaitReply( NULL, &unix_handle, 0 );
-        if (unix_handle == -1) return FALSE;
-
-        if ((result = write( unix_handle, buffer, bytesToWrite )) == -1)
-            FILE_SetDosError();
-        close( unix_handle );
         K32OBJ_DecCount( ptr );
-        if (result == -1) return FALSE;
-        if (bytesWritten) *bytesWritten = result;
-        return TRUE;
+        return FALSE;
     }
-    else
+    CLIENT_SendRequest( REQ_GET_WRITE_FD, -1, 1, &req, sizeof(req) );
+    CLIENT_WaitReply( NULL, &unix_handle, 0 );
+    K32OBJ_DecCount( ptr );
+    if (unix_handle == -1) return FALSE;
+    while ((result = write( unix_handle, buffer, bytesToWrite )) == -1)
     {
-        BOOL32 status = FALSE;
-        if (K32OBJ_OPS(ptr)->write)
-            status = K32OBJ_OPS(ptr)->write( ptr, buffer, bytesToWrite,
-                                             bytesWritten, overlapped );
-        K32OBJ_DecCount( ptr );
-        return status;
+        if ((errno == EAGAIN) || (errno == EINTR)) continue;
+        FILE_SetDosError();
+        break;
     }
+    close( unix_handle );
+    if (result == -1) return FALSE;
+    if (bytesWritten) *bytesWritten = result;
+    return TRUE;
 }
 
 
diff --git a/include/k32obj.h b/include/k32obj.h
index b0e8633f4bb9101f8d164c9f897f0e29ba02d49f..281b3ed996e4a52289caad5ddf87f4f957c27b63 100644
--- a/include/k32obj.h
+++ b/include/k32obj.h
@@ -44,12 +44,6 @@ typedef struct
 /* Kernel object operations */
 typedef struct
 {
-    BOOL32 (*signaled)(K32OBJ*,DWORD);    /* Is object signaled? */
-    BOOL32 (*satisfied)(K32OBJ*,DWORD);   /* Wait on object is satisfied */
-    void   (*add_wait)(K32OBJ*,DWORD);    /* Add thread to wait queue */
-    void   (*remove_wait)(K32OBJ*,DWORD); /* Remove thread from wait queue */
-    BOOL32 (*read)(K32OBJ*,LPVOID,DWORD,LPDWORD,LPOVERLAPPED);
-    BOOL32 (*write)(K32OBJ*,LPCVOID,DWORD,LPDWORD,LPOVERLAPPED);
     void   (*destroy)(K32OBJ *);          /* Destroy object on refcount==0 */
 } K32OBJ_OPS;
 
diff --git a/include/process.h b/include/process.h
index 51e62073ed635475c8aa2a7c835c752cc0fff7ce..f562ac5adae4bf944b08b7ca8eee6707337a3310 100644
--- a/include/process.h
+++ b/include/process.h
@@ -63,7 +63,7 @@ typedef struct _PDB32
 {
     K32OBJ           header;           /* 00 Kernel object header */
     DWORD            unknown1;         /* 08 Unknown */
-    K32OBJ          *event;            /* 0c Pointer to an event object */
+    K32OBJ          *event;            /* 0c Pointer to an event object (unused) */
     DWORD            exit_code;        /* 10 Process exit code */
     DWORD            unknown2;         /* 14 Unknown */
     HANDLE32         heap;             /* 18 Default process heap */
@@ -102,7 +102,7 @@ typedef struct _PDB32
     K32OBJ          *console_provider; /* b0 Console provider (??) */
     WORD             env_selector;     /* b4 Selector to process environment */
     WORD             error_mode;       /* b6 Error mode */
-    K32OBJ          *load_done_evt;    /* b8 Event for process loading done */
+    HANDLE32         load_done_evt;    /* b8 Event for process loading done */
     DWORD            unknown7;         /* bc Unknown */
     DWORD            unknown8;         /* c0 Unknown (NT) */
     LCID             locale;           /* c4 Locale to be queried by GetThreadLocale (NT) */
@@ -136,6 +136,8 @@ extern HANDLE32 HANDLE_Alloc( PDB32 *pdb, K32OBJ *ptr, DWORD access,
 extern K32OBJ *HANDLE_GetObjPtr( PDB32 *pdb, HANDLE32 handle,
                                  K32OBJ_TYPE type, DWORD access,
                                  int *server_handle );
+extern int HANDLE_GetServerHandle( PDB32 *pdb, HANDLE32 handle,
+                                   K32OBJ_TYPE type, DWORD access );
 extern BOOL32 HANDLE_SetObjPtr( PDB32 *pdb, HANDLE32 handle,
                                 K32OBJ *ptr, DWORD access );
 extern void HANDLE_CloseAll( PDB32 *pdb, K32OBJ *ptr );
diff --git a/include/thread.h b/include/thread.h
index 4ce3e161f8b7158bd61912084abcec53526fdc99..3dac713d905849b4364a72f4558dc1084f8bf776 100644
--- a/include/thread.h
+++ b/include/thread.h
@@ -64,7 +64,6 @@ typedef struct
     DWORD         signaled;  /* Index of signaled object (or WAIT_FAILED)*/
     BOOL32        wait_all;  /* Wait for all objects flag */
     BOOL32        wait_msg;  /* Wait for message flag */
-    BOOL32        use_server; /* Use server call for waiting */
     K32OBJ       *objs[MAXIMUM_WAIT_OBJECTS];  /* Object pointers */
     int           server[MAXIMUM_WAIT_OBJECTS];  /* Server handles */
 } WAIT_STRUCT;
@@ -107,8 +106,7 @@ typedef struct _THDB
     void          *entry_point;    /* 1c0 Thread entry point (was: unknown) */
     void          *entry_arg;      /* 1c4 Entry point arg (was: unknown) */
     int            unix_pid;       /* 1c8 Unix thread pid (was: unknown) */
-    K32OBJ        *mutex_list;     /* 1cc List of owned mutex (was: unknown)*/
-    DWORD          unknown5[2];    /* 1d0 Unknown */
+    DWORD          unknown5[3];    /* 1cc Unknown */
     DWORD          sys_count[4];   /* 1d8 Syslevel mutex entry counters */
     CRITICAL_SECTION *sys_mutex[4];/* 1e8 Syslevel mutex pointers */
     DWORD          unknown6[2];    /* 1f8 Unknown */
@@ -162,18 +160,7 @@ extern void THREAD_AddQueue( THREAD_QUEUE *queue, THDB *thread );
 extern void THREAD_RemoveQueue( THREAD_QUEUE *queue, THDB *thread );
 extern DWORD THREAD_TlsAlloc( THDB *thread );
 
-/* scheduler/event.c */
-extern void EVENT_Set( K32OBJ *obj );
-extern K32OBJ *EVENT_Create( BOOL32 manual_reset, BOOL32 initial_state );
-
-/* scheduler/mutex.c */
-extern void MUTEX_Abandon( K32OBJ *obj );
-
 /* scheduler/synchro.c */
-extern void SYNC_WaitForCondition( WAIT_STRUCT *wait, DWORD timeout );
-extern void SYNC_WakeUp( THREAD_QUEUE *queue, DWORD max );
-extern void SYNC_MsgWakeUp( THDB *thdb );
-extern void SYNC_SetupSignals(void);
 extern DWORD SYNC_DoWait( DWORD count, const HANDLE32 *handles,
                           BOOL32 wait_all, DWORD timeout,
                           BOOL32 alertable, BOOL32 wait_msg );
diff --git a/loader/signal.c b/loader/signal.c
index ed18a3a48bcca833c55b32512f5de79f2fcaf61a..7e8c29f07c6c5376e27eba0e4aa53a561bedfebf 100644
--- a/loader/signal.c
+++ b/loader/signal.c
@@ -156,8 +156,6 @@ extern void ASYNC_sigio(int a);
  */
 BOOL32 SIGNAL_Init(void)
 {
-    extern void SYNC_SetupSignals(void);
-
 #ifdef HAVE_WORKING_SIGALTSTACK
     struct sigaltstack ss;
     ss.ss_sp    = SIGNAL_Stack;
@@ -187,8 +185,6 @@ BOOL32 SIGNAL_Init(void)
 
     /* ignore SIGPIPE so that WINSOCK can get a EPIPE error instead  */
     signal (SIGPIPE, SIG_IGN);
-
-    SYNC_SetupSignals();
     return TRUE;
 }
 
diff --git a/memory/virtual.c b/memory/virtual.c
index 7493022ba8b1a96d08fd00ec78f0041386e57365..70779c5fde8aace816bf34039f26cd225e54336b 100644
--- a/memory/virtual.c
+++ b/memory/virtual.c
@@ -110,13 +110,6 @@ static void VIRTUAL_DestroyMapping( K32OBJ *obj );
 
 const K32OBJ_OPS MEM_MAPPED_FILE_Ops =
 {
-    /* Object cannot be waited upon, so we don't need these (except destroy) */
-    NULL,                      /* signaled */
-    NULL,                      /* satisfied */
-    NULL,                      /* add_wait */
-    NULL,                      /* remove_wait */
-    NULL,                      /* read */
-    NULL,                      /* write */
     VIRTUAL_DestroyMapping     /* destroy */
 };
 
diff --git a/misc/toolhelp.c b/misc/toolhelp.c
index f69039c45a92fa33a67c72814999a9c59406cb38..751b620fd3e9f534a46904395a37875620beebcd 100644
--- a/misc/toolhelp.c
+++ b/misc/toolhelp.c
@@ -29,12 +29,6 @@ static void SNAPSHOT_Destroy( K32OBJ *obj );
 
 const K32OBJ_OPS SNAPSHOT_Ops =
 {
-  NULL,    		/* signaled */
-  NULL,   		/* satisfied */
-  NULL,     		/* add_wait */
-  NULL,  		/* remove_wait */
-  NULL,			/* read */
-  NULL,			/* write */
   SNAPSHOT_Destroy	/* destroy */
 };
 
diff --git a/scheduler/client.c b/scheduler/client.c
index 47670a4c42197e5fb2f1535cf8d93c8d61dc8778..4f01efd78564f073ae705340f2ff28cee9ab4a30 100644
--- a/scheduler/client.c
+++ b/scheduler/client.c
@@ -327,32 +327,6 @@ int CLIENT_SetDebug( int level )
     return CLIENT_WaitReply( NULL, NULL, 0 );
 }
 
-/***********************************************************************
- *           CLIENT_TerminateProcess
- *
- * Send a terminate process request. Return 0 if OK.
- */
-int CLIENT_TerminateProcess( int handle, int exit_code )
-{
-    CLIENT_SendRequest( REQ_TERMINATE_PROCESS, -1, 2,
-                        &handle, sizeof(handle),
-                        &exit_code, sizeof(exit_code) );
-    return CLIENT_WaitReply( NULL, NULL, 0 );
-}
-
-/***********************************************************************
- *           CLIENT_TerminateThread
- *
- * Send a terminate thread request. Return 0 if OK.
- */
-int CLIENT_TerminateThread( int handle, int exit_code )
-{
-    CLIENT_SendRequest( REQ_TERMINATE_THREAD, -1, 2,
-                        &handle, sizeof(handle),
-                        &exit_code, sizeof(exit_code) );
-    return CLIENT_WaitReply( NULL, NULL, 0 );
-}
-
 /***********************************************************************
  *           CLIENT_CloseHandle
  *
diff --git a/scheduler/event.c b/scheduler/event.c
index 552568d773bfa5dcf47b7fc6cb1195616c6ff6f2..30a1c76d48c9863219fa1609eab3c5262ddfb638 100644
--- a/scheduler/event.c
+++ b/scheduler/event.c
@@ -18,68 +18,16 @@
 typedef struct
 {
     K32OBJ        header;
-    THREAD_QUEUE  wait_queue;
-    BOOL32        manual_reset;
-    BOOL32        signaled;
 } EVENT;
 
-static BOOL32 EVENT_Signaled( K32OBJ *obj, DWORD thread_id );
-static BOOL32 EVENT_Satisfied( K32OBJ *obj, DWORD thread_id );
-static void EVENT_AddWait( K32OBJ *obj, DWORD thread_id );
-static void EVENT_RemoveWait( K32OBJ *obj, DWORD thread_id );
 static void EVENT_Destroy( K32OBJ *obj );
 
 const K32OBJ_OPS EVENT_Ops =
 {
-    EVENT_Signaled,     /* signaled */
-    EVENT_Satisfied,    /* satisfied */
-    EVENT_AddWait,      /* add_wait */
-    EVENT_RemoveWait,   /* remove_wait */
-    NULL,               /* read */
-    NULL,               /* write */
     EVENT_Destroy       /* destroy */
 };
 
 
-/***********************************************************************
- *           EVENT_Set
- *
- * Implementation of SetEvent. Used by ExitThread and ExitProcess.
- */
-void EVENT_Set( K32OBJ *obj )
-{
-    EVENT *event = (EVENT *)obj;
-    assert( obj->type == K32OBJ_EVENT );
-    SYSTEM_LOCK();
-    event->signaled = TRUE;
-    SYNC_WakeUp( &event->wait_queue, event->manual_reset ? INFINITE32 : 1 );
-    SYSTEM_UNLOCK();
-}
-
-/***********************************************************************
- *           EVENT_Create
- *
- * Partial implementation of CreateEvent.
- * Used internally by processes and threads.
- */
-K32OBJ *EVENT_Create( BOOL32 manual_reset, BOOL32 initial_state )
-{
-    EVENT *event;
-
-    SYSTEM_LOCK();
-    if ((event = HeapAlloc( SystemHeap, 0, sizeof(*event) )))
-    {
-        event->header.type     = K32OBJ_EVENT;
-        event->header.refcount = 1;
-        event->wait_queue      = NULL;
-        event->manual_reset    = manual_reset;
-        event->signaled        = initial_state;
-    }
-    SYSTEM_UNLOCK();
-    return event ? &event->header : NULL;
-}
-
-
 /***********************************************************************
  *           CreateEvent32A    (KERNEL32.156)
  */
@@ -99,20 +47,15 @@ HANDLE32 WINAPI CreateEvent32A( SECURITY_ATTRIBUTES *sa, BOOL32 manual_reset,
     CLIENT_SendRequest( REQ_CREATE_EVENT, -1, 2, &req, sizeof(req), name, len );
     CLIENT_WaitReply( &len, NULL, 1, &reply, sizeof(reply) );
     CHECK_LEN( len, sizeof(reply) );
-    if (reply.handle == -1) return NULL;
+    if (reply.handle == -1) return 0;
 
     SYSTEM_LOCK();
     event = (EVENT *)K32OBJ_Create( K32OBJ_EVENT, sizeof(*event), name,
                                     reply.handle, EVENT_ALL_ACCESS, sa, &handle );
     if (event)
-    {
-        /* Finish initializing it */
-        event->wait_queue   = NULL;
-        event->manual_reset = manual_reset;
-        event->signaled     = initial_state;
         K32OBJ_DecCount( &event->header );
-    }
     SYSTEM_UNLOCK();
+    if (handle == INVALID_HANDLE_VALUE32) handle = 0;
     return handle;
 }
 
@@ -145,13 +88,29 @@ HANDLE32 WINAPI OpenEvent32A( DWORD access, BOOL32 inherit, LPCSTR name )
 {
     HANDLE32 handle = 0;
     K32OBJ *obj;
-    SYSTEM_LOCK();
-    if ((obj = K32OBJ_FindNameType( name, K32OBJ_EVENT )) != NULL)
+    struct open_named_obj_request req;
+    struct open_named_obj_reply reply;
+    int len = name ? strlen(name) + 1 : 0;
+
+    req.type    = OPEN_EVENT;
+    req.access  = access;
+    req.inherit = inherit;
+    CLIENT_SendRequest( REQ_OPEN_NAMED_OBJ, -1, 2, &req, sizeof(req), name, len );
+    CLIENT_WaitReply( &len, NULL, 1, &reply, sizeof(reply) );
+    CHECK_LEN( len, sizeof(reply) );
+    if (reply.handle != -1)
     {
-        handle = HANDLE_Alloc( PROCESS_Current(), obj, access, inherit, -1 );
-        K32OBJ_DecCount( obj );
+        SYSTEM_LOCK();
+        if ((obj = K32OBJ_FindNameType( name, K32OBJ_EVENT )) != NULL)
+        {
+            handle = HANDLE_Alloc( PROCESS_Current(), obj, access, inherit, reply.handle );
+            K32OBJ_DecCount( obj );
+            if (handle == INVALID_HANDLE_VALUE32)
+                handle = 0; /* must return 0 on failure, not -1 */
+        }
+        else CLIENT_CloseHandle( reply.handle );
+        SYSTEM_UNLOCK();
     }
-    SYSTEM_UNLOCK();
     return handle;
 }
 
@@ -169,144 +128,47 @@ HANDLE32 WINAPI OpenEvent32W( DWORD access, BOOL32 inherit, LPCWSTR name )
 
 
 /***********************************************************************
- *           PulseEvent    (KERNEL32.557)
- */
-BOOL32 WINAPI PulseEvent( HANDLE32 handle )
-{
-    struct event_op_request req;
-    EVENT *event;
-    SYSTEM_LOCK();
-    if (!(event = (EVENT *)HANDLE_GetObjPtr(PROCESS_Current(), handle,
-                                            K32OBJ_EVENT, EVENT_MODIFY_STATE,
-                                            &req.handle )))
-    {
-        SYSTEM_UNLOCK();
-        return FALSE;
-    }
-    if (req.handle != -1)
-    {
-        SYSTEM_UNLOCK();
-        req.op = PULSE_EVENT;
-        CLIENT_SendRequest( REQ_EVENT_OP, -1, 1, &req, sizeof(req) );
-        return !CLIENT_WaitReply( NULL, NULL, 0 );
-    }
-    event->signaled = TRUE;
-    SYNC_WakeUp( &event->wait_queue, event->manual_reset ? INFINITE32 : 1 );
-    event->signaled = FALSE;
-    K32OBJ_DecCount( &event->header );
-    SYSTEM_UNLOCK();
-    return TRUE;
-}
-
-
-/***********************************************************************
- *           SetEvent    (KERNEL32.644)
- */
-BOOL32 WINAPI SetEvent( HANDLE32 handle )
-{
-    struct event_op_request req;
-    EVENT *event;
-    SYSTEM_LOCK();
-    if (!(event = (EVENT *)HANDLE_GetObjPtr(PROCESS_Current(), handle,
-                                            K32OBJ_EVENT, EVENT_MODIFY_STATE,
-                                            &req.handle )))
-    {
-        SYSTEM_UNLOCK();
-        return FALSE;
-    }
-    if (req.handle != -1)
-    {
-        SYSTEM_UNLOCK();
-        req.op = SET_EVENT;
-        CLIENT_SendRequest( REQ_EVENT_OP, -1, 1, &req, sizeof(req) );
-        return !CLIENT_WaitReply( NULL, NULL, 0 );
-    }
-    event->signaled = TRUE;
-    SYNC_WakeUp( &event->wait_queue, event->manual_reset ? INFINITE32 : 1 );
-    K32OBJ_DecCount( &event->header );
-    SYSTEM_UNLOCK();
-    return TRUE;
-}
-
-
-/***********************************************************************
- *           ResetEvent    (KERNEL32.586)
+ *           EVENT_Operation
+ *
+ * Execute an event operation (set,reset,pulse).
  */
-BOOL32 WINAPI ResetEvent( HANDLE32 handle )
+static BOOL32 EVENT_Operation( HANDLE32 handle, enum event_op op )
 {
     struct event_op_request req;
-    EVENT *event;
-    SYSTEM_LOCK();
-    if (!(event = (EVENT *)HANDLE_GetObjPtr(PROCESS_Current(), handle,
-                                            K32OBJ_EVENT, EVENT_MODIFY_STATE,
-                                            &req.handle )))
-    {
-        SYSTEM_UNLOCK();
-        return FALSE;
-    }
-    if (req.handle != -1)
-    {
-        SYSTEM_UNLOCK();
-        req.op = RESET_EVENT;
-        CLIENT_SendRequest( REQ_EVENT_OP, -1, 1, &req, sizeof(req) );
-        return !CLIENT_WaitReply( NULL, NULL, 0 );
-    }
-    event->signaled = FALSE;
-    K32OBJ_DecCount( &event->header );
-    SYSTEM_UNLOCK();
-    return TRUE;
-}
 
-
-/***********************************************************************
- *           EVENT_Signaled
- */
-static BOOL32 EVENT_Signaled( K32OBJ *obj, DWORD thread_id )
-{
-    EVENT *event = (EVENT *)obj;
-    assert( obj->type == K32OBJ_EVENT );
-    return event->signaled;
+    req.handle = HANDLE_GetServerHandle( PROCESS_Current(), handle,
+                                         K32OBJ_EVENT, EVENT_MODIFY_STATE );
+    if (req.handle == -1) return FALSE;
+    req.op = op;
+    CLIENT_SendRequest( REQ_EVENT_OP, -1, 1, &req, sizeof(req) );
+    return !CLIENT_WaitReply( NULL, NULL, 0 );
 }
 
 
 /***********************************************************************
- *           EVENT_Satisfied
- *
- * Wait on this object has been satisfied.
+ *           PulseEvent    (KERNEL32.557)
  */
-static BOOL32 EVENT_Satisfied( K32OBJ *obj, DWORD thread_id )
+BOOL32 WINAPI PulseEvent( HANDLE32 handle )
 {
-    EVENT *event = (EVENT *)obj;
-    assert( obj->type == K32OBJ_EVENT );
-    /* Reset if it's an auto-reset event */
-    if (!event->manual_reset) event->signaled = FALSE;
-    return FALSE;  /* Not abandoned */
+    return EVENT_Operation( handle, PULSE_EVENT );
 }
 
 
 /***********************************************************************
- *           EVENT_AddWait
- *
- * Add thread to object wait queue.
+ *           SetEvent    (KERNEL32.644)
  */
-static void EVENT_AddWait( K32OBJ *obj, DWORD thread_id )
+BOOL32 WINAPI SetEvent( HANDLE32 handle )
 {
-    EVENT *event = (EVENT *)obj;
-    assert( obj->type == K32OBJ_EVENT );
-    THREAD_AddQueue( &event->wait_queue, THREAD_ID_TO_THDB(thread_id) );
+    return EVENT_Operation( handle, SET_EVENT );
 }
 
 
 /***********************************************************************
- *           EVENT_RemoveWait
- *
- * Remove thread from object wait queue.
+ *           ResetEvent    (KERNEL32.586)
  */
-static void EVENT_RemoveWait( K32OBJ *obj, DWORD thread_id )
+BOOL32 WINAPI ResetEvent( HANDLE32 handle )
 {
-    EVENT *event = (EVENT *)obj;
-    assert( obj->type == K32OBJ_EVENT );
-    THREAD_RemoveQueue( &event->wait_queue, THREAD_ID_TO_THDB(thread_id) );
+    return EVENT_Operation( handle, RESET_EVENT );
 }
 
 
@@ -317,8 +179,6 @@ static void EVENT_Destroy( K32OBJ *obj )
 {
     EVENT *event = (EVENT *)obj;
     assert( obj->type == K32OBJ_EVENT );
-    /* There cannot be any thread on the list since the ref count is 0 */
-    assert( event->wait_queue == NULL );
     obj->type = K32OBJ_UNKNOWN;
     HeapFree( SystemHeap, 0, event );
 }
diff --git a/scheduler/handle.c b/scheduler/handle.c
index 5abf0a6502275c8e8fca9a470ed7f04cd9558a99..ec34184adf06f157a00196dd7eb1a857eac676f6 100644
--- a/scheduler/handle.c
+++ b/scheduler/handle.c
@@ -191,6 +191,27 @@ K32OBJ *HANDLE_GetObjPtr( PDB32 *pdb, HANDLE32 handle,
 }
 
 
+/***********************************************************************
+ *           HANDLE_GetServerHandle
+ *
+ * Retrieve the server handle associated to an object.
+ */
+int HANDLE_GetServerHandle( PDB32 *pdb, HANDLE32 handle,
+                            K32OBJ_TYPE type, DWORD access )
+{
+    int server_handle;
+    K32OBJ *obj;
+
+    SYSTEM_LOCK();
+    if ((obj = HANDLE_GetObjPtr( pdb, handle, type, access, &server_handle )))
+        K32OBJ_DecCount( obj );
+    else
+        server_handle = -1;
+    SYSTEM_UNLOCK();
+    return server_handle;
+}
+
+
 /***********************************************************************
  *           HANDLE_SetObjPtr
  *
@@ -413,3 +434,38 @@ done:
     SYSTEM_UNLOCK();
     return ret;
 }
+
+
+/***********************************************************************
+ *           ConvertToGlobalHandle    		(KERNEL32)
+ */
+HANDLE32 WINAPI ConvertToGlobalHandle(HANDLE32 hSrc)
+{
+    int src_handle, dst_handle;
+    HANDLE32 handle;
+    K32OBJ *obj = NULL;
+    DWORD access;
+
+    if (HANDLE_IS_GLOBAL(hSrc))
+        return hSrc;
+
+    if (!(obj = HANDLE_GetObjPtr( PROCESS_Current(), hSrc, K32OBJ_UNKNOWN, 0, &src_handle )))
+        return 0;
+
+    HANDLE_GetAccess( PROCESS_Current(), hSrc, &access );
+
+    if (src_handle != -1)
+        dst_handle = CLIENT_DuplicateHandle( GetCurrentProcess(), src_handle, -1, -1, 0, FALSE,
+                                             DUP_HANDLE_MAKE_GLOBAL | DUP_HANDLE_SAME_ACCESS );
+    else
+        dst_handle = -1;
+
+    if ((handle = HANDLE_Alloc( PROCESS_Initial(), obj, access, FALSE,
+                                dst_handle )) != INVALID_HANDLE_VALUE32)
+        handle = HANDLE_LOCAL_TO_GLOBAL(handle);
+    else
+        handle = 0;
+
+    CloseHandle( hSrc );
+    return handle;
+}
diff --git a/scheduler/k32obj.c b/scheduler/k32obj.c
index d8aca634eac7e316c6a152ad2fc92f1f8e1c8f68..a0b8e82f87630fa9b56254459bd364d19a3e4d46 100644
--- a/scheduler/k32obj.c
+++ b/scheduler/k32obj.c
@@ -12,7 +12,6 @@
 
 
 /* The declarations are here to avoid including a lot of unnecessary files */
-extern const K32OBJ_OPS CRITICAL_SECTION_Ops;
 extern const K32OBJ_OPS PROCESS_Ops;
 extern const K32OBJ_OPS THREAD_Ops;
 extern const K32OBJ_OPS FILE_Ops;
@@ -30,12 +29,6 @@ extern const K32OBJ_OPS PIPE_Ops;
 
 static const K32OBJ_OPS K32OBJ_NullOps =
 {
-    NULL,    /* signaled */
-    NULL,    /* satisfied */
-    NULL,    /* add_wait */
-    NULL,    /* remove_wait */
-    NULL,    /* read */
-    NULL,    /* write */
     NULL     /* destroy */
 };
 
@@ -45,7 +38,7 @@ const K32OBJ_OPS * const K32OBJ_Ops[K32OBJ_NBOBJECTS] =
     &SEMAPHORE_Ops,         /* K32OBJ_SEMAPHORE */
     &EVENT_Ops,             /* K32OBJ_EVENT */
     &MUTEX_Ops,             /* K32OBJ_MUTEX */
-    &CRITICAL_SECTION_Ops,  /* K32OBJ_CRITICAL_SECTION */
+    &K32OBJ_NullOps,        /* K32OBJ_CRITICAL_SECTION */
     &PROCESS_Ops,           /* K32OBJ_PROCESS */
     &THREAD_Ops,            /* K32OBJ_THREAD */
     &FILE_Ops,              /* K32OBJ_FILE */
diff --git a/scheduler/mutex.c b/scheduler/mutex.c
index 4a32e15065bcdf46075052e7f560cdc30655dcea..05c72ed0d6faac7b4b229f53d43547f6b00922c9 100644
--- a/scheduler/mutex.c
+++ b/scheduler/mutex.c
@@ -17,66 +17,16 @@
 typedef struct _MUTEX
 {
     K32OBJ         header;
-    THREAD_QUEUE   wait_queue;
-    DWORD          owner;
-    DWORD          count;
-    BOOL32         abandoned;
-    struct _MUTEX *next;
-    struct _MUTEX *prev;
 } MUTEX;
 
-static BOOL32 MUTEX_Signaled( K32OBJ *obj, DWORD thread_id );
-static BOOL32 MUTEX_Satisfied( K32OBJ *obj, DWORD thread_id );
-static void MUTEX_AddWait( K32OBJ *obj, DWORD thread_id );
-static void MUTEX_RemoveWait( K32OBJ *obj, DWORD thread_id );
 static void MUTEX_Destroy( K32OBJ *obj );
 
 const K32OBJ_OPS MUTEX_Ops =
 {
-    MUTEX_Signaled,    /* signaled */
-    MUTEX_Satisfied,   /* satisfied */
-    MUTEX_AddWait,     /* add_wait */
-    MUTEX_RemoveWait,  /* remove_wait */
-    NULL,              /* read */
-    NULL,              /* write */
     MUTEX_Destroy      /* destroy */
 };
 
 
-/***********************************************************************
- *           MUTEX_Release
- *
- * Release a mutex once the count is 0.
- * Helper function for MUTEX_Abandon and ReleaseMutex.
- */
-static void MUTEX_Release( MUTEX *mutex )
-{
-    /* Remove the mutex from the thread list of owned mutexes */
-    if (mutex->next) mutex->next->prev = mutex->prev;
-    if (mutex->prev) mutex->prev->next = mutex->next;
-    else THREAD_Current()->mutex_list = &mutex->next->header;
-    mutex->next = mutex->prev = NULL;
-    mutex->owner = 0;
-    SYNC_WakeUp( &mutex->wait_queue, INFINITE32 );
-}
-
-
-/***********************************************************************
- *           MUTEX_Abandon
- *
- * Abandon a mutex.
- */
-void MUTEX_Abandon( K32OBJ *obj )
-{
-    MUTEX *mutex = (MUTEX *)obj;
-    assert( obj->type == K32OBJ_MUTEX );
-    assert( mutex->count && (mutex->owner == GetCurrentThreadId()) );
-    mutex->count = 0;
-    mutex->abandoned = TRUE;
-    MUTEX_Release( mutex );
-}
-
-
 /***********************************************************************
  *           CreateMutex32A   (KERNEL32.166)
  */
@@ -95,37 +45,14 @@ HANDLE32 WINAPI CreateMutex32A( SECURITY_ATTRIBUTES *sa, BOOL32 owner,
     CLIENT_SendRequest( REQ_CREATE_MUTEX, -1, 2, &req, sizeof(req), name, len );
     CLIENT_WaitReply( &len, NULL, 1, &reply, sizeof(reply) );
     CHECK_LEN( len, sizeof(reply) );
-    if (reply.handle == -1) return NULL;
+    if (reply.handle == -1) return 0;
 
     SYSTEM_LOCK();
     mutex = (MUTEX *)K32OBJ_Create( K32OBJ_MUTEX, sizeof(*mutex),
                                     name, reply.handle, MUTEX_ALL_ACCESS,
                                     sa, &handle );
-    if (mutex)
-    {
-        /* Finish initializing it */
-        mutex->wait_queue = NULL;
-        mutex->abandoned  = FALSE;
-        mutex->prev       = NULL;
-        if (owner)
-        {
-            K32OBJ **list;
-            mutex->owner = GetCurrentThreadId();
-            mutex->count = 1;
-            /* Add the mutex in the thread list of owned mutexes */
-            list = &THREAD_Current()->mutex_list;
-            if ((mutex->next = (MUTEX *)*list)) mutex->next->prev = mutex;
-            *list = &mutex->header;
-        }
-        else
-        {
-            mutex->owner = 0;
-            mutex->count = 0;
-            mutex->next  = NULL;
-        }
-        K32OBJ_DecCount( &mutex->header );
-    }
-    SetLastError(0); /* FIXME */
+    if (mutex) K32OBJ_DecCount( &mutex->header );
+    if (handle == INVALID_HANDLE_VALUE32) handle = 0;
     SYSTEM_UNLOCK();
     return handle;
 }
@@ -151,13 +78,29 @@ HANDLE32 WINAPI OpenMutex32A( DWORD access, BOOL32 inherit, LPCSTR name )
 {
     HANDLE32 handle = 0;
     K32OBJ *obj;
-    SYSTEM_LOCK();
-    if ((obj = K32OBJ_FindNameType( name, K32OBJ_MUTEX )) != NULL)
+    struct open_named_obj_request req;
+    struct open_named_obj_reply reply;
+    int len = name ? strlen(name) + 1 : 0;
+
+    req.type    = OPEN_MUTEX;
+    req.access  = access;
+    req.inherit = inherit;
+    CLIENT_SendRequest( REQ_OPEN_NAMED_OBJ, -1, 2, &req, sizeof(req), name, len );
+    CLIENT_WaitReply( &len, NULL, 1, &reply, sizeof(reply) );
+    CHECK_LEN( len, sizeof(reply) );
+    if (reply.handle != -1)
     {
-        handle = HANDLE_Alloc( PROCESS_Current(), obj, access, inherit, -1 );
-        K32OBJ_DecCount( obj );
+        SYSTEM_LOCK();
+        if ((obj = K32OBJ_FindNameType( name, K32OBJ_MUTEX )) != NULL)
+        {
+            handle = HANDLE_Alloc( PROCESS_Current(), obj, access, inherit, reply.handle );
+            K32OBJ_DecCount( obj );
+            if (handle == INVALID_HANDLE_VALUE32)
+                handle = 0; /* must return 0 on failure, not -1 */
+        }
+        else CLIENT_CloseHandle( reply.handle );
+        SYSTEM_UNLOCK();
     }
-    SYSTEM_UNLOCK();
     return handle;
 }
 
@@ -180,95 +123,12 @@ HANDLE32 WINAPI OpenMutex32W( DWORD access, BOOL32 inherit, LPCWSTR name )
 BOOL32 WINAPI ReleaseMutex( HANDLE32 handle )
 {
     struct release_mutex_request req;
-    MUTEX *mutex;
-    SYSTEM_LOCK();
-    if (!(mutex = (MUTEX *)HANDLE_GetObjPtr(PROCESS_Current(), handle,
-                                            K32OBJ_MUTEX, MUTEX_MODIFY_STATE,
-                                            &req.handle )))
-    {
-        SYSTEM_UNLOCK();
-        return FALSE;
-    }
-    if (req.handle != -1)
-    {
-        SYSTEM_UNLOCK();
-        CLIENT_SendRequest( REQ_RELEASE_MUTEX, -1, 1, &req, sizeof(req) );
-        return !CLIENT_WaitReply( NULL, NULL, 0 );
-    }
-    if (!mutex->count || (mutex->owner != GetCurrentThreadId()))
-    {
-        SYSTEM_UNLOCK();
-        SetLastError( ERROR_NOT_OWNER );
-        return FALSE;
-    }
-    if (!--mutex->count) MUTEX_Release( mutex );
-    K32OBJ_DecCount( &mutex->header );
-    SYSTEM_UNLOCK();
-    return TRUE;
-}
-
-
-/***********************************************************************
- *           MUTEX_Signaled
- */
-static BOOL32 MUTEX_Signaled( K32OBJ *obj, DWORD thread_id )
-{
-    MUTEX *mutex = (MUTEX *)obj;
-    assert( obj->type == K32OBJ_MUTEX );
-    return (!mutex->count || (mutex->owner == thread_id));
-}
-
-
-/***********************************************************************
- *           MUTEX_Satisfied
- *
- * Wait on this object has been satisfied.
- */
-static BOOL32 MUTEX_Satisfied( K32OBJ *obj, DWORD thread_id )
-{
-    BOOL32 ret;
-    MUTEX *mutex = (MUTEX *)obj;
-    assert( obj->type == K32OBJ_MUTEX );
-    assert( !mutex->count || (mutex->owner == thread_id) );
-    mutex->owner = thread_id;
-    if (!mutex->count++)
-    {
-        /* Add the mutex in the thread list of owned mutexes */
-        K32OBJ **list = &THREAD_ID_TO_THDB( thread_id )->mutex_list;
-        assert( !mutex->next );
-        if ((mutex->next = (MUTEX *)*list)) mutex->next->prev = mutex;
-        *list = &mutex->header;
-        mutex->prev = NULL;
-    }
-    ret = mutex->abandoned;
-    mutex->abandoned = FALSE;
-    return ret;
-}
-
-
-/***********************************************************************
- *           MUTEX_AddWait
- *
- * Add a thread to the object wait queue.
- */
-static void MUTEX_AddWait( K32OBJ *obj, DWORD thread_id )
-{
-    MUTEX *mutex = (MUTEX *)obj;
-    assert( obj->type == K32OBJ_MUTEX );
-    THREAD_AddQueue( &mutex->wait_queue, THREAD_ID_TO_THDB(thread_id) );
-}
 
-
-/***********************************************************************
- *           MUTEX_RemoveWait
- *
- * Remove a thread from the object wait queue.
- */
-static void MUTEX_RemoveWait( K32OBJ *obj, DWORD thread_id )
-{
-    MUTEX *mutex = (MUTEX *)obj;
-    assert( obj->type == K32OBJ_MUTEX );
-    THREAD_RemoveQueue( &mutex->wait_queue, THREAD_ID_TO_THDB(thread_id) );
+    req.handle = HANDLE_GetServerHandle( PROCESS_Current(), handle,
+                                         K32OBJ_MUTEX, MUTEX_MODIFY_STATE );
+    if (req.handle == -1) return FALSE;
+    CLIENT_SendRequest( REQ_RELEASE_MUTEX, -1, 1, &req, sizeof(req) );
+    return !CLIENT_WaitReply( NULL, NULL, 0 );
 }
 
 
@@ -279,8 +139,6 @@ static void MUTEX_Destroy( K32OBJ *obj )
 {
     MUTEX *mutex = (MUTEX *)obj;
     assert( obj->type == K32OBJ_MUTEX );
-    /* There cannot be any thread on the list since the ref count is 0 */
-    assert( mutex->wait_queue == NULL );
     obj->type = K32OBJ_UNKNOWN;
     HeapFree( SystemHeap, 0, mutex );
 }
diff --git a/scheduler/pipe.c b/scheduler/pipe.c
index 854801304f45d7d365e24b8d33d95588ac97d4c4..94279fb3e3e53a9da9f724fa01848692daa0b21e 100644
--- a/scheduler/pipe.c
+++ b/scheduler/pipe.c
@@ -23,12 +23,6 @@ static void PIPE_Destroy( K32OBJ *obj );
 
 const K32OBJ_OPS PIPE_Ops =
 {
-    NULL,             /* signaled */
-    NULL,             /* satisfied */
-    NULL,             /* add_wait */
-    NULL,             /* remove_wait */
-    NULL,             /* read */
-    NULL,             /* write */
     PIPE_Destroy      /* destroy */
 };
 
diff --git a/scheduler/process.c b/scheduler/process.c
index 1432ea74d232776d2f7c22bee502a15d286096b5..6ddc950d54c3c6fa1a051a931ac826ac0db2cf3c 100644
--- a/scheduler/process.c
+++ b/scheduler/process.c
@@ -23,20 +23,10 @@
 #include "server.h"
 #include "debug.h"
 
-static BOOL32 PROCESS_Signaled( K32OBJ *obj, DWORD thread_id );
-static BOOL32 PROCESS_Satisfied( K32OBJ *obj, DWORD thread_id );
-static void PROCESS_AddWait( K32OBJ *obj, DWORD thread_id );
-static void PROCESS_RemoveWait( K32OBJ *obj, DWORD thread_id );
 static void PROCESS_Destroy( K32OBJ *obj );
 
 const K32OBJ_OPS PROCESS_Ops =
 {
-    PROCESS_Signaled,    /* signaled */
-    PROCESS_Satisfied,   /* satisfied */
-    PROCESS_AddWait,     /* add_wait */
-    PROCESS_RemoveWait,  /* remove_wait */
-    NULL,                /* read */
-    NULL,                /* write */
     PROCESS_Destroy      /* destroy */
 };
 
@@ -295,8 +285,6 @@ static void PROCESS_FreePDB( PDB32 *pdb )
     if (pdb->handle_table) HANDLE_CloseAll( pdb, NULL );
     ENV_FreeEnvironment( pdb );
     if (pdb->heap && (pdb->heap != pdb->system_heap)) HeapDestroy( pdb->heap );
-    if (pdb->load_done_evt) K32OBJ_DecCount( pdb->load_done_evt );
-    if (pdb->event) K32OBJ_DecCount( pdb->event );
     DeleteCriticalSection( &pdb->crit_section );
     HeapFree( SystemHeap, 0, pdb );
 }
@@ -325,19 +313,11 @@ static PDB32 *PROCESS_CreatePDB( PDB32 *parent )
     pdb->priority        = 8;  /* Normal */
     pdb->heap            = pdb->system_heap;  /* will be changed later on */
 
-    InitializeCriticalSection( &pdb->crit_section );
-
-    /* Allocate the events */
-
-    if (!(pdb->event = EVENT_Create( TRUE, FALSE ))) goto error;
-    if (!(pdb->load_done_evt = EVENT_Create( TRUE, FALSE ))) goto error;
-
     /* Create the handle table */
 
     if (!HANDLE_CreateTable( pdb, TRUE )) goto error;
 
     PROCESS_PDBList_Insert (pdb);
-
     return pdb;
 
 error:
@@ -346,6 +326,21 @@ error:
 }
 
 
+/***********************************************************************
+ *           PROCESS_FinishCreatePDB
+ *
+ * Second part of CreatePDB
+ */
+static BOOL32 PROCESS_FinishCreatePDB( PDB32 *pdb )
+{
+    InitializeCriticalSection( &pdb->crit_section );
+    /* Allocate the event */
+    if (!(pdb->load_done_evt = CreateEvent32A( NULL, TRUE, FALSE, NULL )))
+        return FALSE;
+    return TRUE;
+}
+
+
 /***********************************************************************
  *           PROCESS_Init
  */
@@ -357,9 +352,8 @@ BOOL32 PROCESS_Init(void)
     /* Initialize virtual memory management */
     if (!VIRTUAL_Init()) return FALSE;
 
-    /* Create the system and SEGPTR heaps */
+    /* Create the system heaps */
     if (!(SystemHeap = HeapCreate( HEAP_GROWABLE, 0x10000, 0 ))) return FALSE;
-    if (!(SegptrHeap = HeapCreate( HEAP_WINE_SEGPTR, 0, 0 ))) return FALSE;
 
     /* Create the initial process and thread structures */
     if (!(pdb = PROCESS_CreatePDB( NULL ))) return FALSE;
@@ -376,6 +370,10 @@ BOOL32 PROCESS_Init(void)
 
     /* Initialize the first thread */
     if (CLIENT_InitThread()) return FALSE;
+    if (!PROCESS_FinishCreatePDB( pdb )) return FALSE;
+
+    /* Create the SEGPTR heap */
+    if (!(SegptrHeap = HeapCreate( HEAP_WINE_SEGPTR, 0, 0 ))) return FALSE;
 
     return TRUE;
 }
@@ -400,6 +398,7 @@ PDB32 *PROCESS_Create( NE_MODULE *pModule, LPCSTR cmd_line, LPCSTR env,
 
     if (!pdb) return NULL;
     info->hThread = info->hProcess = INVALID_HANDLE_VALUE32;
+    if (!PROCESS_FinishCreatePDB( pdb )) goto error;
 
     /* Create the heap */
 
@@ -472,56 +471,6 @@ error:
 }
 
 
-/***********************************************************************
- *           PROCESS_Signaled
- */
-static BOOL32 PROCESS_Signaled( K32OBJ *obj, DWORD thread_id )
-{
-    PDB32 *pdb = (PDB32 *)obj;
-    assert( obj->type == K32OBJ_PROCESS );
-    return K32OBJ_OPS( pdb->event )->signaled( pdb->event, thread_id );
-}
-
-
-/***********************************************************************
- *           PROCESS_Satisfied
- *
- * Wait on this object has been satisfied.
- */
-static BOOL32 PROCESS_Satisfied( K32OBJ *obj, DWORD thread_id )
-{
-    PDB32 *pdb = (PDB32 *)obj;
-    assert( obj->type == K32OBJ_PROCESS );
-    return K32OBJ_OPS( pdb->event )->satisfied( pdb->event, thread_id );
-}
-
-
-/***********************************************************************
- *           PROCESS_AddWait
- *
- * Add thread to object wait queue.
- */
-static void PROCESS_AddWait( K32OBJ *obj, DWORD thread_id )
-{
-    PDB32 *pdb = (PDB32 *)obj;
-    assert( obj->type == K32OBJ_PROCESS );
-    return K32OBJ_OPS( pdb->event )->add_wait( pdb->event, thread_id );
-}
-
-
-/***********************************************************************
- *           PROCESS_RemoveWait
- *
- * Remove thread from object wait queue.
- */
-static void PROCESS_RemoveWait( K32OBJ *obj, DWORD thread_id )
-{
-    PDB32 *pdb = (PDB32 *)obj;
-    assert( obj->type == K32OBJ_PROCESS );
-    return K32OBJ_OPS( pdb->event )->remove_wait( pdb->event, thread_id );
-}
-
-
 /***********************************************************************
  *           PROCESS_Destroy
  */
@@ -552,7 +501,6 @@ void WINAPI ExitProcess( DWORD status )
     SYSTEM_LOCK();
     /* FIXME: should kill all running threads of this process */
     pdb->exit_code = status;
-    EVENT_Set( pdb->event );
     if (pdb->console) FreeConsole();
     SYSTEM_UNLOCK();
 
@@ -566,13 +514,13 @@ void WINAPI ExitProcess( DWORD status )
  */
 BOOL32 WINAPI TerminateProcess( HANDLE32 handle, DWORD exit_code )
 {
-    int server_handle;
-    BOOL32 ret;
-    PDB32 *pdb = PROCESS_GetPtr( handle, PROCESS_TERMINATE, &server_handle );
-    if (!pdb) return FALSE;
-    ret = !CLIENT_TerminateProcess( server_handle, exit_code );
-    K32OBJ_DecCount( &pdb->header );
-    return ret;
+    struct terminate_process_request req;
+
+    req.handle = HANDLE_GetServerHandle( PROCESS_Current(), handle,
+                                         K32OBJ_PROCESS, PROCESS_TERMINATE );
+    req.exit_code = exit_code;
+    CLIENT_SendRequest( REQ_TERMINATE_PROCESS, -1, 1, &req, sizeof(req) );
+    return !CLIENT_WaitReply( NULL, NULL, 0 );
 }
 
 /***********************************************************************
@@ -832,8 +780,8 @@ BOOL32 WINAPI GetProcessWorkingSetSize(HANDLE32 hProcess,LPDWORD minset,
  * It really shouldn't be here, but I'll move it when it's been checked!
  */
 #define SHUTDOWN_NORETRY 1
-extern unsigned int shutdown_noretry = 0;
-extern unsigned int shutdown_priority = 0x280L;
+static unsigned int shutdown_noretry = 0;
+static unsigned int shutdown_priority = 0x280L;
 BOOL32 WINAPI SetProcessShutdownParameters(DWORD level,DWORD flags)
 {
     if (flags & SHUTDOWN_NORETRY)
@@ -900,28 +848,6 @@ BOOL32 WINAPI WriteProcessMemory(HANDLE32 hProcess, LPVOID lpBaseAddress,
 	return TRUE;
 }
 
-/***********************************************************************
- *           ConvertToGlobalHandle    		(KERNEL32)
- */
-HANDLE32 WINAPI ConvertToGlobalHandle(HANDLE32 hSrc)
-{
-    HANDLE32 hProcessInit, hDest;
-
-    /* Get a handle to the initial process */
-    hProcessInit = OpenProcess( PROCESS_ALL_ACCESS, FALSE, PROCESS_InitialProcessID );
-
-    /* Duplicate the handle into the initial process */
-    if ( !DuplicateHandle( GetCurrentProcess(), hSrc, hProcessInit, &hDest,
-                           0, FALSE, DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE ) )
-        hDest = 0;
-
-    /* Close initial process handle */
-    CloseHandle( hProcessInit );
-
-    /* Return obfuscated global handle */
-    return hDest? HANDLE_LOCAL_TO_GLOBAL( hDest ) : 0;
-}
-
 /***********************************************************************
  *           RegisterServiceProcess             (KERNEL, KERNEL32)
  *
@@ -942,28 +868,17 @@ DWORD WINAPI RegisterServiceProcess(DWORD dwProcessId, DWORD dwType)
  * RETURNS
  *   Success: TRUE
  *   Failure: FALSE
- * 
- * FIXME
- *   Should call SetLastError (but doesn't).
  */
 BOOL32 WINAPI GetExitCodeProcess(
     HANDLE32 hProcess,  /* [I] handle to the process */
     LPDWORD lpExitCode) /* [O] address to receive termination status */
 {
-    PDB32 *process;
-    int server_handle;
     struct get_process_info_reply info;
+    int handle = HANDLE_GetServerHandle( PROCESS_Current(), hProcess,
+                                         K32OBJ_PROCESS, PROCESS_QUERY_INFORMATION );
 
-    if (!(process = PROCESS_GetPtr( hProcess, PROCESS_QUERY_INFORMATION,
-                                    &server_handle )))
-        return FALSE;
-    if (server_handle != -1)
-    {
-        CLIENT_GetProcessInfo( server_handle, &info );
-        if (lpExitCode) *lpExitCode = info.exit_code;
-    }
-    else if (lpExitCode) *lpExitCode = process->exit_code;
-    K32OBJ_DecCount( &process->header );
+    if (CLIENT_GetProcessInfo( handle, &info )) return FALSE;
+    if (lpExitCode) *lpExitCode = info.exit_code;
     return TRUE;
 }
 
diff --git a/scheduler/semaphore.c b/scheduler/semaphore.c
index 7c71a100624baa81ba9a6732042f9e1d3b1777d8..561d536d69c93909062631b4b86345a305b78573 100644
--- a/scheduler/semaphore.c
+++ b/scheduler/semaphore.c
@@ -17,25 +17,12 @@
 typedef struct
 {
     K32OBJ        header;
-    THREAD_QUEUE  wait_queue;
-    LONG          count;
-    LONG          max;
 } SEMAPHORE;
 
-static BOOL32 SEMAPHORE_Signaled( K32OBJ *obj, DWORD thread_id );
-static BOOL32 SEMAPHORE_Satisfied( K32OBJ *obj, DWORD thread_id );
-static void SEMAPHORE_AddWait( K32OBJ *obj, DWORD thread_id );
-static void SEMAPHORE_RemoveWait( K32OBJ *obj, DWORD thread_id );
 static void SEMAPHORE_Destroy( K32OBJ *obj );
 
 const K32OBJ_OPS SEMAPHORE_Ops =
 {
-    SEMAPHORE_Signaled,    /* signaled */
-    SEMAPHORE_Satisfied,   /* satisfied */
-    SEMAPHORE_AddWait,     /* add_wait */
-    SEMAPHORE_RemoveWait,  /* remove_wait */
-    NULL,                  /* read */
-    NULL,                  /* write */
     SEMAPHORE_Destroy      /* destroy */
 };
 
@@ -57,7 +44,7 @@ HANDLE32 WINAPI CreateSemaphore32A( SECURITY_ATTRIBUTES *sa, LONG initial,
     if ((max <= 0) || (initial < 0) || (initial > max))
     {
         SetLastError( ERROR_INVALID_PARAMETER );
-        return INVALID_HANDLE_VALUE32;
+        return 0;
     }
 
     req.initial = (unsigned int)initial;
@@ -67,21 +54,15 @@ HANDLE32 WINAPI CreateSemaphore32A( SECURITY_ATTRIBUTES *sa, LONG initial,
     CLIENT_SendRequest( REQ_CREATE_SEMAPHORE, -1, 2, &req, sizeof(req), name, len );
     CLIENT_WaitReply( &len, NULL, 1, &reply, sizeof(reply) );
     CHECK_LEN( len, sizeof(reply) );
-    if (reply.handle == -1) return NULL;
+    if (reply.handle == -1) return 0;
 
     SYSTEM_LOCK();
     sem = (SEMAPHORE *)K32OBJ_Create( K32OBJ_SEMAPHORE, sizeof(*sem),
                                       name, reply.handle, SEMAPHORE_ALL_ACCESS,
                                       sa, &handle);
-    if (sem)
-    {
-        /* Finish initializing it */
-        sem->wait_queue = NULL;
-        sem->count      = initial;
-        sem->max        = max;
-        K32OBJ_DecCount( &sem->header );
-    }
+    if (sem) K32OBJ_DecCount( &sem->header );
     SYSTEM_UNLOCK();
+    if (handle == INVALID_HANDLE_VALUE32) handle = 0;
     return handle;
 }
 
@@ -106,13 +87,29 @@ HANDLE32 WINAPI OpenSemaphore32A( DWORD access, BOOL32 inherit, LPCSTR name )
 {
     HANDLE32 handle = 0;
     K32OBJ *obj;
-    SYSTEM_LOCK();
-    if ((obj = K32OBJ_FindNameType( name, K32OBJ_SEMAPHORE )) != NULL)
+    struct open_named_obj_request req;
+    struct open_named_obj_reply reply;
+    int len = name ? strlen(name) + 1 : 0;
+
+    req.type    = OPEN_SEMAPHORE;
+    req.access  = access;
+    req.inherit = inherit;
+    CLIENT_SendRequest( REQ_OPEN_NAMED_OBJ, -1, 2, &req, sizeof(req), name, len );
+    CLIENT_WaitReply( &len, NULL, 1, &reply, sizeof(reply) );
+    CHECK_LEN( len, sizeof(reply) );
+    if (reply.handle != -1)
     {
-        handle = HANDLE_Alloc( PROCESS_Current(), obj, access, inherit, -1 );
-        K32OBJ_DecCount( obj );
+        SYSTEM_LOCK();
+        if ((obj = K32OBJ_FindNameType( name, K32OBJ_SEMAPHORE )) != NULL)
+        {
+            handle = HANDLE_Alloc( PROCESS_Current(), obj, access, inherit, reply.handle );
+            K32OBJ_DecCount( obj );
+            if (handle == INVALID_HANDLE_VALUE32)
+                handle = 0; /* must return 0 on failure, not -1 */
+        }
+        else CLIENT_CloseHandle( reply.handle );
+        SYSTEM_UNLOCK();
     }
-    SYSTEM_UNLOCK();
     return handle;
 }
 
@@ -135,110 +132,26 @@ HANDLE32 WINAPI OpenSemaphore32W( DWORD access, BOOL32 inherit, LPCWSTR name )
 BOOL32 WINAPI ReleaseSemaphore( HANDLE32 handle, LONG count, LONG *previous )
 {
     struct release_semaphore_request req;
-    SEMAPHORE *sem;
+    struct release_semaphore_reply reply;
+    int len;
 
     if (count < 0)
     {
         SetLastError( ERROR_INVALID_PARAMETER );
         return FALSE;
     }
-    SYSTEM_LOCK();
-    if (!(sem = (SEMAPHORE *)HANDLE_GetObjPtr( PROCESS_Current(), handle,
-                                               K32OBJ_SEMAPHORE,
-                                               SEMAPHORE_MODIFY_STATE, &req.handle )))
-    {
-        SYSTEM_UNLOCK();
-        return FALSE;
-    }
-    if (req.handle != -1)
-    {
-        struct release_semaphore_reply reply;
-        int len;
-
-        SYSTEM_UNLOCK();
-        req.count = (unsigned int)count;
-        CLIENT_SendRequest( REQ_RELEASE_SEMAPHORE, -1, 1, &req, sizeof(req) );
-        if (CLIENT_WaitReply( &len, NULL, 1, &reply, sizeof(reply) )) return FALSE;
-        CHECK_LEN( len, sizeof(reply) );
-        if (previous) *previous = reply.prev_count;
-        return TRUE;
-    }
-    if (previous) *previous = sem->count;
-    if (sem->count + count > sem->max)
-    {
-        SYSTEM_UNLOCK();
-        SetLastError( ERROR_TOO_MANY_POSTS );
-        return FALSE;
-    }
-    if (sem->count > 0)
-    {
-        /* There cannot be any thread waiting if the count is > 0 */
-        assert( sem->wait_queue == NULL );
-        sem->count += count;
-    }
-    else
-    {
-        sem->count = count;
-        SYNC_WakeUp( &sem->wait_queue, count );
-    }
-    K32OBJ_DecCount( &sem->header );
-    SYSTEM_UNLOCK();
+    req.handle = HANDLE_GetServerHandle( PROCESS_Current(), handle,
+                                         K32OBJ_SEMAPHORE, SEMAPHORE_MODIFY_STATE );
+    if (req.handle == -1) return FALSE;
+    req.count = (unsigned int)count;
+    CLIENT_SendRequest( REQ_RELEASE_SEMAPHORE, -1, 1, &req, sizeof(req) );
+    if (CLIENT_WaitReply( &len, NULL, 1, &reply, sizeof(reply) )) return FALSE;
+    CHECK_LEN( len, sizeof(reply) );
+    if (previous) *previous = reply.prev_count;
     return TRUE;
 }
 
 
-/***********************************************************************
- *           SEMAPHORE_Signaled
- */
-static BOOL32 SEMAPHORE_Signaled( K32OBJ *obj, DWORD thread_id )
-{
-    SEMAPHORE *sem = (SEMAPHORE *)obj;
-    assert( obj->type == K32OBJ_SEMAPHORE );
-    return (sem->count > 0);
-}
-
-
-/***********************************************************************
- *           SEMAPHORE_Satisfied
- *
- * Wait on this object has been satisfied.
- */
-static BOOL32 SEMAPHORE_Satisfied( K32OBJ *obj, DWORD thread_id )
-{
-    SEMAPHORE *sem = (SEMAPHORE *)obj;
-    assert( obj->type == K32OBJ_SEMAPHORE );
-    assert( sem->count > 0 );
-    sem->count--;
-    return FALSE;  /* Not abandoned */
-}
-
-
-/***********************************************************************
- *           SEMAPHORE_AddWait
- *
- * Add current thread to object wait queue.
- */
-static void SEMAPHORE_AddWait( K32OBJ *obj, DWORD thread_id )
-{
-    SEMAPHORE *sem = (SEMAPHORE *)obj;
-    assert( obj->type == K32OBJ_SEMAPHORE );
-    THREAD_AddQueue( &sem->wait_queue, THREAD_ID_TO_THDB(thread_id) );
-}
-
-
-/***********************************************************************
- *           SEMAPHORE_RemoveWait
- *
- * Remove thread from object wait queue.
- */
-static void SEMAPHORE_RemoveWait( K32OBJ *obj, DWORD thread_id )
-{
-    SEMAPHORE *sem = (SEMAPHORE *)obj;
-    assert( obj->type == K32OBJ_SEMAPHORE );
-    THREAD_RemoveQueue( &sem->wait_queue, THREAD_ID_TO_THDB(thread_id) );
-}
-
-
 /***********************************************************************
  *           SEMAPHORE_Destroy
  */
@@ -247,7 +160,6 @@ static void SEMAPHORE_Destroy( K32OBJ *obj )
     SEMAPHORE *sem = (SEMAPHORE *)obj;
     assert( obj->type == K32OBJ_SEMAPHORE );
     /* There cannot be any thread on the list since the ref count is 0 */
-    assert( sem->wait_queue == NULL );
     obj->type = K32OBJ_UNKNOWN;
     HeapFree( SystemHeap, 0, sem );
 }
diff --git a/scheduler/synchro.c b/scheduler/synchro.c
index 9fdea037119648e4f152bea88c5ac01d228cddba..f2f4560085142ebb46446ea9522a8ccc027b1935 100644
--- a/scheduler/synchro.c
+++ b/scheduler/synchro.c
@@ -24,7 +24,7 @@ static BOOL32 SYNC_BuildWaitStruct( DWORD count, const HANDLE32 *handles,
                                     BOOL32 wait_all, BOOL32 wait_msg, 
                                     WAIT_STRUCT *wait )
 {
-    DWORD i, j;
+    DWORD i;
     K32OBJ **ptr;
 
     SYSTEM_LOCK();
@@ -32,7 +32,6 @@ static BOOL32 SYNC_BuildWaitStruct( DWORD count, const HANDLE32 *handles,
     wait->signaled = WAIT_FAILED;
     wait->wait_all = wait_all;
     wait->wait_msg = wait_msg;
-    wait->use_server = TRUE;
     for (i = 0, ptr = wait->objs; i < count; i++, ptr++)
     {
         if (!(*ptr = HANDLE_GetObjPtr( PROCESS_Current(), handles[i],
@@ -43,28 +42,11 @@ static BOOL32 SYNC_BuildWaitStruct( DWORD count, const HANDLE32 *handles,
             break; 
         }
         if (wait->server[i] == -1)
-        {
             WARN(win32,"No server handle for %08x (type %d)\n",
                  handles[i], (*ptr)->type );
-            wait->use_server = FALSE;
-        }
     }
 
-    if (!wait->use_server)
-    {
-        for (j = 0, ptr = wait->objs; j < i; j++, ptr++)
-        {
-            if (!K32OBJ_OPS( *ptr )->signaled)
-            {
-                /* This object type cannot be waited upon */
-                ERR(win32, "Cannot wait on handle %08x\n", handles[j]); 
-                break;
-            }
-        }
-    }
-    else j = count;
-
-    if ((i != count) || (j != count))
+    if (i != count)
     {
         /* There was an error */
         wait->wait_msg = FALSE;
@@ -90,224 +72,6 @@ static void SYNC_FreeWaitStruct( WAIT_STRUCT *wait )
 }
 
 
-/***********************************************************************
- *           SYNC_CheckCondition
- */
-static BOOL32 SYNC_CheckCondition( WAIT_STRUCT *wait, DWORD thread_id )
-{
-    DWORD i;
-    K32OBJ **ptr;
-
-    SYSTEM_LOCK();
-    if (wait->wait_all)
-    {
-        for (i = 0, ptr = wait->objs; i < wait->count; i++, ptr++)
-        {
-            if (!K32OBJ_OPS( *ptr )->signaled( *ptr, thread_id ))
-            {
-                SYSTEM_UNLOCK();
-                return FALSE;
-            }
-        }
-        /* Wait satisfied: tell it to all objects */
-        wait->signaled = WAIT_OBJECT_0;
-        for (i = 0, ptr = wait->objs; i < wait->count; i++, ptr++)
-            if (K32OBJ_OPS( *ptr )->satisfied( *ptr, thread_id ))
-                wait->signaled = WAIT_ABANDONED_0;
-        SYSTEM_UNLOCK();
-        return TRUE;
-    }
-    else
-    {
-        for (i = 0, ptr = wait->objs; i < wait->count; i++, ptr++)
-        {
-            if (K32OBJ_OPS( *ptr )->signaled( *ptr, thread_id ))
-            {
-                /* Wait satisfied: tell it to the object */
-                wait->signaled = WAIT_OBJECT_0 + i;
-                if (K32OBJ_OPS( *ptr )->satisfied( *ptr, thread_id ))
-                    wait->signaled = WAIT_ABANDONED_0 + i;
-                SYSTEM_UNLOCK();
-                return TRUE;
-            }
-        }
-        SYSTEM_UNLOCK();
-        return FALSE;
-    }
-}
-
-
-/***********************************************************************
- *           SYNC_WaitForCondition
- */
-void SYNC_WaitForCondition( WAIT_STRUCT *wait, DWORD timeout )
-{
-    DWORD i, thread_id = GetCurrentThreadId();
-    LONG count;
-    K32OBJ **ptr;
-    sigset_t set;
-
-    SYSTEM_LOCK();
-    if (SYNC_CheckCondition( wait, thread_id ))
-        goto done;  /* Condition already satisfied */
-    if (!timeout)
-    {
-        /* No need to wait */
-        wait->signaled = WAIT_TIMEOUT;
-        goto done;
-    }
-
-    /* Add ourselves to the waiting list of all objects */
-
-    for (i = 0, ptr = wait->objs; i < wait->count; i++, ptr++)
-        K32OBJ_OPS( *ptr )->add_wait( *ptr, thread_id );
-
-    /* Release the system lock completely */
-
-    count = SYSTEM_LOCK_COUNT();
-    for (i = count; i > 0; i--) SYSTEM_UNLOCK();
-
-    /* Now wait for it */
-
-    TRACE(win32, "starting wait (%p %04x)\n",
-		 THREAD_Current(), THREAD_Current()->teb_sel );
-
-    sigprocmask( SIG_SETMASK, NULL, &set );
-    sigdelset( &set, SIGUSR1 );
-    sigdelset( &set, SIGALRM );
-    if (timeout != INFINITE32)
-    {
-        while (wait->signaled == WAIT_FAILED)
-        {
-            struct itimerval timer;
-            DWORD start_ticks, elapsed;
-            timer.it_interval.tv_sec = timer.it_interval.tv_usec = 0;
-            timer.it_value.tv_sec = timeout / 1000;
-            timer.it_value.tv_usec = (timeout % 1000) * 1000;
-            start_ticks = GetTickCount();
-            setitimer( ITIMER_REAL, &timer, NULL );
-            sigsuspend( &set );
-            if (wait->signaled != WAIT_FAILED) break;
-            /* Recompute the timer value */
-            elapsed = GetTickCount() - start_ticks;
-            if (elapsed >= timeout) wait->signaled = WAIT_TIMEOUT;
-            else timeout -= elapsed;
-        }
-    }
-    else
-    {
-        while (wait->signaled == WAIT_FAILED)
-        {
-            sigsuspend( &set );
-        }
-    }
-
-    /* Grab the system lock again */
-
-    while (count--) SYSTEM_LOCK();
-    TRACE(win32, "wait finished (%p %04x)\n",
-		 THREAD_Current(), THREAD_Current()->teb_sel );
-
-    /* Remove ourselves from the lists */
-
-    for (i = 0, ptr = wait->objs; i < wait->count; i++, ptr++)
-        K32OBJ_OPS( *ptr )->remove_wait( *ptr, thread_id );
-
-done:
-    SYSTEM_UNLOCK();
-}
-
-
-/***********************************************************************
- *           SYNC_DummySigHandler
- *
- * Dummy signal handler
- */
-static void SYNC_DummySigHandler(void)
-{
-}
-
-
-/***********************************************************************
- *           SYNC_SetupSignals
- *
- * Setup signal handlers for a new thread.
- * FIXME: should merge with SIGNAL_Init.
- */
-void SYNC_SetupSignals(void)
-{
-    sigset_t set;
-    SIGNAL_SetHandler( SIGUSR1, SYNC_DummySigHandler, 0 );
-    /* FIXME: conflicts with system timers */
-    SIGNAL_SetHandler( SIGALRM, SYNC_DummySigHandler, 0 );
-    sigemptyset( &set );
-    /* Make sure these are blocked by default */
-    sigaddset( &set, SIGUSR1 );
-    sigaddset( &set, SIGALRM );
-    sigprocmask( SIG_BLOCK , &set, NULL);
-}
-
-
-/***********************************************************************
- *           SYNC_WakeUp
- */
-void SYNC_WakeUp( THREAD_QUEUE *wait_queue, DWORD max )
-{
-    THREAD_ENTRY *entry;
-
-    if (!max) max = INFINITE32;
-    SYSTEM_LOCK();
-    if (!*wait_queue)
-    {
-        SYSTEM_UNLOCK();
-        return;
-    }
-    entry = (*wait_queue)->next;
-    for (;;)
-    {
-        THDB *thdb = entry->thread;
-        if (SYNC_CheckCondition( &thdb->wait_struct, THDB_TO_THREAD_ID(thdb) ))
-        {
-            TRACE(win32, "waking up %04x (pid %d)\n", thdb->teb_sel, thdb->unix_pid );
-            if (thdb->unix_pid)
-	    	kill( thdb->unix_pid, SIGUSR1 );
-	    else
-	    	FIXME(win32,"have got unix_pid 0\n");
-            if (!--max) break;
-        }
-        if (entry == *wait_queue) break;
-        entry = entry->next;
-    }
-    SYSTEM_UNLOCK();
-}
-
-/***********************************************************************
- *           SYNC_MsgWakeUp
- */
-void SYNC_MsgWakeUp( THDB *thdb )
-{
-    SYSTEM_LOCK();
-
-    if (!thdb) 
-    {
-        SYSTEM_UNLOCK();
-        return;
-    }
-
-    if (thdb->wait_struct.wait_msg)
-    {
-        thdb->wait_struct.signaled = thdb->wait_struct.count;
-
-        TRACE(win32, "waking up %04x for message\n", thdb->teb_sel );
-        if (thdb->unix_pid)
-            kill( thdb->unix_pid, SIGUSR1 );
-        else
-            FIXME(win32,"have got unix_pid 0\n");
-    }
-
-    SYSTEM_UNLOCK();
-}
-
 /***********************************************************************
  *           SYNC_DoWait
  */
@@ -326,30 +90,18 @@ DWORD SYNC_DoWait( DWORD count, const HANDLE32 *handles,
     if (alertable)
         FIXME(win32, "alertable not implemented\n" );
 
-    SYSTEM_LOCK();
     if (!SYNC_BuildWaitStruct( count, handles, wait_all, wait_msg, wait ))
         wait->signaled = WAIT_FAILED;
     else
     {
-        /* Check if we can use a server wait */
-        if (wait->use_server)
-        {
-            int flags = 0;
-            SYSTEM_UNLOCK();
-            if (wait_all) flags |= SELECT_ALL;
-            if (alertable) flags |= SELECT_ALERTABLE;
-            if (wait_msg) flags |= SELECT_MSG;
-            if (timeout != INFINITE32) flags |= SELECT_TIMEOUT;
-            return CLIENT_Select( count, wait->server, flags, timeout );
-        }
-        else
-        {
-            /* Now wait for it */
-            SYNC_WaitForCondition( wait, timeout );
-            SYNC_FreeWaitStruct( wait );
-        }
+        int flags = 0;
+        if (wait_all) flags |= SELECT_ALL;
+        if (alertable) flags |= SELECT_ALERTABLE;
+        if (wait_msg) flags |= SELECT_MSG;
+        if (timeout != INFINITE32) flags |= SELECT_TIMEOUT;
+        wait->signaled = CLIENT_Select( count, wait->server, flags, timeout );
+        SYNC_FreeWaitStruct( wait );
     }
-    SYSTEM_UNLOCK();
     return wait->signaled;
 }
 
diff --git a/scheduler/thread.c b/scheduler/thread.c
index 91eb1837eee1da60af7e12de747e059965acadbf..4888ae7f837b6d684bcc6668d25a6b531c321070 100644
--- a/scheduler/thread.c
+++ b/scheduler/thread.c
@@ -25,20 +25,10 @@
 THDB *pCurrentThread;
 #endif
 
-static BOOL32 THREAD_Signaled( K32OBJ *obj, DWORD thread_id );
-static BOOL32 THREAD_Satisfied( K32OBJ *obj, DWORD thread_id );
-static void THREAD_AddWait( K32OBJ *obj, DWORD thread_id );
-static void THREAD_RemoveWait( K32OBJ *obj, DWORD thread_id );
 static void THREAD_Destroy( K32OBJ *obj );
 
 const K32OBJ_OPS THREAD_Ops =
 {
-    THREAD_Signaled,    /* signaled */
-    THREAD_Satisfied,   /* satisfied */
-    THREAD_AddWait,     /* add_wait */
-    THREAD_RemoveWait,  /* remove_wait */
-    NULL,               /* read */
-    NULL,               /* write */
     THREAD_Destroy      /* destroy */
 };
 
@@ -234,10 +224,6 @@ THDB *THREAD_Create( PDB32 *pdb, DWORD stack_size, BOOL32 alloc_stack16,
                                                  0x10000 - sizeof(STACK16FRAME) );
     }
 
-    /* Allocate the event */
-
-    if (!(thdb->event = EVENT_Create( TRUE, FALSE ))) goto error;
-
     /* Create the thread socket */
 
     if (CLIENT_NewThread( thdb, server_thandle, server_phandle )) goto error;
@@ -273,56 +259,6 @@ error:
 }
 
 
-/***********************************************************************
- *           THREAD_Signaled
- */
-static BOOL32 THREAD_Signaled( K32OBJ *obj, DWORD thread_id )
-{
-    THDB *thdb = (THDB *)obj;
-    assert( obj->type == K32OBJ_THREAD );
-    return K32OBJ_OPS( thdb->event )->signaled( thdb->event, thread_id );
-}
-
-
-/***********************************************************************
- *           THREAD_Satisfied
- *
- * Wait on this object has been satisfied.
- */
-static BOOL32 THREAD_Satisfied( K32OBJ *obj, DWORD thread_id )
-{
-    THDB *thdb = (THDB *)obj;
-    assert( obj->type == K32OBJ_THREAD );
-    return K32OBJ_OPS( thdb->event )->satisfied( thdb->event, thread_id );
-}
-
-
-/***********************************************************************
- *           THREAD_AddWait
- *
- * Add thread to object wait queue.
- */
-static void THREAD_AddWait( K32OBJ *obj, DWORD thread_id )
-{
-    THDB *thdb = (THDB *)obj;
-    assert( obj->type == K32OBJ_THREAD );
-    return K32OBJ_OPS( thdb->event )->add_wait( thdb->event, thread_id );
-}
-
-
-/***********************************************************************
- *           THREAD_RemoveWait
- *
- * Remove thread from object wait queue.
- */
-static void THREAD_RemoveWait( K32OBJ *obj, DWORD thread_id )
-{
-    THDB *thdb = (THDB *)obj;
-    assert( obj->type == K32OBJ_THREAD );
-    return K32OBJ_OPS( thdb->event )->remove_wait( thdb->event, thread_id );
-}
-
-
 /***********************************************************************
  *           THREAD_Destroy
  */
@@ -348,7 +284,6 @@ static void THREAD_Destroy( K32OBJ *ptr )
     }
 #endif
     close( thdb->socket );
-    K32OBJ_DecCount( thdb->event );
     SELECTOR_FreeBlock( thdb->teb_sel, 1 );
     if (thdb->teb.stack_sel) SELECTOR_FreeBlock( thdb->teb.stack_sel, 1 );
     HeapFree( SystemHeap, 0, thdb );
@@ -418,10 +353,6 @@ void WINAPI ExitThread(
 
     SYSTEM_LOCK();
     thdb->exit_code = code;
-    EVENT_Set( thdb->event );
-
-    /* Abandon all owned mutexes */
-    while (thdb->mutex_list) MUTEX_Abandon( thdb->mutex_list );
 
     /* FIXME: should free the stack somehow */
 #if 0
@@ -731,15 +662,13 @@ BOOL32 WINAPI TerminateThread(
     HANDLE32 handle, /* [in] Handle to thread */
     DWORD exitcode)  /* [in] Exit code for thread */
 {
-    int server_handle;
-    BOOL32 ret;
-    THDB *thread;
-    
-    if (!(thread = THREAD_GetPtr( handle, THREAD_TERMINATE, &server_handle )))
-        return FALSE;
-    ret = !CLIENT_TerminateThread( server_handle, exitcode );
-    K32OBJ_DecCount( &thread->header );
-    return ret;
+    struct terminate_thread_request req;
+
+    req.handle = HANDLE_GetServerHandle( PROCESS_Current(), handle,
+                                         K32OBJ_THREAD, THREAD_TERMINATE );
+    req.exit_code = exitcode;
+    CLIENT_SendRequest( REQ_TERMINATE_THREAD, -1, 1, &req, sizeof(req) );
+    return !CLIENT_WaitReply( NULL, NULL, 0 );
 }
 
 
@@ -754,19 +683,11 @@ BOOL32 WINAPI GetExitCodeThread(
     HANDLE32 hthread, /* [in]  Handle to thread */
     LPDWORD exitcode) /* [out] Address to receive termination status */
 {
-    THDB *thread;
-    int server_handle;
-
-    if (!(thread = THREAD_GetPtr( hthread, THREAD_QUERY_INFORMATION, &server_handle )))
-        return FALSE;
-    if (server_handle != -1)
-    {
-        struct get_thread_info_reply info;
-        CLIENT_GetThreadInfo( server_handle, &info );
-        if (exitcode) *exitcode = info.exit_code;
-    }
-    else if (exitcode) *exitcode = thread->exit_code;
-    K32OBJ_DecCount( &thread->header );
+    struct get_thread_info_reply info;
+    int handle = HANDLE_GetServerHandle( PROCESS_Current(), hthread,
+                                         K32OBJ_THREAD, THREAD_QUERY_INFORMATION );
+    if (CLIENT_GetThreadInfo( handle, &info )) return FALSE;
+    if (exitcode) *exitcode = info.exit_code;
     return TRUE;
 }
 
diff --git a/win32/console.c b/win32/console.c
index dad241f7f9bfaec6afd23ea9721b33dc8fd22c61..ae53a8b5a296e4a21850c429f46dea60925a39e2 100644
--- a/win32/console.c
+++ b/win32/console.c
@@ -63,26 +63,10 @@ typedef struct _CONSOLE {
 	THREAD_QUEUE   		wait_queue;
 } CONSOLE;
 
-static void CONSOLE_AddWait(K32OBJ *ptr, DWORD thread_id);
-static void CONSOLE_RemoveWait(K32OBJ *ptr, DWORD thread_id);
-static BOOL32 CONSOLE_Satisfied(K32OBJ *ptr, DWORD thread_id);
-static BOOL32 CONSOLE_Signaled(K32OBJ *ptr, DWORD thread_id);
 static void CONSOLE_Destroy( K32OBJ *obj );
-static BOOL32 CONSOLE_Write(K32OBJ *ptr, LPCVOID lpBuffer, 
-			    DWORD nNumberOfChars,  LPDWORD lpNumberOfChars, 
-			    LPOVERLAPPED lpOverlapped);
-static BOOL32 CONSOLE_Read(K32OBJ *ptr, LPVOID lpBuffer, 
-			   DWORD nNumberOfChars, LPDWORD lpNumberOfChars, 
-			   LPOVERLAPPED lpOverlapped);
 
 const K32OBJ_OPS CONSOLE_Ops =
 {
-	CONSOLE_Signaled,	/* signaled */
-	CONSOLE_Satisfied,	/* satisfied */
-	CONSOLE_AddWait,	/* add_wait */
-	CONSOLE_RemoveWait,	/* remove_wait */
-	CONSOLE_Read,		/* read */
-	CONSOLE_Write,		/* write */
 	CONSOLE_Destroy		/* destroy */
 };
 
@@ -106,63 +90,6 @@ static void CONSOLE_Destroy(K32OBJ *obj)
 }
 
 
-/***********************************************************************
- * CONSOLE_Read
- *
- * NOTES
- *    lpOverlapped is ignored
- */
-static BOOL32 CONSOLE_Read(K32OBJ *ptr, LPVOID lpBuffer, DWORD nNumberOfChars,
-			LPDWORD lpNumberOfChars, LPOVERLAPPED lpOverlapped)
-{
-	CONSOLE *console = (CONSOLE *)ptr;
-	int result;
-
-	TRACE(console, "%p %p %ld\n", ptr, lpBuffer, nNumberOfChars);
-	*lpNumberOfChars = 0; 
-	if ((result = read(console->infd, lpBuffer, nNumberOfChars)) == -1) {
-		FILE_SetDosError();
-		return FALSE;
-	}
-	*lpNumberOfChars = result;
-	return TRUE;
-}
-
-
-/***********************************************************************
- * CONSOLE_Write
- *
- * NOTES
- *    lpOverlapped is ignored
- */
-static BOOL32 CONSOLE_Write(K32OBJ *ptr, LPCVOID lpBuffer, 
-			    DWORD nNumberOfChars,
-			    LPDWORD lpNumberOfChars, LPOVERLAPPED lpOverlapped)
-{
-	CONSOLE *console = (CONSOLE *)ptr;
-	int result;
-
-	TRACE(console, "%p %p %ld\n", ptr, lpBuffer, nNumberOfChars);
-	*lpNumberOfChars = 0; 
-	/* 
-	 * I assume this loop around EAGAIN is here because
-	 * win32 doesn't have interrupted system calls 
-	 */
-
-	for (;;)
-        {
-		result = write(console->outfd, lpBuffer, nNumberOfChars);
-		if (result != -1) {
-			*lpNumberOfChars = result;
-                        return TRUE;
-		}
-		if (errno != EINTR) {
-			FILE_SetDosError();
-			return FALSE;
-		}
-        }
-}
-
 /****************************************************************************
  *		CONSOLE_add_input_record			[internal]
  *
@@ -181,9 +108,11 @@ CONSOLE_add_input_record(CONSOLE *console,INPUT_RECORD *inp) {
  * queue. Does translation of vt100 style function keys and xterm-mouse clicks.
  */
 static void
-CONSOLE_string_to_IR(CONSOLE *console,unsigned char *buf,int len) {
+CONSOLE_string_to_IR( HANDLE32 hConsoleInput,unsigned char *buf,int len) {
     int			j,k;
     INPUT_RECORD	ir;
+    CONSOLE *console = (CONSOLE*)HANDLE_GetObjPtr( PROCESS_Current(), hConsoleInput,
+                                                   K32OBJ_CONSOLE, 0, NULL);
 
     for (j=0;j<len;j++) {
     	unsigned char inchar = buf[j];
@@ -326,39 +255,31 @@ CONSOLE_string_to_IR(CONSOLE *console,unsigned char *buf,int len) {
 	    }
 	}
     }
+    K32OBJ_DecCount(&console->header);
 }
+
 /****************************************************************************
  * 		CONSOLE_get_input		(internal)
  *
  * Reads (nonblocking) as much input events as possible and stores them
  * in an internal queue.
- * (not necessarily XTERM dependend, but UNIX filedescriptor...)
  */
 static void
-CONSOLE_get_input(CONSOLE *console) {
+CONSOLE_get_input( HANDLE32 handle )
+{
     char	*buf = HeapAlloc(GetProcessHeap(),0,1);
     int		len = 0;
 
-    while (1) {
-	fd_set	infds;
-	DWORD	res;
-	struct timeval tv;
-	char		inchar;
-
-	FD_ZERO(&infds);
-	FD_SET(console->infd,&infds);
-	memset(&tv,0,sizeof(tv));
-	if (select(console->infd+1,&infds,NULL,NULL,&tv)<1)
-	    break; /* no input there */
-
-	if (!FD_ISSET(console->infd,&infds))
-	    break;
-	if (!CONSOLE_Read((K32OBJ*)console,&inchar,1,&res,NULL))
-	    break;
+    while (1)
+    {
+	DWORD res;
+	char inchar;
+        if (!WaitForSingleObject( handle, 0 )) break;
+        if (!ReadFile( handle, &inchar, 1, &res, NULL )) break;
 	buf = HeapReAlloc(GetProcessHeap(),0,buf,len+1);
 	buf[len++]=inchar;
     }
-    CONSOLE_string_to_IR(console,buf,len);
+    CONSOLE_string_to_IR(handle,buf,len);
     HeapFree(GetProcessHeap(),0,buf);
 }
 
@@ -385,73 +306,6 @@ CONSOLE_drain_input(CONSOLE *console,int n) {
     }
 }
 
-/***********************************************************************
- *		CONSOLE_async_handler			[internal]
- */
-static void
-CONSOLE_async_handler(int unixfd,void *private) {
-	CONSOLE *console = (CONSOLE*)private;
-
-	SYNC_WakeUp(&console->wait_queue,INFINITE32);
-}
-
-/***********************************************************************
- *		CONSOLE_Signaled			[internal]
- *
- * Checks if we can read something. (Hmm, what about writing ?)
- */
-static BOOL32
-CONSOLE_Signaled(K32OBJ *ptr,DWORD tid) {
-	CONSOLE	*console =(CONSOLE*)ptr;
-
-	if (ptr->type!= K32OBJ_CONSOLE)
-		return FALSE;
-	CONSOLE_get_input(console);
-	if (console->nrofirs!=0)
-		return TRUE;
-	/* addref console */
-	return FALSE;
-}
-
-/***********************************************************************
- *		CONSOLE_AddWait			[internal]
- *
- * Add thread to our waitqueue (so we can signal it if we have input).
- */
-static void CONSOLE_AddWait(K32OBJ *ptr, DWORD thread_id)
-{
-    CONSOLE *console = (CONSOLE *)ptr;
-
-    /* register our unix filedescriptors for async IO */
-    if (!console->wait_queue)
-    	ASYNC_RegisterFD(console->infd,CONSOLE_async_handler,console);
-    THREAD_AddQueue( &console->wait_queue, THREAD_ID_TO_THDB(thread_id) );
-}
-
-/***********************************************************************
- *		CONSOLE_RemoveWait			[internal]
- *
- * Remove thread from our waitqueue.
- */
-static void CONSOLE_RemoveWait(K32OBJ *ptr, DWORD thread_id)
-{
-    CONSOLE *console = (CONSOLE *)ptr;
-
-    THREAD_RemoveQueue( &console->wait_queue, THREAD_ID_TO_THDB(thread_id) );
-    if (!console->wait_queue)
-    	ASYNC_UnregisterFD(console->infd,CONSOLE_async_handler);
-}
-
-/***********************************************************************
- *		CONSOLE_Satisfied			[internal]
- *
- * Condition from last Signaled is satisfied and will be used now.
- */
-static BOOL32 CONSOLE_Satisfied(K32OBJ *ptr, DWORD thread_id)
-{
-    return FALSE;
-}
-
 
 /******************************************************************************
  * SetConsoleCtrlHandler [KERNEL32.459]  Adds function to calling process list
@@ -711,7 +565,7 @@ static int CONSOLE_openpty(CONSOLE *console, char *name,
  *
  * To test for complex console: pid == -1 -> simple, otherwise complex.
  */
-static BOOL32 CONSOLE_make_complex(CONSOLE *console)
+static BOOL32 CONSOLE_make_complex(HANDLE32 handle,CONSOLE *console)
 {
 	struct termios term;
 	char buf[30];
@@ -757,7 +611,7 @@ static BOOL32 CONSOLE_make_complex(CONSOLE *console)
 	}
 	/* enable mouseclicks */
 	sprintf(buf,"%c[?1001s%c[?1000h",27,27);
-	CONSOLE_Write(&console->header,buf,strlen(buf),&xlen,NULL);
+	WriteFile(handle,buf,strlen(buf),&xlen,NULL);
 	return TRUE;
 
 }
@@ -1033,7 +887,7 @@ BOOL32 WINAPI WriteConsoleOutput32A( HANDLE32 hConsoleOutput,
     	FIXME(console,"(%d,...): no console handle!\n",hConsoleOutput);
 	return FALSE;
     }
-    CONSOLE_make_complex(console);
+    CONSOLE_make_complex(hConsoleOutput,console);
     buffer = HeapAlloc(GetProcessHeap(),0,100);;
     curbufsize = 100;
 
@@ -1114,7 +968,7 @@ BOOL32 WINAPI ReadConsole32A( HANDLE32 hConsoleInput,
 	    hConsoleInput,lpBuffer,nNumberOfCharsToRead,
 	    lpNumberOfCharsRead,lpReserved
     );
-    CONSOLE_get_input(console);
+    CONSOLE_get_input(hConsoleInput);
 
     /* FIXME:	should this drain everything from the input queue and just 
      * 		put the keypresses in the buffer? Needs further thought.
@@ -1186,7 +1040,7 @@ BOOL32 WINAPI ReadConsoleInput32A(HANDLE32 hConsoleInput,
 		lpBuffer, nLength, lpNumberOfEventsRead);
 	return FALSE;
     }
-    CONSOLE_get_input(console);
+    CONSOLE_get_input(hConsoleInput);
     if (nLength>console->nrofirs)
     	nLength = console->nrofirs;
     memcpy(lpBuffer,console->irs,sizeof(INPUT_RECORD)*nLength);
@@ -1232,7 +1086,8 @@ BOOL32 WINAPI SetConsoleTitle32A(LPCSTR title)
 
     sprintf(titlestring,titleformat,title);
     /* FIXME: hmm, should use WriteFile probably... */
-    CONSOLE_Write(&console->header,titlestring,strlen(titlestring),&written,NULL);
+    /*CONSOLE_Write(&console->header,titlestring,strlen(titlestring),&written,NULL);*/
+    WriteFile(GetStdHandle(STD_OUTPUT_HANDLE),titlestring,strlen(titlestring),&written,NULL);
     if (written == strlen(titlestring))
 	ret =TRUE;
     HeapFree( GetProcessHeap(), 0, titlestring );
@@ -1311,7 +1166,7 @@ BOOL32 WINAPI SetConsoleCursorPosition( HANDLE32 hcon, COORD pos )
     	FIXME(console,"(%d,...), no console handle!\n",hcon);
     	return FALSE;
     }
-    CONSOLE_make_complex(console);
+    CONSOLE_make_complex(hcon,console);
     TRACE(console, "%d (%dx%d)\n", hcon, pos.x , pos.y );
     /* x are columns, y rows */
     sprintf(xbuf,"%c[%d;%dH", 0x1B, pos.y+1, pos.x+1);
@@ -1332,7 +1187,7 @@ BOOL32 WINAPI GetNumberOfConsoleInputEvents(HANDLE32 hcon,LPDWORD nrofevents)
     	FIXME(console,"(%d,%p), no console handle!\n",hcon,nrofevents);
     	return FALSE;
     }
-    CONSOLE_get_input(console);
+    CONSOLE_get_input(hcon);
     *nrofevents = console->nrofirs;
     K32OBJ_DecCount(&console->header);
     return TRUE;
@@ -1367,7 +1222,7 @@ BOOL32 WINAPI PeekConsoleInput32A(HANDLE32 hConsoleInput,
     	return FALSE;
     }
     TRACE(console,"(%d,%p,%ld,%p)\n",hConsoleInput, pirBuffer, cInRecords, lpcRead);
-    CONSOLE_get_input(console);
+    CONSOLE_get_input(hConsoleInput);
     if (cInRecords>console->nrofirs)
     	cInRecords = console->nrofirs;
     if (pirBuffer)
@@ -1438,7 +1293,7 @@ BOOL32 WINAPI SetConsoleCursorInfo32(
     TRACE(console, "(%x,%ld,%i): stub\n", hcon,cinfo->dwSize,cinfo->bVisible);
     if (!console)
     	return FALSE;
-    CONSOLE_make_complex(console);
+    CONSOLE_make_complex(hcon,console);
     sprintf(buf,"%c[?25%c",27,cinfo->bVisible?'h':'l');
     WriteFile(hcon,buf,strlen(buf),&xlen,NULL);
     console->cinfo = *cinfo;
diff --git a/win32/device.c b/win32/device.c
index 3131b218ddb48a4fbae3ba5c74fdee0afe92ca26..75bab3a5d72429946605e5969c2f7c52c058b8d0 100644
--- a/win32/device.c
+++ b/win32/device.c
@@ -32,14 +32,9 @@
 #include "miscemu.h"
 
 static void DEVICE_Destroy(K32OBJ *dev);
+
 const K32OBJ_OPS DEVICE_Ops =
 {
-    NULL,		/* signaled */
-    NULL,		/* satisfied */
-    NULL,		/* add_wait */
-    NULL,		/* remove_wait */
-    NULL,		/* read */
-    NULL,		/* write */
     DEVICE_Destroy	/* destroy */
 };
 
diff --git a/windows/queue.c b/windows/queue.c
index eee5c8a6f2ce674ce0baa6a5e5f6d2aed76054b7..da782e971feaee60501cecfd020c13979c708374 100644
--- a/windows/queue.c
+++ b/windows/queue.c
@@ -235,6 +235,8 @@ void QUEUE_Signal( HTASK16 hTask )
     /* NOTE: This should really wake up *the* thread that owns
              the queue. Since we dont't have thread-local message
              queues yet, we wake up all waiting threads ... */
+#if 0
+    /* FIXME: should be replaced by a server event */
     SYSTEM_LOCK();
     pdb = pTask->thdb->process;
     entry = pdb? pdb->thread_list->next : NULL;
@@ -251,6 +253,7 @@ void QUEUE_Signal( HTASK16 hTask )
             entry = entry->next;
         }
     SYSTEM_UNLOCK();
+#endif
 
 /*    if ( !wakeup )*/
         PostEvent( hTask );