Set or clear the BeingDebugged flag in the PEB when a debugger is
attached to or detached from a process.
Don't send exception events to the server unless a debugger is
present.

diff --git a/server/debugger.c b/server/debugger.c
index 5670617..e7c1b9a 100644
--- a/server/debugger.c
+++ b/server/debugger.c
@@ -436,6 +436,12 @@
         resume_process( process );
         return 0;
     }
+    if (!set_process_debug_flag( process, 1 ))
+    {
+        process->debugger = NULL;
+        resume_process( process );
+        return 0;
+    }
     return 1;
 
  error:
@@ -480,8 +486,7 @@
 
     /* remove relationships between process and its debugger */
     process->debugger = NULL;
-    release_object( debugger->debug_ctx );
-    debugger->debug_ctx = NULL;
+    if (!set_process_debug_flag( process, 0 )) clear_error();  /* ignore error */
     detach_process( process );
 
     /* from this function */
diff --git a/server/process.c b/server/process.c
index 7be8afd..fd96614 100644
--- a/server/process.c
+++ b/server/process.c
@@ -271,6 +271,7 @@
     process->idle_event      = NULL;
     process->queue           = NULL;
     process->atom_table      = NULL;
+    process->peb             = NULL;
     process->ldt_copy        = NULL;
     process->exe.next        = NULL;
     process->exe.prev        = NULL;
@@ -720,30 +721,6 @@
 }
 
 
-/* get all information about a process */
-static void get_process_info( struct process *process, struct get_process_info_reply *reply )
-{
-    reply->pid              = get_process_id( process );
-    reply->debugged         = (process->debugger != 0);
-    reply->exit_code        = process->exit_code;
-    reply->priority         = process->priority;
-    reply->process_affinity = process->affinity;
-    reply->system_affinity  = 1;
-}
-
-/* set all information about a process */
-static void set_process_info( struct process *process,
-                              const struct set_process_info_request *req )
-{
-    if (req->mask & SET_PROCESS_INFO_PRIORITY)
-        process->priority = req->priority;
-    if (req->mask & SET_PROCESS_INFO_AFFINITY)
-    {
-        if (req->affinity != 1) set_error( STATUS_INVALID_PARAMETER );
-        else process->affinity = req->affinity;
-    }
-}
-
 /* read data from a process memory space */
 /* len is the total size (in ints) */
 static int read_process_memory( struct process *process, const int *addr, size_t len, int *dest )
@@ -788,17 +765,18 @@
 /* write data to a process memory space */
 /* len is the total size (in ints), max is the size we can actually read from the input buffer */
 /* we check the total size for write permissions */
-static void write_process_memory( struct process *process, int *addr, size_t len,
-                                  unsigned int first_mask, unsigned int last_mask, const int *src )
+static int write_process_memory( struct process *process, int *addr, size_t len,
+                                 unsigned int first_mask, unsigned int last_mask, const int *src )
 {
     struct thread *thread = process->thread_list;
+    int ret = 0;
 
     assert( !((unsigned int)addr % sizeof(int) ));  /* address must be aligned */
 
     if (!thread)  /* process is dead */
     {
         set_error( STATUS_ACCESS_DENIED );
-        return;
+        return 0;
     }
     if (suspend_for_ptrace( thread ))
     {
@@ -823,10 +801,23 @@
 
         /* last word is special too */
         if (write_thread_int( thread, addr, *src, last_mask ) == -1) goto done;
+        ret = 1;
 
     done:
         resume_after_ptrace( thread );
     }
+    return ret;
+}
+
+/* set the debugged flag in the process PEB */
+int set_process_debug_flag( struct process *process, int flag )
+{
+    int mask = 0, data = 0;
+
+    /* BeingDebugged flag is the byte at offset 2 in the PEB */
+    memset( (char *)&mask + 2, 0xff, 1 );
+    memset( (char *)&data + 2, flag, 1 );
+    return write_process_memory( process, process->peb, 1, mask, mask, &data );
 }
 
 /* take a snapshot of currently running processes */
@@ -965,7 +956,18 @@
         fatal_protocol_error( current, "init_process: called twice\n" );
         return;
     }
+    if (!req->peb || (unsigned int)req->peb % sizeof(int))
+    {
+        fatal_protocol_error( current, "init_process: bad peb address\n" );
+        return;
+    }
+    if (!req->ldt_copy || (unsigned int)req->ldt_copy % sizeof(int))
+    {
+        fatal_protocol_error( current, "init_process: bad ldt_copy address\n" );
+        return;
+    }
     reply->info_size = 0;
+    current->process->peb = req->peb;
     current->process->ldt_copy = req->ldt_copy;
     current->process->startup_info = init_process( reply );
 }
