Moved some of the process functions to dlls/kernel.
Removed kernel dependencies from sysdeps.c and moved it to dlls/ntdll.

diff --git a/dlls/kernel/Makefile.in b/dlls/kernel/Makefile.in
index 2636e27..403951a 100644
--- a/dlls/kernel/Makefile.in
+++ b/dlls/kernel/Makefile.in
@@ -35,6 +35,7 @@
 	lcformat.c \
 	local16.c \
 	locale.c \
+	process.c \
 	resource.c \
 	resource16.c \
 	stress.c \
diff --git a/dlls/kernel/process.c b/dlls/kernel/process.c
new file mode 100644
index 0000000..32aa36e
--- /dev/null
+++ b/dlls/kernel/process.c
@@ -0,0 +1,524 @@
+/*
+ * Win32 processes
+ *
+ * Copyright 1996, 1998 Alexandre Julliard
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include "config.h"
+#include "wine/port.h"
+
+#include "wine/winbase16.h"
+#include "wine/winuser16.h"
+#include "wine/server.h"
+#include "wine/debug.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(process);
+
+/* Process flags */
+#define PDB32_DEBUGGED      0x0001  /* Process is being debugged */
+#define PDB32_WIN16_PROC    0x0008  /* Win16 process */
+#define PDB32_DOS_PROC      0x0010  /* Dos process */
+#define PDB32_CONSOLE_PROC  0x0020  /* Console process */
+#define PDB32_FILE_APIS_OEM 0x0040  /* File APIs are OEM */
+#define PDB32_WIN32S_PROC   0x8000  /* Win32s process */
+
+
+static DWORD shutdown_flags = 0;
+static DWORD shutdown_priority = 0x280;
+static DWORD process_dword;
+static BOOL oem_file_apis;
+
+
+/***********************************************************************
+ *           GetProcessFlags    (KERNEL32.@)
+ */
+DWORD WINAPI GetProcessFlags( DWORD processid )
+{
+    IMAGE_NT_HEADERS *nt;
+    DWORD flags = 0;
+
+    if (processid && processid != GetCurrentProcessId()) return 0;
+
+    if ((nt = RtlImageNtHeader( NtCurrentTeb()->Peb->ImageBaseAddress )))
+    {
+        if (nt->OptionalHeader.Subsystem == IMAGE_SUBSYSTEM_WINDOWS_CUI)
+            flags |= PDB32_CONSOLE_PROC;
+    }
+    if (!AreFileApisANSI()) flags |= PDB32_FILE_APIS_OEM;
+    if (IsDebuggerPresent()) flags |= PDB32_DEBUGGED;
+    return flags;
+}
+
+
+/***********************************************************************
+ *           GetProcessDword    (KERNEL.485)
+ *           GetProcessDword    (KERNEL32.18)
+ * 'Of course you cannot directly access Windows internal structures'
+ */
+DWORD WINAPI GetProcessDword( DWORD dwProcessID, INT offset )
+{
+    DWORD               x, y;
+    STARTUPINFOW        siw;
+
+    TRACE("(%ld, %d)\n", dwProcessID, offset );
+
+    if (dwProcessID && dwProcessID != GetCurrentProcessId())
+    {
+        ERR("%d: process %lx not accessible\n", offset, dwProcessID);
+        return 0;
+    }
+
+    switch ( offset )
+    {
+    case GPD_APP_COMPAT_FLAGS:
+        return GetAppCompatFlags16(0);
+    case GPD_LOAD_DONE_EVENT:
+        return 0;
+    case GPD_HINSTANCE16:
+        return GetTaskDS16();
+    case GPD_WINDOWS_VERSION:
+        return GetExeVersion16();
+    case GPD_THDB:
+        return (DWORD)NtCurrentTeb() - 0x10 /* FIXME */;
+    case GPD_PDB:
+        return (DWORD)NtCurrentTeb()->Peb;
+    case GPD_STARTF_SHELLDATA: /* return stdoutput handle from startupinfo ??? */
+        GetStartupInfoW(&siw);
+        return (DWORD)siw.hStdOutput;
+    case GPD_STARTF_HOTKEY: /* return stdinput handle from startupinfo ??? */
+        GetStartupInfoW(&siw);
+        return (DWORD)siw.hStdInput;
+    case GPD_STARTF_SHOWWINDOW:
+        GetStartupInfoW(&siw);
+        return siw.wShowWindow;
+    case GPD_STARTF_SIZE:
+        GetStartupInfoW(&siw);
+        x = siw.dwXSize;
+        if ( (INT)x == CW_USEDEFAULT ) x = CW_USEDEFAULT16;
+        y = siw.dwYSize;
+        if ( (INT)y == CW_USEDEFAULT ) y = CW_USEDEFAULT16;
+        return MAKELONG( x, y );
+    case GPD_STARTF_POSITION:
+        GetStartupInfoW(&siw);
+        x = siw.dwX;
+        if ( (INT)x == CW_USEDEFAULT ) x = CW_USEDEFAULT16;
+        y = siw.dwY;
+        if ( (INT)y == CW_USEDEFAULT ) y = CW_USEDEFAULT16;
+        return MAKELONG( x, y );
+    case GPD_STARTF_FLAGS:
+        GetStartupInfoW(&siw);
+        return siw.dwFlags;
+    case GPD_PARENT:
+        return 0;
+    case GPD_FLAGS:
+        return GetProcessFlags(0);
+    case GPD_USERDATA:
+        return process_dword;
+    default:
+        ERR("Unknown offset %d\n", offset );
+        return 0;
+    }
+}
+
+/***********************************************************************
+ *           SetProcessDword    (KERNEL.484)
+ * 'Of course you cannot directly access Windows internal structures'
+ */
+void WINAPI SetProcessDword( DWORD dwProcessID, INT offset, DWORD value )
+{
+    TRACE("(%ld, %d)\n", dwProcessID, offset );
+
+    if (dwProcessID && dwProcessID != GetCurrentProcessId())
+    {
+        ERR("%d: process %lx not accessible\n", offset, dwProcessID);
+        return;
+    }
+
+    switch ( offset )
+    {
+    case GPD_APP_COMPAT_FLAGS:
+    case GPD_LOAD_DONE_EVENT:
+    case GPD_HINSTANCE16:
+    case GPD_WINDOWS_VERSION:
+    case GPD_THDB:
+    case GPD_PDB:
+    case GPD_STARTF_SHELLDATA:
+    case GPD_STARTF_HOTKEY:
+    case GPD_STARTF_SHOWWINDOW:
+    case GPD_STARTF_SIZE:
+    case GPD_STARTF_POSITION:
+    case GPD_STARTF_FLAGS:
+    case GPD_PARENT:
+    case GPD_FLAGS:
+        ERR("Not allowed to modify offset %d\n", offset );
+        break;
+    case GPD_USERDATA:
+        process_dword = value;
+        break;
+    default:
+        ERR("Unknown offset %d\n", offset );
+        break;
+    }
+}
+
+
+/***********************************************************************
+ *           ExitProcess   (KERNEL.466)
+ */
+void WINAPI ExitProcess16( WORD status )
+{
+    DWORD count;
+    ReleaseThunkLock( &count );
+    ExitProcess( status );
+}
+
+
+/*********************************************************************
+ *           OpenProcess   (KERNEL32.@)
+ */
+HANDLE WINAPI OpenProcess( DWORD access, BOOL inherit, DWORD id )
+{
+    HANDLE ret = 0;
+    SERVER_START_REQ( open_process )
+    {
+        req->pid     = id;
+        req->access  = access;
+        req->inherit = inherit;
+        if (!wine_server_call_err( req )) ret = reply->handle;
+    }
+    SERVER_END_REQ;
+    return ret;
+}
+
+
+/*********************************************************************
+ *           MapProcessHandle   (KERNEL.483)
+ */
+DWORD WINAPI MapProcessHandle( HANDLE handle )
+{
+    DWORD ret = 0;
+    SERVER_START_REQ( get_process_info )
+    {
+        req->handle = handle;
+        if (!wine_server_call_err( req )) ret = reply->pid;
+    }
+    SERVER_END_REQ;
+    return ret;
+}
+
+
+/***********************************************************************
+ *           SetPriorityClass   (KERNEL32.@)
+ */
+BOOL WINAPI SetPriorityClass( HANDLE hprocess, DWORD priorityclass )
+{
+    BOOL ret;
+    SERVER_START_REQ( set_process_info )
+    {
+        req->handle   = hprocess;
+        req->priority = priorityclass;
+        req->mask     = SET_PROCESS_INFO_PRIORITY;
+        ret = !wine_server_call_err( req );
+    }
+    SERVER_END_REQ;
+    return ret;
+}
+
+
+/***********************************************************************
+ *           GetPriorityClass   (KERNEL32.@)
+ */
+DWORD WINAPI GetPriorityClass(HANDLE hprocess)
+{
+    DWORD ret = 0;
+    SERVER_START_REQ( get_process_info )
+    {
+        req->handle = hprocess;
+        if (!wine_server_call_err( req )) ret = reply->priority;
+    }
+    SERVER_END_REQ;
+    return ret;
+}
+
+
+/***********************************************************************
+ *          SetProcessAffinityMask   (KERNEL32.@)
+ */
+BOOL WINAPI SetProcessAffinityMask( HANDLE hProcess, DWORD affmask )
+{
+    BOOL ret;
+    SERVER_START_REQ( set_process_info )
+    {
+        req->handle   = hProcess;
+        req->affinity = affmask;
+        req->mask     = SET_PROCESS_INFO_AFFINITY;
+        ret = !wine_server_call_err( req );
+    }
+    SERVER_END_REQ;
+    return ret;
+}
+
+
+/**********************************************************************
+ *          GetProcessAffinityMask    (KERNEL32.@)
+ */
+BOOL WINAPI GetProcessAffinityMask( HANDLE hProcess,
+                                      LPDWORD lpProcessAffinityMask,
+                                      LPDWORD lpSystemAffinityMask )
+{
+    BOOL ret = FALSE;
+    SERVER_START_REQ( get_process_info )
+    {
+        req->handle = hProcess;
+        if (!wine_server_call_err( req ))
+        {
+            if (lpProcessAffinityMask) *lpProcessAffinityMask = reply->process_affinity;
+            if (lpSystemAffinityMask) *lpSystemAffinityMask = reply->system_affinity;
+            ret = TRUE;
+        }
+    }
+    SERVER_END_REQ;
+    return ret;
+}
+
+
+/***********************************************************************
+ *           GetProcessVersion    (KERNEL32.@)
+ */
+DWORD WINAPI GetProcessVersion( DWORD processid )
+{
+    IMAGE_NT_HEADERS *nt;
+
+    if (processid && processid != GetCurrentProcessId())
+    {
+        FIXME("should use ReadProcessMemory\n");
+        return 0;
+    }
+    if ((nt = RtlImageNtHeader( NtCurrentTeb()->Peb->ImageBaseAddress )))
+        return ((nt->OptionalHeader.MajorSubsystemVersion << 16) |
+                nt->OptionalHeader.MinorSubsystemVersion);
+    return 0;
+}
+
+
+/***********************************************************************
+ *		SetProcessWorkingSetSize	[KERNEL32.@]
+ * Sets the min/max working set sizes for a specified process.
+ *
+ * PARAMS
+ *    hProcess [I] Handle to the process of interest
+ *    minset   [I] Specifies minimum working set size
+ *    maxset   [I] Specifies maximum working set size
+ *
+ * RETURNS  STD
+ */
+BOOL WINAPI SetProcessWorkingSetSize(HANDLE hProcess, SIZE_T minset,
+                                     SIZE_T maxset)
+{
+    FIXME("(%p,%ld,%ld): stub - harmless\n",hProcess,minset,maxset);
+    if(( minset == (SIZE_T)-1) && (maxset == (SIZE_T)-1)) {
+        /* Trim the working set to zero */
+        /* Swap the process out of physical RAM */
+    }
+    return TRUE;
+}
+
+/***********************************************************************
+ *           GetProcessWorkingSetSize    (KERNEL32.@)
+ */
+BOOL WINAPI GetProcessWorkingSetSize(HANDLE hProcess, PSIZE_T minset,
+                                     PSIZE_T maxset)
+{
+    FIXME("(%p,%p,%p): stub\n",hProcess,minset,maxset);
+    /* 32 MB working set size */
+    if (minset) *minset = 32*1024*1024;
+    if (maxset) *maxset = 32*1024*1024;
+    return TRUE;
+}
+
+
+/***********************************************************************
+ *           SetProcessShutdownParameters    (KERNEL32.@)
+ */
+BOOL WINAPI SetProcessShutdownParameters(DWORD level, DWORD flags)
+{
+    FIXME("(%08lx, %08lx): partial stub.\n", level, flags);
+    shutdown_flags = flags;
+    shutdown_priority = level;
+    return TRUE;
+}
+
+
+/***********************************************************************
+ * GetProcessShutdownParameters                 (KERNEL32.@)
+ *
+ */
+BOOL WINAPI GetProcessShutdownParameters( LPDWORD lpdwLevel, LPDWORD lpdwFlags )
+{
+    *lpdwLevel = shutdown_priority;
+    *lpdwFlags = shutdown_flags;
+    return TRUE;
+}
+
+
+/***********************************************************************
+ *           GetProcessPriorityBoost    (KERNEL32.@)
+ */
+BOOL WINAPI GetProcessPriorityBoost(HANDLE hprocess,PBOOL pDisablePriorityBoost)
+{
+    FIXME("(%p,%p): semi-stub\n", hprocess, pDisablePriorityBoost);
+    
+    /* Report that no boost is present.. */
+    *pDisablePriorityBoost = FALSE;
+    
+    return TRUE;
+}
+
+/***********************************************************************
+ *           SetProcessPriorityBoost    (KERNEL32.@)
+ */
+BOOL WINAPI SetProcessPriorityBoost(HANDLE hprocess,BOOL disableboost)
+{
+    FIXME("(%p,%d): stub\n",hprocess,disableboost);
+    /* Say we can do it. I doubt the program will notice that we don't. */
+    return TRUE;
+}
+
+
+/***********************************************************************
+ *		ReadProcessMemory (KERNEL32.@)
+ */
+BOOL WINAPI ReadProcessMemory( HANDLE process, LPCVOID addr, LPVOID buffer, SIZE_T size,
+                               SIZE_T *bytes_read )
+{
+    DWORD res;
+
+    SERVER_START_REQ( read_process_memory )
+    {
+        req->handle = process;
+        req->addr   = (void *)addr;
+        wine_server_set_reply( req, buffer, size );
+        if ((res = wine_server_call_err( req ))) size = 0;
+    }
+    SERVER_END_REQ;
+    if (bytes_read) *bytes_read = size;
+    return !res;
+}
+
+
+/***********************************************************************
+ *           WriteProcessMemory    		(KERNEL32.@)
+ */
+BOOL WINAPI WriteProcessMemory( HANDLE process, LPVOID addr, LPCVOID buffer, SIZE_T size,
+                                SIZE_T *bytes_written )
+{
+    static const int zero;
+    unsigned int first_offset, last_offset, first_mask, last_mask;
+    DWORD res;
+
+    if (!size)
+    {
+        SetLastError( ERROR_INVALID_PARAMETER );
+        return FALSE;
+    }
+
+    /* compute the mask for the first int */
+    first_mask = ~0;
+    first_offset = (unsigned int)addr % sizeof(int);
+    memset( &first_mask, 0, first_offset );
+
+    /* compute the mask for the last int */
+    last_offset = (size + first_offset) % sizeof(int);
+    last_mask = 0;
+    memset( &last_mask, 0xff, last_offset ? last_offset : sizeof(int) );
+
+    SERVER_START_REQ( write_process_memory )
+    {
+        req->handle     = process;
+        req->addr       = (char *)addr - first_offset;
+        req->first_mask = first_mask;
+        req->last_mask  = last_mask;
+        if (first_offset) wine_server_add_data( req, &zero, first_offset );
+        wine_server_add_data( req, buffer, size );
+        if (last_offset) wine_server_add_data( req, &zero, sizeof(int) - last_offset );
+
+        if ((res = wine_server_call_err( req ))) size = 0;
+    }
+    SERVER_END_REQ;
+    if (bytes_written) *bytes_written = size;
+    {
+        char dummy[32];
+        SIZE_T read;
+        ReadProcessMemory( process, addr, dummy, sizeof(dummy), &read );
+    }
+    return !res;
+}
+
+
+/***********************************************************************
+ *		RegisterServiceProcess (KERNEL.491)
+ *		RegisterServiceProcess (KERNEL32.@)
+ *
+ * A service process calls this function to ensure that it continues to run
+ * even after a user logged off.
+ */
+DWORD WINAPI RegisterServiceProcess(DWORD dwProcessId, DWORD dwType)
+{
+    /* I don't think that Wine needs to do anything in that function */
+    return 1; /* success */
+}
+
+
+/**************************************************************************
+ *              SetFileApisToOEM   (KERNEL32.@)
+ */
+VOID WINAPI SetFileApisToOEM(void)
+{
+    oem_file_apis = TRUE;
+}
+
+
+/**************************************************************************
+ *              SetFileApisToANSI   (KERNEL32.@)
+ */
+VOID WINAPI SetFileApisToANSI(void)
+{
+    oem_file_apis = FALSE;
+}
+
+
+/******************************************************************************
+ * AreFileApisANSI [KERNEL32.@]  Determines if file functions are using ANSI
+ *
+ * RETURNS
+ *    TRUE:  Set of file functions is using ANSI code page
+ *    FALSE: Set of file functions is using OEM code page
+ */
+BOOL WINAPI AreFileApisANSI(void)
+{
+    return !oem_file_apis;
+}
+
+
+/***********************************************************************
+ *           GetCurrentProcess   (KERNEL32.@)
+ */
+#undef GetCurrentProcess
+HANDLE WINAPI GetCurrentProcess(void)
+{
+    return (HANDLE)0xffffffff;
+}
diff --git a/dlls/ntdll/Makefile.in b/dlls/ntdll/Makefile.in
index b0b1d13..7890956 100644
--- a/dlls/ntdll/Makefile.in
+++ b/dlls/ntdll/Makefile.in
@@ -49,7 +49,6 @@
 	$(TOPOBJDIR)/scheduler/process.c \
 	$(TOPOBJDIR)/scheduler/pthread.c \
 	$(TOPOBJDIR)/scheduler/synchro.c \
