Removed PDB32_DEBUGGED flag and send all debug events unconditionally.
Implemented IsDebuggerPresent().

diff --git a/dlls/ntdll/exception.c b/dlls/ntdll/exception.c
index f7b6893..c8426b2 100644
--- a/dlls/ntdll/exception.c
+++ b/dlls/ntdll/exception.c
@@ -13,7 +13,6 @@
 #include "wine/exception.h"
 #include "stackframe.h"
 #include "miscemu.h"
-#include "debugger.h"
 #include "debugtools.h"
 
 DEFAULT_DEBUG_CHANNEL(seh)
@@ -92,11 +91,7 @@
  */
 static void EXC_DefaultHandling( EXCEPTION_RECORD *rec, CONTEXT *context )
 {
-    if ((PROCESS_Current()->flags & PDB32_DEBUGGED) &&
-        (DEBUG_SendExceptionEvent( rec, FALSE, context ) == DBG_CONTINUE))
-        return;  /* continue execution */
-
-    if (wine_debugger( rec, context, FALSE ) == DBG_CONTINUE)
+    if (DEBUG_SendExceptionEvent( rec, FALSE, context ) == DBG_CONTINUE)
         return;  /* continue execution */
 
     if (rec->ExceptionFlags & EH_STACK_INVALID)
@@ -122,11 +117,7 @@
 
     TRACE( "code=%lx flags=%lx\n", rec->ExceptionCode, rec->ExceptionFlags );
 
-    if ((PROCESS_Current()->flags & PDB32_DEBUGGED) &&
-        (DEBUG_SendExceptionEvent( rec, TRUE, context ) == DBG_CONTINUE))
-        return;  /* continue execution */
-
-    if (wine_debugger( rec, context, TRUE ) == DBG_CONTINUE)
+    if (DEBUG_SendExceptionEvent( rec, TRUE, context ) == DBG_CONTINUE)
         return;  /* continue execution */
 
     frame = NtCurrentTeb()->except;
@@ -286,30 +277,3 @@
     ExceptionRec.NumberParameters = 0;
     RtlRaiseException( &ExceptionRec );
 }
-
-
-/***********************************************************************
- *           DebugBreak (KERNEL32.181)
- */
-void WINAPI DebugBreak(void)
-{
-    DbgBreakPoint();
-}
-
-
-/***********************************************************************
- *           DebugBreak16   (KERNEL.203)
- */
-void WINAPI DebugBreak16( CONTEXT86 *context )
-{
-#ifdef __i386__
-    EXCEPTION_RECORD rec;
-
-    rec.ExceptionCode    = EXCEPTION_BREAKPOINT;
-    rec.ExceptionFlags   = 0;
-    rec.ExceptionRecord  = NULL;
-    rec.ExceptionAddress = GET_IP(context); 
-    rec.NumberParameters = 0;
-    EXC_RtlRaiseException( &rec, context );
-#endif  /* defined(__i386__) */
-}
diff --git a/include/ntddk.h b/include/ntddk.h
index 7877549..9c573d6 100644
--- a/include/ntddk.h
+++ b/include/ntddk.h
@@ -961,7 +961,13 @@
 
 /*	misc */
 
+#if defined(__i386__) && defined(__GNUC__)
+static inline void WINAPI DbgBreakPoint(void) { __asm__ __volatile__("int3"); }
+static inline void WINAPI DbgUserBreakPoint(void) { __asm__ __volatile__("int3"); }
+#else  /* __i386__ && __GNUC__ */
 void WINAPI DbgBreakPoint(void);
+void WINAPI DbgUserBreakPoint(void);
+#endif  /* __i386__ && __GNUC__ */
 void WINAPIV DbgPrint(LPCSTR fmt, ...);
 
 DWORD WINAPI RtlAdjustPrivilege(DWORD x1,DWORD x2,DWORD x3,DWORD x4);