@@ -1002,7 +1004,7 @@
 
     if (req->gui) process->idle_event = create_event( NULL, 0, 1, 0 );
     if (current->suspend + process->suspend > 0) stop_thread( current );
-    reply->debugged = (process->debugger != 0);
+    if (process->debugger) set_process_debug_flag( process, 1 );
 }
 
 /* open a handle to a process */
@@ -1037,7 +1039,11 @@
 
     if ((process = get_process_from_handle( req->handle, PROCESS_QUERY_INFORMATION )))
     {
-        get_process_info( process, reply );
+        reply->pid              = get_process_id( process );
+        reply->exit_code        = process->exit_code;
+        reply->priority         = process->priority;
+        reply->process_affinity = process->affinity;
+        reply->system_affinity  = 1;
         release_object( process );
     }
 }
@@ -1049,7 +1055,12 @@
 
     if ((process = get_process_from_handle( req->handle, PROCESS_SET_INFORMATION )))
     {
-        set_process_info( process, req );
+        if (req->mask & SET_PROCESS_INFO_PRIORITY) process->priority = req->priority;
+        if (req->mask & SET_PROCESS_INFO_AFFINITY)
+        {
+            if (req->affinity != 1) set_error( STATUS_INVALID_PARAMETER );
+            else process->affinity = req->affinity;
+        }
         release_object( process );
     }
 }
diff --git a/server/process.h b/server/process.h
index 10709d4..cd759f2 100644
--- a/server/process.h
+++ b/server/process.h
@@ -76,8 +76,8 @@
     struct atom_table   *atom_table;      /* pointer to local atom table */
     struct token        *token;           /* security token associated with this process */
     struct process_dll   exe;             /* main exe file */
+    void                *peb;             /* PEB address in client address space */
     void                *ldt_copy;        /* pointer to LDT copy in client addr space */
-    void                *ldt_flags;       /* pointer to LDT flags in client addr space */
 };
 
 struct process_snapshot
@@ -107,6 +107,7 @@
 extern struct process *get_process_from_handle( obj_handle_t handle, unsigned int access );
 extern int process_set_debugger( struct process *process, struct thread *thread );
 extern int debugger_detach( struct process* process, struct thread* debugger );
+extern int set_process_debug_flag( struct process *process, int flag );
 
 extern void add_process_thread( struct process *process,
                                 struct thread *thread );
diff --git a/server/protocol.def b/server/protocol.def
index e11111c..384eb24 100644
--- a/server/protocol.def
+++ b/server/protocol.def
@@ -229,6 +229,7 @@
 
 /* Initialize a process; called from the new process context */
 @REQ(init_process)
+    void*        peb;          /* addr of PEB */
     void*        ldt_copy;     /* addr of LDT copy */
 @REPLY
     int          create_flags; /* creation flags */
@@ -257,8 +258,6 @@
     obj_handle_t exe_file;     /* file handle for main exe */
     int          gui;          /* is it a GUI process? */
     VARARG(filename,unicode_str); /* file name of main exe */
-@REPLY
-    int          debugged;     /* being debugged? */
 @END
 
 
@@ -302,7 +301,6 @@
     obj_handle_t handle;           /* process handle */
 @REPLY
     process_id_t pid;              /* server process id */
-    int          debugged;         /* debugged? */
     int          exit_code;        /* process exit code */
     int          priority;         /* priority class */
     int          process_affinity; /* process affinity mask */
diff --git a/server/trace.c b/server/trace.c
index 99ae649..fb93e53 100644
--- a/server/trace.c
+++ b/server/trace.c
@@ -451,6 +451,7 @@
 
 static void dump_init_process_request( const struct init_process_request *req )
 {
+    fprintf( stderr, " peb=%p,", req->peb );
     fprintf( stderr, " ldt_copy=%p", req->ldt_copy );
 }
 
@@ -487,11 +488,6 @@
     dump_varargs_unicode_str( cur_size );
 }
 
-static void dump_init_process_done_reply( const struct init_process_done_reply *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 );
@@ -541,7 +537,6 @@
 static void dump_get_process_info_reply( const struct get_process_info_reply *req )
 {
     fprintf( stderr, " pid=%04x,", 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 );
@@ -2738,7 +2733,7 @@
     (dump_func)0,
     (dump_func)dump_init_process_reply,
     (dump_func)dump_get_startup_info_reply,
-    (dump_func)dump_init_process_done_reply,
+    (dump_func)0,
     (dump_func)dump_init_thread_reply,
     (dump_func)dump_terminate_process_reply,
     (dump_func)dump_terminate_thread_reply,