-	$(TOPOBJDIR)/scheduler/sysdeps.c \
 	$(TOPOBJDIR)/scheduler/syslevel.c \
 	$(TOPOBJDIR)/scheduler/thread.c \
 	$(TOPOBJDIR)/win32/device.c \
@@ -80,6 +79,7 @@
 	signal_sparc.c \
 	string.c \
 	sync.c \
+	sysdeps.c \
 	thread.c \
 	time.c \
 	virtual.c \
diff --git a/scheduler/sysdeps.c b/dlls/ntdll/sysdeps.c
similarity index 89%
rename from scheduler/sysdeps.c
rename to dlls/ntdll/sysdeps.c
index 933b24c..c6ddba8 100644
--- a/scheduler/sysdeps.c
+++ b/dlls/ntdll/sysdeps.c
@@ -55,8 +55,6 @@
 #include "thread.h"
 #include "wine/server.h"
 #include "winbase.h"
-#include "wine/winbase16.h"
-#include "wine/exception.h"
 #include "wine/library.h"
 #include "wine/debug.h"
 
@@ -101,27 +99,6 @@
 
 
 /***********************************************************************
- *           call_on_thread_stack
- *
- * Call a function once we switched to the thread stack.
- */
-static void call_on_thread_stack( void *func )
-{
-    __TRY
-    {
-        void (*funcptr)(void) = func;
-        funcptr();
-    }
-    __EXCEPT(UnhandledExceptionFilter)
-    {
-        TerminateThread( GetCurrentThread(), GetExceptionCode() );
-    }
-    __ENDTRY
-    SYSDEPS_ExitThread(0);  /* should never get here */
-}
-
-
-/***********************************************************************
  *           get_temp_stack
  *
  * Get a temporary stack address to run the thread exit code on.
@@ -161,15 +138,7 @@
     SYSDEPS_SetCurThread( teb );
     SIGNAL_Init();
     CLIENT_InitThread();
-    __TRY
-    {
-        teb->startup();
-    }
-    __EXCEPT(UnhandledExceptionFilter)
-    {
-        TerminateThread( GetCurrentThread(), GetExceptionCode() );
-    }
-    __ENDTRY
+    teb->startup();
     SYSDEPS_ExitThread(0);  /* should never get here */
 }
 