diff --git a/include/server.h b/include/server.h
index 2c5f91c..28c5199 100644
--- a/include/server.h
+++ b/include/server.h
@@ -167,6 +167,7 @@
 {
     IN  void*        module;       /* main module base address */
     IN  void*        entry;        /* process entry point */
+    OUT int          debugged;     /* being debugged? */
 };
 
 
@@ -209,8 +210,9 @@
 /* Retrieve information about a process */
 struct get_process_info_request
 {
-    IN  int          handle;       /* process handle */
+    IN  int          handle;           /* process handle */
     OUT void*        pid;              /* server process id */
+    OUT int          debugged;         /* debugged? */
     OUT int          exit_code;        /* process exit code */
     OUT int          priority;         /* priority class */
     OUT int          process_affinity; /* process affinity mask */
diff --git a/include/winbase.h b/include/winbase.h
index d66b5c6..95169b6 100644
--- a/include/winbase.h
+++ b/include/winbase.h
@@ -1659,8 +1659,9 @@
 BOOL      WINAPI IsBadStringPtrA(LPCSTR,UINT);
 BOOL      WINAPI IsBadStringPtrW(LPCWSTR,UINT);
 #define     IsBadStringPtr WINELIB_NAME_AW(IsBadStringPtr)
-BOOL      WINAPI IsBadWritePtr(LPVOID,UINT);
-BOOL      WINAPI IsDBCSLeadByte(BYTE);
+BOOL        WINAPI IsBadWritePtr(LPVOID,UINT);
+BOOL        WINAPI IsDBCSLeadByte(BYTE);
+BOOL        WINAPI IsDebuggerPresent(void);
 HINSTANCE16 WINAPI LoadLibrary16(LPCSTR);
 HMODULE   WINAPI LoadLibraryA(LPCSTR);
 HMODULE   WINAPI LoadLibraryW(LPCWSTR);
@@ -1689,8 +1690,9 @@
 VOID        WINAPI OutputDebugStringA(LPCSTR);
 VOID        WINAPI OutputDebugStringW(LPCWSTR);
 #define     OutputDebugString WINELIB_NAME_AW(OutputDebugString)
-BOOL      WINAPI RemoveDirectoryA(LPCSTR);
-BOOL      WINAPI RemoveDirectoryW(LPCWSTR);
+BOOL        WINAPI ReadProcessMemory(HANDLE, LPCVOID, LPVOID, DWORD, LPDWORD);
+BOOL        WINAPI RemoveDirectoryA(LPCSTR);
+BOOL        WINAPI RemoveDirectoryW(LPCWSTR);
 #define     RemoveDirectory WINELIB_NAME_AW(RemoveDirectory)
 BOOL      WINAPI SetCurrentDirectoryA(LPCSTR);
 BOOL      WINAPI SetCurrentDirectoryW(LPCWSTR);
@@ -1718,8 +1720,9 @@
 BOOL      WINAPI WritePrivateProfileStructA(LPCSTR,LPCSTR,LPVOID,UINT,LPCSTR);
 BOOL      WINAPI WritePrivateProfileStructW(LPCWSTR,LPCWSTR,LPVOID,UINT,LPCWSTR);
 #define     WritePrivateProfileStruct WINELIB_NAME_AW(WritePrivateProfileStruct)
-BOOL      WINAPI WriteProfileStringA(LPCSTR,LPCSTR,LPCSTR);
-BOOL      WINAPI WriteProfileStringW(LPCWSTR,LPCWSTR,LPCWSTR);
+BOOL        WINAPI WriteProcessMemory(HANDLE, LPVOID, LPVOID, DWORD, LPDWORD);
+BOOL        WINAPI WriteProfileStringA(LPCSTR,LPCSTR,LPCSTR);
+BOOL        WINAPI WriteProfileStringW(LPCWSTR,LPCWSTR,LPCWSTR);
 #define     WriteProfileString WINELIB_NAME_AW(WriteProfileString)
 #define     Yield32()
 LPSTR       WINAPI lstrcatA(LPSTR,LPCSTR);
diff --git a/loader/module.c b/loader/module.c
index bac3f6a..c7a343b 100644
--- a/loader/module.c
+++ b/loader/module.c
@@ -1351,8 +1351,7 @@
 	wm = MODULE_LoadLibraryExA( libname, hfile, flags );
 	if ( wm )
 	{
-		if ( PROCESS_Current()->flags & PDB32_DEBUGGED )
-			MODULE_SendLoadDLLEvents();
+                MODULE_SendLoadDLLEvents();
                         
 		if ( !MODULE_DllProcessAttach( wm, NULL ) )
 		{
@@ -1611,8 +1610,7 @@
     if ( PROCESS_Current()->free_lib_count <= 1 )
     {
         MODULE_DllProcessDetach( FALSE, NULL );
-        if (PROCESS_Current()->flags & PDB32_DEBUGGED)
-            DEBUG_SendUnloadDLLEvent( wm->module );
+        DEBUG_SendUnloadDLLEvent( wm->module );
     }
 
     TRACE("(%s) - END\n", wm->modname );
diff --git a/scheduler/debugger.c b/scheduler/debugger.c
index f8357d1..4479368 100644
--- a/scheduler/debugger.c
+++ b/scheduler/debugger.c
@@ -195,16 +195,12 @@
  */
 void WINAPI OutputDebugStringA( LPCSTR str )
 {
-    if (PROCESS_Current()->flags & PDB32_DEBUGGED)
-    {
-        struct send_debug_event_request *req = get_req_buffer();
-        req->event.code = OUTPUT_DEBUG_STRING_EVENT;
-        req->event.info.output_string.string  = (void *)str;
-        req->event.info.output_string.unicode = 0;
-        req->event.info.output_string.length  = strlen(str) + 1;
-        server_call( REQ_SEND_DEBUG_EVENT );
-    }
-
+    struct send_debug_event_request *req = get_req_buffer();
+    req->event.code = OUTPUT_DEBUG_STRING_EVENT;
+    req->event.info.output_string.string  = (void *)str;
+    req->event.info.output_string.unicode = 0;
+    req->event.info.output_string.length  = strlen(str) + 1;
+    server_call_noerr( REQ_SEND_DEBUG_EVENT );
     TRACE("%s\n", str);
 }
 
@@ -214,16 +210,12 @@
  */
 void WINAPI OutputDebugStringW( LPCWSTR str )
 {
-    if (PROCESS_Current()->flags & PDB32_DEBUGGED)
-    {
-        struct send_debug_event_request *req = get_req_buffer();
-        req->event.code = OUTPUT_DEBUG_STRING_EVENT;
-        req->event.info.output_string.string  = (void *)str;
-        req->event.info.output_string.unicode = 1;
-        req->event.info.output_string.length  = (lstrlenW(str) + 1) * sizeof(WCHAR);
-        server_call( REQ_SEND_DEBUG_EVENT );
-    }
-
+    struct send_debug_event_request *req = get_req_buffer();
+    req->event.code = OUTPUT_DEBUG_STRING_EVENT;
+    req->event.info.output_string.string  = (void *)str;
+    req->event.info.output_string.unicode = 1;
+    req->event.info.output_string.length  = (lstrlenW(str) + 1) * sizeof(WCHAR);
+    server_call_noerr( REQ_SEND_DEBUG_EVENT );
     TRACE("%s\n", debugstr_w(str));
 }
 
@@ -235,3 +227,43 @@
 {
     OutputDebugStringA( str );
 }
+
+
+/***********************************************************************
+ *           DebugBreak   (KERNEL32.181)
+ */
+void WINAPI DebugBreak(void)
+{
+    DbgBreakPoint();
+}
+
+
+/***********************************************************************
+ *           DebugBreak16   (KERNEL.203)
+ */
+void WINAPI DebugBreak16( CONTEXT86 *context )
+{
+#ifdef __i386__
+    EXCEPTION_RECORD rec;
+
+    rec.ExceptionCode    = EXCEPTION_BREAKPOINT;
+    rec.ExceptionFlags   = 0;
+    rec.ExceptionRecord  = NULL;
+    rec.ExceptionAddress = GET_IP(context); 
+    rec.NumberParameters = 0;
+    NtRaiseException( &rec, context, TRUE );
+#endif  /* defined(__i386__) */
+}
+
+
+/***********************************************************************
+ *           IsDebuggerPresent   (KERNEL32)
+ */
+BOOL WINAPI IsDebuggerPresent(void)
+{
+    BOOL ret = FALSE;
+    struct get_process_info_request *req = get_req_buffer();
+    req->handle = GetCurrentProcess();
+    if (!server_call( REQ_GET_PROCESS_INFO )) ret = req->debugged;
+    return ret;
+}
diff --git a/scheduler/process.c b/scheduler/process.c
index a1b68f7..b7dc85a 100644
--- a/scheduler/process.c
+++ b/scheduler/process.c
@@ -371,6 +371,7 @@
 void PROCESS_Start(void)
 {
     struct init_process_done_request *req = get_req_buffer();
+    int debugged;
     UINT cmdShow = SW_SHOWNORMAL;
     LPTHREAD_START_ROUTINE entry = NULL;
     PDB *pdb = PROCESS_Current();
@@ -455,9 +456,10 @@
     req->module = (void *)pModule->module32;
     req->entry  = entry;
     server_call( REQ_INIT_PROCESS_DONE );
+    debugged = req->debugged;
 
     /* Send all required start-up debugger events */
-    if ( type == PROC_WIN32 && (pdb->flags & PDB32_DEBUGGED) )
+    if (type == PROC_WIN32 && debugged)
     {
         EnterCriticalSection( &pdb->crit_section );
         MODULE_SendLoadDLLEvents();
@@ -498,7 +500,7 @@
 
     case PROC_WIN32:
         TRACE_(relay)( "Starting Win32 process (entryproc=%p)\n", entry );
-        if (pdb->flags & PDB32_DEBUGGED) DebugBreak();
+        if (debugged) DbgBreakPoint();
 	/* FIXME: should use _PEB as parameter for NT 3.5 programs !
 	 * Dunno about other OSs */
         ExitProcess( entry(NULL) );
@@ -563,10 +565,6 @@
     info->hThread     = req->thandle;
     info->dwThreadId  = (DWORD)req->tid;
 
-    if ((flags & (DEBUG_PROCESS|DEBUG_ONLY_THIS_PROCESS)) ||
-        ((parent->flags & PDB32_DEBUGGED) && !(flags & DEBUG_ONLY_THIS_PROCESS)))
-        pdb->flags |= PDB32_DEBUGGED;
-
     if (pModule->module32)   /* Win32 process */
     {
         IMAGE_OPTIONAL_HEADER *header = &PE_HEADER(pModule->module32)->OptionalHeader;
diff --git a/server/process.c b/server/process.c
index 9d01b5f..ddd8226 100644
--- a/server/process.c
+++ b/server/process.c
@@ -366,6 +366,7 @@
 static void get_process_info( struct process *process, struct get_process_info_request *req )
 {
     req->pid              = process;
+    req->debugged         = (process->debugger != 0);
     req->exit_code        = process->exit_code;
     req->priority         = process->priority;
     req->process_affinity = process->affinity;
@@ -398,6 +399,11 @@
         set_error( STATUS_INVALID_PARAMETER );
         return;
     }
+    if (!thread)  /* process is dead */
+    {
+        set_error( STATUS_ACCESS_DENIED );
+        return;
+    }
     suspend_thread( thread, 0 );
     if (thread->attached)
     {
@@ -439,6 +445,11 @@
         set_error( STATUS_INVALID_PARAMETER );
         return;
     }
+    if (!thread)  /* process is dead */
+    {
+        set_error( STATUS_ACCESS_DENIED );
+        return;
+    }
     suspend_thread( thread, 0 );
     if (thread->attached)
     {
@@ -591,6 +602,7 @@
     release_object( process->init_event );
     process->init_event = NULL;
     if (current->suspend + current->process->suspend > 0) stop_thread( current );
+    req->debugged = (current->process->debugger != 0);
 }
 
 /* open a handle to a process */
diff --git a/server/trace.c b/server/trace.c
index 79ffa2e..2bdecde 100644
--- a/server/trace.c
+++ b/server/trace.c
@@ -262,6 +262,11 @@
     fprintf( stderr, " entry=%p", req->entry );
 }
 
+static void dump_init_process_done_reply( const struct init_process_done_request *req )
+{
+    fprintf( stderr, " debugged=%d", req->debugged );
+}
+
 static void dump_init_thread_request( const struct init_thread_request *req )
 {
     fprintf( stderr, " unix_pid=%d,", req->unix_pid );
@@ -300,6 +305,7 @@
 static void dump_get_process_info_reply( const struct get_process_info_request *req )
 {
     fprintf( stderr, " pid=%p,", req->pid );
+    fprintf( stderr, " debugged=%d,", req->debugged );
     fprintf( stderr, " exit_code=%d,", req->exit_code );
     fprintf( stderr, " priority=%d,", req->priority );
     fprintf( stderr, " process_affinity=%d,", req->process_affinity );
@@ -1329,7 +1335,7 @@
     (dump_func)dump_new_thread_reply,
     (dump_func)0,
     (dump_func)dump_init_process_reply,
-    (dump_func)0,
+    (dump_func)dump_init_process_done_reply,
     (dump_func)0,
     (dump_func)dump_get_thread_buffer_reply,
     (dump_func)0,
diff --git a/win32/except.c b/win32/except.c
index e1ed667..0f2fe0d 100644
--- a/win32/except.c
+++ b/win32/except.c
@@ -34,7 +34,6 @@
 #include "process.h"
 #include "thread.h"
 #include "stackframe.h"
-#include "debugger.h"
 #include "debugtools.h"
 
 DEFAULT_DEBUG_CHANNEL(seh)
@@ -73,7 +72,9 @@
     char message[80];
     PDB *pdb = PROCESS_Current();
 
-    if (pdb->flags & PDB32_DEBUGGED) return EXCEPTION_CONTINUE_SEARCH;
+    if (DEBUG_SendExceptionEvent( epointers->ExceptionRecord, FALSE,
+                                  epointers->ContextRecord ) == DBG_CONTINUE)
+        return EXCEPTION_CONTINUE_EXECUTION;
 
     if (pdb->top_filter)
     {
@@ -81,11 +82,6 @@
         if (ret != EXCEPTION_CONTINUE_SEARCH) return ret;
     }
 
-    /* FIXME: does not belong here */
-    if (wine_debugger( epointers->ExceptionRecord,
-                       epointers->ContextRecord, FALSE ) == DBG_CONTINUE)
-        return EXCEPTION_CONTINUE_EXECUTION;
-
     /* FIXME: Should check the current error mode */
 
     sprintf( message, "Unhandled exception 0x%08lx at address 0x%08lx.",
diff --git a/win32/newfns.c b/win32/newfns.c
index 86bc23a..efb40d3 100644
--- a/win32/newfns.c
+++ b/win32/newfns.c
@@ -294,15 +294,6 @@
 }
 
 /******************************************************************************
- * IsDebuggerPresent [KERNEL32.827]
- *
- */
-BOOL WINAPI IsDebuggerPresent() {
-	FIXME(" ... no debuggers yet, returning FALSE.\n");
-	return FALSE; 
-}
-
-/******************************************************************************
  * OpenDesktop32A [USER32.408]
  *
  * NOTES