@@ -230,12 +199,15 @@
 
 
 /***********************************************************************
- *           SYSDEPS_CallOnStack
+ *           SYSDEPS_SwitchToThreadStack
+ *
+ * Switch to the stack specified in the current thread TEB
+ * and call the specified function.
  */
-void DECLSPEC_NORETURN SYSDEPS_CallOnStack( void (*func)(LPVOID), LPVOID arg );
+void DECLSPEC_NORETURN SYSDEPS_SwitchToThreadStack( void (*func)(void *), void *arg );
 #ifdef __i386__
 #  ifdef __GNUC__
-__ASM_GLOBAL_FUNC( SYSDEPS_CallOnStack,
+__ASM_GLOBAL_FUNC( SYSDEPS_SwitchToThreadStack,
                    "movl 4(%esp),%ecx\n\t"  /* func */
                    "movl 8(%esp),%edx\n\t"  /* arg */
                    ".byte 0x64\n\tmovl 0x04,%esp\n\t"  /* teb->stack_top */
@@ -244,7 +216,7 @@
                    "call *%ecx\n\t"
                    "int $3" /* we never return here */ );
 #  elif defined(_MSC_VER)
-__declspec(naked) void SYSDEPS_CallOnStack( void (*func)(LPVOID), LPVOID arg )
+__declspec(naked) void SYSDEPS_SwitchToThreadStack( void (*func)(void *), void *arg )
 {
   __asm mov ecx, 4[esp];
   __asm mov edx, 8[esp];
@@ -256,7 +228,7 @@
 }
 #  endif /* defined(__GNUC__) || defined(_MSC_VER) */
 #elif defined(__sparc__) && defined(__GNUC__)
-__ASM_GLOBAL_FUNC( SYSDEPS_CallOnStack,
+__ASM_GLOBAL_FUNC( SYSDEPS_SwitchToThreadStack,
                    "mov %o0, %l0\n\t" /* store first argument */
                    "call " __ASM_NAME("NtCurrentTeb") ", 0\n\t"
                    "mov %o1, %l1\n\t" /* delay slot: store second argument */
@@ -265,7 +237,7 @@
                    "mov %l1, %o0\n\t" /* delay slot:  arg for func */
                    "ta 0x01\n\t"); /* breakpoint - we never get here */
 #else /* !sparc, !i386 */
-void SYSDEPS_CallOnStack( void (*func)(LPVOID), LPVOID arg )
+void SYSDEPS_SwitchToThreadStack( void (*func)(void *), void *arg )
 {
     func( arg );
     while(1); /* avoid warning */
@@ -274,15 +246,6 @@
 
 
 /***********************************************************************
- *           SYSDEPS_SwitchToThreadStack
- */
-void SYSDEPS_SwitchToThreadStack( void (*func)(void) )
-{
-    SYSDEPS_CallOnStack( call_on_thread_stack, func );
-}
-
-
-/***********************************************************************
  *           SYSDEPS_ExitThread
  *
  * Exit a running thread; must not return.
@@ -292,8 +255,10 @@
     TEB *teb = NtCurrentTeb();
     struct thread_cleanup_info info;
     MEMORY_BASIC_INFORMATION meminfo;
+    DWORD size = 0;
 
-    VirtualQuery( teb->stack_top, &meminfo, sizeof(meminfo) );
+    NtQueryVirtualMemory( GetCurrentProcess(), teb->stack_top, MemoryBasicInformation,
+                          &meminfo, sizeof(meminfo), NULL );
     info.stack_base = meminfo.AllocationBase;
     info.stack_size = meminfo.RegionSize + ((char *)teb->stack_top - (char *)meminfo.AllocationBase);
     info.status     = status;
@@ -304,14 +269,15 @@
     SYSDEPS_AbortThread( status );
 #else
     SIGNAL_Reset();
-    VirtualFree( teb->stack_base, 0, MEM_RELEASE | MEM_SYSTEM );
+    size = 0;
+    NtFreeVirtualMemory( GetCurrentProcess(), &teb->stack_base, &size, MEM_RELEASE | MEM_SYSTEM );
     close( teb->wait_fd[0] );
     close( teb->wait_fd[1] );
     close( teb->reply_fd );
     close( teb->request_fd );
     teb->stack_low = get_temp_stack();
     teb->stack_top = (char *) teb->stack_low + TEMP_STACK_SIZE;
-    SYSDEPS_CallOnStack( cleanup_thread, &info );
+    SYSDEPS_SwitchToThreadStack( cleanup_thread, &info );
 #endif
 }
 
diff --git a/include/thread.h b/include/thread.h
index 9d51d0f..fb14e7b 100644
--- a/include/thread.h
+++ b/include/thread.h
@@ -150,7 +150,7 @@
 extern void SYSDEPS_InitErrno(void);
 extern void DECLSPEC_NORETURN SYSDEPS_ExitThread( int status );
 extern void DECLSPEC_NORETURN SYSDEPS_AbortThread( int status );
-extern void DECLSPEC_NORETURN SYSDEPS_SwitchToThreadStack( void (*func)(void) );
+extern void DECLSPEC_NORETURN SYSDEPS_SwitchToThreadStack( void (*func)(void *), void *arg );
 
 /* signal handling */
 extern BOOL SIGNAL_Init(void);
diff --git a/scheduler/fiber.c b/scheduler/fiber.c
index 570aa41..7a816ce 100644
--- a/scheduler/fiber.c
+++ b/scheduler/fiber.c
@@ -25,6 +25,7 @@
 
 #include "winbase.h"
 #include "winerror.h"
+#include "wine/exception.h"
 #include "thread.h"
 
 struct fiber_data
@@ -41,14 +42,22 @@
 
 
 /* call the fiber initial function once we have switched stack */
-static void start_fiber(void)
+static void start_fiber( void *arg )
 {
-    struct fiber_data *fiber = NtCurrentTeb()->fiber;
+    struct fiber_data *fiber = arg;
     LPFIBER_START_ROUTINE start = fiber->start;
 
-    fiber->start = NULL;
-    start( fiber->param );
-    ExitThread( 1 );
+    __TRY
+    {
+        fiber->start = NULL;
+        start( fiber->param );
+        ExitThread( 1 );
+    }
+    __EXCEPT(UnhandledExceptionFilter)
+    {
+        TerminateThread( GetCurrentThread(), GetExceptionCode() );
+    }
+    __ENDTRY
 }
 
 
@@ -180,7 +189,7 @@
         NtCurrentTeb()->stack_low  = new_fiber->stack_low;
         NtCurrentTeb()->stack_base = new_fiber->stack_base;
         if (new_fiber->start)  /* first time */
-            SYSDEPS_SwitchToThreadStack( start_fiber );
+            SYSDEPS_SwitchToThreadStack( start_fiber, new_fiber );
         else
             longjmp( new_fiber->jmpbuf, 1 );
     }
diff --git a/scheduler/process.c b/scheduler/process.c
index e32a7b1..f21c55e 100644
--- a/scheduler/process.c
+++ b/scheduler/process.c
@@ -109,14 +109,6 @@
 
 static RTL_USER_PROCESS_PARAMETERS     process_pmts;
 
-/* Process flags */
-#define PDB32_DEBUGGED      0x0001  /* Process is being debugged */
-#define PDB32_WIN16_PROC    0x0008  /* Win16 process */
-#define PDB32_DOS_PROC      0x0010  /* Dos process */
-#define PDB32_CONSOLE_PROC  0x0020  /* Console process */
-#define PDB32_FILE_APIS_OEM 0x0040  /* File APIs are OEM */
-#define PDB32_WIN32S_PROC   0x8000  /* Win32s process */
-
 static char main_exe_name[MAX_PATH];
 static char *main_exe_name_ptr = main_exe_name;
 static HANDLE main_exe_file;
@@ -397,78 +389,73 @@
  *
  * Startup routine of a new process. Runs on the new process stack.
  */
-static void start_process(void)
+static void start_process( void *arg )
 {
-    int debugged, console_app;
-    LPTHREAD_START_ROUTINE entry;
-    WINE_MODREF *wm;
-    HANDLE main_file = main_exe_file;
-    IMAGE_NT_HEADERS *nt;
-
-    /* use original argv[0] as name for the main module */
-    if (!main_exe_name[0])
+    __TRY
     {
-        if (!GetLongPathNameA( full_argv0, main_exe_name, sizeof(main_exe_name) ))
-            lstrcpynA( main_exe_name, full_argv0, sizeof(main_exe_name) );
-    }
+        LPTHREAD_START_ROUTINE entry;
+        HANDLE main_file = main_exe_file;
+        IMAGE_NT_HEADERS *nt;
+        PEB *peb = NtCurrentTeb()->Peb;
 
-    if (main_file)
+        if (main_file)
+        {
+            UINT drive_type = GetDriveTypeA( main_exe_name );
+            /* don't keep the file handle open on removable media */
+            if (drive_type == DRIVE_REMOVABLE || drive_type == DRIVE_CDROM) main_file = 0;
+        }
+
+        /* Retrieve entry point address */
+        nt = RtlImageNtHeader( peb->ImageBaseAddress );
+        entry = (LPTHREAD_START_ROUTINE)((char*)peb->ImageBaseAddress +
+                                         nt->OptionalHeader.AddressOfEntryPoint);
+
+        /* Install signal handlers; this cannot be done before, since we cannot
+         * send exceptions to the debugger before the create process event that
+         * is sent by REQ_INIT_PROCESS_DONE.
+         * We do need the handlers in place by the time the request is over, so
+         * we set them up here. If we segfault between here and the server call
+         * something is very wrong... */
+        if (!SIGNAL_Init()) goto error;
+
+        /* Signal the parent process to continue */
+        SERVER_START_REQ( init_process_done )
+        {
+            req->module      = peb->ImageBaseAddress;
+            req->module_size = nt->OptionalHeader.SizeOfImage;
+            req->entry       = entry;
+            /* API requires a double indirection */
+            req->name        = &main_exe_name_ptr;
+            req->exe_file    = main_file;
+            req->gui         = (nt->OptionalHeader.Subsystem != IMAGE_SUBSYSTEM_WINDOWS_CUI);
+            wine_server_add_data( req, main_exe_name, strlen(main_exe_name) );
+            wine_server_call( req );
+            peb->BeingDebugged = reply->debugged;
+        }
+        SERVER_END_REQ;
+
+        /* create the main modref and load dependencies */
+        if (!PE_CreateModule( peb->ImageBaseAddress, main_exe_name, 0, 0, FALSE )) goto error;
+
+        if (main_exe_file) CloseHandle( main_exe_file ); /* we no longer need it */
+
+        MODULE_DllProcessAttach( NULL, (LPVOID)1 );
+
+        if (TRACE_ON(relay))
+            DPRINTF( "%04lx:Starting process %s (entryproc=%p)\n",
+                     GetCurrentThreadId(), main_exe_name, entry );
+        if (peb->BeingDebugged) DbgBreakPoint();
+        SetLastError(0);  /* clear error code */
+        ExitThread( entry( NtCurrentTeb()->Peb ) );
+
+    error:
+        ExitProcess( GetLastError() );
+    }
+    __EXCEPT(UnhandledExceptionFilter)
     {
-        UINT drive_type = GetDriveTypeA( main_exe_name );
-        /* don't keep the file handle open on removable media */
-        if (drive_type == DRIVE_REMOVABLE || drive_type == DRIVE_CDROM) main_file = 0;
+        TerminateThread( GetCurrentThread(), GetExceptionCode() );
     }
-
-    /* Retrieve entry point address */
-    nt = RtlImageNtHeader( current_process.module );
-    entry = (LPTHREAD_START_ROUTINE)((char*)current_process.module +
-                                     nt->OptionalHeader.AddressOfEntryPoint);
-    console_app = (nt->OptionalHeader.Subsystem == IMAGE_SUBSYSTEM_WINDOWS_CUI);
-    if (console_app) current_process.flags |= PDB32_CONSOLE_PROC;
-
-    /* Install signal handlers; this cannot be done before, since we cannot
-     * send exceptions to the debugger before the create process event that
-     * is sent by REQ_INIT_PROCESS_DONE.
-     * We do need the handlers in place by the time the request is over, so
-     * we set them up here. If we segfault between here and the server call
-     * something is very wrong... */
-    if (!SIGNAL_Init()) goto error;
-
-    /* Signal the parent process to continue */
-    SERVER_START_REQ( init_process_done )
-    {
-        req->module      = (void *)current_process.module;
-        req->module_size = nt->OptionalHeader.SizeOfImage;
-        req->entry    = entry;
-        /* API requires a double indirection */
-        req->name     = &main_exe_name_ptr;
-        req->exe_file = main_file;
-        req->gui      = !console_app;
-        wine_server_add_data( req, main_exe_name, strlen(main_exe_name) );
-        wine_server_call( req );
-        debugged = reply->debugged;
-    }
-    SERVER_END_REQ;
-
-    /* create the main modref and load dependencies */
-    if (!(wm = PE_CreateModule( current_process.module, main_exe_name, 0, 0, FALSE )))
-        goto error;
-
-    if (main_exe_file) CloseHandle( main_exe_file ); /* we no longer need it */
-
-    MODULE_DllProcessAttach( NULL, (LPVOID)1 );
-
-    if (TRACE_ON(relay))
-        DPRINTF( "%04lx:Starting process %s (entryproc=%p)\n",
-                 GetCurrentThreadId(), main_exe_name, entry );
-    if (debugged) DbgBreakPoint();
-    /* FIXME: should use _PEB as parameter for NT 3.5 programs !
-     * Dunno about other OSs */
-    SetLastError(0);  /* clear error code */
-    ExitThread( entry(NULL) );
-
- error:
-    ExitProcess( GetLastError() );
+    __ENDTRY
 }
 
 
@@ -586,7 +573,7 @@
     if (!THREAD_InitStack( NtCurrentTeb(), stack_size )) goto error;
 
     /* switch to the new stack */
-    SYSDEPS_SwitchToThreadStack( start_process );
+    SYSDEPS_SwitchToThreadStack( start_process, NULL );
 
  error:
     ExitProcess( GetLastError() );
@@ -1387,16 +1374,6 @@
     exit( status );
 }
 
-/***********************************************************************
- *           ExitProcess   (KERNEL.466)
- */
-void WINAPI ExitProcess16( WORD status )
-{
-    DWORD count;
-    ReleaseThunkLock( &count );
-    ExitProcess( status );
-}
-
 /******************************************************************************
  *           TerminateProcess   (KERNEL32.@)
  */
@@ -1409,441 +1386,6 @@
 
 
 /***********************************************************************
- *           GetProcessDword    (KERNEL.485)
- *           GetProcessDword    (KERNEL32.18)
- * 'Of course you cannot directly access Windows internal structures'
- */
-DWORD WINAPI GetProcessDword( DWORD dwProcessID, INT offset )
-{
-    DWORD               x, y;
-    STARTUPINFOW        siw;
-
-    TRACE_(win32)("(%ld, %d)\n", dwProcessID, offset );
-
-    if (dwProcessID && dwProcessID != GetCurrentProcessId())
-    {
-        ERR("%d: process %lx not accessible\n", offset, dwProcessID);
-        return 0;
-    }
-
-    switch ( offset )
-    {
-    case GPD_APP_COMPAT_FLAGS:
-        return GetAppCompatFlags16(0);
-
-    case GPD_LOAD_DONE_EVENT:
-        return (DWORD)current_process.load_done_evt;
-
-    case GPD_HINSTANCE16:
-        return GetTaskDS16();
-
-    case GPD_WINDOWS_VERSION:
-        return GetExeVersion16();
-
-    case GPD_THDB:
-        return (DWORD)NtCurrentTeb() - 0x10 /* FIXME */;
-
-    case GPD_PDB:
-        return (DWORD)&current_process;
-
-    case GPD_STARTF_SHELLDATA: /* return stdoutput handle from startupinfo ??? */
-        GetStartupInfoW(&siw);
-        return (DWORD)siw.hStdOutput;
-
-    case GPD_STARTF_HOTKEY: /* return stdinput handle from startupinfo ??? */
-        GetStartupInfoW(&siw);
-        return (DWORD)siw.hStdInput;
-
-    case GPD_STARTF_SHOWWINDOW:
-        GetStartupInfoW(&siw);
-        return siw.wShowWindow;
-
-    case GPD_STARTF_SIZE:
-        GetStartupInfoW(&siw);
-        x = siw.dwXSize;
-        if ( (INT)x == CW_USEDEFAULT ) x = CW_USEDEFAULT16;
-        y = siw.dwYSize;
-        if ( (INT)y == CW_USEDEFAULT ) y = CW_USEDEFAULT16;
-        return MAKELONG( x, y );
-
-    case GPD_STARTF_POSITION:
-        GetStartupInfoW(&siw);
-        x = siw.dwX;
-        if ( (INT)x == CW_USEDEFAULT ) x = CW_USEDEFAULT16;
-        y = siw.dwY;
-        if ( (INT)y == CW_USEDEFAULT ) y = CW_USEDEFAULT16;
-        return MAKELONG( x, y );
-
-    case GPD_STARTF_FLAGS:
-        GetStartupInfoW(&siw);
-        return process_pmts.dwFlags;
-
-    case GPD_PARENT:
-        return 0;
-
-    case GPD_FLAGS:
-        return current_process.flags;
-
-    case GPD_USERDATA:
-        return current_process.process_dword;
-
-    default:
-        ERR_(win32)("Unknown offset %d\n", offset );
-        return 0;
-    }
-}
-
-/***********************************************************************
- *           SetProcessDword    (KERNEL.484)
- * 'Of course you cannot directly access Windows internal structures'
- */
-void WINAPI SetProcessDword( DWORD dwProcessID, INT offset, DWORD value )
-{
-    TRACE_(win32)("(%ld, %d)\n", dwProcessID, offset );
-
-    if (dwProcessID && dwProcessID != GetCurrentProcessId())
-    {
-        ERR("%d: process %lx not accessible\n", offset, dwProcessID);
-        return;
-    }
-
-    switch ( offset )
-    {
-    case GPD_APP_COMPAT_FLAGS:
-    case GPD_LOAD_DONE_EVENT:
-    case GPD_HINSTANCE16:
-    case GPD_WINDOWS_VERSION:
-    case GPD_THDB:
-    case GPD_PDB:
-    case GPD_STARTF_SHELLDATA:
-    case GPD_STARTF_HOTKEY:
-    case GPD_STARTF_SHOWWINDOW:
-    case GPD_STARTF_SIZE:
-    case GPD_STARTF_POSITION:
-    case GPD_STARTF_FLAGS:
-    case GPD_PARENT:
-    case GPD_FLAGS:
-        ERR_(win32)("Not allowed to modify offset %d\n", offset );
-        break;
-
-    case GPD_USERDATA:
-        current_process.process_dword = value;
-        break;
-
-    default:
-        ERR_(win32)("Unknown offset %d\n", offset );
-        break;
-    }
-}
-
-
-/*********************************************************************
- *           OpenProcess   (KERNEL32.@)
- */
-HANDLE WINAPI OpenProcess( DWORD access, BOOL inherit, DWORD id )
-{
-    HANDLE ret = 0;
-    SERVER_START_REQ( open_process )
-    {
-        req->pid     = id;
-        req->access  = access;
-        req->inherit = inherit;
-        if (!wine_server_call_err( req )) ret = reply->handle;
-    }
-    SERVER_END_REQ;
-    return ret;
-}
-
-/*********************************************************************
- *           MapProcessHandle   (KERNEL.483)
- */
-DWORD WINAPI MapProcessHandle( HANDLE handle )
-{
-    DWORD ret = 0;
-    SERVER_START_REQ( get_process_info )
-    {
-        req->handle = handle;
-        if (!wine_server_call_err( req )) ret = (DWORD)reply->pid;
-    }
-    SERVER_END_REQ;
-    return ret;
-}
-
-/***********************************************************************
- *           SetPriorityClass   (KERNEL32.@)
- */
-BOOL WINAPI SetPriorityClass( HANDLE hprocess, DWORD priorityclass )
-{
-    BOOL ret;
-    SERVER_START_REQ( set_process_info )
-    {
-        req->handle   = hprocess;
-        req->priority = priorityclass;
-        req->mask     = SET_PROCESS_INFO_PRIORITY;
-        ret = !wine_server_call_err( req );
-    }
-    SERVER_END_REQ;
-    return ret;
-}
-
-
-/***********************************************************************
- *           GetPriorityClass   (KERNEL32.@)
- */
-DWORD WINAPI GetPriorityClass(HANDLE hprocess)
-{
-    DWORD ret = 0;
-    SERVER_START_REQ( get_process_info )
-    {
-        req->handle = hprocess;
-        if (!wine_server_call_err( req )) ret = reply->priority;
-    }
-    SERVER_END_REQ;
-    return ret;
-}
-
-
-/***********************************************************************
- *          SetProcessAffinityMask   (KERNEL32.@)
- */
-BOOL WINAPI SetProcessAffinityMask( HANDLE hProcess, DWORD affmask )
-{
-    BOOL ret;
-    SERVER_START_REQ( set_process_info )
-    {
-        req->handle   = hProcess;
-        req->affinity = affmask;
-        req->mask     = SET_PROCESS_INFO_AFFINITY;
-        ret = !wine_server_call_err( req );
-    }
-    SERVER_END_REQ;
-    return ret;
-}
-
-/**********************************************************************
- *          GetProcessAffinityMask    (KERNEL32.@)
- */
-BOOL WINAPI GetProcessAffinityMask( HANDLE hProcess,
-                                      LPDWORD lpProcessAffinityMask,
-                                      LPDWORD lpSystemAffinityMask )
-{
-    BOOL ret = FALSE;
-    SERVER_START_REQ( get_process_info )
-    {
-        req->handle = hProcess;
-        if (!wine_server_call_err( req ))
-        {
-            if (lpProcessAffinityMask) *lpProcessAffinityMask = reply->process_affinity;
-            if (lpSystemAffinityMask) *lpSystemAffinityMask = reply->system_affinity;
-            ret = TRUE;
-        }
-    }
-    SERVER_END_REQ;
-    return ret;
-}
-
-
-/***********************************************************************
- *           GetProcessVersion    (KERNEL32.@)
- */
-DWORD WINAPI GetProcessVersion( DWORD processid )
-{
-    IMAGE_NT_HEADERS *nt;
-
-    if (processid && processid != GetCurrentProcessId())
-    {
-	FIXME("should use ReadProcessMemory\n");
-        return 0;
-    }
-    if ((nt = RtlImageNtHeader( current_process.module )))
-        return ((nt->OptionalHeader.MajorSubsystemVersion << 16) |
-                nt->OptionalHeader.MinorSubsystemVersion);
-    return 0;
-}
-
-/***********************************************************************
- *           GetProcessFlags    (KERNEL32.@)
- */
-DWORD WINAPI GetProcessFlags( DWORD processid )
-{
-    if (processid && processid != GetCurrentProcessId()) return 0;
-    return current_process.flags;
-}
-
-
-/***********************************************************************
- *		SetProcessWorkingSetSize	[KERNEL32.@]
- * Sets the min/max working set sizes for a specified process.
- *
- * PARAMS
- *    hProcess [I] Handle to the process of interest
- *    minset   [I] Specifies minimum working set size
- *    maxset   [I] Specifies maximum working set size
- *
- * RETURNS  STD
- */
-BOOL WINAPI SetProcessWorkingSetSize(HANDLE hProcess, SIZE_T minset,
-                                     SIZE_T maxset)
-{
-    FIXME("(%p,%ld,%ld): stub - harmless\n",hProcess,minset,maxset);
-    if(( minset == (SIZE_T)-1) && (maxset == (SIZE_T)-1)) {
-        /* Trim the working set to zero */
-        /* Swap the process out of physical RAM */
-    }
-    return TRUE;
-}
-
-/***********************************************************************
- *           GetProcessWorkingSetSize    (KERNEL32.@)
- */
-BOOL WINAPI GetProcessWorkingSetSize(HANDLE hProcess, PSIZE_T minset,
-                                     PSIZE_T maxset)
-{
-	FIXME("(%p,%p,%p): stub\n",hProcess,minset,maxset);
-	/* 32 MB working set size */
-	if (minset) *minset = 32*1024*1024;
-	if (maxset) *maxset = 32*1024*1024;
-	return TRUE;
-}
-
-/***********************************************************************
- *           SetProcessShutdownParameters    (KERNEL32.@)
- *
- * CHANGED - James Sutherland (JamesSutherland@gmx.de)
- * Now tracks changes made (but does not act on these changes)
- */
-static DWORD shutdown_flags = 0;
-static DWORD shutdown_priority = 0x280;
-
-BOOL WINAPI SetProcessShutdownParameters(DWORD level, DWORD flags)
-{
-    FIXME("(%08lx, %08lx): partial stub.\n", level, flags);
-    shutdown_flags = flags;
-    shutdown_priority = level;
-    return TRUE;
-}
-
-
-/***********************************************************************
- * GetProcessShutdownParameters                 (KERNEL32.@)
- *
- */
-BOOL WINAPI GetProcessShutdownParameters( LPDWORD lpdwLevel, LPDWORD lpdwFlags )
-{
-    *lpdwLevel = shutdown_priority;
-    *lpdwFlags = shutdown_flags;
-    return TRUE;
-}
-
-
-/***********************************************************************
- *           GetProcessPriorityBoost    (KERNEL32.@)
- */
-BOOL WINAPI GetProcessPriorityBoost(HANDLE hprocess,PBOOL pDisablePriorityBoost)
-{
-    FIXME("(%p,%p): semi-stub\n", hprocess, pDisablePriorityBoost);
-    
-    /* Report that no boost is present.. */
-    *pDisablePriorityBoost = FALSE;
-    
-    return TRUE;
-}
-
-/***********************************************************************
- *           SetProcessPriorityBoost    (KERNEL32.@)
- */
-BOOL WINAPI SetProcessPriorityBoost(HANDLE hprocess,BOOL disableboost)
-{
-    FIXME("(%p,%d): stub\n",hprocess,disableboost);
-    /* Say we can do it. I doubt the program will notice that we don't. */
-    return TRUE;
-}
-
-
-/***********************************************************************
- *		ReadProcessMemory (KERNEL32.@)
- */
-BOOL WINAPI ReadProcessMemory( HANDLE process, LPCVOID addr, LPVOID buffer, SIZE_T size,
-                               SIZE_T *bytes_read )
-{
-    DWORD res;
-
-    SERVER_START_REQ( read_process_memory )
-    {
-        req->handle = process;
-        req->addr   = (void *)addr;
-        wine_server_set_reply( req, buffer, size );
-        if ((res = wine_server_call_err( req ))) size = 0;
-    }
-    SERVER_END_REQ;
-    if (bytes_read) *bytes_read = size;
-    return !res;
-}
-
-
-/***********************************************************************
- *           WriteProcessMemory    		(KERNEL32.@)
- */
-BOOL WINAPI WriteProcessMemory( HANDLE process, LPVOID addr, LPCVOID buffer, SIZE_T size,
-                                SIZE_T *bytes_written )
-{
-    static const int zero;
-    unsigned int first_offset, last_offset, first_mask, last_mask;
-    DWORD res;
-
-    if (!size)
-    {
-        SetLastError( ERROR_INVALID_PARAMETER );
-        return FALSE;
-    }
-
-    /* compute the mask for the first int */
-    first_mask = ~0;
-    first_offset = (unsigned int)addr % sizeof(int);
-    memset( &first_mask, 0, first_offset );
-
-    /* compute the mask for the last int */
-    last_offset = (size + first_offset) % sizeof(int);
-    last_mask = 0;
-    memset( &last_mask, 0xff, last_offset ? last_offset : sizeof(int) );
-
-    SERVER_START_REQ( write_process_memory )
-    {
-        req->handle     = process;
-        req->addr       = (char *)addr - first_offset;
-        req->first_mask = first_mask;
-        req->last_mask  = last_mask;
-        if (first_offset) wine_server_add_data( req, &zero, first_offset );
-        wine_server_add_data( req, buffer, size );
-        if (last_offset) wine_server_add_data( req, &zero, sizeof(int) - last_offset );
-
-        if ((res = wine_server_call_err( req ))) size = 0;
-    }
-    SERVER_END_REQ;
-    if (bytes_written) *bytes_written = size;
-    {
-        char dummy[32];
-        SIZE_T read;
-        ReadProcessMemory( process, addr, dummy, sizeof(dummy), &read );
-    }
-    return !res;
-}
-
-
-/***********************************************************************
- *		RegisterServiceProcess (KERNEL.491)
- *		RegisterServiceProcess (KERNEL32.@)
- *
- * A service process calls this function to ensure that it continues to run
- * even after a user logged off.
- */
-DWORD WINAPI RegisterServiceProcess(DWORD dwProcessId, DWORD dwType)
-{
-	/* I don't think that Wine needs to do anything in that function */
-	return 1; /* success */
-}
-
-/***********************************************************************
  * GetExitCodeProcess [KERNEL32.@]
  *
  * Gets termination status of specified process
@@ -1879,37 +1421,6 @@
 }
 
 
-/**************************************************************************
- *              SetFileApisToOEM   (KERNEL32.@)
- */
-VOID WINAPI SetFileApisToOEM(void)
-{
-    current_process.flags |= PDB32_FILE_APIS_OEM;
-}
-
-
-/**************************************************************************
- *              SetFileApisToANSI   (KERNEL32.@)
- */
-VOID WINAPI SetFileApisToANSI(void)
-{
-    current_process.flags &= ~PDB32_FILE_APIS_OEM;
-}
-
-
-/******************************************************************************
- * AreFileApisANSI [KERNEL32.@]  Determines if file functions are using ANSI
- *
- * RETURNS
- *    TRUE:  Set of file functions is using ANSI code page
- *    FALSE: Set of file functions is using OEM code page
- */
-BOOL WINAPI AreFileApisANSI(void)
-{
-    return !(current_process.flags & PDB32_FILE_APIS_OEM);
-}
-
-
 /***********************************************************************
  *           GetTickCount       (KERNEL32.@)
  *
@@ -2031,13 +1542,3 @@
     NtCurrentTeb()->tls_array[index] = value;
     return TRUE;
 }
-
-
-/***********************************************************************
- *           GetCurrentProcess   (KERNEL32.@)
- */
-#undef GetCurrentProcess
-HANDLE WINAPI GetCurrentProcess(void)
-{
-    return (HANDLE)0xffffffff;
-}
diff --git a/scheduler/thread.c b/scheduler/thread.c
index e285465..04f3f03 100644
--- a/scheduler/thread.c
+++ b/scheduler/thread.c
@@ -232,8 +232,16 @@
     if (TRACE_ON(relay))
         DPRINTF("%04lx:Starting thread (entryproc=%p)\n", GetCurrentThreadId(), func );
 
-    MODULE_DllThreadAttach( NULL );
-    ExitThread( func( NtCurrentTeb()->entry_arg ) );
+    __TRY
+    {
+        MODULE_DllThreadAttach( NULL );
+        ExitThread( func( NtCurrentTeb()->entry_arg ) );
+    }
+    __EXCEPT(UnhandledExceptionFilter)
+    {
+        TerminateThread( GetCurrentThread(), GetExceptionCode() );
+    }
+    __ENDTRY
 }